Merge with mainline.
authorMohnish Anumala <Mohnish_Anumala@Dell.com>
Wed, 16 Dec 2015 00:39:42 +0000 (16:39 -0800)
committerMohnish Anumala <Mohnish_Anumala@Dell.com>
Wed, 16 Dec 2015 00:39:42 +0000 (16:39 -0800)
Conflicts:
.gitreview
commons/integrationtest/pom.xml
commons/parent/pom.xml
features/ovsdb/pom.xml
features/ovsdb/src/main/features/features.xml
features/pom.xml
hwvtepsouthbound/hwvtepsouthbound-api/pom.xml
hwvtepsouthbound/hwvtepsouthbound-artifacts/pom.xml
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/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-it/pom.xml
hwvtepsouthbound/hwvtepsouthbound-karaf/pom.xml
hwvtepsouthbound/pom.xml
integrationtest/pom.xml
library/artifacts/pom.xml
library/features/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/OvsdbClient.java
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/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/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/library/impl/rev141210/LibraryModuleTest.java
library/it/pom.xml
library/it/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestIT.java
library/it/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestTypedIT.java
library/it/src/test/java/org/opendaylight/ovsdb/integrationtest/schema/openvswitch/OpenVSwitchIT.java
library/it/src/test/java/org/opendaylight/ovsdb/lib/it/LibraryIntegrationTestBase.java
library/pom.xml
northbound/pom.xml
northbound/src/main/java/org/opendaylight/ovsdb/northbound/DatabaseResource.java
northbound/src/main/java/org/opendaylight/ovsdb/northbound/NodeResource.java
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV2.java
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3.java
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRow.java
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRows.java
northbound/src/main/java/org/opendaylight/ovsdb/northbound/RowResource.java
northbound/src/main/java/org/opendaylight/ovsdb/northbound/TableResource.java
northbound/src/test/java/org/opendaylight/ovsdb/northbound/NodeResourceTest.java
openstack/net-virt-it/pom.xml
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/SouthboundMapper.java
openstack/net-virt-providers/pom.xml
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/AbstractServiceInstance.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/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/L2ForwardingService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/RoutingService.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/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpResolverMetadata.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpSender.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/GatewayMacResolverService.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/LoadBalancerServiceTest.java
openstack/net-virt-sfc/api/pom.xml
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/artifacts/pom.xml
openstack/net-virt-sfc/features/pom.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/NetvirtSfcProvider.java
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/karaf/pom.xml
openstack/net-virt-sfc/pom.xml
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/LBaaSPoolMemberHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NetworkHandler.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/PortSecurityHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/SouthboundHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/BridgeConfigurationManager.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/GatewayMacResolver.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/SecurityServicesManager.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/UuidUtils.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/BridgeConfigurationManagerImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/EventDispatcherImpl.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/SecurityServicesImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SouthboundImpl.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/SecurityServicesImplTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/TenantNetworkManagerImplTest.java
ovs-sfc/pom.xml
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AbstractDataListener.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AclUtils.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/EventHandler.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/Flows.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/InstanceIdentifierUtils.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsSfcProvider.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsUtils.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfUtils.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcDataListener.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcEvent.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffDataListener.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffUtils.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpDataListener.java
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpHandler.java
pom.xml
schemas/openvswitch/src/main/java/org/opendaylight/ovsdb/schema/openvswitch/Manager.java
southbound/pom.xml
southbound/southbound-api/src/main/yang/ovsdb.yang
southbound/southbound-features/src/main/features/features.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/SouthboundMapper.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/OvsdbNodeUpdateCommand.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/transactions/md/OpenVSwitchUpdateCommand.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/test/java/org/opendaylight/ovsdb/southbound/InstanceIdentifierCodecTest.java
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/OvsdbMonitorCallbackTest.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbSchemaContantsTest.java
southbound/southbound-it/pom.xml
southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/MdsalUtils.java
southbound/southbound-it/src/test/java/org/opendaylight/ovsdb/southbound/it/SouthboundIT.java
utils/mdsal-openflow/pom.xml
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java
utils/mdsal-utils/pom.xml
utils/pom.xml

Signed-off-by: Mohnish Anumala <Mohnish_Anumala@Dell.com>
382 files changed:
.gitreview
README
commons/integrationtest/pom.xml [deleted file]
commons/it/pom.xml [new file with mode: 0644]
commons/parent/pom.xml [deleted file]
commons/parent/src/main/resources/ovsdb_checks.xml [deleted file]
commons/pom.xml
features/ovs-sfc/pom.xml [deleted file]
features/ovs-sfc/src/main/resources/features.xml [deleted file]
features/ovsdb/pom.xml [deleted file]
features/pom.xml
features/src/main/features/features.xml [moved from features/ovsdb/src/main/features/features.xml with 51% similarity]
integrationtest/.gitignore [deleted file]
integrationtest/pom.xml [deleted file]
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestIT.java [deleted file]
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestITTyped.java [deleted file]
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbTestBase.java [deleted file]
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/TestBridge.java [deleted file]
integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/VersionIncompatibleBridge.java [deleted file]
integrationtest/src/test/resources/controller.xml [deleted file]
integrationtest/src/test/resources/exam.properties [deleted file]
integrationtest/src/test/resources/logback.xml [deleted file]
integrationtest/src/test/resources/northbound.yaml [deleted file]
integrationtest/src/test/resources/tomcat-server.xml [deleted file]
northbound/enunciate.xml [deleted file]
northbound/pom.xml [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/DatabaseResource.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/NodeResource.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV2.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRow.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRows.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/RowResource.java [deleted file]
northbound/src/main/java/org/opendaylight/ovsdb/northbound/TableResource.java [deleted file]
northbound/src/main/resources/WEB-INF/web.xml [deleted file]
northbound/src/test/java/org/opendaylight/ovsdb/northbound/NodeResourceTest.java [deleted file]
northbound/src/test/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3Test.java [deleted file]
openstack/net-virt-it/pom.xml
openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/MdsalUtils.java [deleted file]
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/NetvirtITConstants.java
openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundConstants.java [deleted file]
openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundMapper.java [deleted file]
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/AbstractServiceInstance.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/InboundNatService.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/L2ForwardingService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/OutboundNatService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/RoutingService.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/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpResolverMetadata.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpSender.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/GatewayMacResolverService.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/OF13ProviderTest.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/netvirt-acl.yang
openstack/net-virt-sfc/api/src/main/yang/netvirt-classifier.yang
openstack/net-virt-sfc/artifacts/pom.xml
openstack/net-virt-sfc/features/pom.xml
openstack/net-virt-sfc/features/production/pom.xml [new file with mode: 0644]
openstack/net-virt-sfc/features/production/src/main/features/features.xml [new file with mode: 0644]
openstack/net-virt-sfc/features/test/pom.xml [new file with mode: 0644]
openstack/net-virt-sfc/features/test/src/main/features/features.xml [new file with mode: 0644]
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 [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/INetvirtSfcDataProcessor.java [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/INetvirtSfcOF13Provider.java [new file with mode: 0644]
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 [new file with mode: 0644]
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcClassifierListener.java [new file with mode: 0644]
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/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 [new file with mode: 0644]
openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ClassifierUtils.java [new file with mode: 0644]
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 [new file with mode: 0644]
openstack/net-virt-sfc/karaf/pom.xml
openstack/net-virt-sfc/pom.xml
openstack/net-virt/pom.xml
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/AbstractEvent.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/ConfigActivator.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/ConfigInterface.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/FWaasHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/FloatingIPHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.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/NetworkHandler.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/PortHandler.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/RouterHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/SouthboundHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/SubnetHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/BridgeConfigurationManager.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/ConfigurationService.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/GatewayMacResolver.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/NetworkingProvider.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/api/TenantNetworkManager.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/UuidUtils.java [deleted file]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/BridgeConfigurationManagerImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/ConfigurationServiceImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/EventDispatcherImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtils.java [deleted file]
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/OpenstackRouter.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/ProviderNetworkManagerImpl.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/impl/TenantNetworkManagerImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/VlanConfigurationCacheImpl.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/INeutronObject.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewall.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallPolicy.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallRule.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFloatingIP.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancer.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerHealthMonitor.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPool.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPoolMember.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancer_SessionPersistence.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronNetwork.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronNetwork_Segment.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_AllowedAddressPairs.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_ExtraDHCPOption.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_VIFDetail.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter_Interface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter_NetworkReference.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityGroup.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityRule.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnet.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnetIPAllocationPool.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnet_HostRoute.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/Neutron_ID.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/Neutron_IPs.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallPolicyCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallRuleCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFloatingIPCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerHealthMonitorCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerListenerCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerPoolCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerPoolMemberCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronNetworkCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronPortCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronRouterCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSecurityGroupCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSecurityRuleCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSubnetCRUD.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/NeutronCRUDInterfaces.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/AbstractNeutronInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallPolicyInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallRuleInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFloatingIPInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerHealthMonitorInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerListenerInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerPoolInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerPoolMemberInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronNetworkInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronPortInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronRouterInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityGroupInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityRuleInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSubnetInterface.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallPolicyAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallRuleAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFloatingIPAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerHealthMonitorAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerListenerAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerPoolAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerPoolMemberAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronNetworkAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronPortAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronRouterAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSecurityGroupAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSecurityRuleAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSubnetAware.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronFloatingIPChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronIAwareUtil.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronLoadBalancerPoolChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronLoadBalancerPoolMemberChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronNetworkChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronPortChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronRouterChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityGroupDataChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityRuleDataChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSubnetChangeListener.java [new file with mode: 0644]
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/AbstractEventTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/FWaasHandlerTest.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/LBaaSHandlerTest.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/NetworkHandlerTest.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/RouterHandlerTest.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/api/UuidUtilsTest.java [deleted file]
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/ConfigurationServiceImplTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtilsTest.java [deleted file]
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/SecurityGroupCacheManagerImplTest.java [new file with mode: 0644]
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
openstack/pom.xml
ovs-sfc/pom.xml [deleted file]
ovs-sfc/src/main/java/org/opendaylight/controller/config/yang/config/ovssfc_provider/impl/OvsSfcProviderModule.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/controller/config/yang/config/ovssfc_provider/impl/OvsSfcProviderModuleFactory.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AbstractDataListener.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AclUtils.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/EventHandler.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/Flows.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/InstanceIdentifierUtils.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsSfcProvider.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsUtils.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfUtils.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcDataListener.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcEvent.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffDataListener.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffUtils.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpDataListener.java [deleted file]
ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpHandler.java [deleted file]
ovs-sfc/src/main/resources/initial/53-ovssfc-provider.xml [deleted file]
ovs-sfc/src/main/yang/ovssfc-provider-impl.yang [deleted file]
ovs-sfc/src/test/java/org/opendaylight/ovsdb/ovssfc/EventHandlerTest.java [deleted file]
ovs-sfc/src/test/resources/ServiceFunctionAcl.json [deleted file]
ovs-sfc/src/test/resources/ServiceFunctionChains.json [deleted file]
ovs-sfc/src/test/resources/ServiceFunctionForwarders.json [deleted file]
ovs-sfc/src/test/resources/ServiceFunctionPaths.json [deleted file]
ovs-sfc/src/test/resources/ServiceFunctions.json [deleted file]
ovsdb-artifacts/pom.xml
ovsdb-ui/bundle/pom.xml
ovsdb-ui/bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml
ovsdb-ui/module/pom.xml
ovsdb-ui/module/src/main/resources/ovsdb/Graph.js [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/LogicalGraph.js [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/OvsCore.js [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/assets/dhcp.png [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/assets/router.png [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/assets/vm.png [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/css/ovsdb.css [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/css/select2.min.css [new file with mode: 0755]
ovsdb-ui/module/src/main/resources/ovsdb/css/toggle-switch.css [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/index.tpl.html [deleted file]
ovsdb-ui/module/src/main/resources/ovsdb/lib/d3.min.js [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/lib/select2.full.min.js [new file with mode: 0755]
ovsdb-ui/module/src/main/resources/ovsdb/lib/sylvester.js [new file with mode: 0755]
ovsdb-ui/module/src/main/resources/ovsdb/matrix.js [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.controller.js [deleted file]
ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.module.js [deleted file]
ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.services.js [deleted file]
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.constant.js [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.controller.js
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.css [deleted file]
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.directives.js [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.module.js
ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.services.js
ovsdb-ui/module/src/main/resources/ovsdb/spec/ovsdb.spec.js [deleted file]
ovsdb-ui/module/src/main/resources/ovsdb/views/graph_header.tpl.html [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/views/index.tpl.html [new file with mode: 0644]
ovsdb-ui/module/src/main/resources/ovsdb/views/root.tpl.html [moved from ovsdb-ui/module/src/main/resources/ovsdb/root.tpl.html with 97% similarity]
ovsdb-ui/pom.xml
pom.xml
resources/commons/3-Node-Cluster-Setup-Environment-Variables.postman_environment [new file with mode: 0644]
resources/commons/NetvirtSfc.json.postman_collection [new file with mode: 0644]
resources/commons/ODL-Clustering.json.postman_collection [new file with mode: 0644]
resources/commons/OVSDB_Northbound_APIs.json.postman_collection [deleted file]
resources/commons/OVSDB_Northbound_v3_APIs.json.postman_collection [deleted file]
resources/commons/OVSDB_Southbound.postman_collection [deleted file]
resources/commons/Ovsdb-HwvtepSouthbound-Collection.json.postman_collection [new file with mode: 0755]
resources/commons/Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection [new file with mode: 0644]
resources/commons/Ovsdb-Southbound-Collection-for-Single-Node-Cluster.json.postman_collection [new file with mode: 0644]
resources/commons/README
resources/commons/Single-Node-Cluster-Setup-Environment-Variables.postman_environment [new file with mode: 0644]
resources/demo/netvirtsfc-env/README.md [new file with mode: 0755]
resources/demo/netvirtsfc-env/Vagrantfile [new file with mode: 0644]
resources/demo/netvirtsfc-env/bootstrap.sh [new file with mode: 0644]
resources/demo/netvirtsfc-env/checkdemo.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/cleandemo.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/cleanodl.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/demo-asymmetric-chain/rest.py [new file with mode: 0755]
resources/demo/netvirtsfc-env/dpdumpflows.py [new file with mode: 0755]
resources/demo/netvirtsfc-env/dumpflows.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/env.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/flowcount.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/images/asymmetric-sfc-demo.png [new file with mode: 0644]
resources/demo/netvirtsfc-env/infrastructure_launch.py [new file with mode: 0755]
resources/demo/netvirtsfc-env/ovswork.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/pollflows.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/resetcontroller.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/rest-clean.py [new file with mode: 0755]
resources/demo/netvirtsfc-env/setsfc.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/startdemo.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/traceflow.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/utils/hosts [new file with mode: 0644]
resources/demo/netvirtsfc-env/utils/overlay-flows.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/utils/setuphosts.sh [new file with mode: 0755]
resources/demo/netvirtsfc-env/vmclean.sh [new file with mode: 0755]
routemgr/routemgr-api/pom.xml
routemgr/routemgr-impl/pom.xml
utils/config/pom.xml
utils/config/src/test/java/org/opendaylight/ovsdb/utils/config/ConfigPropertiesTest.java
utils/mdsal-node/pom.xml
utils/mdsal-node/src/main/java/org/opendaylight/ovsdb/utils/mdsal/node/StringConvertor.java
utils/mdsal-node/src/test/java/org/opendaylight/ovsdb/utils/mdsal/node/NodeUtilsTest.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-openflow/src/test/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtilsTest.java
utils/mdsal-utils/pom.xml
utils/neutron-utils/pom.xml [new file with mode: 0644]
utils/neutron-utils/src/main/java/org/opendaylight/ovsdb/utils/neutron/utils/NeutronModelsDataStoreHelper.java [new file with mode: 0644]
utils/pom.xml
utils/servicehelper/pom.xml
utils/servicehelper/src/test/java/org/opendaylight/ovsdb/utils/servicehelper/ServiceHelperTest.java
utils/southbound-utils/pom.xml [new file with mode: 0644]
utils/southbound-utils/src/main/java/org/opendaylight/ovsdb/utils/southbound/utils/SouthboundUtils.java [new file with mode: 0644]
utils/southbound-utils/src/test/java/SouthboundUtilsTest.java [new file with mode: 0644]

index 37aef656e5c05e59e613a05b0e2df5894b8186eb..e5e0d6befe0a18b066a29d34f6f68f99bcfb881c 100644 (file)
@@ -3,3 +3,4 @@ host=git.opendaylight.org
 port=29418
 project=ovsdb.git
 defaultbranch=topic/routermanager
+
diff --git a/README b/README
index b4072ea9d92e92991991a88fa7ae8f8a1e397f73..a3a45ae871640ac0a3ec207b374edf3efdb146dd 100644 (file)
--- a/README
+++ b/README
@@ -3,7 +3,6 @@ DIRECTORY ORGANIZATION
 
 - commons
   +-- parent : Contains Parent pom.xml for all the ovsdb modules.
-  +-- integrationtest : Contains the parent pom.xml for all the integrationtest needs.
 
 - distribution : Builds a working controller distribution based on the controller + ovsdb modules and other
                  dependant modules such as openflowplugin
@@ -12,16 +11,10 @@ DIRECTORY ORGANIZATION
 
 - features : This folder contains all the Karaf related files.
 
-- integrationtest : Contains all the PAX-Exam based integrationTests that covers IT for all the modules.
-
 - library : Contains Schema-independent library that is a reference implementation for RFC 7047.
             This module doesn't depend on any of the Opendaylight components.
             This library module can also be used independently in a non-OSGi environment.
 
-- northbound : Provides AD-SAL style Northbound REST APIs.
-               Supports the legacy v2 APIs to provide backward compatibility for Hydrogen Release
-               Also supports the newer v3 APIs to provide schema-independent access to the OVSDB protocol.
-
 - openstack
   +-- net-virt : Handles the Openstack Neutron ML2 and Network Service calls and performs all the logic required
                  for Network Virtualization.
@@ -67,7 +60,7 @@ Pre-requisites : JDK 1.7+, Maven 3+
 
    4. Once karaf has started and you see the Opendaylight ascii art in the console, the last step
       is to start the OVSDB plugin framework with the following command in the karaf console:
-      "feature:install odl-ovsdb-openstack odl-ovsdb-northbound" (without quotation marks).
+      "feature:install odl-ovsdb-openstack" (without quotation marks).
 
    Sample output from Karaf console :
 
@@ -76,8 +69,6 @@ Pre-requisites : JDK 1.7+, Maven 3+
    odl-ovsdb-library                | 1.0.0-SNAPSHOT      | x         | ovsdb-1.0.0-SNAPSHOT                  | OVSDB :: Library
    odl-ovsdb-schema-openvswitch     | 1.0.0-SNAPSHOT      | x         | ovsdb-1.0.0-SNAPSHOT                  | OVSDB :: Schema :: Open_vSwitch
    odl-ovsdb-schema-hardwarevtep    | 1.0.0-SNAPSHOT      | x         | ovsdb-1.0.0-SNAPSHOT                  | OVSDB :: Schema :: hardware_vtep
-   odl-ovsdb-plugin                 | 1.0.0-SNAPSHOT      | x         | ovsdb-1.0.0-SNAPSHOT                  | OpenDaylight :: OVSDB :: Plugin
-   odl-ovsdb-northbound             | 0.6.0-SNAPSHOT      |           | ovsdb-1.0.0-SNAPSHOT                  | OpenDaylight :: OVSDB :: Northbound
    odl-ovsdb-openstack              | 1.0.0-SNAPSHOT      | x         | ovsdb-1.0.0-SNAPSHOT                  | OpenDaylight :: OVSDB :: OpenStack Network Virtual
    odl-ovsdb-ovssfc                 | 0.0.1-SNAPSHOT      |           | ovsdb-0.0.1-SNAPSHOT                  | OpenDaylight :: OVSDB :: OVS Service Function Chai
 
diff --git a/commons/integrationtest/pom.xml b/commons/integrationtest/pom.xml
deleted file mode 100644 (file)
index 3c13a00..0000000
+++ /dev/null
@@ -1,583 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>commons</artifactId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../parent</relativePath>
-  </parent>
-
-  <artifactId>commons.integrationtest</artifactId>
-  <name>${project.artifactId}.parent</name>
-  <version>1.4.0-SNAPSHOT</version>
-  <packaging>pom</packaging>
-  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
-  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
-  <licenses>
-    <license>
-      <name>Eclipse Public License v1.0</name>
-      <url>http://www.eclipse.org/legal/epl-v10.html</url>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>Sam Hague</name>
-      <email>shague@gmail.com</email>
-      <url>https://github.com/shague</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>
-    <!-- Overrides -->
-    <!-- Controller Dependencies for Pax Exam -->
-    <configuration.implementation.version>0.6.0-SNAPSHOT</configuration.implementation.version>
-    <configuration.version>0.6.0-SNAPSHOT</configuration.version>
-    <connectionmanager.version>0.3.0-SNAPSHOT</connectionmanager.version>
-    <containermanager.it.version>0.7.0-SNAPSHOT</containermanager.it.version>
-    <flowprogrammer.northbound.version>0.6.0-SNAPSHOT</flowprogrammer.northbound.version>
-    <forwarding.staticrouting>0.7.0-SNAPSHOT</forwarding.staticrouting>
-    <forwarding.staticrouting.northbound.version>0.6.0-SNAPSHOT</forwarding.staticrouting.northbound.version>
-    <forwardingrulesmanager.implementation.version>0.6.0-SNAPSHOT</forwardingrulesmanager.implementation.version>
-    <hosttracker.api.version>0.7.0-SNAPSHOT</hosttracker.api.version>
-    <hosttracker.implementation.version>0.7.0-SNAPSHOT</hosttracker.implementation.version>
-    <hosttracker.northbound.version>0.6.0-SNAPSHOT</hosttracker.northbound.version>
-    <logging.bridge.version>0.6.0-SNAPSHOT</logging.bridge.version>
-    <routing.dijkstra_implementation.version>0.6.0-SNAPSHOT</routing.dijkstra_implementation.version>
-    <sal.implementation.version>0.6.0-SNAPSHOT</sal.implementation.version>
-    <security.version>0.6.0-SNAPSHOT</security.version>
-    <statistics.northbound.version>0.6.0-SNAPSHOT</statistics.northbound.version>
-    <statisticsmanager.implementation.version>0.6.0-SNAPSHOT</statisticsmanager.implementation.version>
-    <statisticsmanager.version>0.7.0-SNAPSHOT</statisticsmanager.version>
-    <subnets.northbound.version>0.6.0-SNAPSHOT</subnets.northbound.version>
-    <switchmanager.implementation.version>0.6.0-SNAPSHOT</switchmanager.implementation.version>
-    <switchmanager.northbound.version>0.6.0-SNAPSHOT</switchmanager.northbound.version>
-    <topology.northbound.version>0.6.0-SNAPSHOT</topology.northbound.version>
-    <topology.web.version>0.6.0-SNAPSHOT</topology.web.version>
-    <topologymanager.version>0.6.0-SNAPSHOT</topologymanager.version>
-    <usermanager.implementation.version>0.6.0-SNAPSHOT</usermanager.implementation.version>
-    <usermanager.northbound.version>0.2.0-SNAPSHOT</usermanager.northbound.version>
-    <usermanager.version>0.6.0-SNAPSHOT</usermanager.version>
-    <!-- 3rd Party Dependencies -->
-    <yaml.version>1.10</yaml.version>
-  </properties>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.yaml</groupId>
-        <artifactId>snakeyaml</artifactId>
-        <version>${yaml.version}</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <dependencies>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-classic</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-core</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-annotations</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.fasterxml.jackson.jaxrs</groupId>
-      <artifactId>jackson-jaxrs-json-provider</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.fasterxml.jackson.module</groupId>
-      <artifactId>jackson-module-jaxb-annotations</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <!-- Jersey for JAXRS -->
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-server</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-client</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-net</groupId>
-      <artifactId>commons-net</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-collections</groupId>
-      <artifactId>commons-collections</artifactId>
-      <version>1.0</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-fileupload</groupId>
-      <artifactId>commons-fileupload</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>2.3</version>
-    </dependency>
-    <dependency>
-      <groupId>eclipselink</groupId>
-      <artifactId>javax.persistence</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>eclipselink</groupId>
-      <artifactId>javax.resource</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>javax.servlet</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>javax.servlet.jsp</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.gogo.command</artifactId>
-      <version>0.14.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.gogo.runtime</artifactId>
-      <version>0.12.1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.gogo.shell</artifactId>
-      <version>0.10.0</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.cm</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.console</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.ds</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.launcher</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.util</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.osgi</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.osgi.services</artifactId>
-    </dependency>
-    <!-- Gemini Web -->
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.gemini.web.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.gemini.web.extender</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.gemini.web.tomcat</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.kernel.equinox.extensions</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.math</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.osgi</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.osgi.manifest</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.parser.manifest</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-buffer</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-handler</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-transport</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.portlet</groupId>
-      <artifactId>portlet-api</artifactId>
-      <version>2.0</version>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.activation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.annotation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.ejb</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.el</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.mail.glassfish</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.servlet.jsp.jstl</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.servlet.jsp.jstl.impl</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.xml.rpc</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.catalina</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.catalina.ha</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.catalina.tribes</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.coyote</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.el</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.jasper</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.juli.extras</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.tomcat.api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.tomcat.util</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.aopalliance</groupId>
-      <artifactId>com.springsource.org.aopalliance</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.dependencymanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.fileinstall</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore-nio</artifactId>
-      <version>4.2.1</version>
-      <optional>true</optional>
-    </dependency>
-
-    <dependency>
-      <groupId>org.codehaus.enunciate</groupId>
-      <artifactId>enunciate-core-annotations</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.codehaus.jettison</groupId>
-      <artifactId>jettison</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.spec.javax.transaction</groupId>
-      <artifactId>jboss-transaction-api_1.1_spec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-it</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>com.sun.jersey.jersey-servlet</artifactId>
-      <version>${jersey-servlet.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
-      <version>${corsfilter.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.ow2.asm</groupId>
-      <artifactId>asm-all</artifactId>
-      <version>${asm.version}</version>
-    </dependency>
-    <!-- Visual VM hook -->
-    <dependency>
-      <groupId>org.ow2.chameleon.management</groupId>
-      <artifactId>chameleon-mbeans</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>jcl-over-slf4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>log4j-over-slf4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.aop</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.asm</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.beans</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.context</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.context.support</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.expression</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.transaction</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.web.servlet</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-config</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-taglibs</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>virgomirror</groupId>
-      <artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>library</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>openstack.net-virt</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>schema.hardwarevtep</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>schema.openvswitch</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>utils.servicehelper</artifactId>
-    </dependency>
-
-    <!-- Add Pax Exam -->
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-junit4</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-link-mvn</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.url</groupId>
-      <artifactId>pax-url-aether</artifactId>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>properties-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>set-system-properties</goal>
-            </goals>
-            <configuration>
-              <properties>
-                <property>
-                  <name>logback.configurationFile</name>
-                  <!--<value>${project.parent.basedir}/logback.xml</value>-->
-                </property>
-              </properties>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.ops4j.pax.exam</groupId>
-        <artifactId>maven-paxexam-plugin</artifactId>
-        <version>1.2.4</version>
-        <executions>
-          <execution>
-            <id>generate-config</id>
-            <phase>none</phase>
-            <goals>
-              <goal>generate-depends-file</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/commons/it/pom.xml b/commons/it/pom.xml
new file mode 100644 (file)
index 0000000..4063868
--- /dev/null
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>mdsal-it-parent</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.ovsdb</groupId>
+  <artifactId>it</artifactId>
+  <version>1.2.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
+  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
+  <licenses>
+    <license>
+      <name>Eclipse Public License v1.0</name>
+      <url>http://www.eclipse.org/legal/epl-v10.html</url>
+    </license>
+  </licenses>
+  <developers>
+    <developer>
+      <name>Sam Hague</name>
+      <email>shague@gmail.com</email>
+      <url>https://github.com/shague</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>
+
+  <prerequisites>
+    <maven>3.1.1</maven>
+  </prerequisites>
+
+  <profiles>
+    <profile>
+      <id>default</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <properties>
+        <skipITs>true</skipITs>
+      </properties>
+    </profile>
+    <profile>
+      <id>integrationtest</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+      </activation>
+      <properties>
+        <skipITs>false</skipITs>
+      </properties>
+    </profile>
+  </profiles>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.codehaus.sonar-plugins.java</groupId>
+        <artifactId>sonar-jacoco-listeners</artifactId>
+        <version>${sonar-jacoco-listeners.version}</version>
+        <scope>test</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-failsafe-plugin</artifactId>
+        <configuration>
+          <properties>
+            <property>
+              <name>listener</name>
+              <value>org.sonar.java.jacoco.JUnitListener</value>
+            </property>
+          </properties>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>prep-jacoco-agent</id>
+            <phase>pre-integration-test</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target>
+                <copy file="${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar"
+                      tofile="target/exam/jars/org.jacoco.agent.jar" />
+              </target>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/commons/parent/pom.xml b/commons/parent/pom.xml
deleted file mode 100644 (file)
index 5cb6e26..0000000
+++ /dev/null
@@ -1,620 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.odlparent</groupId>
-    <artifactId>odlparent</artifactId>
-    <version>1.6.0-SNAPSHOT</version>
-    <relativePath/>
-  </parent>
-
-  <groupId>org.opendaylight.ovsdb</groupId>
-  <artifactId>commons</artifactId>
-  <name>${project.artifactId}.parent</name>
-  <version>1.4.0-SNAPSHOT</version>
-  <packaging>pom</packaging>
-  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
-  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
-  <licenses>
-    <license>
-      <name>Eclipse Public License v1.0</name>
-      <url>http://www.eclipse.org/legal/epl-v10.html</url>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>Sam Hague</name>
-      <email>shague@gmail.com</email>
-      <url>https://github.com/shague</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>
-
-  <prerequisites>
-    <maven>3.1.1</maven>
-  </prerequisites>
-
-  <properties>
-    <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version>
-    <!-- Surefire/Failsafe Arguments -->
-    <argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
-    <!-- OVSDB Component Versions -->
-    <openstack.netvirt.version>1.2.1-SNAPSHOT</openstack.netvirt.version>
-    <openstack.netvirt.providers.version>1.2.1-SNAPSHOT</openstack.netvirt.providers.version>
-    <ovsdb.features.version>1.2.1-SNAPSHOT</ovsdb.features.version>
-    <ovsdb.library.version>1.2.1-SNAPSHOT</ovsdb.library.version>
-    <ovsdb.northbound.version>0.8.0-SNAPSHOT</ovsdb.northbound.version>
-    <ovsdb.plugin.version>1.2.1-SNAPSHOT</ovsdb.plugin.version>
-    <ovsdb.plugin.compatibility.layer.version>1.2.1-SNAPSHOT</ovsdb.plugin.compatibility.layer.version>
-    <ovsdb.ovssfc.version>0.2.0-SNAPSHOT</ovsdb.ovssfc.version>
-    <ovsdb.utils.config.version>1.2.1-SNAPSHOT</ovsdb.utils.config.version>
-    <ovsdb.utils.mdsal.node.version>1.2.1-SNAPSHOT</ovsdb.utils.mdsal.node.version>
-    <ovsdb.utils.mdsal.openflow.version>1.2.1-SNAPSHOT</ovsdb.utils.mdsal.openflow.version>
-    <ovsdb.utils.servicehelper.version>1.2.1-SNAPSHOT</ovsdb.utils.servicehelper.version>
-    <plugin.shell.version>1.2.1-SNAPSHOT</plugin.shell.version>
-    <schema.hardwarevtep.version>1.2.1-SNAPSHOT</schema.hardwarevtep.version>
-    <schema.openvswitch.version>1.2.1-SNAPSHOT</schema.openvswitch.version>
-    <!-- Skip Coverage and IT by default -->
-    <skip.coverage>true</skip.coverage>
-    <skip.distribution>false</skip.distribution>
-    <skip.integrationtest>true</skip.integrationtest>
-    <skip.karaf.featureTest>false</skip.karaf.featureTest>
-    <!-- The directory where maven was executed TODO see if this can be removed -->
-    <root.directory>${env.PWD}</root.directory>
-    <!-- IT report is aggregated to enable PAX Exam coverage to be logged -->
-    <sonar.jacoco.itReportPath>${root.directory}/target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
-    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
-    <!-- ODL Dependency Versions -->
-    <containermanager.version>0.7.0-SNAPSHOT</containermanager.version>
-    <controller.config.version>0.4.0-SNAPSHOT</controller.config.version>
-    <forwardingrulesmanager.version>0.8.0-SNAPSHOT</forwardingrulesmanager.version>
-    <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
-    <networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
-    <northbound.commons.version>0.6.0-SNAPSHOT</northbound.commons.version>
-    <nsf.version>0.6.0-SNAPSHOT</nsf.version>
-    <odl.karaf.base.version>1.6.0-SNAPSHOT</odl.karaf.base.version>
-    <odlparent.version>1.6.0-SNAPSHOT</odlparent.version>
-    <openflowjava-nicira.version>0.2.0-SNAPSHOT</openflowjava-nicira.version>
-    <openflowjava-extension.version>0.2.0-SNAPSHOT</openflowjava-extension.version>
-    <openflowjava.version>0.7.0-SNAPSHOT</openflowjava.version>
-    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
-    <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>
-    <powermock.version>1.5.2</powermock.version>
-    <ovsdb.ui.version>0.1.0-SNAPSHOT</ovsdb.ui.version>
-    <dlux.loader.version>0.3.0-SNAPSHOT</dlux.loader.version>
-    <dlux.core.version>0.3.0-SNAPSHOT</dlux.core.version>
-  </properties>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.opendaylight.mdsal</groupId>
-        <artifactId>mdsal-artifacts</artifactId>
-        <version>2.0.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.mdsal.model</groupId>
-        <artifactId>mdsal-model-artifacts</artifactId>
-        <version>0.8.0-SNAPSHOT</version>
-        <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>
-        <version>${networkconfig.neutron.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>opendaylight-karaf-empty</artifactId>
-        <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>
-        <artifactId>yangtools-artifacts</artifactId>
-        <version>${yangtools.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>config-artifacts</artifactId>
-        <version>${controller.config.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>mdsal-artifacts</artifactId>
-        <version>${mdsal.version}</version>
-        <scope>import</scope>
-        <type>pom</type>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowjava</groupId>
-        <artifactId>openflowjava-artifacts</artifactId>
-        <version>${openflowjava.version}</version>
-        <type>pom</type>
-        <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>
-        <version>${openflowplugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin.model</groupId>
-        <artifactId>model-flow-service</artifactId>
-        <version>${openflowplugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin.model</groupId>
-        <artifactId>model-flow-statistics</artifactId>
-        <version>${openflowplugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.odlparent</groupId>
-        <artifactId>features-test</artifactId>
-        <version>${odlparent.version}</version>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin</groupId>
-        <artifactId>openflowplugin</artifactId>
-        <version>${openflowplugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin</groupId>
-        <artifactId>openflowjava-extension-nicira</artifactId>
-        <version>${openflowjava-nicira.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin</groupId>
-        <artifactId>openflowjava-extension-nicira-api</artifactId>
-        <version>${openflowjava-nicira.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin</groupId>
-        <artifactId>openflowplugin-extension-api</artifactId>
-        <version>${openflowplugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin</groupId>
-        <artifactId>openflowplugin-extension-nicira</artifactId>
-        <version>${openflowplugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.openflowplugin</groupId>
-        <artifactId>openflowplugin-extension-nicira-config</artifactId>
-        <version>${openflowplugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>features-ovsdb</artifactId>
-        <version>${ovsdb.features.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>library</artifactId>
-        <version>${ovsdb.library.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>northbound</artifactId>
-        <version>${ovsdb.northbound.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>openstack.net-virt</artifactId>
-        <version>${openstack.netvirt.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>openstack.net-virt-providers</artifactId>
-        <version>${openstack.netvirt.providers.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>ovsdb-plugin-compatibility-layer</artifactId>
-        <version>${ovsdb.plugin.compatibility.layer.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>plugin</artifactId>
-        <version>${ovsdb.plugin.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>plugin-mdsal-adapter</artifactId>
-        <version>${ovsdb.plugin.adapter.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>plugin-shell</artifactId>
-        <version>${plugin.shell.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>schema.hardwarevtep</artifactId>
-        <version>${schema.hardwarevtep.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>schema.openvswitch</artifactId>
-        <version>${schema.openvswitch.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>utils.config</artifactId>
-        <version>${ovsdb.utils.config.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>utils.mdsal-node</artifactId>
-        <version>${ovsdb.utils.mdsal.node.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>utils.mdsal-openflow</artifactId>
-        <version>${ovsdb.utils.mdsal.openflow.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>utils.servicehelper</artifactId>
-        <version>${ovsdb.utils.servicehelper.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.powermock</groupId>
-        <artifactId>powermock-module-junit4</artifactId>
-        <version>${powermock.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.powermock</groupId>
-        <artifactId>powermock-api-mockito</artifactId>
-        <version>${powermock.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.powermock</groupId>
-        <artifactId>powermock-core</artifactId>
-        <version>${powermock.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>ovsdb-ui</artifactId>
-        <version>${ovsdb.ui.version}</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-compiler-plugin</artifactId>
-          <configuration>
-            <source>${java.version.source}</source>
-            <target>${java.version.target}</target>
-            <testSource>${java.version.source}</testSource>
-            <testTarget>${java.version.target}</testTarget>
-          </configuration>
-        </plugin>
-        <!-- This configuration should move to ODL-Parent -->
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>${lifecycle.mapping.version}</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.codehaus.mojo</groupId>
-                    <artifactId>properties-maven-plugin</artifactId>
-                    <versionRange>[0.0,)</versionRange>
-                    <goals>
-                      <goal>set-system-properties</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore></ignore>
-                  </action>
-                </pluginExecution>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.jacoco</groupId>
-                    <artifactId>jacoco-maven-plugin</artifactId>
-                    <versionRange>[0.0,)</versionRange>
-                    <goals>
-                      <goal>prepare-agent</goal>
-                      <goal>pre-test</goal>
-                      <goal>post-test</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore></ignore>
-                  </action>
-                </pluginExecution>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.opendaylight.yangtools</groupId>
-                    <artifactId>yang-maven-plugin</artifactId>
-                    <versionRange>[0.5,)</versionRange>
-                    <goals>
-                      <goal>generate-sources</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <execute></execute>
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-checkstyle-plugin</artifactId>
-          <dependencies>
-            <dependency>
-              <groupId>com.puppycrawl.tools</groupId>
-              <artifactId>checkstyle</artifactId>
-              <version>6.4.1</version>
-            </dependency>
-          </dependencies>
-          <configuration>
-            <configLocation>src/main/resources/ovsdb_checks.xml</configLocation>
-            <failsOnError>true</failsOnError>
-            <includes>**/*.java,**/*.xml,**/*.ini,**/*.sh,**/*.bat</includes>
-            <excludes>**/yang/,**/features/,**/integrationtest/,**/northbound/,
-              **/openstack/,**/ovs-sfc/,
-              **/ovsdb-plugin-compatibility-layer/,
-              **/plugin/,**/plugin-shell/,
-              **/schema/hardwarevtep/,**/schema/openvswitch/,
-              **/southbound/,**/utils/
-            </excludes>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.jacoco</groupId>
-          <artifactId>jacoco-maven-plugin</artifactId>
-          <configuration>
-            <skip>${skip.coverage}</skip>
-          </configuration>
-          <executions>
-            <execution>
-              <id>pre-unit-test</id>
-              <goals>
-                <goal>prepare-agent</goal>
-              </goals>
-              <configuration>
-                <destFile>${sonar.jacoco.reportPath}</destFile>
-              </configuration>
-            </execution>
-            <execution>
-              <id>pre-integration-test</id>
-              <goals>
-                <goal>prepare-agent-integration</goal>
-              </goals>
-              <configuration>
-                <destFile>${sonar.jacoco.itReportPath}</destFile>
-                <append>true</append>
-                <skip>${skip.integrationtest}</skip>
-              </configuration>
-            </execution>
-            <execution>
-              <id>post-unit-test</id>
-              <goals>
-                <goal>report</goal>
-              </goals>
-              <configuration>
-                <dataFile>${sonar.jacoco.reportPath}</dataFile>
-              </configuration>
-            </execution>
-            <execution>
-              <id>post-integration-test</id>
-              <goals>
-                <goal>report-integration</goal>
-              </goals>
-              <configuration>
-                <dataFile>${sonar.jacoco.itReportPath}</dataFile>
-                <skip>${skip.integrationtest}</skip>
-              </configuration>
-            </execution>
-          </executions>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-surefire-plugin</artifactId>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-failsafe-plugin</artifactId>
-          <executions>
-            <execution>
-              <id>failsafe-integration-tests</id>
-              <goals>
-                <goal>integration-test</goal>
-                <goal>verify</goal>
-              </goals>
-              <configuration>
-                <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
-                <skipTests>${skip.integrationtest}</skipTests>
-              </configuration>
-            </execution>
-          </executions>
-        </plugin>
-        <plugin>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-maven-plugin</artifactId>
-          <version>${yangtools.version}</version>
-          <executions>
-            <execution>
-              <goals>
-                <goal>generate-sources</goal>
-              </goals>
-              <configuration>
-                <!-- directory containing yang files to parse and generate code -->
-                <yangFilesRootDir>src/main/yang</yangFilesRootDir>
-                <codeGenerators>
-                  <generator>
-                    <codeGeneratorClass>
-                      org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
-                    </codeGeneratorClass>
-                    <!-- directory into which generated files will be placed -->
-                    <outputBaseDir>
-                      target/generated-sources/sal
-                    </outputBaseDir>
-                  </generator>
-                </codeGenerators>
-                <inspectDependencies>true</inspectDependencies>
-              </configuration>
-            </execution>
-          </executions>
-          <dependencies>
-            <dependency>
-              <groupId>org.opendaylight.mdsal</groupId>
-              <artifactId>maven-sal-api-gen-plugin</artifactId>
-              <version>${yangtools.version}</version>
-              <type>jar</type>
-            </dependency>
-          </dependencies>
-        </plugin>
-        <plugin>
-          <groupId>org.codehaus.mojo</groupId>
-          <artifactId>build-helper-maven-plugin</artifactId>
-          <version>1.7</version>
-          <executions>
-            <execution>
-              <phase>generate-sources</phase>
-              <goals>
-                <goal>add-source</goal>
-              </goals>
-              <configuration>
-                <sources>
-                  <source>target/generated-sources/sal</source>
-                </sources>
-              </configuration>
-            </execution>
-          </executions>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-  </build>
-
-  <profiles>
-    <profile>
-      <id>integrationtest</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <properties>
-        <skip.integrationtest>false</skip.integrationtest>
-      </properties>
-    </profile>
-    <profile>
-      <id>coverage</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <properties>
-        <skip.coverage>false</skip.coverage>
-      </properties>
-    </profile>
-    <profile>
-      <id>jenkins</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <properties>
-        <skip.distribution>true</skip.distribution>
-        <root.directory>${env.WORKSPACE}</root.directory>
-      </properties>
-    </profile>
-    <profile>
-      <id>karaf</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <properties>
-        <skip.karaf.featureTest>false</skip.karaf.featureTest>
-      </properties>
-    </profile>
-  </profiles>
-</project>
diff --git a/commons/parent/src/main/resources/ovsdb_checks.xml b/commons/parent/src/main/resources/ovsdb_checks.xml
deleted file mode 100644 (file)
index daf4a17..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE module PUBLIC
-          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
-          "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-
-<!--
-
-    Checkstyle configuration that checks the Google coding conventions from:
-
-    -  Google Java Style
-       https://google-styleguide.googlecode.com/svn-history/r130/trunk/javaguide.html
-
-    Checkstyle is very configurable. Be sure to read the documentation at
-    http://checkstyle.sf.net (or in your downloaded distribution).
-
-    Most Checks are configurable, be sure to consult the documentation.
-
-    To completely disable a check, just comment it out or delete it from the file.
-
-    Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
-
- -->
-
-<module name = "Checker">
-    <property name="charset" value="UTF-8"/>
-    <!-- Change to error to fail the build. Having severity here
-         ignores the FailsOnError setting in the pom.xml -->
-    <property name="severity" value="error"/>
-
-    <!-- Checks for whitespace                               -->
-    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
-        <module name="FileTabCharacter">
-            <property name="eachLine" value="true"/>
-        </module>
-
-    <module name="SuppressWarningsFilter"/>
-    <module name="TreeWalker">
-        <module name="SuppressWarningsHolder"/>
-        <module name="UnusedImports"/>
-        <module name="OuterTypeFilename"/>
-        <module name="IllegalTokenText">
-            <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
-            <property name="format" value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
-            <property name="message" value="Avoid using corresponding octal or Unicode escape."/>
-        </module>
-    <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-        <module name="AvoidEscapedUnicodeCharacters">
-            <property name="allowEscapesForControlCharacters" value="true"/>
-            <property name="allowByTailComment" value="true"/>
-            <property name="allowNonPrintableEscapes" value="true"/>
-        </module>
-    -->
-        <module name="LineLength">
-            <property name="max" value="120"/><!-- ODL projects use 120 max line length -->
-            <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
-        </module>
-        <module name="AvoidStarImport"/>
-    <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-        <module name="OneTopLevelClass"/>
-        <module name="NoLineWrap"/>
-    -->
-        <module name="EmptyBlock">
-            <property name="option" value="TEXT"/>
-            <property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
-        </module>
-        <module name="NeedBraces"/>
-        <module name="LeftCurly">
-            <property name="maxLineLength" value="100"/>
-        </module>
-        <module name="RightCurly"/>
-        <module name="RightCurly">
-            <property name="option" value="alone"/>
-            <property name="tokens" value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, STATIC_INIT, INSTANCE_INIT"/>
-        </module>
-        <module name="WhitespaceAround">
-            <property name="allowEmptyConstructors" value="true"/>
-            <property name="allowEmptyMethods" value="true"/>
-        <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-            <property name="allowEmptyTypes" value="true"/>
-            <property name="allowEmptyLoops" value="true"/>
-        -->
-            <message key="ws.notFollowed"
-             value="WhitespaceAround: ''{0}'' is not followed by whitespace."/>
-             <message key="ws.notPreceded"
-             value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
-        </module>
-        <module name="OneStatementPerLine"/>
-        <module name="MultipleVariableDeclarations"/>
-        <module name="ArrayTypeStyle"/>
-        <module name="MissingSwitchDefault"/>
-        <module name="FallThrough"/>
-        <module name="UpperEll"/>
-        <module name="ModifierOrder"/>
-    <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-        <module name="EmptyLineSeparator">
-            <property name="allowNoEmptyLineBetweenFields" value="true"/>
-        </module>
-        <module name="SeparatorWrap">
-            <property name="tokens" value="DOT"/>
-            <property name="option" value="nl"/>
-        </module>
-        <module name="SeparatorWrap">
-            <property name="tokens" value="COMMA"/>
-            <property name="option" value="EOL"/>
-        </module>
-    -->
-        <module name="PackageName">
-            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
-            <message key="name.invalidPattern"
-             value="Package name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-        <module name="TypeName">
-            <message key="name.invalidPattern"
-             value="Type name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-        <module name="MemberName">
-            <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
-            <message key="name.invalidPattern"
-             value="Member name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-        <module name="ParameterName">
-            <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
-            <message key="name.invalidPattern"
-             value="Parameter name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-        <module name="LocalVariableName">
-            <property name="tokens" value="VARIABLE_DEF"/>
-            <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
-        <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-            <property name="allowOneCharVarInForLoop" value="true"/>
-        -->
-            <message key="name.invalidPattern"
-             value="Local variable name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-        <module name="ClassTypeParameterName">
-            <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
-            <message key="name.invalidPattern"
-             value="Class type name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-        <module name="MethodTypeParameterName">
-            <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
-            <message key="name.invalidPattern"
-             value="Method type name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-        <module name="NoFinalizer"/>
-        <module name="GenericWhitespace">
-            <message key="ws.followed"
-             value="GenericWhitespace ''{0}'' is followed by whitespace."/>
-             <message key="ws.preceded"
-             value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
-             <message key="ws.illegalFollow"
-             value="GenericWhitespace ''{0}'' should followed by whitespace."/>
-             <message key="ws.notPreceded"
-             value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
-        </module>
-        <module name="Indentation">
-            <property name="basicOffset" value="4"/>
-            <property name="braceAdjustment" value="0"/>
-            <property name="caseIndent" value="4"/>
-            <property name="throwsIndent" value="4"/>
-        <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-            <property name="lineWrappingIndentation" value="4"/>
-            <property name="arrayInitIndent" value="4"/>
-        -->
-        </module>
-    <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-        <module name="AbbreviationAsWordInName">
-            <property name="ignoreFinal" value="false"/>
-            <property name="allowedAbbreviationLength" value="1"/>
-        </module>
-        <module name="OverloadMethodsDeclarationOrder"/>
-        <module name="VariableDeclarationUsageDistance"/>
-        <module name="CustomImportOrder">
-            <property name="thirdPartyPackageRegExp" value=".*"/>
-            <property name="specialImportsRegExp" value="com.google"/>
-            <property name="sortImportsInGroupAlphabetically" value="true"/>
-            <property name="customImportOrderRules" value="STATIC###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE"/>
-        </module>
-    -->
-        <module name="MethodParamPad"/>
-        <module name="OperatorWrap">
-            <property name="option" value="NL"/>
-            <property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/>
-        </module>
-    <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-        <module name="AnnotationLocation">
-            <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
-        </module>
-        <module name="AnnotationLocation">
-            <property name="tokens" value="VARIABLE_DEF"/>
-            <property name="allowSamelineMultipleAnnotations" value="true"/>
-        </module>
-        <module name="NonEmptyAtclauseDescription"/>
-        <module name="JavadocTagContinuationIndentation"/>
-        <module name="SummaryJavadocCheck">
-            <property name="forbiddenSummaryFragments" value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
-        </module>
-        <module name="JavadocParagraph"/>
-        <module name="AtclauseOrder">
-            <property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
-            <property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
-        </module>
-    -->
-        <!--sh<module name="JavadocMethod">
-            <property name="scope" value="public"/>
-            <property name="allowMissingParamTags" value="true"/>
-            <property name="allowMissingThrowsTags" value="true"/>
-            <property name="allowMissingReturnTag" value="true"/>sh-->
-        <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-            <property name="minLineCount" value="2"/>
-            <property name="allowedAnnotations" value="Override, Test"/>
-        -->
-            <!--sh<property name="allowThrowsTagsForSubclasses" value="true"/>
-        </module>-->
-        <module name="MethodName">
-            <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
-            <message key="name.invalidPattern"
-             value="Method name ''{0}'' must match pattern ''{1}''."/>
-        </module>
-    <!-- Not yet supported https://jira.codehaus.org/browse/MCHECKSTYLE-261
-        <module name="SingleLineJavadoc"/>
-    -->
-
-    </module>
-
-    <!--<module name="RegexpHeader">
-        <property name="headerFile" value="${checkstyle.header.file}"/>
-        <property name="multiLines" value="2"/>
-    </module>-->
-</module>
index 54170414a3ba04eeb85794e57f15cdd3e0866e9d..daf34731c7c78ed0c774a1b1e1bbd1064b0297f6 100644 (file)
@@ -12,12 +12,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>parents</artifactId>
   <version>1.2.1-SNAPSHOT</version>
   <name>${project.artifactId}</name>
@@ -48,7 +49,26 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <maven>3.1.1</maven>
   </prerequisites>
   <modules>
-    <module>integrationtest</module>
-    <module>parent</module>
+    <module>it</module>
   </modules>
+
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/features/ovs-sfc/pom.xml b/features/ovs-sfc/pom.xml
deleted file mode 100644 (file)
index da573b4..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>commons</artifactId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../../commons/parent</relativePath>
-  </parent>
-
-  <artifactId>features-ovs-sfc</artifactId>
-  <version>0.2.0-SNAPSHOT</version>
-  <packaging>jar</packaging>
-  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
-  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
-  <licenses>
-    <license>
-      <name>Eclipse Public License v1.0</name>
-      <url>http://www.eclipse.org/legal/epl-v10.html</url>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>Sam Hague</name>
-      <email>shague@gmail.com</email>
-      <url>https://github.com/shague</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>
-    <features.file>features.xml</features.file>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>opendaylight-karaf-empty</artifactId>
-      <type>zip</type>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.odlparent</groupId>
-      <artifactId>features-test</artifactId>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <resources>
-      <resource>
-        <filtering>true</filtering>
-        <directory>src/main/resources</directory>
-      </resource>
-    </resources>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>attach-artifacts</id>
-            <goals>
-              <goal>attach-artifact</goal>
-            </goals>
-            <phase>package</phase>
-            <configuration>
-              <artifacts>
-                <artifact>
-                  <file>${project.build.directory}/classes/${features.file}</file>
-                  <type>xml</type>
-                  <classifier>features</classifier>
-                </artifact>
-              </artifacts>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <skip>${skip.karaf.featureTest}</skip>
-          <systemPropertyVariables>
-            <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
-            <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
-            <karaf.distro.version>1.6.0-SNAPSHOT</karaf.distro.version>
-          </systemPropertyVariables>
-          <dependenciesToScan>
-           <dependency>org.opendaylight.odlparent:features-test</dependency>
-          </dependenciesToScan>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/features/ovs-sfc/src/main/resources/features.xml b/features/ovs-sfc/src/main/resources/features.xml
deleted file mode 100644 (file)
index 404a0df..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<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">
-
-  <feature name="odl-ovsdb-ovssfc"
-           description="OpenDaylight :: OVSDB :: OVS Service Function Chaining"
-           version='${ovsdb.ovssfc.version}'>
-  </feature>
-</features>
diff --git a/features/ovsdb/pom.xml b/features/ovsdb/pom.xml
deleted file mode 100644 (file)
index 1d480d7..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.odlparent</groupId>
-    <artifactId>features-parent</artifactId>
-    <version>1.6.0-SNAPSHOT</version>
-    <relativePath></relativePath>
-  </parent>
-
-  <groupId>org.opendaylight.ovsdb</groupId>
-  <artifactId>features-ovsdb</artifactId>
-  <version>1.2.1-SNAPSHOT</version>
-  <packaging>jar</packaging>
-  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
-  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
-  <licenses>
-    <license>
-      <name>Eclipse Public License v1.0</name>
-      <url>http://www.eclipse.org/legal/epl-v10.html</url>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>Sam Hague</name>
-      <email>shague@gmail.com</email>
-      <url>https://github.com/shague</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>
-    <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>
-    <openstack.netvirt.providers.version>1.2.1-SNAPSHOT</openstack.netvirt.providers.version>
-    <ovsdb.plugin.version>1.2.1-SNAPSHOT</ovsdb.plugin.version>
-    <ovsdb.plugin.compatibility.layer.version>1.2.1-SNAPSHOT</ovsdb.plugin.compatibility.layer.version>
-    <ovsdb.utils.servicehelper.version>1.2.1-SNAPSHOT</ovsdb.utils.servicehelper.version>
-    <plugin.shell.version>1.2.1-SNAPSHOT</plugin.shell.version>
-    <schema.hardwarevtep.version>1.2.1-SNAPSHOT</schema.hardwarevtep.version>
-    <schema.openvswitch.version>1.2.1-SNAPSHOT</schema.openvswitch.version>
-    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
-    <sal.version>0.10.0-SNAPSHOT</sal.version>
-    <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
-    <dlux.core.version>0.3.0-SNAPSHOT</dlux.core.version>
-    <ovsdb.ui.version>0.1.0-SNAPSHOT</ovsdb.ui.version>
-    <config.version>0.4.0-SNAPSHOT</config.version>
-  </properties>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.opendaylight.yangtools</groupId>
-        <artifactId>yangtools-artifacts</artifactId>
-        <version>${yangtools.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>mdsal-artifacts</artifactId>
-        <version>${mdsal.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-  <dependencies>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.compendium</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.dependencymanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-annotations</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <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>
-      <artifactId>netty-all</artifactId>
-      <version>${netty.version}</version>
-    </dependency>
-    <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>
-      <artifactId>org.apache.felix.gogo.command</artifactId>
-      <version>0.8.0.v201108120515</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.apache.felix.gogo.runtime</artifactId>
-      <version>0.8.0.v201108120515</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.apache.felix.gogo.shell</artifactId>
-      <version>0.8.0.v201110170705</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.cm</artifactId>
-      <version>1.0.400.v20120522-1841</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.console</artifactId>
-      <version>1.0.0.v20120522-1841</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.ds</artifactId>
-      <version>1.4.0.v20120522-1841</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.launcher</artifactId>
-      <version>1.3.0.v20120522-1813</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.util</artifactId>
-      <version>1.0.400.v20120522-2049</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.osgi</artifactId>
-      <version>3.8.1.v20120830-144521</version>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.osgi.services</artifactId>
-      <version>3.3.100.v20120522-1822</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.neutron</groupId>
-      <artifactId>features-neutron</artifactId>
-      <version>${networkconfig.neutron.version}</version>
-      <classifier>features</classifier>
-      <type>xml</type>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.openflowplugin</groupId>
-      <artifactId>features-openflowplugin</artifactId>
-      <version>${openflowplugin.version}</version>
-      <classifier>features</classifier>
-      <type>xml</type>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.openflowplugin</groupId>
-      <artifactId>features-openflowplugin-extension</artifactId>
-      <version>${openflowplugin.version}</version>
-      <classifier>features</classifier>
-      <type>xml</type>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>openstack.net-virt</artifactId>
-      <version>${openstack.netvirt.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>openstack.net-virt</artifactId>
-      <version>${openstack.netvirt.version}</version>
-      <type>xml</type>
-      <classifier>config</classifier>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>openstack.net-virt-providers</artifactId>
-      <version>${openstack.netvirt.providers.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>openstack.net-virt-providers</artifactId>
-      <version>${openstack.netvirt.providers.version}</version>
-      <type>xml</type>
-      <classifier>config</classifier>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>schema.openvswitch</artifactId>
-      <version>${schema.openvswitch.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>schema.hardwarevtep</artifactId>
-      <version>${schema.hardwarevtep.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>utils.servicehelper</artifactId>
-      <version>${ovsdb.utils.servicehelper.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>features-mdsal</artifactId>
-      <type>xml</type>
-      <classifier>features</classifier>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>ovsdb-ui-bundle</artifactId>
-      <version>${ovsdb.ui.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>southbound-features</artifactId>
-      <version>${project.version}</version>
-      <type>xml</type>
-      <classifier>features</classifier>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>library-features</artifactId>
-      <version>${ovsdb.library.version}</version>
-      <type>xml</type>
-      <classifier>features</classifier>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>routemgr-features</artifactId>
-      <version>${project.version}</version>
-      <type>xml</type>
-      <classifier>features</classifier>
-    </dependency>
-  </dependencies>
-</project>
index 4ecf374e6becb6d1f520999ed2e6829086eeb0ae..4f87311f8e58b7d1953346f5c0be51b185ae2cf2 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-Copyright (C) 2015 Red Hat, Inc. and others. All rights reserved.
+Copyright (C) 2014 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,
@@ -12,15 +12,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>features-parent</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
-  <artifactId>features</artifactId>
+  <groupId>org.opendaylight.ovsdb</groupId>
+  <artifactId>features-ovsdb</artifactId>
   <version>1.2.1-SNAPSHOT</version>
-  <name>${project.artifactId}</name>
   <packaging>pom</packaging>
   <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
   <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
@@ -44,11 +44,259 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
   </scm>
 
-  <prerequisites>
-    <maven>3.1.1</maven>
-  </prerequisites>
-  <modules>
-    <module>ovs-sfc</module>
-    <module>ovsdb</module>
-  </modules>
+  <properties>
+    <odl.karaf.base.version>1.6.0-SNAPSHOT</odl.karaf.base.version>
+    <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+    <neutron.version>0.6.0-SNAPSHOT</neutron.version>
+    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+    <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
+    <dlux.version>0.3.0-SNAPSHOT</dlux.version>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.opendaylight.yangtools</groupId>
+        <artifactId>yangtools-artifacts</artifactId>
+        <version>${yangtools.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>mdsal-artifacts</artifactId>
+        <version>${mdsal.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <!-- controller dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-mdsal</artifactId>
+      <type>xml</type>
+      <classifier>features</classifier>
+    </dependency>
+    <!-- external dependencies -->
+    <!-- TODO clean up based on what is provided by odlparent -->
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.dependencymanager</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-buffer</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-codec-http</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-handler</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty-transport</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>javax.servlet</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>javax.servlet.jsp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.command</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.runtime</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.apache.felix.gogo.shell</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.cm</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.console</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.ds</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.launcher</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.equinox.util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.osgi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>equinoxSDK381</groupId>
+      <artifactId>org.eclipse.osgi.services</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+    </dependency>
+    <!-- neutron dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.neutron</groupId>
+      <artifactId>features-neutron</artifactId>
+      <version>${neutron.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+     <dependency>
+      <groupId>org.opendaylight.neutron</groupId>
+      <artifactId>dummyprovider</artifactId>
+      <version>${neutron.version}</version>
+    </dependency>
+    <!-- openflowplugin dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin</artifactId>
+      <version>${openflowplugin.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin-extension</artifactId>
+      <version>${openflowplugin.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <!-- project specific dependencies -->
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt-providers</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt-providers</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>schema.openvswitch</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>schema.hardwarevtep</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.servicehelper</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>ovsdb-ui-bundle</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>southbound-features</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>features</classifier>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>library-features</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>features</classifier>
+    </dependency>
+    <!-- DLUX dependency for the UI -->
+    <dependency>
+      <groupId>org.opendaylight.dlux</groupId>
+      <artifactId>features-dlux</artifactId>
+      <version>${dlux.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>routemgr-features</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>features</classifier>
+    </dependency>
+  </dependencies>
 </project>
similarity index 51%
rename from features/ovsdb/src/main/features/features.xml
rename to features/src/main/features/features.xml
index 56daee3484b5b45d59c298adbe2404c990191fc4..6e89f2a63e8d90d7dcb792c428cefd91d910e6b4 100644 (file)
@@ -2,48 +2,53 @@
 <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/routemgr-features/1.2.1-SNAPSHOT/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.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 version="${ovsdb.library.version}">odl-ovsdb-library</feature>
+    <feature version="${project.version}">odl-ovsdb-library</feature>
   </feature>
 
   <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>
+           version='${project.version}'>
+    <feature version="${project.version}">odl-ovsdb-library</feature>
+    <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>
+           version='${project.version}'>
+    <feature version="${project.version}">odl-ovsdb-library</feature>
+    <bundle>mvn:org.opendaylight.ovsdb/schema.hardwarevtep/{{VERSION}}</bundle>
   </feature>
 
   <feature name="odl-ovsdb-openstack" description="OpenDaylight :: OVSDB :: OpenStack Network Virtualization"
-           version='${openstack.netvirt.version}'>
+           version='${project.version}'>
     <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="${neutron.version}">odl-neutron-service</feature>
     <feature version="1.2.1-SNAPSHOT">odl-routemgr-plugin</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>
-    <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.neutron-utils/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.mdsal-utils/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.southbound-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.core.version}">odl-dlux-core</feature>
-    <bundle>mvn:org.opendaylight.ovsdb/ovsdb-ui-bundle/${ovsdb.ui.version}</bundle>
+    <feature version="${dlux.version}">odl-dlux-core</feature>
+    <bundle>mvn:org.opendaylight.ovsdb/ovsdb-ui-bundle/{{VERSION}}</bundle>
   </feature>
 </features>
diff --git a/integrationtest/.gitignore b/integrationtest/.gitignore
deleted file mode 100644 (file)
index b677ad3..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-/target-ide
-PutObjectStoreHere
-ObjectStore
-logs
diff --git a/integrationtest/pom.xml b/integrationtest/pom.xml
deleted file mode 100644 (file)
index c6a9c3d..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>commons.integrationtest</artifactId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/integrationtest</relativePath>
-  </parent>
-
-  <artifactId>integrationtest</artifactId>
-  <version>1.4.0-SNAPSHOT</version>
-  <packaging>jar</packaging>
-  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
-  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
-  <licenses>
-    <license>
-      <name>Eclipse Public License v1.0</name>
-      <url>http://www.eclipse.org/legal/epl-v10.html</url>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>Sam Hague</name>
-      <email>shague@gmail.com</email>
-      <url>https://github.com/shague</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>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-it</artifactId>
-      <scope>test</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>org.ops4j.pax.exam</groupId>
-          <artifactId>pax-exam-container-native</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.model</groupId>
-      <artifactId>model-inventory</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-spi</artifactId>
-      <!-- Should be in a parent POM -->
-      <version>4.4.0</version>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <scope>provided</scope>
-    </dependency>
-
-    <!-- Cache surefire in Maven Local repo for offline builds -->
-    <dependency>
-      <groupId>org.apache.maven.surefire</groupId>
-      <artifactId>surefire-junit4</artifactId>
-      <version>${maven.surefire.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.surefire</groupId>
-      <artifactId>surefire-junit47</artifactId>
-      <version>${maven.surefire.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.eclipse.m2e</groupId>
-          <artifactId>lifecycle-mapping</artifactId>
-          <version>${lifecycle.mapping.version}</version>
-          <configuration>
-            <lifecycleMappingMetadata>
-              <pluginExecutions>
-                <pluginExecution>
-                  <pluginExecutionFilter>
-                    <groupId>org.apache.servicemix.tooling</groupId>
-                    <artifactId>depends-maven-plugin</artifactId>
-                    <versionRange>[0,)</versionRange>
-                    <goals>
-                      <goal>generate-depends-file</goal>
-                    </goals>
-                  </pluginExecutionFilter>
-                  <action>
-                    <ignore/>
-                  </action>
-                </pluginExecution>
-              </pluginExecutions>
-            </lifecycleMappingMetadata>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-    <plugins>
-      <plugin>
-        <groupId>org.ops4j.pax.exam</groupId>
-        <artifactId>maven-paxexam-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>generate-config</id>
-            <goals>
-              <goal>generate-depends-file</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.servicemix.tooling</groupId>
-        <artifactId>depends-maven-plugin</artifactId>
-        <version>1.2</version>
-        <executions>
-          <execution>
-            <id>generate-depends-file</id>
-            <goals>
-              <goal>generate-depends-file</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>failsafe-integration-tests</id>
-            <phase>integration-test</phase>
-            <goals>
-              <goal>integration-test</goal>
-            </goals>
-            <configuration>
-              <forkCount>1</forkCount>
-              <reuseForks>false</reuseForks>
-              <parallel>none</parallel>
-              <threadCount>1</threadCount>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>default</id>
-      <activation>
-        <activeByDefault>true</activeByDefault>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.ops4j.pax.exam</groupId>
-          <artifactId>pax-exam-container-native</artifactId>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>karafit</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>org.ops4j.pax.exam</groupId>
-          <artifactId>pax-exam-container-karaf</artifactId>
-        </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
-</project>
diff --git a/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestIT.java b/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestIT.java
deleted file mode 100644 (file)
index 2903677..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2014 EBay Software Foundation
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Authors : Ashwin Raveendran
- */
-package org.opendaylight.ovsdb.integrationtest.ovsdbclient;
-
-import static org.opendaylight.ovsdb.lib.operations.Operations.op;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.ovsdb.lib.MonitorCallBack;
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
-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.TableUpdate;
-import org.opendaylight.ovsdb.lib.message.TableUpdates;
-import org.opendaylight.ovsdb.lib.message.UpdateNotification;
-import org.opendaylight.ovsdb.lib.notation.Column;
-import org.opendaylight.ovsdb.lib.notation.Mutator;
-import org.opendaylight.ovsdb.lib.notation.Row;
-import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.lib.operations.OperationResult;
-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.TableSchema;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.ListenableFuture;
-
-
-public class OvsdbClientTestIT extends OvsdbTestBase {
-
-    OvsdbClient ovs;
-    DatabaseSchema dbSchema = null;
-    static String testBridgeName = "br-test";
-    static UUID testBridgeUuid = null;
-
-    /**
-     * Test general OVSDB transactions (viz., insert, select, update,
-     * mutate, comment, delete, where, commit) as well as the special
-     * transactions (viz., abort and assert)
-     */
-    @Test
-    public void testTransact() throws IOException, InterruptedException, ExecutionException {
-        Assert.assertNotNull(dbSchema);
-        TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
-
-        createBridgeTransaction();
-        abortTransaction();
-        assertTransaction();
-    }
-
-    /**
-     * Test OVS monitor request and reply, with and without specific column filters,
-     * for the Bridge table in the OVSDB. The setup involves creating a test bridge with 5
-     * flood_vlans and 2 key-value pairs, and monitoring the DB update.
-     */
-    @Test
-    public void testMonitorRequest() throws ExecutionException, InterruptedException, IOException {
-        Assert.assertNotNull(dbSchema);
-        // Create Test Bridge before testing the Monitor operation
-        createBridgeTransaction();
-        sendBridgeMonitorRequest(true); // Test monitor request with Column filters
-        sendBridgeMonitorRequest(false); // Test monitor request without filters
-    }
-
-    public void sendBridgeMonitorRequest(boolean filter) throws ExecutionException, InterruptedException, IOException {
-        Assert.assertNotNull(dbSchema);
-        GenericTableSchema bridge = dbSchema.table("Bridge", GenericTableSchema.class);
-
-        List<MonitorRequest<GenericTableSchema>> 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);
-        MonitorRequestBuilder<GenericTableSchema> builder = MonitorRequestBuilder.builder(bridge);
-        if (filter) {
-            builder.addColumn(bridge.column("name"))
-                   .addColumn(bridge.column("fail_mode", String.class))
-                   .addColumn(flood_vlans)
-                   .addColumn(externalIds);
-        }
-        monitorRequests.add(builder.with(new MonitorSelect(true, true, true, true))
-                                   .build());
-
-        final List<Object> results = Lists.newArrayList();
-
-        TableUpdates updates = ovs.monitor(dbSchema, monitorRequests, new MonitorCallBack() {
-            @Override
-            public void update(TableUpdates result, DatabaseSchema dbSchema) {
-                results.add(result);
-                System.out.println("result = " + result);
-            }
-
-            @Override
-            public void exception(Throwable t) {
-                results.add(t);
-                System.out.println("t = " + t);
-            }
-        });
-        if (updates != null) {
-            results.add(updates);
-        }
-        for (int i = 0; i < 3 ; i++) { //wait 3 seconds to get a result
-            System.out.println("waiting on monitor response for Bridge Table...");
-            if (!results.isEmpty()) {
-                break;
-            }
-            Thread.sleep(1000);
-        }
-
-        Assert.assertTrue(!results.isEmpty());
-        Object result = results.get(0);
-        Assert.assertTrue(result instanceof TableUpdates);
-        updates = (TableUpdates) result;
-        TableUpdate<GenericTableSchema> update = updates.getUpdate(bridge);
-        Assert.assertTrue(update.getRows().size() > 0);
-        for (UUID uuid : update.getRows().keySet()) {
-            Row<GenericTableSchema> aNew = update.getNew(uuid);
-            if (!aNew.getColumn(name).getData().equals(testBridgeName)) {
-                continue;
-            }
-            if (filter) {
-                Assert.assertEquals(builder.getColumns().size(), aNew.getColumns().size());
-            } else {
-                // As per RFC7047, Section 4.1.5 : If "columns" is omitted, all columns in the table, except for "_uuid", are monitored.
-                Assert.assertEquals(bridge.getColumns().size() - 1, aNew.getColumns().size());
-            }
-            for (Column<GenericTableSchema, ?> column: aNew.getColumns()) {
-                if (column.getSchema().equals(flood_vlans)) {
-                    // Test for the 5 flood_vlans inserted in Bridge br-test in createBridgeTransaction
-                    Set<Integer> data = column.getData(flood_vlans);
-                    Assert.assertNotNull(data);
-                    Assert.assertTrue(!data.isEmpty());
-                    Assert.assertEquals(5, data.size());
-                } else if (column.getSchema().equals(externalIds)) {
-                    // Test for the {"key", "value"} external_ids inserted in Bridge br-test in createBridgeTransaction
-                    Map<String, String> data = column.getData(externalIds);
-                    Assert.assertNotNull(data);
-                    Assert.assertNotNull(data.get("key"));
-                    Assert.assertEquals("value", data.get("key"));
-                    // Test for {"key2", "value2"} external_ids mutation-inserted in Bridge br-test in createBridgeTransaction
-                    Assert.assertNotNull(data.get("key2"));
-                    Assert.assertEquals("value2", data.get("key2"));
-                }
-            }
-            return;
-        }
-        Assert.fail("Bridge being monitored :"+testBridgeName+" Not found");
-    }
-
-    /*
-     * TODO : selectOpenVSwitchTableUuid method isn't working as expected due to the Jackson
-     * parsing challenges on the Row object returned by the Select operation.
-     */
-    private UUID selectOpenVSwitchTableUuid() throws ExecutionException, InterruptedException {
-        Assert.assertNotNull(dbSchema);
-        GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
-
-        List<MonitorRequest<GenericTableSchema>> monitorRequests = Lists.newArrayList();
-        ColumnSchema<GenericTableSchema, UUID> _uuid = ovsTable.column("_uuid", UUID.class);
-
-        List<OperationResult> results = ovs.transactBuilder(dbSchema)
-               .add(op.select(ovsTable)
-                      .column(_uuid))
-                      .execute()
-                      .get();
-
-        Assert.assertTrue(!results.isEmpty());
-        OperationResult result = results.get(0);
-        List<Row<GenericTableSchema>> rows = result.getRows();
-        Row<GenericTableSchema> ovsTableRow = rows.get(0);
-        return ovsTableRow.getColumn(_uuid).getData();
-    }
-
-    private void createBridgeTransaction() throws IOException, InterruptedException, ExecutionException {
-        Assert.assertNotNull(dbSchema);
-        TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
-        GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
-
-        ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
-        ColumnSchema<GenericTableSchema, String> fail_mode = bridge.column("fail_mode", String.class);
-        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, Set<UUID>> bridges = ovsTable.multiValuedColumn("bridges", UUID.class);
-        ColumnSchema<GenericTableSchema, UUID> _uuid = ovsTable.column("_uuid", UUID.class);
-
-        String namedUuid = "br_test";
-        int insertOperationIndex = 0;
-        UUID parentTable = selectOpenVSwitchTableUuid();
-        TransactionBuilder transactionBuilder = ovs.transactBuilder(dbSchema)
-                 /*
-                  * Make sure that the position of insert operation matches the insertOperationIndex.
-                  * This will be used later when the Results are processed.
-                  */
-                .add(op.insert(bridge)
-                        .withId(namedUuid)
-                        .value(name, testBridgeName)
-                        .value(flood_vlans, Sets.newHashSet(100, 101, 4001))
-                        .value(externalIds, ImmutableMap.of("key","value")))
-                .add(op.comment("Inserting Bridge br-int"))
-                .add(op.update(bridge)
-                        .set(fail_mode, "secure")
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.select(bridge)
-                        .column(name)
-                        .column(_uuid)
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.mutate(bridge)
-                        .addMutation(flood_vlans, Mutator.INSERT, Sets.newHashSet(200,400))
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.mutate(bridge)
-                        .addMutation(externalIds, Mutator.INSERT, ImmutableMap.of("key2","value2"))
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.mutate(ovsTable)
-                        .addMutation(bridges, Mutator.INSERT, Sets.newHashSet(new UUID(namedUuid)))
-                        .where(_uuid.opEqual(parentTable))
-                        .build())
-                .add(op.commit(true));
-
-        ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
-        List<OperationResult> operationResults = results.get();
-        Assert.assertFalse(operationResults.isEmpty());
-        // Check if Results matches the number of operations in transaction
-        Assert.assertEquals(transactionBuilder.getOperations().size(), operationResults.size());
-        System.out.println("Insert & Update operation results = " + operationResults);
-        for (OperationResult result : operationResults) {
-            Assert.assertNull(result.getError());
-        }
-        testBridgeUuid = operationResults.get(insertOperationIndex).getUuid();
-    }
-
-    private void assertTransaction() throws InterruptedException, ExecutionException {
-        Assert.assertNotNull(dbSchema);
-        TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
-
-        /*
-         * Adding a separate Assert operation in a transaction. Lets not mix this with other
-         * valid transactions as above.
-         */
-        ListenableFuture<List<OperationResult>> results = ovs.transactBuilder(dbSchema)
-                .add(op.delete(bridge)
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.assertion("Assert12345")) // Failing intentionally
-                .execute();
-
-        List<OperationResult> operationResults = results.get();
-        Assert.assertFalse(operationResults.isEmpty());
-        /* Testing for an Assertion Error */
-        Assert.assertFalse(operationResults.get(1).getError() == null);
-        System.out.println("Assert operation results = " + operationResults);
-    }
-
-    private void abortTransaction() throws InterruptedException, ExecutionException {
-        Assert.assertNotNull(dbSchema);
-        TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
-
-        /*
-         * Adding a separate Abort operation in a transaction. Lets not mix this with other
-         * valid transactions as above.
-         */
-        ListenableFuture<List<OperationResult>> results = ovs.transactBuilder(dbSchema)
-                .add(op.delete(bridge)
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.abort())
-                .execute();
-
-        List<OperationResult> operationResults = results.get();
-        Assert.assertFalse(operationResults.isEmpty());
-        /* Testing for Abort Error */
-        Assert.assertFalse(operationResults.get(1).getError() == null);
-        System.out.println("Abort operation results = " + operationResults);
-    }
-
-    public void testGetDBs() throws ExecutionException, InterruptedException {
-        ListenableFuture<List<String>> databases = ovs.getDatabases();
-        List<String> dbNames = databases.get();
-        Assert.assertNotNull(dbNames);
-        boolean hasOpenVswitchSchema = false;
-        for(String dbName : dbNames) {
-           if (dbName.equals(OPEN_VSWITCH_SCHEMA)) {
-                hasOpenVswitchSchema = true;
-                break;
-           }
-        }
-        Assert.assertTrue(OPEN_VSWITCH_SCHEMA+" schema is not supported by the switch", hasOpenVswitchSchema);
-    }
-
-    @Before
-    public  void setUp() throws IOException, ExecutionException, InterruptedException, TimeoutException {
-        if (ovs != null) {
-            return;
-        }
-
-        ovs = getTestConnection();
-        System.out.println("Connection Info :" + ovs.getConnectionInfo().toString());
-        testGetDBs();
-        dbSchema = ovs.getSchema(OPEN_VSWITCH_SCHEMA).get();
-    }
-
-    @After
-    public void tearDown() throws InterruptedException, ExecutionException {
-        if (dbSchema == null) {
-            return;
-        }
-        TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
-        GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, Set<UUID>> bridges = ovsTable.multiValuedColumn("bridges", UUID.class);
-        ColumnSchema<GenericTableSchema, UUID> _uuid = ovsTable.column("_uuid", UUID.class);
-        UUID parentTable = selectOpenVSwitchTableUuid();
-
-        ListenableFuture<List<OperationResult>> results = ovs.transactBuilder(dbSchema)
-                .add(op.delete(bridge)
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.mutate(ovsTable)
-                        .addMutation(bridges, Mutator.DELETE, Sets.newHashSet(testBridgeUuid))
-                        .where(_uuid.opEqual(parentTable))
-                        .build())
-                .add(op.commit(true))
-                .execute();
-
-        List<OperationResult> operationResults = results.get();
-        System.out.println("Delete operation results = " + operationResults);
-        OvsdbConnectionService.getService().disconnect(ovs);
-    }
-
-
-    @Override
-    public void update(Object node, UpdateNotification upadateNotification) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void locked(Object node, List<String> ids) {
-        // TODO Auto-generated method stub
-
-    }
-    @Override
-    public void stolen(Object node, List<String> ids) {
-        // TODO Auto-generated method stub
-
-    }
-}
diff --git a/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestITTyped.java b/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbClientTestITTyped.java
deleted file mode 100644 (file)
index b11a887..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2014 EBay Software Foundation
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Authors : Ashwin Raveendran, Madhu Venugopal
- */
-
-package org.opendaylight.ovsdb.integrationtest.ovsdbclient;
-
-import static org.opendaylight.ovsdb.lib.operations.Operations.op;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.lib.impl.OvsdbConnectionService;
-import org.opendaylight.ovsdb.lib.message.UpdateNotification;
-import org.opendaylight.ovsdb.lib.notation.Mutator;
-import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.lib.operations.OperationResult;
-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.TableSchema;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class OvsdbClientTestITTyped extends OvsdbTestBase {
-
-    OvsdbClient ovs;
-    DatabaseSchema dbSchema = null;
-    static String testBridgeName = "br_test";
-    static UUID testBridgeUuid = null;
-
-    /**
-     * Test creation of statically typed bridge table as defined in
-     * ovs-vswitchd.conf.db with get/set for all relevant columns. The
-     * SETDATA methods for "name", "status" and "flood_vlans" columns
-     * are verified.
-     */
-    @Test
-    public void testTypedBridgeCreate() throws IOException, InterruptedException, ExecutionException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-        TestBridge rBridge = ovs.createTypedRowWrapper(TestBridge.class);
-        rBridge.setName(testBridgeName);
-        rBridge.setStatus(ImmutableMap.of("key","value"));
-        rBridge.setFloodVlans(Sets.newHashSet(34));
-
-        GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, Set<UUID>> bridges = ovsTable.multiValuedColumn("bridges", UUID.class);
-
-        String namedUuid = "br_test";
-        int insertOperationIndex = 0;
-
-        TransactionBuilder transactionBuilder = ovs.transactBuilder(dbSchema)
-                .add(op.insert(rBridge)
-                        .withId(namedUuid))
-                .add(op.mutate(ovsTable)
-                        .addMutation(bridges, Mutator.INSERT, Sets.newHashSet(new UUID(namedUuid))));
-
-        ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
-        List<OperationResult> operationResults = results.get();
-        Assert.assertFalse(operationResults.isEmpty());
-        // Check if Results matches the number of operations in transaction
-        Assert.assertEquals(transactionBuilder.getOperations().size(), operationResults.size());
-        System.out.println("Insert & Update operation results = " + operationResults);
-        testBridgeUuid = operationResults.get(insertOperationIndex).getUuid();
-    }
-
-    public void testGetDBs() throws ExecutionException, InterruptedException {
-        ListenableFuture<List<String>> databases = ovs.getDatabases();
-        List<String> dbNames = databases.get();
-        Assert.assertNotNull(dbNames);
-        boolean hasOpenVswitchSchema = false;
-        for(String dbName : dbNames) {
-           if (dbName.equals(OPEN_VSWITCH_SCHEMA)) {
-                hasOpenVswitchSchema = true;
-                break;
-           }
-        }
-        Assert.assertTrue(OPEN_VSWITCH_SCHEMA+" schema is not supported by the switch", hasOpenVswitchSchema);
-    }
-
-    @Before
-    public  void setUp() throws IOException, ExecutionException, InterruptedException, TimeoutException {
-        if (ovs != null) {
-            return;
-        }
-        ovs = this.getTestConnection();
-        testGetDBs();
-        dbSchema = ovs.getSchema(OPEN_VSWITCH_SCHEMA).get();
-    }
-
-    @After
-    public void tearDown() throws InterruptedException, ExecutionException {
-        TableSchema<GenericTableSchema> bridge = dbSchema.table("Bridge", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, String> name = bridge.column("name", String.class);
-        GenericTableSchema ovsTable = dbSchema.table("Open_vSwitch", GenericTableSchema.class);
-        ColumnSchema<GenericTableSchema, Set<UUID>> bridges = ovsTable.multiValuedColumn("bridges", UUID.class);
-
-        ListenableFuture<List<OperationResult>> results = ovs.transactBuilder(dbSchema)
-                .add(op.delete(bridge)
-                        .where(name.opEqual(testBridgeName))
-                        .build())
-                .add(op.mutate(ovsTable)
-                        .addMutation(bridges, Mutator.DELETE, Sets.newHashSet(testBridgeUuid)))
-                .add(op.commit(true))
-                .execute();
-
-        List<OperationResult> operationResults = results.get();
-        System.out.println("Delete operation results = " + operationResults);
-        OvsdbConnectionService.getService().disconnect(ovs);
-    }
-
-    @Override
-    public void update(Object node, UpdateNotification upadateNotification) {
-        // TODO Auto-generated method stub
-
-    }
-    @Override
-    public void locked(Object node, List<String> ids) {
-        // TODO Auto-generated method stub
-
-    }
-    @Override
-    public void stolen(Object node, List<String> ids) {
-        // TODO Auto-generated method stub
-
-    }
-}
diff --git a/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbTestBase.java b/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/OvsdbTestBase.java
deleted file mode 100644 (file)
index c66c78f..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2014 Red Hat, Inc.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Authors : Madhu Venugopal
- */
-package org.opendaylight.ovsdb.integrationtest.ovsdbclient;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.Properties;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.rules.TestRule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-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.message.OvsdbRPC;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class OvsdbTestBase implements OvsdbRPC.Callback{
-    private static final Logger LOG = LoggerFactory.getLogger(OvsdbTestBase.class);
-    private final static String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
-    private final static String SERVER_PORT = "ovsdbserver.port";
-    private final static String CONNECTION_TYPE = "ovsdbserver.connection";
-    private final static String CONNECTION_TYPE_ACTIVE = "active";
-    private final static String CONNECTION_TYPE_PASSIVE = "passive";
-
-    private final static String DEFAULT_SERVER_PORT = "6640";
-
-    /**
-     * Represents the Open Vswitch Schema
-     */
-    public final static String OPEN_VSWITCH_SCHEMA = "Open_vSwitch";
-
-    public Properties loadProperties() {
-        Properties props = new Properties(System.getProperties());
-        return props;
-    }
-
-    public OvsdbClient getTestConnection() throws IOException, InterruptedException, ExecutionException, TimeoutException {
-        Properties props = loadProperties();
-        String addressStr = props.getProperty(SERVER_IPADDRESS);
-        String portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
-        String connectionType = props.getProperty(CONNECTION_TYPE, "active");
-
-        // If the connection type is active, controller connects to the ovsdb-server
-        if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
-            if (addressStr == null) {
-                Assert.fail(usage());
-            }
-
-            InetAddress address;
-            try {
-                address = InetAddress.getByName(addressStr);
-            } catch (Exception e) {
-                System.out.println("Unable to resolve " + addressStr);
-                e.printStackTrace();
-                return null;
-            }
-
-            Integer port;
-            try {
-                port = Integer.parseInt(portStr);
-            } catch (NumberFormatException e) {
-                System.out.println("Invalid port number : " + portStr);
-                e.printStackTrace();
-                return null;
-            }
-
-            OvsdbConnection connection = OvsdbConnectionService.getService();
-            return connection.connect(address, port);
-        } else if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_PASSIVE)) {
-            ExecutorService executor = Executors.newFixedThreadPool(1);
-            Future<OvsdbClient> passiveConnection = executor.submit(new PassiveListener());
-            return passiveConnection.get(60, TimeUnit.SECONDS);
-        }
-        Assert.fail("Connection parameter ("+CONNECTION_TYPE+") must be either active or passive");
-        return null;
-    }
-
-    private String usage() {
-        return "Integration Test needs a valid connection configuration as follows :\n" +
-               "active connection : mvn -Pintegrationtest -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"+
-               "passive connection : mvn -Pintegrationtest -Dovsdbserver.connection=passive verify\n";
-    }
-
-    public class PassiveListener implements Callable<OvsdbClient>, OvsdbConnectionListener {
-        OvsdbClient client = null;
-        @Override
-        public OvsdbClient call() throws Exception {
-            OvsdbConnection connection = OvsdbConnectionService.getService();
-            connection.registerConnectionListener(this);
-            while (client == null) {
-                Thread.sleep(500);
-            }
-            return client;
-        }
-
-        @Override
-        public void connected(OvsdbClient client) {
-            this.client = client;
-        }
-
-        @Override
-        public void disconnected(OvsdbClient client) {
-            Assert.assertEquals(this.client.getConnectionInfo(), client.getConnectionInfo());
-            this.client = null;
-        }
-    }
-
-    @Rule
-    public TestRule watcher = new TestWatcher() {
-        @Override
-        protected void starting(Description description) {
-            LOG.info("TestWatcher: Starting test: {}",
-                    description.getDisplayName());
-        }
-
-        @Override
-        protected void finished(Description description) {
-            LOG.info("TestWatcher: Finished test: {}", description.getDisplayName());
-        }
-    };
-}
diff --git a/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/TestBridge.java b/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/TestBridge.java
deleted file mode 100644 (file)
index c40f479..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2014 Red Hat, Inc.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Authors : Madhu Venugopal
- */
-
-package org.opendaylight.ovsdb.integrationtest.ovsdbclient;
-import java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.ovsdb.lib.notation.Column;
-import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
-import org.opendaylight.ovsdb.lib.schema.typed.MethodType;
-import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
-import org.opendaylight.ovsdb.lib.schema.typed.TypedColumn;
-import org.opendaylight.ovsdb.lib.schema.typed.TypedTable;
-
-/**
- * Statically Typed Bridge Table as defined in ovs-vswitchd.conf.db
- */
-
-/*
- * Interface name was set to TestBridge on purpose to test the @TypeTable annotation
- * functionality of TyperHelper.java
- */
-@TypedTable(name="Bridge", database="Open_vSwitch")
-public interface TestBridge extends TypedBaseTable {
-    /*
-     * Its a good practice to set the @TypedColumn to these Statically typed Tables & Columns.
-     * Implementations can choose to use GETDATA or GETCOLUMN or both to get the data.
-     * But GETCOLUMN gives more info on ColumnSchema.
-     * The following "name" column is decorated with both GETDATA and GETCOLUMN and the corresponding test
-     * will test both the options.
-     */
-    @TypedColumn(name="name", method=MethodType.GETDATA)
-    String getName();
-
-    @TypedColumn(name="name", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, String> getNameColumn();
-
-    @TypedColumn(name="name", method=MethodType.SETDATA)
-    void setName(String name);
-
-   /*
-    * Annotations are NOT added to the Status column on purpose to test the backup
-    * functionality on getter, setter, column name derivation etc.  TyperHelper.java.
-    */
-   Column<GenericTableSchema, Map<String, String>> getStatusColumn();
-    void setStatus(Map<String, String> status);
-
-    /*
-     * TypedColumn's name Annotation should override the method name based Column derivation.
-     * The method name and TypedColumn name was kept different on purpose to test the name
-     * resolution priority of TyperHelper.java
-     */
-    @TypedColumn(name="flood_vlans", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<Integer>> getFloodVlansColumn();
-
-    @TypedColumn(name="flood_vlans", method=MethodType.SETDATA)
-    void setFloodVlans(Set<Integer> vlans);
-
-
-    @TypedColumn(name="ports", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<UUID>> getPortsColumn();
-
-    @TypedColumn(name="ports", method=MethodType.SETDATA)
-    void setPorts(Set<UUID> ports);
-
-
-    @TypedColumn(name="mirrors", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<UUID>> getMirrorsColumn();
-
-    @TypedColumn(name="mirrors", method=MethodType.SETDATA)
-    void setMirrors(Set<UUID> mirrors);
-
-
-    @TypedColumn(name="controller", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<UUID>> getControllerColumn();
-
-    @TypedColumn(name="controller", method=MethodType.SETDATA)
-    void setController(Set<UUID> controller);
-
-
-    @TypedColumn(name="datapath_id", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<String>> getDatapathIdColumn();
-
-    @TypedColumn(name="datapath_id", method=MethodType.SETDATA)
-    void setDatapathId(Set<String> datapathId);
-
-
-    @TypedColumn(name="datapath_type", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, String> getDatapathTypeColumn();
-
-    @TypedColumn(name="datapath_type", method=MethodType.SETDATA)
-    void setDatapathType(String datapathType);
-
-
-    @TypedColumn(name="fail_mode", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<String>> getFailModeColumn();
-
-    @TypedColumn(name="fail_mode", method=MethodType.SETDATA)
-    void setFailMode(Set<String> failMode);
-
-
-    @TypedColumn(name="sflow", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<UUID>> getSflowColumn();
-
-    @TypedColumn(name="sflow", method=MethodType.SETDATA)
-    void setSflow(Set<UUID> sflow);
-
-
-    @TypedColumn(name="netflow", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<UUID>> getNetflowColumn();
-
-    @TypedColumn(name="netflow", method=MethodType.SETDATA)
-    void setNetflow(Set<UUID> netflow);
-
-
-    @TypedColumn(name="flow_tables", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Map<Integer, UUID>> getFlowTablesColumn();
-
-    @TypedColumn(name="flow_tables", method=MethodType.SETDATA)
-    void setFlowTables(Map<Integer, UUID> flowTables);
-
-
-    @TypedColumn(name="stp_enable", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Boolean> getStpEnableColumn();
-
-    @TypedColumn(name="stp_enable", method=MethodType.SETDATA)
-    void setStpEnable(Boolean stp_enable);
-
-
-    @TypedColumn(name="protocols", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<String>> getProtocolsColumn();
-
-    @TypedColumn(name="protocols", method=MethodType.SETDATA)
-    void setProtocols(Set<String> protocols);
-
-
-    @TypedColumn(name="other_config", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Map<String, String>> getOtherConfigColumn();
-
-    @TypedColumn(name="other_config", method=MethodType.SETDATA)
-    void setOtherConfig(Map<String, String> other_config);
-
-
-    @TypedColumn(name="external_ids", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Map<String, String>> getExternalIdsColumn();
-
-    @TypedColumn(name="external_ids", method=MethodType.SETDATA)
-    void setExternalIds(Map<String, String> externalIds);
-
-
-    @TypedColumn(name="ipfix", method=MethodType.GETCOLUMN)
-    Column<GenericTableSchema, Set<UUID>> getIpfixColumn();
-
-    @TypedColumn(name="ipfix", method=MethodType.SETDATA)
-    void setIpfix(Set<UUID> ipfix);
-}
diff --git a/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/VersionIncompatibleBridge.java b/integrationtest/src/test/java/org/opendaylight/ovsdb/integrationtest/ovsdbclient/VersionIncompatibleBridge.java
deleted file mode 100644 (file)
index 4fdc93a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2014 Red Hat, Inc.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Authors : Madhu Venugopal
- */
-
-package org.opendaylight.ovsdb.integrationtest.ovsdbclient;
-import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
-import org.opendaylight.ovsdb.lib.schema.typed.TypedTable;
-
-/**
- * VersionIncompatibleBridge is used to test the Version Compatibility logic in the Library
- * with an absurdly low fromVersion and untilVersion which will fail for all the OVS versions.
- */
-@TypedTable(name="Bridge", database="Open_vSwitch", fromVersion="0.0.1", untilVersion="0.0.2")
-public interface VersionIncompatibleBridge extends TypedBaseTable {
-}
diff --git a/integrationtest/src/test/resources/controller.xml b/integrationtest/src/test/resources/controller.xml
deleted file mode 100644 (file)
index 3cecc8b..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<persisted-snapshots>
-  <snapshots>
-    <snapshot>
-      <required-capabilities>
-        <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&amp;revision=2013-08-27</capability>
-        <capability>
-          urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28
-        </capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
-        <capability>
-          urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05
-        </capability>
-        <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
-        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
-        <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&amp;revision=2013-06-17
-        </capability>
-        <capability>
-          urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28
-        </capability>
-        <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24
-        </capability>
-        <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24
-        </capability>
-        <capability>
-          urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28
-        </capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&amp;revision=2013-07-16</capability>
-        <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&amp;revision=2013-07-09
-        </capability>
-        <capability>
-          urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28
-        </capability>
-
-        <!-- openflowjava -->
-        <capability>urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider:impl?module=openflow-switch-connection-provider-impl&amp;revision=2014-03-28</capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider?module=openflow-switch-connection-provider&amp;revision=2014-03-28</capability>
-        <!-- openflowplugin -->
-        <capability>urn:opendaylight:params:xml:ns:yang:openflow:common:config:impl?module=openflow-provider-impl&amp;revision=2014-03-26</capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:openflow:common:config?module=openflow-provider&amp;revision=2014-03-26</capability>
-      </required-capabilities>
-      <configuration>
-
-        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-          <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
-              <name>yang-schema-service</name>
-            </module>
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
-              <name>runtime-mapping-singleton</name>
-            </module>
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
-              <name>binding-notification-broker</name>
-            </module>
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
-              <name>binding-broker-impl</name>
-              <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-                <name>binding-notification-broker</name>
-              </notification-service>
-              <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-                <name>binding-data-broker</name>
-              </data-broker>
-              <root-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
-                <name>binding-data-broker</name>
-              </root-data-broker>
-            </module>
-            <!--
-                 Tree-based in-memory data store. This is the data store which is currently
-                 recommended for single-node deployments.
-            -->
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
-              <name>inmemory-data-broker</name>
-              <schema-service>
-                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-                <name>yang-schema-service</name>
-              </schema-service>
-            </module>
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
-              <name>inmemory-dom-broker</name>
-              <async-data-broker>
-                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
-                <name>inmemory-data-broker</name>
-              </async-data-broker>
-            </module>
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-compatible-broker</type>
-              <name>inmemory-binding-data-broker</name>
-              <dom-async-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-                <name>dom-broker</name>
-              </dom-async-broker>
-              <binding-mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
-                <name>runtime-mapping-singleton</name>
-              </binding-mapping-service>
-            </module>
-            <module>
-              <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-forwarded-data-broker</type>
-              <name>binding-async-data-broker</name>
-              <binding-forwarded-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                <dom-async-broker>
-                  <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
-                  <name>inmemory-data-broker</name>
-                </dom-async-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-mapping-service>
-                  <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
-                  <name>runtime-mapping-singleton</name>
-                </binding-mapping-service>
-              </binding-forwarded-data-broker>
-            </module>
-
-          </modules>
-
-          <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-            <service>
-              <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-              <instance>
-                <name>yang-schema-service</name>
-                <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
-              </instance>
-            </service>
-            <service>
-              <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
-              <instance>
-                <name>runtime-mapping-singleton</name>
-                <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
-              </instance>
-            </service>
-            <service>
-              <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-              <instance>
-                <name>binding-notification-broker</name>
-                <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
-              </instance>
-            </service>
-            <service>
-              <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
-              <instance>
-                <name>binding-osgi-broker</name>
-                <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-              </instance>
-            </service>
-            <service>
-              <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
-              <instance>
-                <name>binding-rpc-broker</name>
-                <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-              </instance>
-            </service>
-
-            <service>
-              <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-              <instance>
-                <name>dom-broker</name>
-                <provider>/modules/module[type='dom-broker-impl'][name='inmemory-dom-broker']</provider>
-              </instance>
-            </service>
-
-            <service>
-              <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-              <instance>
-                <name>binding-data-broker</name>
-                <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']</provider>
-              </instance>
-            </service>
-
-            <service>
-              <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
-              <instance>
-                <name>binding-data-broker</name>
-                <provider>/modules/module[type='binding-forwarded-data-broker'][name='binding-async-data-broker']</provider>
-              </instance>
-            </service>
-
-            <service>
-              <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
-              <instance>
-                <name>inmemory-data-broker</name>
-                <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
-              </instance>
-            </service>
-
-          </services>
-        </data>
-
-      </configuration>
-    </snapshot>
-
-  </snapshots>
-</persisted-snapshots>
diff --git a/integrationtest/src/test/resources/exam.properties b/integrationtest/src/test/resources/exam.properties
deleted file mode 100644 (file)
index 4936b4a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-pax.exam.logging = none
-pax.exam.service.timeout = 5000
diff --git a/integrationtest/src/test/resources/logback.xml b/integrationtest/src/test/resources/logback.xml
deleted file mode 100644 (file)
index faac2b0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<configuration scan="true">
-  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-    <encoder>
-      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
-    </encoder>
-  </appender>
-
-  <logger name="org.opendaylight.ovsdb" level="INFO" />
-
-  <logger name="org.opendaylight.ovsdb.lib.jsonrpc.JsonRpcEndpoint" level="TRACE" additivity="false">
-    <appender-ref ref="STDOUT" />
-  </logger>
-
-  <root level="ERROR">
-    <appender-ref ref="STDOUT" />
-  </root>
-</configuration>
diff --git a/integrationtest/src/test/resources/northbound.yaml b/integrationtest/src/test/resources/northbound.yaml
deleted file mode 100644 (file)
index c6c1981..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-# This file contains test cases for the OVSDB Northbound API
-# The ordering of the test data MUST be as follows:
-#   name:
-#   operation:
-#   uri:
-#   json:
-#   expected:
-#
-# The tests are run in the order specified in this file
-# The following variables are permitted in the URI or JSON:
-#
-# ${node} = The node identifier
-# ${uuid} = The last UUID returned by a POST operation
-# ${bridge_uuid} = The UUID of the test bridge
-# ${port_uuid} = The UUID of the test port
----
-- name: testGetBridgeRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows
-  json:
-  expected: 200
-
-- name: testGetPortRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows
-  json:
-  expected: 200
-
-- name: testGetInterfaceRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows
-  json:
-  expected: 200
-
-- name: testGetControllerRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows
-  json:
-  expected: 200
-
-- name: testGetSslRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows
-  json:
-  expected: 200
-
-- name: testGetSflowRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows
-  json:
-  expected: 200
-
-- name: testGetQosRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows
-  json:
-  expected: 200
-
-- name: testGetQueueRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows
-  json:
-  expected: 200
-
-- name: testGetNetflowRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows
-  json:
-  expected: 200
-
-- name: testGetManagerRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows
-  json:
-  expected: 200
-
-- name: testGetOpenVswitchRows
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/open_vswitch/rows
-  json:
-  expected: 200
-
-# Bridge
-
-- name: testCreateBridge
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows
-  json: >
-    {
-      "row": {
-        "Bridge": {
-        "name": "bridge1",
-        "datapath_type": "OPENFLOW"
-        }
-     }
-    }
-  expected: 201
-
-- name: testGetBridgeRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateBridgeRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows/${uuid}
-  json: >
-    {
-      "row": {
-        "Bridge": {
-          "stp_enable": true
-        }
-     }
-    }
-  expected: 200
-
-# Port
-
-- name: testCreatePort
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows
-  json: >
-    {
-      "parent_uuid":"${bridge_uuid}",
-        "row":{
-          "Port":{
-            "name":"testPort1"
-          }
-        }
-    }
-  expected: 201
-
-- name: testGetPortRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdatePortRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows/${uuid}
-  json: >
-    {
-       "row": {
-         "Port": {
-            "fake_bridge": true
-         }
-       }
-    }
-  expected: 200
-
-# Interface
-
-- name: testCreateInteface
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows
-  json: >
-    {
-      "parent_uuid": "${port_uuid}",
-        "row":{
-          "Interface":{
-            "name":"testInterface",
-            "admin_state":"up"
-        }
-      }
-    }
-  expected: 201
-
-- name: testGetInterfaceRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateInterfaceRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows/${uuid}
-  json: >
-    {
-      "row":{
-        "Interface":{
-          "type": "gre"
-        }
-      }
-    }
-  expected: 200
-
-- name: testDeleteInterfaceRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/interface/rows/${uuid}
-  json:
-  expected: 204
-
-# Controller
-
-- name: testCreateController
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows
-  json: >
-    {
-      "parent_uuid" : "${bridge_uuid}",
-      "row" : {
-        "Controller": {
-          "target": "1.1.1.1"
-            }
-        }
-    }
-  expected: 201
-
-- name: testGetControllerRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateControllerRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows/${uuid}
-  json: >
-    {
-      "row":{
-        "Controller":{
-          "is_connected": false
-        }
-      }
-    }
-  expected: 200
-
-- name: testDeleteControllerRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/controller/rows/${uuid}
-  json:
-  expected: 204
-
-# SSL
-
-- name: testCreateSslRow
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows
-  json: >
-    {
-        "row":{
-          "SSL":{
-            "name":"mySSL",
-            "ca_cert" : "ca_cert",
-            "bootstrap_ca_cert" : true,
-            "certificate":"pieceofpaper",
-            "private_key" : "private"
-          }
-        }
-    }
-  expected: 201
-
-- name: testGetSslRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateSslRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows/${uuid}
-  json: >
-    {
-      "row":{
-        "SSL":{
-          "private_key" : "secret"
-        }
-      }
-    }
-  expected: 200
-
-- name: testDeleteSslRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/ssl/rows/${uuid}
-  json:
-  expected: 204
-
-# sFlow
-
-- name: testCreateSflowRow
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows
-  json: >
-    {
-      "parent_uuid": "${bridge_uuid}",
-      "row": {
-        "sFlow": {
-          "targets": [
-            "set",
-            [
-              "targets_string"
-            ]
-          ]
-        }
-      }
-    }
-  expected: 201
-
-- name: testGetSflowRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateSflowRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows/${uuid}
-  json: >
-    {
-      "row":{
-        "sFlow":{
-          "targets": [
-            "set",
-            [
-              "targets_string",
-              "second_target"
-            ]
-          ]
-        }
-      }
-    }
-  expected: 200
-
-- name: testDeleteSflowRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/sflow/rows/${uuid}
-  json:
-  expected: 204
-
-# QoS
-
-- name: testCreateQosRow
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows
-  json: >
-    {
-      "parent_uuid" : "${port_uuid}",
-      "row" : {
-        "QoS": {
-          "type": "linux-htb"
-        }
-      }
-    }
-  expected: 201
-
-- name: testGetQosRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateQosRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows/${uuid}
-  json: >
-    {
-      "row":{
-        "QoS":{
-          "type": "linux-hfsc"
-        }
-      }
-    }
-  expected: 200
-
-# Queue
-
-- name: testCreateQueueRow
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows
-  json: >
-    {
-      "parent_uuid": "${qos_uuid}",
-      "row": {
-        "Queue": {
-          "dscp" : [
-          "set",
-          [
-              25
-            ]
-          ]
-        }
-      }
-    }
-  expected: 201
-
-- name: testGetQueueRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateQueueRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows/${uuid}
-  json: >
-    {
-      "row":{
-        "Queue":{
-          "other_config" : [
-            "map", ["foo", "bar" ]
-          ]
-        }
-      }
-    }
-  expected: 200
-
-- name: testDeleteQueueRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/queue/rows/${uuid}
-  json:
-  expected: 204
-
-# NetFlow
-
-- name: testCreateNetflowRow
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows
-  json: >
-    {
-      "parent_uuid":"${bridge_uuid}",
-      "row" : {
-        "NetFlow":{
-          "targets" : [
-            "set", ["192.168.1.102:9998"]],
-          "active_timeout" : "0"
-          }
-      }
-    }
-  expected: 201
-
-- name: testGetNetflowRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateNetflowRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows/${uuid}
-  json: >
-    {
-      "row" : {
-        "NetFlow":{
-          "targets" : [
-            "set", ["192.168.1.102:9998", "192.168.2.102:9998"]]
-          }
-      }
-    }
-  expected: 200
-
-- name: testDeleteNetflowRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/netflow/rows/${uuid}
-  json:
-  expected: 204
-
-# Manager
-
-- name: testCreateManagerRow
-  operation: POST
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows
-  json: >
-    {
-      "parent_uuid":"${ovs_uuid}",
-        "row":{
-          "Manager":{
-            "target":"a_string",
-            "is_connected": true,
-            "state":"active"
-          }
-        }
-    }
-  expected: 201
-
-- name: testGetManagerRow
-  operation: GET
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows/${uuid}
-  json:
-  expected: 200
-
-- name: testUpdateManagerRow
-  operation: PUT
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows/${uuid}
-  json: >
-    {
-        "row":{
-          "Manager":{
-            "is_connected": false
-          }
-        }
-    }
-  expected: 200
-
-- name: testDeleteManagerRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/manager/rows/${uuid}
-  json:
-  expected: 204
-
-# Cleanup
-
-- name: testDeleteQosRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/qos/rows/${qos_uuid}
-  json:
-  expected: 204
-
-- name: testDeletePortRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/port/rows/${port_uuid}
-  json:
-  expected: 204
-
-- name: testDeleteBridgeRow
-  operation: DELETE
-  uri: /ovsdb/nb/v2/node/OVS/${node}/tables/bridge/rows/${bridge_uuid}
-  json:
-  expected: 204
diff --git a/integrationtest/src/test/resources/tomcat-server.xml b/integrationtest/src/test/resources/tomcat-server.xml
deleted file mode 100644 (file)
index 433bceb..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<Server>
-  <!--APR library loader. Documentation at /docs/apr.html -->
-  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
-  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
-  <Listener className="org.apache.catalina.core.JasperListener" />
-  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
-  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
-  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
-  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
-
-  <Service name="Catalina">
-    <Connector port="8888" protocol="org.apache.coyote.http11.Http11NioProtocol"
-               connectionTimeout="20000"
-               redirectPort="8443" />
-
-    <!--
-            Please remove the comments around the following Connector tag to enable HTTPS Authentication support.
-            Remember to add a valid keystore in the configuration folder.
-            More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
-    -->
-
-    <!--
-       <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
-                  maxThreads="150" scheme="https" secure="true"
-                  clientAuth="false" sslProtocol="TLS"
-                  keystoreFile="configuration/keystore"
-                  keystorePass="changeit"/>
-    -->
-
-    <Engine name="Catalina" defaultHost="localhost">
-      <Host name="localhost" appBase=""
-            unpackWARs="false" autoDeploy="false"
-            deployOnStartup="false" createDirs="false">
-        <Realm className="org.opendaylight.controller.security.ControllerCustomRealm" />
-        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-
-        <!--
-        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
-               prefix="web_access_log_" suffix=".txt" resolveHosts="false"
-               rotatable="true" fileDateFormat="yyyy-MM"
-               pattern="%{yyyy-MM-dd HH:mm:ss.SSS z}t - [%a] - %r"/>
-        -->
-
-      </Host>
-    </Engine>
-  </Service>
-</Server>
diff --git a/northbound/enunciate.xml b/northbound/enunciate.xml
deleted file mode 100644 (file)
index e6faef2..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<enunciate label="full" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.26.xsd">
-
-  <services>
-    <rest defaultRestSubcontext="/ovsdb/nb/v2"/>
-  </services>
-
-  <modules>
-    <docs docsDir="rest" title="OVSDB Table operations over REST" includeExampleXml="true" includeExampleJson="true"/>
-  </modules>
-</enunciate>
diff --git a/northbound/pom.xml b/northbound/pom.xml
deleted file mode 100644 (file)
index 73ad141..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>commons</artifactId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/parent</relativePath>
-  </parent>
-
-  <artifactId>northbound</artifactId>
-  <version>0.8.0-SNAPSHOT</version>
-  <packaging>bundle</packaging>
-  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
-  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
-  <licenses>
-    <license>
-      <name>Eclipse Public License v1.0</name>
-      <url>http://www.eclipse.org/legal/epl-v10.html</url>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>Sam Hague</name>
-      <email>shague@gmail.com</email>
-      <url>https://github.com/shague</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>
-
-  <dependencies>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.enunciate</groupId>
-      <artifactId>enunciate-core-annotations</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-mockito</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>commons.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>library</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>plugin</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>utils.servicehelper</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Import-Package>org.opendaylight.controller.sal.utils,
-              org.opendaylight.controller.northbound.commons,
-              org.opendaylight.controller.northbound.commons.exception,
-              org.opendaylight.controller.northbound.commons.utils,
-              com.sun.jersey.spi.container.servlet,
-              org.opendaylight.controller.sal.core,
-              org.opendaylight.controller.sal.authorization,
-              org.opendaylight.ovsdb.plugin.api,
-              org.opendaylight.ovsdb.lib,
-              org.opendaylight.ovsdb.lib.jsonrpc,
-              org.opendaylight.ovsdb.lib.notation,
-              org.opendaylight.ovsdb.lib.operations,
-              org.opendaylight.ovsdb.lib.message,
-              org.opendaylight.ovsdb.lib.schema,
-              org.opendaylight.ovsdb.lib.schema.typed,
-              javax.ws.rs,
-              javax.ws.rs.core,
-              javax.xml.bind,
-              javax.xml.bind.annotation,
-              org.slf4j,
-              org.apache.catalina.filters,
-              !org.codehaus.enunciate.jaxrs,*</Import-Package>
-            <Export-Package/>
-            <Web-ContextPath>/ovsdb/nb</Web-ContextPath>
-            <Jaxrs-Resources>,${classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
-          </instructions>
-          <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.enunciate</groupId>
-        <artifactId>maven-enunciate-plugin</artifactId>
-        <version>${enunciate.version}</version>
-      </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/DatabaseResource.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/DatabaseResource.java
deleted file mode 100644 (file)
index 84b52dc..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2014, 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.northbound;
-
-import com.fasterxml.jackson.databind.SerializationFeature;
-import java.util.List;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * Northbound interface for OVSDB Databases
- */
-public class DatabaseResource {
-
-    String nodeId;
-    ObjectMapper objectMapper;
-    DatabaseResource(String id) {
-        this.nodeId = id;
-        objectMapper = new ObjectMapper();
-        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
-    }
-
-    private DatabaseSchema getDatabaseSchema (String databaseName) {
-        String csDatabaseName = this.caseSensitiveDatabaseName(databaseName);
-        OvsdbClient client = NodeResource.getOvsdbClient(nodeId, this);
-        return client.getDatabaseSchema(csDatabaseName);
-    }
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getDatabases(){
-        OvsdbClient client = NodeResource.getOvsdbClient(nodeId, this);
-        try {
-            List<String> databases = client.getDatabases().get();
-            if (databases == null) {
-                return Response.noContent().build();
-            }
-            String response = objectMapper.writeValueAsString(databases);
-            return Response.status(Response.Status.OK)
-                    .entity(response)
-                    .build();
-        } catch (Exception e) {
-            throw new InternalServerErrorException("Failed due to exception " + e.getMessage());
-        }
-    }
-
-    @GET
-    @Path("{name}")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getDatabases(@PathParam("name") String name) throws JsonProcessingException {
-        DatabaseSchema dbSchema = this.getDatabaseSchema(name);
-        String response = objectMapper.writeValueAsString(dbSchema);
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @Path("{name}/table")
-    public TableResource getDatabaseTables(@PathParam("name") String name){
-        String csDatabaseName = this.caseSensitiveDatabaseName(name);
-        return new TableResource(nodeId, csDatabaseName);
-    }
-
-    private String caseSensitiveDatabaseName (String ciDatabaseName) {
-        OvsdbClient client = NodeResource.getOvsdbClient(nodeId, this);
-        try {
-            List<String> databases = client.getDatabases().get();
-            if (databases == null) {
-                return ciDatabaseName;
-            }
-            for (String csDatabaseName : databases) {
-                if (csDatabaseName.equalsIgnoreCase(ciDatabaseName)) {
-                    return csDatabaseName;
-                }
-            }
-            return ciDatabaseName;
-        } catch (Exception e) {
-            return ciDatabaseName;
-        }
-    }
-}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/NodeResource.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/NodeResource.java
deleted file mode 100644 (file)
index 5ccdf4f..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2014, 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.northbound;
-
-import com.fasterxml.jackson.databind.SerializationFeature;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.List;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.opendaylight.controller.northbound.commons.RestMessages;
-import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.plugin.api.Connection;
-import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
-import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.Lists;
-
-/**
- * Northbound Interface for OVSDB Nodes
- */
-public class NodeResource {
-    ObjectMapper objectMapper;
-    public NodeResource () {
-        objectMapper = new ObjectMapper();
-        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
-    }
-
-    public static Node getOvsdbNode(String nodeId, Object bundleClassRef) {
-        OvsdbConnectionService connectionService =
-                (OvsdbConnectionService)ServiceHelper.
-                        getGlobalInstance(OvsdbConnectionService.class, bundleClassRef);
-        if (connectionService == null) {
-            throw new ServiceUnavailableException("Ovsdb ConnectionService "
-                    + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        Node node = connectionService.getNode(nodeId);
-        if (node == null) {
-            throw new ResourceNotFoundException("Node "+nodeId+" not found");
-        }
-
-        return node;
-    }
-
-    public static Connection getOvsdbConnection(String nodeId, Object bundleClassRef) {
-        OvsdbConnectionService connectionService =
-                (OvsdbConnectionService)ServiceHelper.
-                        getGlobalInstance(OvsdbConnectionService.class, bundleClassRef);
-        if (connectionService == null) {
-            throw new ServiceUnavailableException("Ovsdb ConnectionService "
-                    + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        Node node = connectionService.getNode(nodeId);
-        if (node == null) {
-            throw new ResourceNotFoundException("Node "+nodeId+" not found");
-        }
-
-        Connection connection = connectionService.getConnection(node);
-        if (connection == null) {
-            throw new ResourceNotFoundException("Connection for "+nodeId+" not available");
-        }
-
-        return connection;
-    }
-
-    public static OvsdbClient getOvsdbClient(String nodeId, Object bundleClassRef) {
-        Connection connection = NodeResource.getOvsdbConnection(nodeId, bundleClassRef);
-        OvsdbClient client = connection.getClient();
-        if (client == null) {
-            throw new ResourceNotFoundException("No Ovsdb Client to handle Node "+nodeId);
-        }
-        return client;
-    }
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getNodes() throws JsonProcessingException {
-        OvsdbConnectionService connectionService = (OvsdbConnectionService)ServiceHelper.getGlobalInstance(OvsdbConnectionService.class, this);
-        List<Node> nodes = connectionService.getNodes();
-        if (nodes == null) {
-            return Response.noContent().build();
-        }
-
-        List<String> nodeIds = Lists.newArrayList();
-        for (Node node : nodes) {
-            nodeIds.add(node.getId().getValue());
-        }
-        Collections.sort(nodeIds);
-
-        String response = objectMapper.writeValueAsString(nodeIds);
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @POST
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response createNode(InputStream is){
-        return Response.noContent().build();
-    }
-
-    @GET
-    @Path("{id}")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getNode(@PathParam("id") String id) throws JsonProcessingException {
-        OvsdbClient client = NodeResource.getOvsdbClient(id, this);
-        String response = objectMapper.writeValueAsString(client.getConnectionInfo());
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @PUT
-    @Path("{id}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response updateNode(@PathParam("id") String id, InputStream is){
-        return Response.noContent().build();
-    }
-
-    @DELETE
-    @Path("{id}")
-    public Response deleteNode(@PathParam("id") String id){
-        return Response.noContent().build();
-    }
-
-    @Path("{id}/database")
-    public DatabaseResource getNodeDatabase(@PathParam("id") String nodeId){
-        return new DatabaseResource(nodeId);
-    }
-
-}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV2.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV2.java
deleted file mode 100644 (file)
index be1d98e..0000000
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * Copyright (c) 2014, 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.northbound;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.SecurityContext;
-import javax.ws.rs.core.UriInfo;
-
-import org.codehaus.enunciate.jaxrs.ResponseCode;
-import org.codehaus.enunciate.jaxrs.StatusCodes;
-import org.codehaus.enunciate.jaxrs.TypeHint;
-import org.opendaylight.controller.northbound.commons.RestMessages;
-import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
-import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
-import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
-import org.opendaylight.controller.sal.authorization.Privilege;
-import org.opendaylight.ovsdb.plugin.api.Status;
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.lib.notation.Row;
-import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
-import org.opendaylight.ovsdb.plugin.api.OvsVswitchdSchemaConstants;
-import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
-import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
-import org.opendaylight.ovsdb.plugin.api.StatusWithUuid;
-import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-/**
-* OVSDB Northbound REST API.<br>
-* This class provides REST APIs to Create, Read, Update and Delete OVSDB Row in any of the ovsdb table
-* database one at a time. The JSON used to create rows is in the same format as the OVSDB JSON-RPC messages.
-* This format is documented in the <a href="http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf">OVSDB Schema</a>
-* and in <a href="http://tools.ietf.org/rfc/rfc7047.txt">RFC 7047</a>.
-*
-* <br>
-* <br>
-* Authentication scheme : <b>HTTP Basic</b><br>
-* Authentication realm : <b>opendaylight</b><br>
-* Transport : <b>HTTP and HTTPS</b><br>
-* <br>
-* HTTPS Authentication is disabled by default.
-*/
-
-@Path("/v2/")
-@Deprecated
-public class OvsdbNorthboundV2 {
-
-    @Context
-    private UriInfo _uriInfo;
-    private String username;
-
-    @Context
-    public void setSecurityContext(SecurityContext context) {
-        if (context != null && context.getUserPrincipal() != null) {
-            username = context.getUserPrincipal().getName();
-        }
-    }
-
-    protected String getUserName() {
-        return username;
-    }
-
-    /**
-     * Create a Row for Open_vSwitch schema
-     *
-     * @param nodeType type of node e.g OVS
-     * @param nodeId ID of the node
-     * @param tableName name of the OVSDB table
-     * @param rowJson the {@link OvsdbRow} Row that is being inserted
-     *
-     * @return Response as dictated by the HTTP Response Status code
-     *
-     * <br>
-     * Examples:
-     * <br>
-     * Create a Bridge Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows
-     *
-     * JSON:
-     * {
-     *   "row": {
-     *     "Bridge": {
-     *       "name": "bridge1",
-     *       "datapath_type": "OPENFLOW"
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create a Port Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows
-     *
-     * JSON:
-     * {
-     *   "parent_uuid": "b01cd26b-9c63-4216-8cf2-55f7087adab1",
-     *   "row": {
-     *     "Port": {
-     *       "name": "port1",
-     *       "mac": [
-     *         "set",
-     *         "00:00:00:00:00:01"
-     *       ],
-     *       "tag": [
-     *         "set",
-     *         200
-     *       ]
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create an Interface Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows
-     *
-     * JSON:
-     * {
-     *   "parent_uuid": "c7b54c9b-9b25-4801-a81d-d7bc489d4840",
-     *   "row": {
-     *     "Interface": {
-     *       "name": "br2",
-     *       "mac": [
-     *         "set",
-     *         "00:00:bb:bb:00:01"
-     *       ],
-     *       "admin_state": "up"
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create an SSL Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows
-     *
-     * JSON:
-     * {
-     *   "row": {
-     *     "SSL": {
-     *       "name": "mySSL",
-     *       "ca_cert": "ca_cert",
-     *       "bootstrap_ca_cert": true,
-     *       "certificate": "pieceofpaper",
-     *       "private_key": "private"
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create an sFlow Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows
-     *
-     * JSON:
-     * {
-     *   "parent_uuid": "6b3072ba-a120-4db9-82f8-a8ce4eae6942",
-     *   "row": {
-     *     "sFlow": {
-     *       "agent": [
-     *         "set",
-     *         "agent_string"
-     *       ],
-     *       "targets": [
-     *         "set",
-     *         "targets_string"
-     *       ]
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create a QoS Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows
-     *
-     * JSON:
-     * {
-     *   "parent_uuid": "b109dbcf-47bb-4121-b244-e623b3421d6e",
-     *   "row": {
-     *     "QoS": {
-     *       "type": "linux-htb"
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create a Queue Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows
-     *
-     * {
-     *   "parent_uuid": "b16eae7d-7e97-46d2-95d1-333d1de4a3d7",
-     *   "row": {
-     *     "Queue": {
-     *       "dscp": [
-     *         "set",
-     *         "25"
-     *       ]
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create a Netflow Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows
-     *
-     * JSON:
-     * {
-     *   "parent_uuid": "b01cd26b-9c63-4216-8cf2-55f7087adab1",
-     *   "row": {
-     *     "NetFlow": {
-     *       "targets": [
-     *         "set",
-     *         [
-     *           "192.168.1.102:9998"
-     *         ]
-     *       ],
-     *       "active_timeout": "0"
-     *     }
-     *   }
-     * }
-     * </pre>
-     *
-     *
-     * Create a Manager Row:
-     * <pre>
-     *
-     * Request URL:
-     * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows
-     *
-     * JSON:
-     * {
-     *   "parent_uuid": "8d3fb89b-5fac-4631-a990-f5a4e7f5383a",
-     *   "row": {
-     *     "Manager": {
-     *       "target": "a_string",
-     *       "is_connected": true,
-     *       "state": "active"
-     *     }
-     *   }
-     * }
-     * </pre>
-     * @throws IOException
-     * @throws ExecutionException
-     * @throws InterruptedException
-     */
-
-    @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows")
-    @POST
-    @StatusCodes({ @ResponseCode(code = 201, condition = "Row Inserted successfully"),
-        @ResponseCode(code = 400, condition = "Invalid data passed"),
-        @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
-    @Consumes({ MediaType.APPLICATION_JSON})
-    public Response addRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
-                           @PathParam("tableName") String tableName, JsonNode rowJson) throws IOException, InterruptedException, ExecutionException {
-
-        if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
-            throw new UnauthorizedException("User is not authorized to perform this operation");
-        }
-
-        OvsdbConfigurationService
-                ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                            this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        OvsdbConnectionService
-                connectionService = (OvsdbConnectionService)ServiceHelper.getGlobalInstance(OvsdbConnectionService.class, this);
-        Node node = connectionService.getNode(nodeId);
-
-        OvsdbClient client = connectionService.getConnection(node).getClient();
-        OvsdbRow localRow = OvsdbRow.fromJsonNode(client, OvsVswitchdSchemaConstants.DATABASE_NAME, rowJson);
-        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
-
-        if (localRow == null) {
-            return Response.status(Response.Status.BAD_REQUEST).build();
-        }
-
-        StatusWithUuid
-                statusWithUuid = ovsdbTable.insertRow(node, bckCompatibleTableName, localRow.getParentUuid(), localRow.getRow());
-
-        if (statusWithUuid.isSuccess()) {
-            UUID uuid = statusWithUuid.getUuid();
-            return Response.status(Response.Status.CREATED)
-                    .header("Location", String.format("%s/%s", _uriInfo.getAbsolutePath().toString(),
-                                                                uuid.toString()))
-                    .entity(uuid.toString())
-                    .build();
-        }
-        return NorthboundUtils.getResponse(
-                new org.opendaylight.controller.sal.utils.Status(
-                        org.opendaylight.controller.sal.utils.StatusCode.SUCCESS));
-    }
-
-    /**
-     * Read a Row
-     *
-     * @param nodeType type of node e.g OVS
-     * @param nodeId ID of the node
-     * @param tableName name of the ovsdb table
-     * @param rowUuid UUID of the row being read
-     *
-     * @return Row corresponding to the UUID.
-     *
-     * <br>
-     * Examples:
-     * <br>
-     * <pre>
-     * Get a specific Bridge Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific Port Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific Interface Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific Controller Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific SSL Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific sFlow Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific QoS Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific Queue Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific Netflow Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Get a specific Manager Row:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     * </pre>
-     */
-
-    @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows/{rowUuid}")
-    @GET
-    @StatusCodes({ @ResponseCode(code = 200, condition = "Row Updated successfully"),
-        @ResponseCode(code = 400, condition = "Invalid data passed"),
-        @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
-    @Produces({ MediaType.APPLICATION_JSON})
-    @TypeHint(Row.class)
-    public Row getRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
-                           @PathParam("tableName") String tableName, @PathParam("rowUuid") String rowUuid) {
-
-        if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
-            throw new UnauthorizedException("User is not authorized to perform this operation");
-        }
-
-        OvsdbConfigurationService
-                ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                            this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        OvsdbConnectionService
-                connectionService = (OvsdbConnectionService)ServiceHelper.getGlobalInstance(OvsdbConnectionService.class, this);
-        Node node = connectionService.getNode(nodeId);
-        OvsdbClient client = connectionService.getConnection(node).getClient();
-        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
-
-        Row row;
-        try {
-            row = ovsdbTable.getRow(node, bckCompatibleTableName, rowUuid);
-        } catch (Exception e) {
-            throw new BadRequestException(e.getMessage());
-        }
-        return row;
-    }
-
-    /**
-     * Read all Rows of a table
-     *
-     * @param nodeType type of node e.g OVS
-     * @param nodeId ID of the node
-     * @param tableName name of the ovsdb table
-     *
-     * @return All the Rows of a table
-     *
-     * <br>
-     * Examples:
-     * <br>
-     * <pre>
-     * Get all Bridge Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows
-     *
-     * Get all Port Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows
-     *
-     * Get all Interface Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows
-     *
-     * Get all Controller Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows
-     *
-     * Get all SSL Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows
-     *
-     * Get all sFlow Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows
-     *
-     * Get all QoS Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows
-     *
-     * Get all Queue Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows
-     *
-     * Get all Netflow Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows
-     *
-     * Get all Manager Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows
-     *
-     * Get all Open vSwitch Rows:
-     * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/open_vswitch/rows
-     * </pre>
-     */
-
-    @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows")
-    @GET
-    @StatusCodes({ @ResponseCode(code = 200, condition = "Row Updated successfully"),
-        @ResponseCode(code = 400, condition = "Invalid data passed"),
-        @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
-    @Produces({ MediaType.APPLICATION_JSON})
-    @TypeHint(OvsdbRows.class)
-    public OvsdbRows getAllRows(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
-                               @PathParam("tableName") String tableName) {
-        if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
-            throw new UnauthorizedException("User is not authorized to perform this operation");
-        }
-
-        OvsdbConfigurationService
-                ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                            this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        OvsdbConnectionService
-                connectionService = (OvsdbConnectionService)ServiceHelper.getGlobalInstance(OvsdbConnectionService.class, this);
-        Node node = connectionService.getNode(nodeId);
-        OvsdbClient client = connectionService.getConnection(node).getClient();
-        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
-        Map<String, Row> rows;
-        try {
-            rows = ovsdbTable.getRows(node, bckCompatibleTableName);
-        } catch (Exception e) {
-            throw new BadRequestException(e.getMessage());
-        }
-        return new OvsdbRows(rows);
-    }
-
-    /*
-    /**
-     * Update a Row
-     *
-     * @param nodeType type of node e.g OVS
-     * @param nodeId ID of the node
-     * @param tableName name of the ovsdb table
-     * @param rowUuid UUID of the row being updated
-     * @param row the {@link OVSDBRow} Row that is being updated
-     *
-     * @return Response as dictated by the HTTP Response Status code
-     *
-     * <br>
-     * Examples:
-     * <br>
-     * Update the Bridge row to add a controller
-     * <pre>
-     *
-     * Request URL:
-     * PUT http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/b01cd26b-9c63-4216-8cf2-55f7087adab1
-     *
-     * JSON:
-     * {
-     *   "row": {
-     *     "Bridge": {
-     *       "controller": [
-     *         "set",
-     *         [
-     *           [
-     *             "uuid",
-     *             "a566e8b4-fc38-499b-8623-6087d5b36b72"
-     *           ]
-     *         ]
-     *       ]
-     *     }
-     *   }
-     * }
-     * </pre>
-     */
-
-    @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows/{rowUuid}")
-    @PUT
-    @StatusCodes({ @ResponseCode(code = 200, condition = "Row Updated successfully"),
-        @ResponseCode(code = 400, condition = "Invalid data passed"),
-        @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
-    @Consumes({ MediaType.APPLICATION_JSON})
-    public Response updateRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
-                           @PathParam("tableName") String tableName, @PathParam("rowUuid") String rowUuid,
-                           JsonNode rowJson) {
-
-        if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
-            throw new UnauthorizedException("User is not authorized to perform this operation");
-        }
-
-        OvsdbConfigurationService
-                ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                            this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        OvsdbConnectionService
-                connectionService = (OvsdbConnectionService)ServiceHelper.getGlobalInstance(OvsdbConnectionService.class, this);
-        Node node = connectionService.getNode(nodeId);
-        OvsdbClient client = connectionService.getConnection(node).getClient();
-        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
-        OvsdbRow localRow = OvsdbRow.fromJsonNode(client, OvsVswitchdSchemaConstants.DATABASE_NAME, rowJson);
-
-        if (localRow == null) {
-            return Response.status(Response.Status.BAD_REQUEST).build();
-        }
-
-        ovsdbTable.updateRow(node, bckCompatibleTableName, localRow.getParentUuid(), rowUuid, localRow.getRow());
-        return NorthboundUtils.getResponse(
-                new org.opendaylight.controller.sal.utils.Status(
-                        org.opendaylight.controller.sal.utils.StatusCode.SUCCESS));
-    }
-
-    /**
-     * Delete a row
-     *
-     * @param nodeType type of node e.g OVS
-     * @param nodeId ID of the node
-     * @param tableName name of the ovsdb table
-     * @param uuid UUID of the Row to be removed
-     *
-     * @return Response as dictated by the HTTP Response Status code
-     *
-     * <br>
-     * Examples:
-     * <br>
-     * <pre>
-     * Delete a specific Bridge Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific Port Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific Interface Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific Controller Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific SSL Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific sFlow Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific QoS Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific Queue Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific Netflow Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     *
-     * Delete a specific Manager Row:
-     * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows/6f4c602c-026f-4390-beea-d50d6d448100
-     * </pre>
-     */
-
-    @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows/{uuid}")
-    @DELETE
-    @StatusCodes({ @ResponseCode(code = 204, condition = "User Deleted Successfully"),
-        @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
-        @ResponseCode(code = 404, condition = "The userName passed was not found"),
-        @ResponseCode(code = 500, condition = "Internal Server Error : Removal of user failed"),
-        @ResponseCode(code = 503, condition = "Service unavailable") })
-    public Response removeRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
-                              @PathParam("tableName") String tableName, @PathParam("uuid") String uuid) {
-        if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
-            throw new UnauthorizedException("User is not authorized to perform this operation");
-        }
-
-        OvsdbConfigurationService
-                ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        OvsdbConnectionService
-                connectionService = (OvsdbConnectionService)ServiceHelper.getGlobalInstance(OvsdbConnectionService.class, this);
-        Node node = connectionService.getNode(nodeId);
-        OvsdbClient client = connectionService.getConnection(node).getClient();
-        String bckCompatibleTableName = this.getBackwardCompatibleTableName(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
-
-        Status status = ovsdbTable.deleteRow(node, bckCompatibleTableName, uuid);
-        if (status.isSuccess()) {
-            return Response.noContent().build();
-        }
-        return NorthboundUtils.getResponse(
-                new org.opendaylight.controller.sal.utils.Status(
-                        org.opendaylight.controller.sal.utils.StatusCode.SUCCESS));
-    }
-
-    private String getBackwardCompatibleTableName(OvsdbClient client, String databaseName, String tableName) {
-        DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
-        if (dbSchema == null || tableName == null) {
-            return tableName;
-        }
-        for (String dbTableName : dbSchema.getTables()) {
-            if (dbTableName.equalsIgnoreCase(tableName)) {
-                return dbTableName;
-            }
-        }
-        return tableName;
-    }
-}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3.java
deleted file mode 100644 (file)
index 6f1d149..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014, 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.northbound;
-
-import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
-import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
-import org.opendaylight.controller.sal.authorization.Privilege;
-
-import javax.ws.rs.Path;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.SecurityContext;
-import javax.ws.rs.core.UriInfo;
-
-/**
-* OVSDB Northbound V3 REST API
-*/
-
-@Path("/v3/")
-public class OvsdbNorthboundV3 {
-    @Context
-    private UriInfo _uriInfo;
-    private String username;
-
-    @Context
-    public void setSecurityContext(SecurityContext context) {
-        if (context != null && context.getUserPrincipal() != null) {
-            username = context.getUserPrincipal().getName();
-        }
-    }
-
-    protected String getUserName() {
-        return username;
-    }
-
-    @Path("node")
-    public NodeResource getNode(){
-        if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
-            throw new UnauthorizedException("User is not authorized to perform this operation");
-        }
-        return new NodeResource();
-    }
-
-}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRow.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRow.java
deleted file mode 100644 (file)
index ac954bf..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2013, 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.northbound;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.concurrent.ExecutionException;
-
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.lib.notation.Row;
-import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
-import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-public class OvsdbRow {
-    private static final Logger LOG = LoggerFactory.getLogger(OvsdbRow.class);
-    private static final String PARENTUUID = "parent_uuid";
-    private static final String PARENTTABLE = "parent_table";
-    private static final String PARENTCOLUMN = "parent_column";
-    private static final String ROW = "row";
-
-    private String parentUuid;
-    private String parentTable;
-    private String parentColumn;
-    private String tableName;
-    private Row<GenericTableSchema> row;
-
-    public OvsdbRow() {
-    }
-
-    public OvsdbRow(String parentUuid, String tableName, Row<GenericTableSchema> row) {
-        this.parentUuid = parentUuid;
-        this.tableName = tableName;
-        this.row = row;
-    }
-
-    public OvsdbRow(String parentTable, String parentUuid, String parentColumn, String tableName, Row<GenericTableSchema> row) {
-        this.parentTable = parentTable;
-        this.parentColumn = parentColumn;
-        this.parentUuid = parentUuid;
-        this.tableName = tableName;
-        this.row = row;
-    }
-
-    public static OvsdbRow fromJsonNode(OvsdbClient client, String dbName, JsonNode json) {
-        JsonNode parentUuidNode = json.get(PARENTUUID);
-        String parentUuid = null;
-        if (parentUuidNode != null) {
-           parentUuid = parentUuidNode.asText();
-        }
-        JsonNode parentTableNode = json.get(PARENTTABLE);
-        String parentTable = null;
-        if (parentTableNode != null) {
-            parentTable = parentTableNode.asText();
-        }
-        JsonNode parentColumnNode = json.get(PARENTCOLUMN);
-        String parentColumn = null;
-        if (parentColumnNode != null) {
-            parentColumn = parentColumnNode.asText();
-        }
-        JsonNode rowNode = json.get(ROW);
-        if (rowNode == null) {
-            return null;
-        }
-        Iterator<String> fieldNames = rowNode.fieldNames();
-        if (fieldNames.hasNext()) {
-            String tableName = fieldNames.next();
-            try {
-                Row<GenericTableSchema> row = getRow(client, dbName, tableName, rowNode.get(tableName));
-                return new OvsdbRow(parentTable, parentUuid, parentColumn, tableName, row);
-            } catch (InterruptedException | ExecutionException | IOException e) {
-                LOG.error("Error retrieving the row for {}", tableName, e);
-                return null;
-            }
-        }
-        return null;
-    }
-
-    public static Row<GenericTableSchema> getRow(OvsdbClient client, String dbName, String tableName, JsonNode rowJson) throws InterruptedException, ExecutionException, IOException {
-        DatabaseSchema dbSchema = client.getSchema(dbName).get();
-        GenericTableSchema schema = dbSchema.table(tableName, GenericTableSchema.class);
-        return schema.createRow((ObjectNode)rowJson);
-    }
-
-    public String getParentTable() {
-        return parentTable;
-    }
-
-    public String getParentUuid() {
-        return parentUuid;
-    }
-
-    public String getParentColumn() {
-        return parentColumn;
-    }
-
-    public String getTableName() {
-        return tableName;
-    }
-
-    public Row<GenericTableSchema> getRow() {
-        return row;
-    }
-}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRows.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/OvsdbRows.java
deleted file mode 100644 (file)
index 9a1eade..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2013, 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.northbound;
-
-import java.util.Map;
-
-import org.opendaylight.ovsdb.lib.notation.Row;
-
-@Deprecated
-public class OvsdbRows {
-    Map<String, Row> rows;
-
-    public OvsdbRows(Map<String, Row> rows) {
-        super();
-        this.rows = rows;
-    }
-
-    public Map<String, Row> getRows() {
-        return rows;
-    }
-
-    public void setRows(Map<String, Row> rows) {
-        this.rows = rows;
-    }
-}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/RowResource.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/RowResource.java
deleted file mode 100644 (file)
index e656428..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2014, 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.northbound;
-
-import com.fasterxml.jackson.databind.SerializationFeature;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Map;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.opendaylight.controller.northbound.commons.RestMessages;
-import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.lib.notation.Row;
-import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
-import org.opendaylight.ovsdb.plugin.api.OvsVswitchdSchemaConstants;
-import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
-import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * Northbound interface for OVSDB Rows
- */
-public class RowResource {
-
-    String nodeId;
-    String databaseName;
-    String tableName;
-    ObjectMapper objectMapper;
-
-    public RowResource(String nodeId, String databaseName, String tableName) {
-        this.nodeId = nodeId;
-        this.databaseName = databaseName;
-        this.tableName = tableName;
-        objectMapper = new ObjectMapper();
-        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
-    }
-
-    private OvsdbRow getOvsdbRow (InputStream stream) throws IOException {
-        StringBuilder rowNodeStrBuilder = new StringBuilder();
-        BufferedReader in = new BufferedReader(new InputStreamReader(stream));
-        String line = null;
-        while ((line = in.readLine()) != null) {
-            rowNodeStrBuilder.append(line);
-        }
-        JsonNode jsonNode = objectMapper.readTree(rowNodeStrBuilder.toString());
-        OvsdbClient client = NodeResource.getOvsdbClient(nodeId, this);
-        return OvsdbRow.fromJsonNode(client, OvsVswitchdSchemaConstants.DATABASE_NAME, jsonNode);
-    }
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getRows() throws JsonProcessingException {
-        OvsdbConfigurationService
-                ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                            this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("Ovsdb ConfigurationService " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        Node node = NodeResource.getOvsdbNode(nodeId, this);
-        Map<UUID,Row<GenericTableSchema>> rows = null;
-        try {
-            rows = ovsdbTable.getRows(node, databaseName, tableName);
-        } catch (Exception e) {
-            throw new BadRequestException(e.getMessage());
-        }
-        String response = objectMapper.writeValueAsString(rows);
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @POST
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response createRow(InputStream stream) throws IOException {
-        OvsdbRow localRow = this.getOvsdbRow(stream);
-        if (localRow == null) {
-            return Response.status(Response.Status.BAD_REQUEST).build();
-        }
-        OvsdbConfigurationService
-        ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                    this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        Node node = NodeResource.getOvsdbNode(nodeId, this);
-        Row row = ovsdbTable.insertTree(node, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName,
-                localRow.getParentTable(), new UUID(localRow.getParentUuid()), localRow.getParentColumn(),
-                localRow.getRow());
-        String response = objectMapper.writeValueAsString(row);
-        return Response.status(Response.Status.CREATED)
-                .entity(response)
-                .build();
-    }
-
-    @GET
-    @Path("{id}")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getRowDetails(@PathParam("id") String id) throws JsonProcessingException {
-        OvsdbConfigurationService
-        ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                    this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("Ovsdb ConfigurationService " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        Node node = NodeResource.getOvsdbNode(nodeId, this);
-        Row<GenericTableSchema> row = null;
-        try {
-            row = ovsdbTable.getRow(node, databaseName, tableName, new UUID(id));
-        } catch (Exception e) {
-            throw new BadRequestException(e.getMessage());
-        }
-        String response = objectMapper.writeValueAsString(row);
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @PUT
-    @Path("{id}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response updateRow(@PathParam("id") String id, InputStream stream) throws IOException{
-        OvsdbRow localRow = this.getOvsdbRow(stream);
-        if (localRow == null) {
-            return Response.status(Response.Status.BAD_REQUEST).build();
-        }
-        OvsdbConfigurationService ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                    this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        Node node = NodeResource.getOvsdbNode(nodeId, this);
-        Row<GenericTableSchema> row = ovsdbTable.updateRow(node, databaseName, tableName, new UUID(id), localRow.getRow(), true);
-        String response = objectMapper.writeValueAsString(row);
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @DELETE
-    @Path("{id}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response deleteRow(@PathParam("id") String id){
-        OvsdbConfigurationService
-        ovsdbTable = (OvsdbConfigurationService)ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class,
-                                                                                    this);
-        if (ovsdbTable == null) {
-            throw new ServiceUnavailableException("Ovsdb ConfigurationService " + RestMessages.SERVICEUNAVAILABLE.toString());
-        }
-
-        Node node = NodeResource.getOvsdbNode(nodeId, this);
-        try {
-            ovsdbTable.deleteRow(node, databaseName, tableName, new UUID(id));
-        } catch (Exception e) {
-            throw new BadRequestException(e.getMessage());
-        }
-        return Response.status(Response.Status.OK)
-                .build();
-
-    }
-}
diff --git a/northbound/src/main/java/org/opendaylight/ovsdb/northbound/TableResource.java b/northbound/src/main/java/org/opendaylight/ovsdb/northbound/TableResource.java
deleted file mode 100644 (file)
index 309448f..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2014, 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.northbound;
-
-import com.fasterxml.jackson.databind.SerializationFeature;
-import java.util.Set;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.opendaylight.ovsdb.lib.OvsdbClient;
-import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
-import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
-import org.opendaylight.ovsdb.lib.schema.TableSchema;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * Northbound interface for OVSDB tables
- */
-public class TableResource {
-    ObjectMapper objectMapper;
-    String databaseName;
-    String nodeId;
-
-    TableResource(String nodeId, String databaseName){
-        this.nodeId = nodeId;
-        this.databaseName = databaseName;
-        objectMapper = new ObjectMapper();
-        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
-    }
-
-    private DatabaseSchema getDatabaseSchema (String databaseName) {
-        OvsdbClient client = NodeResource.getOvsdbClient(nodeId, this);
-        return client.getDatabaseSchema(databaseName);
-    }
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getTables() throws JsonProcessingException {
-        DatabaseSchema dbSchema = this.getDatabaseSchema(databaseName);
-        if (dbSchema == null) {
-            return Response.noContent().build();
-        }
-        String response = objectMapper.writeValueAsString(dbSchema.getTables());
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @GET
-    @Path("{name}")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getTableDetails(@PathParam("name") String name) throws JsonProcessingException {
-        String csTableName = this.caseSensitiveTableName(databaseName, name);
-        DatabaseSchema dbSchema = this.getDatabaseSchema(databaseName);
-        if (dbSchema == null) {
-            return Response.noContent().build();
-        }
-        TableSchema<GenericTableSchema> tableSchema = dbSchema.table(csTableName, GenericTableSchema.class);
-        String response = objectMapper.writeValueAsString(tableSchema);
-        return Response.status(Response.Status.OK)
-                .entity(response)
-                .build();
-    }
-
-    @Path("{name}/row")
-    public RowResource getDatabaseTables(@PathParam("name") String name){
-        return new RowResource(nodeId, databaseName, name);
-    }
-
-    private String caseSensitiveTableName (String databaseName, String ciTableName) {
-        DatabaseSchema dbSchema = this.getDatabaseSchema(databaseName);
-        if (dbSchema == null) {
-            return ciTableName;
-        }
-        Set<String> tables = dbSchema.getTables();
-        if (tables == null) {
-            return ciTableName;
-        }
-        for (String tableName : tables) {
-            if (tableName.equalsIgnoreCase(ciTableName)) {
-                return tableName;
-            }
-        }
-        return ciTableName;
-    }
-}
diff --git a/northbound/src/main/resources/WEB-INF/web.xml b/northbound/src/main/resources/WEB-INF/web.xml
deleted file mode 100644 (file)
index 61f9014..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
-        version="3.0">
-  <servlet>
-    <servlet-name>OVSDB</servlet-name>
-    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
-    <init-param>
-      <param-name>javax.ws.rs.Application</param-name>
-      <param-value> org.opendaylight.controller.northbound.commons.NorthboundApplication</param-value>
-    </init-param>
-    <init-param>
-        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
-        <param-value>true</param-value>
-    </init-param>
-    <load-on-startup>1</load-on-startup>
-  </servlet>
-
-  <servlet-mapping>
-    <servlet-name>OVSDB</servlet-name>
-    <url-pattern>/*</url-pattern>
-  </servlet-mapping>
-        <filter>
-          <filter-name>CorsFilter</filter-name>
-          <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
-          <init-param>
-            <param-name>cors.allowed.origins</param-name>
-            <param-value>*</param-value>
-          </init-param>
-          <init-param>
-            <param-name>cors.allowed.methods</param-name>
-            <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
-          </init-param>
-          <init-param>
-            <param-name>cors.allowed.headers</param-name>
-            <param-value>Content-Type,X-Requested-With,accept,authorization, origin,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
-          </init-param>
-          <init-param>
-            <param-name>cors.exposed.headers</param-name>
-            <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
-          </init-param>
-          <init-param>
-            <param-name>cors.support.credentials</param-name>
-            <param-value>true</param-value>
-          </init-param>
-          <init-param>
-            <param-name>cors.preflight.maxage</param-name>
-            <param-value>10</param-value>
-          </init-param>
-        </filter>
-        <filter-mapping>
-          <filter-name>CorsFilter</filter-name>
-          <url-pattern>/*</url-pattern>
-        </filter-mapping>
-
-        <security-constraint>
-          <web-resource-collection>
-            <web-resource-name>NB api</web-resource-name>
-            <url-pattern>/*</url-pattern>
-            <http-method>POST</http-method>
-            <http-method>GET</http-method>
-            <http-method>PUT</http-method>
-            <http-method>PATCH</http-method>
-            <http-method>DELETE</http-method>
-            <http-method>HEAD</http-method>
-          </web-resource-collection>
-          <auth-constraint>
-            <role-name>System-Admin</role-name>
-            <role-name>Network-Admin</role-name>
-          </auth-constraint>
-        </security-constraint>
-
-        <security-role>
-                <role-name>System-Admin</role-name>
-        </security-role>
-        <security-role>
-                <role-name>Network-Admin</role-name>
-        </security-role>
-
-        <login-config>
-                <auth-method>BASIC</auth-method>
-                <realm-name>opendaylight</realm-name>
-        </login-config>
-</web-app>
diff --git a/northbound/src/test/java/org/opendaylight/ovsdb/northbound/NodeResourceTest.java b/northbound/src/test/java/org/opendaylight/ovsdb/northbound/NodeResourceTest.java
deleted file mode 100644 (file)
index 872a305..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- *  Copyright (C) 2015 Red Hat, Inc.
- *
- *  This program and the accompanying materials are made available under the
- *  terms of the Eclipse Public License v1.0 which accompanies this distribution,
- *  and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- *  Authors : Sam Hague
- */
-package org.opendaylight.ovsdb.northbound;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.when;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.collect.Lists;
-import java.util.List;
-import javax.ws.rs.core.Response;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
-import org.opendaylight.ovsdb.plugin.api.Connection;
-import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
-import org.opendaylight.ovsdb.plugin.impl.ConnectionServiceImpl;
-import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(ServiceHelper.class)
-public class NodeResourceTest {
-    private static final String OVS = "OVS";
-    private static final String IDENTIFIER = "192.168.120.31:45001";
-    private static final String IDENTIFIER2 = "192.168.120.31:45002";
-    private static final String OVS_IDENTIFIER = OVS + "|" + IDENTIFIER;
-    private static final String OVS_IDENTIFIER2 = OVS + "|" + IDENTIFIER2;
-    private static final String BAD_IDENTIFIER = "BAD" + "|" + IDENTIFIER;
-
-    @Test
-    public void testGetOvsdbNode () {
-        ConnectionServiceImpl connectionService = new ConnectionServiceImpl();
-        Connection connection = new Connection(IDENTIFIER, null);
-        connectionService.putOvsdbConnection(IDENTIFIER, connection);
-
-        PowerMockito.mockStatic(ServiceHelper.class);
-        when(ServiceHelper.getGlobalInstance(eq(OvsdbConnectionService.class), anyObject()))
-                .thenReturn(null)
-                .thenReturn(connectionService)
-                .thenReturn(connectionService);
-
-        try {
-            NodeResource.getOvsdbNode(IDENTIFIER, this);
-            fail("Expected an ServiceUnavailableException to be thrown");
-        } catch (ServiceUnavailableException e) {
-            assertSame(ServiceUnavailableException.class, e.getClass());
-        }
-
-        try {
-            NodeResource.getOvsdbNode(BAD_IDENTIFIER, this);
-            fail("Expected an ResourceNotFoundException to be thrown");
-        } catch (ResourceNotFoundException e) {
-            assertSame(ResourceNotFoundException.class, e.getClass());
-        }
-
-        Node node = NodeResource.getOvsdbNode(OVS_IDENTIFIER, this);
-        assertNotNull("Node " + OVS_IDENTIFIER + " is null", node);
-    }
-
-    @Test
-    public void testGetOvsdbConnection () {
-        ConnectionServiceImpl connectionService = new ConnectionServiceImpl();
-        Connection connection = new Connection(IDENTIFIER, null);
-        connectionService.putOvsdbConnection(IDENTIFIER, connection);
-
-        PowerMockito.mockStatic(ServiceHelper.class);
-        when(ServiceHelper.getGlobalInstance(eq(OvsdbConnectionService.class), anyObject()))
-                .thenReturn(null)
-                .thenReturn(connectionService)
-                .thenReturn(connectionService);
-
-        try {
-            NodeResource.getOvsdbConnection(IDENTIFIER, this);
-            fail("Expected an ServiceUnavailableException to be thrown");
-        } catch (ServiceUnavailableException e) {
-            assertSame(ServiceUnavailableException.class, e.getClass());
-        }
-
-        try {
-            NodeResource.getOvsdbConnection(BAD_IDENTIFIER, this);
-            fail("Expected an ResourceNotFoundException to be thrown");
-        } catch (ResourceNotFoundException e) {
-            assertSame(ResourceNotFoundException.class, e.getClass());
-        }
-
-        Connection testConnection = NodeResource.getOvsdbConnection(IDENTIFIER, this);
-        assertNotNull("Connection " + OVS_IDENTIFIER + " is null", testConnection);
-    }
-
-    @Test
-    public void testGetNodes () {
-        ConnectionServiceImpl connectionService = new ConnectionServiceImpl();
-
-        PowerMockito.mockStatic(ServiceHelper.class);
-        when(ServiceHelper.getGlobalInstance(eq(OvsdbConnectionService.class), anyObject()))
-                .thenReturn(connectionService)
-                .thenReturn(connectionService)
-                .thenReturn(connectionService);
-
-        NodeResource nodeResource = new NodeResource();
-
-        // Check getNodes when there are no nodes
-        try {
-            Response response = nodeResource.getNodes();
-            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
-            assertNotNull("entity should not be null", response.getEntity());
-            String id = "";
-            List<String> ids = Lists.newArrayList();
-            ids.add(id);
-            assertEquals("there should be no nodes", ids.toString(), response.getEntity());
-        } catch (JsonProcessingException ex) {
-            fail("Exception should not have been caught");
-        }
-
-        // Check getNodes when there is a node
-        Connection connection = new Connection(IDENTIFIER, null);
-        connectionService.putOvsdbConnection(IDENTIFIER, connection);
-
-        try {
-            Response response = nodeResource.getNodes();
-            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
-            assertNotNull("entity should not be null", response.getEntity());
-            String id = "\"" + OVS_IDENTIFIER + "\"";
-            List<String> ids = Lists.newArrayList();
-            ids.add(id);
-            assertEquals(OVS_IDENTIFIER + " should be found", ids.toString(), response.getEntity());
-        } catch (JsonProcessingException ex) {
-            fail("Exception should not have been caught");
-        }
-
-        // Check getNodes when there are multiple nodes
-        connection = new Connection(IDENTIFIER2, null);
-        connectionService.putOvsdbConnection(IDENTIFIER2, connection);
-
-        try {
-            Response response = nodeResource.getNodes();
-            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
-            assertNotNull("entity should not be null", response.getEntity());
-            String id = "\"" + OVS_IDENTIFIER + "\"";
-            String id2 = "\"" + OVS_IDENTIFIER2 + "\"";
-            List<String> ids = Lists.newArrayList();
-            ids.add(id);
-            ids.add(id2);
-            assertEquals(OVS_IDENTIFIER + " and " + OVS_IDENTIFIER2 + " should be found",
-                    ids.toString().replaceAll("\\s",""), response.getEntity());
-        } catch (JsonProcessingException ex) {
-            fail("Exception should not have been caught");
-        }
-    }
-}
diff --git a/northbound/src/test/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3Test.java b/northbound/src/test/java/org/opendaylight/ovsdb/northbound/OvsdbNorthboundV3Test.java
deleted file mode 100644 (file)
index 9ecaf40..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-* Copyright (C) 2014 Red Hat, Inc.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*
-* Authors : Sam Hague
-*/
-package org.opendaylight.ovsdb.northbound;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.security.Principal;
-import javax.ws.rs.core.SecurityContext;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
-import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
-import org.opendaylight.controller.sal.authorization.Privilege;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(NorthboundUtils.class)
-public class OvsdbNorthboundV3Test {
-    private static final String USER = "admin";
-
-    @Test
-    public void testSetSecurityContext () {
-        SecurityContext securityContext = mock(SecurityContext.class);
-        Principal principal = mock(Principal.class);
-
-        when(securityContext.getUserPrincipal()).thenReturn(null)
-                .thenReturn(principal);
-        when(principal.getName()).thenReturn(USER);
-
-        OvsdbNorthboundV3 ovsdbNorthboundV3 = new OvsdbNorthboundV3();
-
-        // Check if SecurityContext is null
-        ovsdbNorthboundV3.setSecurityContext(null);
-        String userName = ovsdbNorthboundV3.getUserName();
-        assertNull(userName);
-
-        // Check if user has no Principal
-        ovsdbNorthboundV3.setSecurityContext(securityContext);
-        userName = ovsdbNorthboundV3.getUserName();
-        assertNull(userName);
-
-        // Success case
-        ovsdbNorthboundV3.setSecurityContext(securityContext);
-        userName = ovsdbNorthboundV3.getUserName();
-        assertEquals(USER, userName);
-    }
-
-    @Test
-    public void testGetNode () {
-        PowerMockito.mockStatic(NorthboundUtils.class);
-        when(NorthboundUtils.isAuthorized(anyString(), eq("default"), eq(Privilege.WRITE), anyObject()))
-                .thenReturn(false)
-                .thenReturn(true);
-
-        OvsdbNorthboundV3 ovsdbNorthboundV3 = new OvsdbNorthboundV3();
-
-        // Check for unauthorized user
-        try {
-            NodeResource nodeResource = ovsdbNorthboundV3.getNode();
-            fail("Expected an UnauthorizedException to be thrown");
-        } catch (UnauthorizedException e) {
-            assertSame(UnauthorizedException.class, e.getClass());
-        }
-
-        // Success case
-        NodeResource nodeResource = ovsdbNorthboundV3.getNode();
-        assertNotNull(nodeResource);
-    }
-}
index 95d4f75c3f3081f3cd52abb29461ce5a3fb16996..45699700631e75cf822ff6fa19e6a8a19b573fdc 100644 (file)
@@ -9,10 +9,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
   <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>mdsal-it-parent</artifactId>
-    <version>1.3.0-SNAPSHOT</version>
-    <relativePath/>
+    <groupId>org.opendaylight.ovsdb</groupId>
+    <artifactId>it</artifactId>
+    <version>1.2.1-SNAPSHOT</version>
+    <relativePath>../../commons/it</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.opendaylight.ovsdb</groupId>
@@ -40,12 +40,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <tag>HEAD</tag>
     <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
   </scm>
+
   <properties>
-    <skip.integrationtest>true</skip.integrationtest>
-    <sonar-jacoco-listeners.version>2.4</sonar-jacoco-listeners.version>
-    <root.directory>${env.PWD}</root.directory>
-    <sonar.jacoco.itReportPath>${root.directory}/target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
+    <karaf.distro.groupId>org.opendaylight.ovsdb</karaf.distro.groupId>
+    <karaf.distro.artifactId>karaf</karaf.distro.artifactId>
+    <karaf.distro.version>${project.version}</karaf.distro.version>
+    <karaf.distro.type>zip</karaf.distro.type>
   </properties>
+
   <dependencyManagement>
     <dependencies>
       <dependency>
@@ -91,190 +93,26 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>config-util</artifactId>
     </dependency>
-    <!-- Dependencies for pax exam karaf container -->
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-container-karaf</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam-junit4</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.exam</groupId>
-      <artifactId>pax-exam</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.ops4j.pax.url</groupId>
-      <artifactId>pax-url-aether</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>javax.inject</groupId>
-      <artifactId>javax.inject</artifactId>
-      <version>1</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.karaf.features</groupId>
-      <artifactId>org.apache.karaf.features.core</artifactId>
-      <version>${karaf.version}</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>compile</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>
-    <!-- AbstractConfigTestBase::getKarafDistro() needs this to find its version -->
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>karaf</artifactId>
-      <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <configuration>
-          <!-- Specific to generate mapping between tests and covered code -->
-          <!--<argLine>${jacoco.agent.it.arg}</argLine>-->
-          <properties>
-            <property>
-              <name>listener</name>
-              <value>org.sonar.java.jacoco.JUnitListener</value>
-            </property>
-          </properties>
-          <!-- Let's put failsafe reports with surefire to have access to tests failures/success reports in sonar -->
-          <!--<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>-->
-        </configuration>
-        <executions>
-          <execution>
-            <goals>
-              <goal>integration-test</goal>
-              <goal>verify</goal>
-            </goals>
-            <configuration>
-              <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
-              <skipTests>${skip.integrationtest}</skipTests>
-            </configuration>
-          </execution>
-        </executions>
+        <groupId>org.jacoco</groupId>
+        <artifactId>jacoco-maven-plugin</artifactId>
       </plugin>
-      <!-- Needed if you use versionAsInProject() -->
       <plugin>
-        <groupId>org.apache.servicemix.tooling</groupId>
-        <artifactId>depends-maven-plugin</artifactId>
-        <version>1.2</version>
-        <executions>
-          <execution>
-            <id>generate-depends-file</id>
-            <goals>
-              <goal>generate-depends-file</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <!--<plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-checkstyle-plugin</artifactId>
-        <configuration>
-          <configLocation>
-            ${project.basedir}/../../commons/parent/src/main/resources/ovsdb_checks.xml
-          </configLocation>
-          <includeTestSourceDirectory>true</includeTestSourceDirectory>
-          <failsOnError>true</failsOnError>
-          <includes>**/*.java,**/*.xml,**/*.ini,**/*.sh,**/*.bat</includes>
-          <excludes>**/yang/</excludes>
-        </configuration>
-      </plugin>-->
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>prepare-ut-agent</id>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-            <configuration>
-              <destFile>${sonar.jacoco.reportPath}</destFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>prepare-it-agent</id>
-            <goals>
-              <goal>prepare-agent-integration</goal>
-            </goals>
-            <configuration>
-              <append>true</append>
-              <destFile>${sonar.jacoco.itReportPath}</destFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>default-report</id>
-            <goals>
-              <goal>report</goal>
-            </goals>
-            <configuration>
-              <dataFile>${sonar.jacoco.reportPath}</dataFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>default-report-integration</id>
-            <goals>
-              <goal>report-integration</goal>
-            </goals>
-            <configuration>
-              <dataFile>${sonar.jacoco.itReportPath}</dataFile>
-            </configuration>
-          </execution>
-        </executions>
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <!-- Specific to generate mapping between tests and covered code -->
-          <!--<argLine>${jacoco.agent.ut.arg}</argLine>-->
-          <properties>
-            <property>
-              <name>listener</name>
-              <value>org.sonar.java.jacoco.JUnitListener</value>
-            </property>
-          </properties>
-          <!-- Let's put failsafe reports with surefire to have access to tests failures/success reports in sonar -->
-          <!--<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>-->
-        </configuration>
+        <artifactId>maven-failsafe-plugin</artifactId>
       </plugin>
     </plugins>
   </build>
-  <profiles>
-    <profile>
-      <id>integrationtest</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <properties>
-        <skip.integrationtest>false</skip.integrationtest>
-      </properties>
-    </profile>
-  </profiles>
 </project>
diff --git a/openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/MdsalUtils.java b/openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/MdsalUtils.java
deleted file mode 100644 (file)
index 927f8ea..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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.openstack.netvirt.it;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-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;
-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.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class for mdsal transactions.
- *
- * @author Sam Hague (shague@redhat.com)
- */
-public class MdsalUtils {
-    private static final Logger LOG = LoggerFactory.getLogger(MdsalUtils.class);
-    private DataBroker databroker = null;
-
-    /**
-     * Class constructor setting the data broker.
-     *
-     * @param dataBroker the {@link DataBroker}
-     */
-    public MdsalUtils(DataBroker dataBroker) {
-        this.databroker = dataBroker;
-    }
-
-    /**
-     * Executes delete as a blocking transaction.
-     *
-     * @param store {@link LogicalDatastoreType} which should be modified
-     * @param path {@link InstanceIdentifier} to read from
-     * @param <D> the data object type
-     * @return the result of the request
-     */
-    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();
-            result = true;
-        } catch (TransactionCommitFailedException e) {
-            LOG.warn("Failed to delete {} ", path, e);
-        }
-        return result;
-    }
-
-    /**
-     * Executes merge as a blocking transaction.
-     *
-     * @param logicalDatastoreType {@link LogicalDatastoreType} which should be modified
-     * @param path {@link InstanceIdentifier} for path to read
-     * @param <D> the data object type
-     * @return the result of the request
-     */
-    public <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean merge(
-            final LogicalDatastoreType logicalDatastoreType, final InstanceIdentifier<D> path, D data)  {
-        boolean result = false;
-        final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
-        transaction.merge(logicalDatastoreType, path, data, true);
-        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
-        try {
-            future.checkedGet();
-            result = true;
-        } catch (TransactionCommitFailedException e) {
-            LOG.warn("Failed to merge {} ", path, e);
-        }
-        return result;
-    }
-
-    /**
-     * Executes put as a blocking transaction.
-     *
-     * @param logicalDatastoreType {@link LogicalDatastoreType} which should be modified
-     * @param path {@link InstanceIdentifier} for path to read
-     * @param <D> the data object type
-     * @return the result of the request
-     */
-    public <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean put(
-            final LogicalDatastoreType logicalDatastoreType, final InstanceIdentifier<D> path, D data)  {
-        boolean result = false;
-        final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
-        transaction.put(logicalDatastoreType, path, data, true);
-        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
-        try {
-            future.checkedGet();
-            result = true;
-        } catch (TransactionCommitFailedException e) {
-            LOG.warn("Failed to put {} ", path, e);
-        }
-        return result;
-    }
-
-    /**
-     * Executes read as a blocking transaction.
-     *
-     * @param store {@link LogicalDatastoreType} to read
-     * @param path {@link InstanceIdentifier} for path to read
-     * @param <D> the data object type
-     * @return the result as the data object requested
-     */
-    public <D extends org.opendaylight.yangtools.yang.binding.DataObject> D read(
-            final LogicalDatastoreType store, final InstanceIdentifier<D> path)  {
-        D result = null;
-        final ReadOnlyTransaction transaction = databroker.newReadOnlyTransaction();
-        Optional<D> optionalDataObject;
-        CheckedFuture<Optional<D>, ReadFailedException> future = transaction.read(store, path);
-        try {
-            optionalDataObject = future.checkedGet();
-            if (optionalDataObject.isPresent()) {
-                result = optionalDataObject.get();
-            } else {
-                LOG.debug("{}: Failed to read {}",
-                        Thread.currentThread().getStackTrace()[1], path);
-            }
-        } catch (ReadFailedException e) {
-            LOG.warn("Failed to read {} ", path, e);
-        }
-        transaction.close();
-        return result;
-    }
-}
index 9d8cab55e70c7495006d1891a895e212004ebd80..2fe803176b59a8d863b5659ae85af571828d368c 100644 (file)
@@ -7,29 +7,35 @@
  */
 package org.opendaylight.ovsdb.openstack.netvirt.it;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+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.when;
+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.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.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 com.google.common.collect.Maps;
 
-import java.io.File;
 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 java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
-import javax.inject.Inject;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -38,22 +44,50 @@ 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;
+import org.opendaylight.neutron.spi.INeutronPortCRUD;
+import org.opendaylight.neutron.spi.INeutronSecurityGroupCRUD;
+import org.opendaylight.neutron.spi.INeutronSecurityRuleCRUD;
+import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
+import org.opendaylight.neutron.spi.NeutronPort;
+import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
+import org.opendaylight.neutron.spi.NeutronSecurityGroup;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.neutron.spi.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 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.southbound.SouthboundMapper;
+import org.opendaylight.ovsdb.utils.config.ConfigProperties;
+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.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.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.FlowId;
+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.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;
-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.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.node.attributes.InterfaceTypeEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
 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.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.node.TerminationPointBuilder;
@@ -62,13 +96,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
 import org.ops4j.pax.exam.options.MavenUrlReference;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -86,58 +117,27 @@ public class NetvirtIT extends AbstractMdsalTestBase {
     private static String addressStr;
     private static String portStr;
     private static String connectionType;
+    private static String controllerStr;
     private static AtomicBoolean setup = new AtomicBoolean(false);
     private static MdsalUtils mdsalUtils = null;
     private static Southbound southbound = null;
-    private static final String NETVIRT = "org.opendaylight.ovsdb.openstack.net-virt";
-    private static final String NETVIRTPROVIDERS = "org.opendaylight.ovsdb.openstack.net-virt-providers";
-
-    // TODO Constants copied frmo AbstractConfigTestBase, need to be removed (see TODO below)
-    private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
-    private static final String KARAF_DEBUG_PORT = "5005";
-    private static final String KARAF_DEBUG_PROP = "karaf.debug";
-    private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
-
-    @Inject
-    private BundleContext bundleContext;
-
-    @Configuration
-    public Option[] config() {
-        // TODO Figure out how to use the parent Karaf setup, then just use super.config()
-        Option[] options = new Option[] {
-                when(Boolean.getBoolean(KARAF_DEBUG_PROP))
-                        .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
-                karafDistributionConfiguration().frameworkUrl(getKarafDistro())
-                        .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
-                        .useDeployFolder(false),
-                when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
-                // Works only if we don't specify the feature repo and name
-                getLoggingOption()};
-        Option[] propertyOptions = getPropertiesOptions();
-        Option[] combinedOptions = new Option[options.length + propertyOptions.length];
-        System.arraycopy(options, 0, combinedOptions, 0, options.length);
-        System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
-        return combinedOptions;
-    }
-
-    @Override
-    public String getKarafDistro() {
-        return maven()
-                .groupId("org.opendaylight.ovsdb")
-                .artifactId("karaf")
-                .versionAsInProject()
-                .type("zip")
-                .getURL();
-    }
+    private static SouthboundUtils southboundUtils;
+    private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
+    private static final String SDPLNAME = "sg1";
+    private static final String NETWORK_ID = "521e29d6-67b8-4b3c-8633-027d21195111";
+    private static final String TENANT_ID = "521e29d6-67b8-4b3c-8633-027d21195100";
+    private static final String SUBNET_ID = "521e29d6-67b8-4b3c-8633-027d21195112";
+    private static final String PORT1_ID = "521e29d6-67b8-4b3c-8633-027d21195113";
+    private static final String DHCPPORT_ID ="521e29d6-67b8-4b3c-8633-027d21195115";
 
     @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
@@ -155,48 +155,84 @@ public class NetvirtIT extends AbstractMdsalTestBase {
         return "odl-ovsdb-openstack";
     }
 
-    protected String usage() {
-        return "Integration Test needs a valid connection configuration as follows :\n"
-                + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
-                + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
+    @Configuration
+    @Override
+    public Option[] config() {
+        Option[] parentOptions = super.config();
+        Option[] propertiesOptions = getPropertiesOptions();
+        Option[] otherOptions = getOtherOptions();
+        Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
+        System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
+        System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
+        System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
+                otherOptions.length);
+        return options;
+    }
+
+    private Option[] getOtherOptions() {
+        return new Option[] {
+                wrappedBundle(
+                        mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
+                                .version(asInProject())
+                                .type("jar")),
+                wrappedBundle(
+                        mavenBundle("org.opendaylight.ovsdb", "utils.config")
+                                .version(asInProject())
+                                .type("jar")),
+                configureConsole().startLocalConsole(),
+                vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
+                keepRuntimeFolder()
+        };
+    }
+
+    public Option[] getPropertiesOptions() {
+        return new Option[] {
+                propagateSystemProperties(NetvirtITConstants.SERVER_IPADDRESS,
+                        NetvirtITConstants.SERVER_PORT, NetvirtITConstants.CONNECTION_TYPE,
+                        NetvirtITConstants.CONTROLLER_IPADDRESS,
+                        NetvirtITConstants.USERSPACE_ENABLED)
+        };
     }
 
     @Override
     public Option getLoggingOption() {
         return composite(
+                //editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
+                //        "log4j.logger.org.opendaylight.controller",
+                //        LogLevelOption.LogLevel.TRACE.name()),
                 editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
                         "log4j.logger.org.opendaylight.ovsdb",
-                        LogLevelOption.LogLevel.DEBUG.name()),
+                        LogLevelOption.LogLevel.TRACE.name()),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        logConfiguration(NetvirtIT.class),
+                        LogLevelOption.LogLevel.INFO.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() {
-        Properties props = new Properties(System.getProperties());
-        String addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS,
-                NetvirtITConstants.DEFAULT_SERVER_IPADDRESS);
-        String portStr = props.getProperty(NetvirtITConstants.SERVER_PORT,
-                NetvirtITConstants.DEFAULT_SERVER_PORT);
-        String connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE,
-                NetvirtITConstants.CONNECTION_TYPE_ACTIVE);
-
-        LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
-                connectionType, addressStr, portStr);
-
-        Option[] options = new Option[] {
-                editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
-                        NetvirtITConstants.SERVER_IPADDRESS, addressStr),
-                editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
-                        NetvirtITConstants.SERVER_PORT, portStr),
-                editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
-                        NetvirtITConstants.CONNECTION_TYPE, connectionType),
-        };
-        return options;
+    }
+
+    protected String usage() {
+        return "Integration Test needs a valid connection configuration as follows :\n"
+                + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
+                + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
+    }
+
+    private void getProperties() {
+        Properties props = System.getProperties();
+        addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
+        portStr = props.getProperty(NetvirtITConstants.SERVER_PORT, NetvirtITConstants.DEFAULT_SERVER_PORT);
+        connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE, "active");
+        controllerStr = props.getProperty(NetvirtITConstants.CONTROLLER_IPADDRESS, "0.0.0.0");
+        String userSpaceEnabled = props.getProperty(NetvirtITConstants.USERSPACE_ENABLED, "no");
+        LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}, controller ip: {}, " +
+                "userspace.enabled: {}",
+                connectionType, addressStr, portStr, controllerStr, userSpaceEnabled);
+        if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
+            if (addressStr == null) {
+                fail(usage());
+            }
+        }
     }
 
     @Before
@@ -213,48 +249,85 @@ public class NetvirtIT extends AbstractMdsalTestBase {
             e.printStackTrace();
         }
 
-        addressStr = bundleContext.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
-        portStr = bundleContext.getProperty(NetvirtITConstants.SERVER_PORT);
-        connectionType = bundleContext.getProperty(NetvirtITConstants.CONNECTION_TYPE);
+        getProperties();
 
-        LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
-                connectionType, addressStr, portStr);
         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
             if (addressStr == null) {
                 fail(usage());
             }
         }
 
-        isBundleReady(bundleContext, NETVIRT);
-        isBundleReady(bundleContext, NETVIRTPROVIDERS);
-
-        //dataBroker = getSession().getSALService(DataBroker.class);
-        //Thread.sleep(3000);
-        //dataBroker = OvsdbInventoryServiceImpl.getDataBroker();
-        for (int i=0; i<20; i++) {
-            southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
-            if (southbound != null) {
-                dataBroker = southbound.getDatabroker();
-                if (dataBroker != null) {
-                    break;
+        dataBroker = getDatabroker(getProviderContext());
+        mdsalUtils = new MdsalUtils(dataBroker);
+        assertNotNull("mdsalUtils should not be null", mdsalUtils);
+        assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, getNetvirtTopology());
+        southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
+        assertNotNull("southbound should not be null", southbound);
+        southboundUtils = new SouthboundUtils(mdsalUtils);
+        setup.set(true);
+    }
+
+    private BindingAwareBroker.ProviderContext getProviderContext() {
+        BindingAwareBroker.ProviderContext providerContext = null;
+        for (int i=0; i < 60; i++) {
+            providerContext = getSession();
+            if (providerContext != null) {
+                break;
+            } else {
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
                 }
             }
-            LOG.warn("NetvirtIT: dataBroker is null");
-            Thread.sleep(5000);
         }
-        Assert.assertNotNull("dataBroker should not be null", dataBroker);
-        Thread.sleep(5000);
-
-        mdsalUtils = new MdsalUtils(dataBroker);
-        setup.set(true);
+        assertNotNull("providercontext should not be null", providerContext);
+        /* One more second to let the provider finish initialization */
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return providerContext;
+    }
+
+    private DataBroker getDatabroker(BindingAwareBroker.ProviderContext providerContext) {
+        DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
+        assertNotNull("dataBroker should not be null", dataBroker);
+        return dataBroker;
+    }
+
+    private Boolean getNetvirtTopology() {
+        LOG.info("getNetvirtTopology: looking for {}...", NETVIRT_TOPOLOGY_ID);
+        Boolean found = false;
+        final TopologyId topologyId = new TopologyId(new Uri(NETVIRT_TOPOLOGY_ID));
+        InstanceIdentifier<Topology> path =
+                InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
+        for (int i = 0; i < 60; i++) {
+            Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
+            if (topology != null) {
+                LOG.info("getNetvirtTopology: found {}...", NETVIRT_TOPOLOGY_ID);
+                found = true;
+                break;
+            } else {
+                LOG.info("getNetvirtTopology: still looking ({})...", i);
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return found;
     }
 
     /**
      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
-     * 6640. This test will wait for incoming connections for {@link NetvirtITConstants.CONNECTION_INIT_TIMEOUT} ms.
+     * 6640. This test will wait for incoming connections for {@link NetvirtITConstants#CONNECTION_INIT_TIMEOUT} ms.
      *
      * @throws InterruptedException
      */
+    @Ignore
     @Test
     public void testPassiveNode() throws InterruptedException {
         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_PASSIVE)) {
@@ -285,26 +358,25 @@ public class NetvirtIT extends AbstractMdsalTestBase {
     }
 
     private String connectionInfoToString(final ConnectionInfo connectionInfo) {
-        return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
+        return String.valueOf(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
     }
 
     private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
-                SouthboundMapper.createInstanceIdentifier(connectionInfo),
-                SouthboundMapper.createNode(connectionInfo));
+                SouthboundUtils.createInstanceIdentifier(connectionInfo),
+                SouthboundUtils.createNode(connectionInfo));
         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
         return result;
     }
 
     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
-        Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
-                SouthboundMapper.createInstanceIdentifier(connectionInfo));
-        return node;
+        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+                SouthboundUtils.createInstanceIdentifier(connectionInfo));
     }
 
     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
-                SouthboundMapper.createInstanceIdentifier(connectionInfo));
+                SouthboundUtils.createInstanceIdentifier(connectionInfo));
         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
         return result;
     }
@@ -326,57 +398,144 @@ public class NetvirtIT extends AbstractMdsalTestBase {
         return true;
     }
 
+    private String getControllerIPAddress() {
+        String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
+        if (addressString != null) {
+            try {
+                if (InetAddress.getByName(addressString) != null) {
+                    return addressString;
+                }
+            } catch (UnknownHostException e) {
+                LOG.error("Host {} is invalid", addressString);
+            }
+        }
+
+        addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
+        if (addressString != null) {
+            try {
+                if (InetAddress.getByName(addressString) != null) {
+                    return addressString;
+                }
+            } catch (UnknownHostException e) {
+                LOG.error("Host {} is invalid", addressString);
+            }
+        }
+
+        return null;
+    }
+
+    private short getControllerOFPort() {
+        short openFlowPort = Constants.OPENFLOW_PORT;
+        String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
+        if (portString != null) {
+            try {
+                openFlowPort = Short.parseShort(portString);
+            } catch (NumberFormatException e) {
+                LOG.warn("Invalid port:{}, use default({})", portString,
+                        openFlowPort);
+            }
+        }
+        return openFlowPort;
+    }
+
+    private List<String> getControllersFromOvsdbNode(Node node) {
+        List<String> controllersStr = new ArrayList<>();
+
+        String controllerIpStr = getControllerIPAddress();
+        if (controllerIpStr != null) {
+            // If codepath makes it here, the ip address to be used was explicitly provided.
+            // Being so, also fetch openflowPort provided via ConfigProperties.
+            controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                    + ":" + controllerIpStr + ":" + getControllerOFPort());
+        } else {
+            // Check if ovsdb node has manager entries
+            OvsdbNodeAugmentation ovsdbNodeAugmentation = southbound.extractOvsdbNode(node);
+            if (ovsdbNodeAugmentation != null) {
+                List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
+                if (managerEntries != null && !managerEntries.isEmpty()) {
+                    for (ManagerEntry managerEntry : managerEntries) {
+                        if (managerEntry == null || managerEntry.getTarget() == null) {
+                            continue;
+                        }
+                        String[] tokens = managerEntry.getTarget().getValue().split(":");
+                        if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
+                            controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                                    + ":" + tokens[1] + ":" + getControllerOFPort());
+                        } else if (tokens[0].equalsIgnoreCase("ptcp")) {
+                            ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
+                            if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
+                                controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
+                                controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                                        + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
+                            } else {
+                                LOG.warn("Ovsdb Node does not contain connection info: {}", node);
+                            }
+                        } else {
+                            LOG.trace("Skipping manager entry {} for node {}",
+                                    managerEntry.getTarget(), node.getNodeId().getValue());
+                        }
+                    }
+                } else {
+                    LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
+                }
+            }
+        }
+
+        if (controllersStr.isEmpty()) {
+            // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
+            LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
+            controllerIpStr = getLocalControllerHostIpAddress();
+            if (controllerIpStr != null) {
+                controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                        + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
+            }
+        }
+
+        if (controllersStr.isEmpty()) {
+            LOG.warn("Failed to determine OpenFlow controller ip address");
+        } else if (LOG.isDebugEnabled()) {
+            controllerIpStr = "";
+            for (String currControllerIpStr : controllersStr) {
+                controllerIpStr += " " + currControllerIpStr;
+            }
+            LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
+        }
+
+        return controllersStr;
+    }
+
     private String getLocalControllerHostIpAddress() {
         String ipaddress = null;
         try{
-            for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
-                 ifaces.hasMoreElements();) {
-                NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
+            for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();ifaces.hasMoreElements();){
+                NetworkInterface iface = ifaces.nextElement();
 
                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
-                    InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
-                    if (!inetAddr.isLoopbackAddress()) {
-                        if (inetAddr.isSiteLocalAddress()) {
-                            ipaddress = inetAddr.getHostAddress();
-                            break;
-                        }
+                    InetAddress inetAddr = inetAddrs.nextElement();
+                    if (!inetAddr.isLoopbackAddress() && inetAddr.isSiteLocalAddress()) {
+                        ipaddress = inetAddr.getHostAddress();
+                        break;
                     }
                 }
             }
         }catch (Exception e){
-            LOG.warn("Exception while fetching local host ip address ",e);
+            LOG.warn("Exception while fetching local host ip address ", e);
         }
         return ipaddress;
     }
 
     private String getControllerTarget(Node ovsdbNode) {
-        String target = null;
-        String ipAddr = null;
-        OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
-        ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
-        LOG.info("connectionInfo: {}", connectionInfo);
-        if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
-            ipAddr = new String(connectionInfo.getLocalIp().getValue());
-        }
-        if (ipAddr == null) {
-            ipAddr = getLocalControllerHostIpAddress();
-        }
-
-        if (ipAddr != null) {
-            target = NetvirtITConstants.OPENFLOW_CONNECTION_PROTOCOL + ":"
-                    + ipAddr + ":" + NetvirtITConstants.DEFAULT_OPENFLOW_PORT;
-        }
-
-        return target;
+        return getControllersFromOvsdbNode(ovsdbNode).get(0);
     }
 
-    //@Ignore//
     @Test
     public void testAddDeleteOvsdbNode() throws InterruptedException {
+        LOG.info("testAddDeleteOvsdbNode enter 3");
         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
         connectOvsdbNode(connectionInfo);
         ControllerEntry controllerEntry;
         for (int i = 0; i < 10; i++) {
+            LOG.info("testAddDeleteOvsdbNode ({}): looking for controller", i);
             Node ovsdbNode = getOvsdbNode(connectionInfo);
             Assert.assertNotNull("ovsdb node not found", ovsdbNode);
             String controllerTarget = getControllerTarget(ovsdbNode);
@@ -422,21 +581,6 @@ public class NetvirtIT extends AbstractMdsalTestBase {
         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
     }
 
-    private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
-                              final ConnectionInfo connectionInfo) {
-        InstanceIdentifier<Node> connectionNodePath = SouthboundMapper.createInstanceIdentifier(connectionInfo);
-        ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
-    }
-
-    private List<ProtocolEntry> createMdsalProtocols() {
-        List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
-        ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
-                SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
-        protocolList.add(new ProtocolEntryBuilder().
-                setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
-        return protocolList;
-    }
-
     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
                 new OvsdbTerminationPointAugmentationBuilder();
@@ -468,83 +612,12 @@ public class NetvirtIT 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<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
-
-        NodeBuilder bridgeNodeBuilder = new NodeBuilder();
-        if (bridgeIid == null) {
-            bridgeIid = SouthboundMapper.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) {
-            ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
-        }
-        if (setManagedBy) {
-            setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
-        }
-        if (dpType != null) {
-            ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
-        }
-        if (externalIds != null) {
-            ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
-        }
-        if (otherConfigs != null) {
-            ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
-        }
-        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 {
-
-        return addBridge(connectionInfo, null, bridgeName, null, true,
-                SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null);
-    }
-
-    private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
-        return getBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
-    }
-
     /**
      * Extract the <code>store</code> type data store contents for the particular bridge identified by
      * <code>bridgeName</code>.
      *
-     * @param connectionInfo
-     * @param bridgeName
+     * @param connectionInfo The connection information.
+     * @param bridgeName The bridge name.
      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
      * @return <code>store</code> type data store contents
      */
@@ -561,8 +634,8 @@ public class NetvirtIT extends AbstractMdsalTestBase {
      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
      * identified by <code>bridgeName</code>
      *
-     * @param connectionInfo
-     * @param bridgeName
+     * @param connectionInfo The connection information.
+     * @param bridgeName The bridge name.
      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
      */
@@ -574,78 +647,37 @@ public class NetvirtIT extends AbstractMdsalTestBase {
      * Extract the node contents from <code>store</code> type data store for the
      * bridge identified by <code>bridgeName</code>
      *
-     * @param connectionInfo
-     * @param bridgeName
+     * @param connectionInfo The connection information.
+     * @param bridgeName The bridge name.
      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
      * @return <code>store</code> type data store contents
      */
     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
         InstanceIdentifier<Node> bridgeIid =
-                SouthboundMapper.createInstanceIdentifier(connectionInfo,
+                SouthboundUtils.createInstanceIdentifier(connectionInfo,
                     new OvsdbBridgeName(bridgeName));
         return mdsalUtils.read(store, bridgeIid);
     }
 
-    /**
-     * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
-     * bridge identified by <code>bridgeName</code>
-     *
-     * @param connectionInfo
-     * @param bridgeName
-     * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
-     */
-    private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
-        return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
-    }
-
-    private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
-        return deleteBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
-    }
-
     private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
         throws InterruptedException {
 
         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
-                SouthboundMapper.createInstanceIdentifier(connectionInfo,
+                SouthboundUtils.createInstanceIdentifier(connectionInfo,
                         new OvsdbBridgeName(bridgeName)));
         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
         return result;
     }
 
     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
-        return SouthboundMapper.createInstanceIdentifier(connectionInfo,
+        return SouthboundUtils.createInstanceIdentifier(connectionInfo,
             bridge.getBridgeName());
     }
 
-    /**
-     * isBundleReady is used to check if the requested bundle is Active
-     */
-    public void isBundleReady(BundleContext bundleContext, String bundleName) throws InterruptedException {
-        boolean ready = false;
-
-        while (!ready) {
-            int state = Bundle.UNINSTALLED;
-            Bundle[] bundles = bundleContext.getBundles();
-            for (Bundle element : bundles) {
-                if (element.getSymbolicName().equals(bundleName)) {
-                    state = element.getState();
-                    LOG.info(">>>>> bundle is ready {}", bundleName);
-                    break;
-                }
-            }
-            if (state != Bundle.ACTIVE) {
-                LOG.info(">>>>> bundle not ready {}", bundleName);
-                Thread.sleep(5000);
-            } else {
-                ready = true;
-            }
-        }
-    }
-
     private void netVirtAddPort(ConnectionInfo connectionInfo) throws InterruptedException {
         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
         Assert.assertNotNull(bridge);
-        NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
+        NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
                 connectionInfo, bridge.getBridgeName()));
         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
                 createGenericOvsdbTerminationPointAugmentationBuilder();
@@ -668,13 +700,45 @@ public class NetvirtIT extends AbstractMdsalTestBase {
      * </pre>
      * @throws InterruptedException
      */
-    // TODO add verification of flows
-    //@Ignore //
     @Test
     public void testNetVirt() throws InterruptedException {
+        LOG.info("testNetVirt: starting test 2");
         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
-        connectOvsdbNode(connectionInfo);
+        Node ovsdbNode = connectOvsdbNode(connectionInfo);
+        LOG.info("testNetVirt: should be connected");
+
         Thread.sleep(10000);
+        LOG.info("testNetVirt: should really be connected after sleep");
+        // 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);
+        LOG.info("testNetVirt: bridgeNode: {}", bridgeNode);
+        long datapathId = southbound.getDataPathId(bridgeNode);
+        assertNotEquals("datapathId was not found", datapathId, 0);
+
+        //TODO add check for controller connection
+        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);
+            Thread.sleep(1000);
+            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));
@@ -688,6 +752,7 @@ public class NetvirtIT extends AbstractMdsalTestBase {
         Thread.sleep(60000);
     }
 
+    @Ignore
     @Test
     public void testReadOvsdbTopologyNodes() throws InterruptedException {
         Thread.sleep(10000);
@@ -696,4 +761,212 @@ public class NetvirtIT extends AbstractMdsalTestBase {
             LOG.info(">>>>> node: {}", node);
         }
     }
+
+    @Test
+    public void testNetVirtFixedSG() throws InterruptedException {
+        ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
+        assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
+        Node ovsdbNode = connectOvsdbNode(connectionInfo);
+        assertNotNull("node is not connected", ovsdbNode);
+
+        Thread.sleep(30000);
+        Node bridgeNode = southbound.getBridgeNode(ovsdbNode, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
+        assertNotNull("bridge " + NetvirtITConstants.INTEGRATION_BRIDGE_NAME + " was not found", bridgeNode);
+        long datapathId = southbound.getDataPathId(bridgeNode);
+        assertNotEquals("datapathId was not found", datapathId, 0);
+
+        NeutronNetwork nn = createNeutronNetwork(NETWORK_ID, TENANT_ID,NetworkHandler.NETWORK_TYPE_VXLAN, "100");
+        NeutronSubnet ns = createNeutronSubnet(SUBNET_ID, TENANT_ID, NETWORK_ID, "10.0.0.0/24");
+        NeutronPort nport = createNeutronPort(NETWORK_ID, SUBNET_ID, PORT1_ID, "compute", "10.0.0.10", "f6:00:00:0f:00:01");
+        NeutronPort dhcp = createNeutronPort(NETWORK_ID, SUBNET_ID, DHCPPORT_ID, "dhcp", "10.0.0.1", "f6:00:00:0f:00:02");
+
+        Thread.sleep(30000);
+        Map<String, String> externalIds = Maps.newHashMap();
+        externalIds.put("attached-mac", "f6:00:00:0f:00:01");
+        externalIds.put("iface-id", PORT1_ID);
+        southboundUtils.addTerminationPoint(bridgeNode, SDPLNAME, "internal", null, externalIds, 3L);
+        southboundUtils.addTerminationPoint(bridgeNode, "vm1", "internal", null, null, 0L);
+        southboundUtils.addTerminationPoint(bridgeNode, "vm2", "internal", null, null, 0L);
+        Map<String, String> options = Maps.newHashMap();
+        options.put("key", "flow");
+        options.put("remote_ip", "192.168.120.32");
+        southboundUtils.addTerminationPoint(bridgeNode, "vx", "vxlan", options, null, 4L);
+        Thread.sleep(1000);
+
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder =
+                FlowUtils.createNodeBuilder(datapathId);
+        MatchBuilder matchBuilder1 = new MatchBuilder();
+        matchBuilder1 = MatchUtils.createDhcpMatch(matchBuilder1, 68, 67);
+        String flowId1 = "Egress_DHCP_Client"  + "_Permit_";
+        FlowBuilder flowBuilder1 = initFlowBuilder(matchBuilder1, flowId1, (short)40);
+        Flow flow1 = getFlow(flowBuilder1, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+        assertNotNull("EgressSG : Could not find flow in configuration ", flow1);
+        flow1 = getFlow(flowBuilder1, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+        assertNotNull("EgressSG Operational : Could not find flow in config", flow1);
+
+        testDefaultsSG(nport, datapathId, nn);
+        Thread.sleep(30000);
+        Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
+        Thread.sleep(10000);
+        Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
+    }
+
+    private void testDefaultsSG(NeutronPort nport, long datapathId, NeutronNetwork nn)
+            throws InterruptedException {
+        INeutronSecurityGroupCRUD ineutronSecurityGroupCRUD =
+                (INeutronSecurityGroupCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityGroupCRUD.class, this);
+        assertNotNull("Could not find ineutronSecurityGroupCRUD Service", ineutronSecurityGroupCRUD);
+        INeutronSecurityRuleCRUD ineutronSecurityRuleCRUD =
+                (INeutronSecurityRuleCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityRuleCRUD.class, this);
+        assertNotNull("Could not find ineutronSecurityRuleCRUD Service", ineutronSecurityRuleCRUD);
+
+        NeutronSecurityGroup neutronSG = new NeutronSecurityGroup();
+        neutronSG.setSecurityGroupDescription("testig defaultSG-IT");
+        neutronSG.setSecurityGroupName("DefaultSG");
+        neutronSG.setSecurityGroupUUID("d3329053-bae5-4bf4-a2d1-7330f11ba5db");
+        neutronSG.setTenantID(TENANT_ID);
+
+        List<NeutronSecurityRule> nsrs = new ArrayList<>();
+        NeutronSecurityRule nsrIN = new NeutronSecurityRule();
+        nsrIN.setSecurityRemoteGroupID(null);
+        nsrIN.setSecurityRuleDirection("ingress");
+        nsrIN.setSecurityRuleEthertype("IPv4");
+        nsrIN.setSecurityRuleGroupID("d3329053-bae5-4bf4-a2d1-7330f11ba5db");
+        nsrIN.setSecurityRuleProtocol("TCP");
+        nsrIN.setSecurityRuleRemoteIpPrefix("10.0.0.0/24");
+        nsrIN.setSecurityRuleUUID("823faaf7-175d-4f01-a271-0bf56fb1e7e6");
+        nsrIN.setTenantID(TENANT_ID);
+
+        NeutronSecurityRule nsrEG = new NeutronSecurityRule();
+        nsrEG.setSecurityRemoteGroupID(null);
+        nsrEG.setSecurityRuleDirection("egress");
+        nsrEG.setSecurityRuleEthertype("IPv4");
+        nsrEG.setSecurityRuleGroupID("d3329053-bae5-4bf4-a2d1-7330f11ba5db");
+        nsrEG.setSecurityRuleProtocol("TCP");
+        nsrEG.setSecurityRuleRemoteIpPrefix("10.0.0.0/24");
+        nsrEG.setSecurityRuleUUID("823faaf7-175d-4f01-a271-0bf56fb1e7e1");
+        nsrEG.setTenantID(TENANT_ID);
+
+        nsrs.add(nsrIN);
+        nsrs.add(nsrEG);
+
+        neutronSG.setSecurityRules(nsrs);
+        ineutronSecurityRuleCRUD.addNeutronSecurityRule(nsrIN);
+        ineutronSecurityRuleCRUD.addNeutronSecurityRule(nsrEG);
+        ineutronSecurityGroupCRUD.add(neutronSG);
+
+        List<NeutronSecurityGroup> sgs = new ArrayList<>();
+        sgs.add(neutronSG);
+        nport.setSecurityGroups(sgs);
+
+        INeutronPortCRUD iNeutronPortCRUD =
+                (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        iNeutronPortCRUD.update(PORT1_ID, nport);
+
+        Thread.sleep(20000);
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilderEg =
+                FlowUtils.createNodeBuilder(datapathId);
+        MatchBuilder matchBuilderEg = new MatchBuilder();
+        matchBuilderEg = MatchUtils.createEtherMatchWithType(matchBuilderEg, null, nport.getMacAddress());
+        String flowIdEg = "Egress_IP" + nn.getProviderSegmentationID() + "_" + nport.getMacAddress() + "_Permit_";
+        FlowBuilder flowBuilderEg = initFlowBuilder(matchBuilderEg, flowIdEg, (short)40);
+        Flow flowEg = getFlow(flowBuilderEg, nodeBuilderEg, LogicalDatastoreType.CONFIGURATION);
+        assertNotNull("EgressSG : Could not find flow in configuration ", flowEg);
+        flowEg = getFlow(flowBuilderEg, nodeBuilderEg, LogicalDatastoreType.OPERATIONAL);
+        assertNotNull("EgressSG Operational : Could not find flow in config", flowEg);
+
+        org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilderIng =
+                FlowUtils.createNodeBuilder(datapathId);
+        MatchBuilder matchBuilderIng = new MatchBuilder();
+        matchBuilderIng = MatchUtils.createEtherMatchWithType(matchBuilderIng,null, nport.getMacAddress());
+        String flowIdIng = "Ingress_IP" + nn.getProviderSegmentationID() + "_" + nport.getMacAddress() + "_Permit_";
+        FlowBuilder flowBuilderIng = initFlowBuilder(matchBuilderIng, flowIdIng, (short)90);
+        Flow flowIng = getFlow(flowBuilderIng, nodeBuilderIng, LogicalDatastoreType.CONFIGURATION);
+        assertNotNull("IngressSG : Could not find flow in configuration ", flowIng);
+        flowIng = getFlow(flowBuilderIng, nodeBuilderIng, LogicalDatastoreType.OPERATIONAL);
+        assertNotNull("IngressSG Operational : Could not find flow in config", flowIng);
+
+    }
+
+    private NeutronPort createNeutronPort(String networkId, String subnetId,
+             String id, String owner, String ipaddr, String mac) {
+        INeutronPortCRUD iNeutronPortCRUD =
+                (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        NeutronPort np = new NeutronPort();
+        np.initDefaults();
+        np.setID(id);
+        np.setDeviceOwner(owner);
+        np.setMacAddress(mac);
+        np.setNetworkUUID(networkId);
+        List<org.opendaylight.neutron.spi.Neutron_IPs> srcAddressList =
+                new ArrayList<>();
+        org.opendaylight.neutron.spi.Neutron_IPs nip = new org.opendaylight.neutron.spi.Neutron_IPs();
+        nip.setIpAddress(ipaddr);
+        nip.setSubnetUUID(subnetId);
+        srcAddressList.add(nip);
+        np.setFixedIPs(srcAddressList);
+        List<NeutronSecurityGroup> nsgs = new ArrayList<>();
+        np.setSecurityGroups(nsgs);
+        iNeutronPortCRUD.add(np);
+        return np;
+    }
+
+    private NeutronSubnet createNeutronSubnet(String subnetId, String tenantId,
+              String networkId, String cidr) {
+        INeutronSubnetCRUD iNeutronSubnetCRUD =
+                (INeutronSubnetCRUD) ServiceHelper.getGlobalInstance(INeutronSubnetCRUD.class, this);
+        NeutronSubnet ns = new NeutronSubnet();
+        ns.setID(subnetId);
+        ns.setCidr(cidr);
+        ns.initDefaults();
+        ns.setNetworkUUID(networkId);
+        ns.setTenantID(tenantId);
+        iNeutronSubnetCRUD.add(ns);
+        return ns;
+    }
+
+    private NeutronNetwork createNeutronNetwork(String uuid, String tenantID, String networkTypeVxlan, String segId) {
+        INeutronNetworkCRUD iNeutronNetworkCRUD =
+                (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
+        NeutronNetwork nn = new NeutronNetwork();
+        nn.setID(uuid);
+        nn.initDefaults();
+        nn.setTenantID(tenantID);
+        nn.setProviderNetworkType(networkTypeVxlan);
+        nn.setProviderSegmentationID(segId);
+        iNeutronNetworkCRUD.addNetwork(nn);
+        return nn;
+    }
+
+    private FlowBuilder initFlowBuilder(MatchBuilder matchBuilder, String flowId, short tableId) {
+        FlowBuilder flowBuilder = new FlowBuilder();
+        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setId(new FlowId(flowId));
+        flowBuilder.setFlowName(flowId);
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setTableId(tableId);
+        flowBuilder.setKey(key);
+        return flowBuilder;
+    }
+
+    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++) {
+            LOG.info("getFlow {}-{}: looking for flowBuilder: {}, nodeBuilder: {}",
+                    i, store, flowBuilder.build(), nodeBuilder.build());
+            flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
+            if (flow != null) {
+                LOG.info("getFlow: found flow({}): {}", store, flow);
+                break;
+            }
+            Thread.sleep(1000);
+        }
+        return flow;
+    }
 }
index e1dc6ad6928e87b11820f860abda2ddd9eb07182..347be949553c2f0723a59f629473578a82a14b4e 100644 (file)
@@ -19,6 +19,8 @@ public final class NetvirtITConstants {
     public static final String CUSTOM_PROPERTIES = "etc/custom.properties";
     public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
     public static final String SERVER_PORT = "ovsdbserver.port";
+    public static final String CONTROLLER_IPADDRESS = "ovsdb.controller.address";
+    public static final String USERSPACE_ENABLED = "ovsdb.userspace.enabled";
     public static final String SERVER_EXTRAS = "ovsdbserver.extras";
     public static final String CONNECTION_TYPE = "ovsdbserver.connection";
     public static final String CONNECTION_TYPE_ACTIVE = "active";
diff --git a/openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundConstants.java b/openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundConstants.java
deleted file mode 100755 (executable)
index e302c2b..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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.openstack.netvirt.it;
-
-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.InterfaceTypeBase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeInternal;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypePatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeSystem;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeTap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGeneve;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre64;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre64;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeLisp;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkr;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhost;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuser;
-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.OvsdbBridgeProtocolOpenflow11;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow12;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow13;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow14;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow15;
-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.OvsdbFailModeSecure;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeStandalone;
-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.DatapathTypeSystem;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-
-import com.google.common.collect.ImmutableBiMap;
-
-public class SouthboundConstants {
-    public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
-    public static final String OVSDB_URI_PREFIX = "ovsdb";
-    public static final String BRIDGE_URI_PREFIX = "bridge";
-    public static final String TP_URI_PREFIX = "terminationpoint";
-    public static final Integer DEFAULT_OVSDB_PORT = 6640;
-    public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
-        = new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
-            .put(OvsdbBridgeProtocolOpenflow10.class,"OpenFlow10")
-            .put(OvsdbBridgeProtocolOpenflow11.class,"OpenFlow11")
-            .put(OvsdbBridgeProtocolOpenflow12.class,"OpenFlow12")
-            .put(OvsdbBridgeProtocolOpenflow13.class,"OpenFlow13")
-            .put(OvsdbBridgeProtocolOpenflow14.class,"OpenFlow14")
-            .put(OvsdbBridgeProtocolOpenflow15.class,"OpenFlow15")
-            .build();
-
-    public static final ImmutableBiMap<Class<? extends OvsdbFailModeBase>,String> OVSDB_FAIL_MODE_MAP
-        = new ImmutableBiMap.Builder<Class<? extends OvsdbFailModeBase>,String>()
-            .put(OvsdbFailModeStandalone.class,"standalone")
-            .put(OvsdbFailModeSecure.class,"secure")
-            .build();
-
-    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 static final ImmutableBiMap<Class<? extends DatapathTypeBase>,String> DATAPATH_TYPE_MAP
-        = new ImmutableBiMap.Builder<Class<? extends DatapathTypeBase>,String>()
-            .put(DatapathTypeSystem.class,"system")
-            .put(DatapathTypeNetdev.class,"netdev")
-            .build();
-    public static final String IID_EXTERNAL_ID_KEY = "opendaylight-iid";
-
-    public static enum VLANMODES {
-        ACCESS("access"),
-        NATIVE_TAGGED("native-tagged"),
-        NATIVE_UNTAGGED("native-untagged"),
-        TRUNK("trunk");
-
-        private final String mode;
-
-        private VLANMODES(String mode) {
-            this.mode = mode;
-        }
-        @Override
-        public String toString() {
-            return mode;
-        }
-
-        public String getMode() {
-            return this.mode;
-        }
-    }
-}
diff --git a/openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundMapper.java b/openstack/net-virt-it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/it/SouthboundMapper.java
deleted file mode 100644 (file)
index 0ca89b0..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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.openstack.netvirt.it;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashSet;
-import java.util.Set;
-
-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.rev150105.DatapathId;
-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.DatapathTypeSystem;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
-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.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.ovsdb.bridge.attributes.ProtocolEntry;
-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.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.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.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableBiMap;
-
-public class SouthboundMapper {
-    private static final Logger LOG = LoggerFactory.getLogger(SouthboundMapper.class);
-
-    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();
-    }
-
-    public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
-        OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
-        ovsdbNodeBuilder.setConnectionInfo(key);
-        return ovsdbNodeBuilder.build();
-    }
-
-    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 InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
-        return InstanceIdentifier
-                .create(NetworkTopology.class)
-                .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
-                .child(Node.class,new NodeKey(nodeId));
-    }
-
-    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
-        return createInstanceIdentifier(createManagedNodeId(key, bridgeName));
-    }
-
-    public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
-        NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
-        return nodeKey.getNodeId();
-    }
-
-    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
-        return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
-    }
-
-    public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
-        InstanceIdentifier<Node> path = InstanceIdentifier
-                .create(NetworkTopology.class)
-                .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
-                .child(Node.class,createNodeKey(ip,port));
-        LOG.debug("Created ovsdb path: {}",path);
-        return path;
-    }
-
-    public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
-        return new NodeKey(createNodeId(ip,port));
-    }
-
-    public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
-        return createManagedNodeId(key.getRemoteIp(),key.getRemotePort(),bridgeName);
-    }
-
-    public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
-        return new NodeId(createNodeId(ip,port).getValue()
-                + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
-    }
-
-    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);
-    }
-
-    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 DatapathId createDatapathId(Set<String> dpids) {
-        Preconditions.checkNotNull(dpids);
-        if (dpids.isEmpty()) {
-            return null;
-        } else {
-            String[] dpidArray = new String[dpids.size()];
-            dpids.toArray(dpidArray);
-            return createDatapathId(dpidArray[0]);
-        }
-    }
-
-    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()));
-            }
-        }
-        return datapathtype;
-    }
-
-    public static  Class<? extends DatapathTypeBase> createDatapathType(String type) {
-        Preconditions.checkNotNull(type);
-        if (type.isEmpty()) {
-            return DatapathTypeSystem.class;
-        } else {
-            ImmutableBiMap<String, Class<? extends DatapathTypeBase>> mapper =
-                    SouthboundConstants.DATAPATH_TYPE_MAP.inverse();
-            return mapper.get(type);
-        }
-    }
-
-    public static DatapathId createDatapathId(String dpid) {
-        Preconditions.checkNotNull(dpid);
-        DatapathId datapath;
-        if (dpid.matches("^[0-9a-fA-F]{16}")) {
-            Splitter splitter = Splitter.fixedLength(2);
-            Joiner joiner = Joiner.on(":");
-            datapath = new DatapathId(joiner.join(splitter.split(dpid)));
-        } else {
-            datapath = new DatapathId(dpid);
-        }
-        return datapath;
-    }
-
-    public static Set<String> createOvsdbBridgeProtocols(OvsdbBridgeAugmentation ovsdbBridgeNode) {
-        Set<String> protocols = new HashSet<String>();
-        if (ovsdbBridgeNode.getProtocolEntry() != null && ovsdbBridgeNode.getProtocolEntry().size() > 0) {
-            for (ProtocolEntry protocol : ovsdbBridgeNode.getProtocolEntry()) {
-                if (SouthboundConstants.OVSDB_PROTOCOL_MAP.get(protocol.getProtocol()) != null) {
-                    protocols.add(SouthboundConstants.OVSDB_PROTOCOL_MAP.get(protocol.getProtocol()));
-                } else {
-                    throw new IllegalArgumentException("Unknown protocol " + protocol.getProtocol());
-                }
-            }
-        }
-        return protocols;
-    }
-
-    public static  Class<? extends InterfaceTypeBase> createInterfaceType(String type) {
-        Preconditions.checkNotNull(type);
-        return SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(type);
-    }
-
-    public static String createOvsdbInterfaceType(Class<? extends InterfaceTypeBase> mdsaltype) {
-        Preconditions.checkNotNull(mdsaltype);
-        ImmutableBiMap<Class<? extends InterfaceTypeBase>, String> mapper =
-                SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.inverse();
-        return mapper.get(mdsaltype);
-    }
-}
index db41788e9a28490a1f3e43cc4c406470130ec6b1..2d7a664cfcd42835b5988c365ceb1c4bb89f2dd5 100644 (file)
@@ -44,72 +44,35 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   </scm>
 
   <properties>
-    <networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
-    <openflowjava-nicira.version>0.2.0-SNAPSHOT</openflowjava-nicira.version>
+    <liblldp.version>0.10.0-SNAPSHOT</liblldp.version>
     <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
-    <ovsdb.utils.config.version>1.2.1-SNAPSHOT</ovsdb.utils.config.version>
-    <ovsdb.utils.mdsal.openflow.version>1.2.1-SNAPSHOT</ovsdb.utils.mdsal.openflow.version>
-    <ovsdb.utils.servicehelper.version>1.2.1-SNAPSHOT</ovsdb.utils.servicehelper.version>
     <powermock.version>1.5.2</powermock.version>
-    <sonar-jacoco-listeners.version>2.4</sonar-jacoco-listeners.version>
-    <liblldp.version>0.10.0-SNAPSHOT</liblldp.version>
-    <root.directory>${env.PWD}</root.directory>
-    <sonar.jacoco.itReportPath>${root.directory}/target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
+    <sonar.jacoco.itReportPath>../net-virt-it/target/jacoco-it.exec</sonar.jacoco.itReportPath>
   </properties>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.opendaylight.mdsal</groupId>
-        <artifactId>mdsal-artifacts</artifactId>
-        <version>2.0.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.mdsal.model</groupId>
-        <artifactId>mdsal-model-artifacts</artifactId>
-        <version>0.8.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
   <dependencies>
+    <!-- project specific dependencies -->
     <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-config</artifactId>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>openstack.net-virt</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-common-api</artifactId>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>utils.mdsal-openflow</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.controller.model</groupId>
-      <artifactId>model-inventory</artifactId>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>southbound-api</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.neutron</groupId>
-      <artifactId>neutron-spi</artifactId>
-      <version>${networkconfig.neutron.version}</version>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>utils.servicehelper</artifactId>
+      <version>${project.version}</version>
     </dependency>
+    <!-- openflowplugin dependencies -->
     <dependency>
       <groupId>org.opendaylight.openflowplugin.model</groupId>
       <artifactId>model-flow-base</artifactId>
@@ -123,7 +86,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <dependency>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <artifactId>openflowjava-extension-nicira</artifactId>
-      <version>${openflowjava-nicira.version}</version>
+      <version>${openflowplugin.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.openflowplugin</groupId>
@@ -131,19 +94,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <version>${openflowplugin.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>openstack.net-virt</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>utils.mdsal-openflow</artifactId>
-      <version>${ovsdb.utils.mdsal.openflow.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.mdsal</groupId>
-      <artifactId>yang-binding</artifactId>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>openflowplugin-api</artifactId>
+      <version>${openflowplugin.version}</version>
     </dependency>
+    <!-- mdsal dependencies -->
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-inet-types</artifactId>
@@ -156,38 +111,17 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>opendaylight-l2-types</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>utils.servicehelper</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>concepts</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-topology</artifactId>
     </dependency>
+    <!-- controller dependencies -->
     <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>southbound-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.openflowplugin</groupId>
-      <artifactId>openflowplugin-api</artifactId>
-      <version>${openflowplugin.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>liblldp</artifactId>
+      <version>${liblldp.version}</version>
     </dependency>
-    <dependency>
-       <groupId>org.opendaylight.controller</groupId>
-       <artifactId>liblldp</artifactId>
-       <version>${liblldp.version}</version>
-     </dependency>
+    <!-- external dependencies -->
     <dependency>
       <groupId>com.google.code.findbugs</groupId>
       <artifactId>jsr305</artifactId>
@@ -195,13 +129,23 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <dependency>
       <groupId>io.netty</groupId>
       <artifactId>netty-buffer</artifactId>
-      <!-- Should be in a parent POM -->
-      <version>4.0.26.Final</version>
     </dependency>
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
     </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.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!-- testing dependencies -->
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
@@ -242,17 +186,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>junit</artifactId>
       <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.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <build>
@@ -265,88 +198,28 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
           <instructions>
             <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,
+              org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13
+            </Export-Package>
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <configuration>
-          <!-- Specific to generate mapping between tests and covered code -->
-          <!--<argLine>${jacoco.agent.it.arg}</argLine>-->
-          <properties>
-          <property>
-          <name>listener</name>
-          <value>org.sonar.java.jacoco.JUnitListener</value>
-          </property>
-          </properties>
-          <!-- Let's put failsafe reports with surefire to have access to tests failures/success reports in sonar -->
-          <!--<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>-->
-        </configuration>
-      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <!-- Specific to generate mapping between tests and covered code -->
-          <!--<argLine>${jacoco.agent.ut.arg}</argLine>-->
+          <excludes>
+            <exclude>**/services/*Test.java</exclude>
+          </excludes>
           <properties>
             <property>
               <name>listener</name>
               <value>org.sonar.java.jacoco.JUnitListener</value>
             </property>
           </properties>
-          <!-- Let's put failsafe reports with surefire to have access to tests failures/success reports in sonar -->
-          <!--<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>-->
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>prepare-ut-agent</id>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-            <configuration>
-              <destFile>${sonar.jacoco.reportPath}</destFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>prepare-it-agent</id>
-            <goals>
-              <goal>prepare-agent-integration</goal>
-            </goals>
-            <configuration>
-              <append>true</append>
-              <destFile>${sonar.jacoco.itReportPath}</destFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>default-report</id>
-            <goals>
-              <goal>report</goal>
-            </goals>
-            <configuration>
-              <dataFile>${sonar.jacoco.reportPath}</dataFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>default-report-integration</id>
-            <goals>
-              <goal>report-integration</goal>
-            </goals>
-            <configuration>
-              <dataFile>${sonar.jacoco.itReportPath}</dataFile>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
     </plugins>
   </build>
 </project>
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 d0083df4366bb585803abab0b7e14666dd059377..4a52cdfc789638b196f5696a1cd5a6429cbcb2af 100644 (file)
@@ -139,17 +139,21 @@ public abstract class AbstractServiceInstance {
     }
 
     protected void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        LOG.debug("writeFlow: flowBuilder: {}, nodeBuilder: {}",
+        LOG.debug("writeFlow 3: flowBuilder: {}, nodeBuilder: {}",
                 flowBuilder.build(), nodeBuilder.build());
         WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
+        LOG.debug("writeFlow: about to put nodePath for Flow {}, nodePath: {}",
+                flowBuilder.getFlowName(), createNodePath(nodeBuilder));
         modification.put(LogicalDatastoreType.CONFIGURATION, createNodePath(nodeBuilder),
                 nodeBuilder.build(), true /*createMissingParents*/);
+        LOG.debug("writeFlow: about to put Flow {}", flowBuilder.getFlowName());
         modification.put(LogicalDatastoreType.CONFIGURATION, createFlowPath(flowBuilder, nodeBuilder),
                 flowBuilder.build(), true /*createMissingParents*/);
-
+        LOG.debug("writeFlow: about to submit Flow {}", flowBuilder.getFlowName());
         CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
+        LOG.debug("writeFlow: checking status of Flow {}", flowBuilder.getFlowName());
         try {
-            commitFuture.get();  // TODO: Make it async (See bug 1362)
+            commitFuture.checkedGet();  // TODO: Make it async (See bug 1362)
             LOG.debug("Transaction success for write of Flow {}", flowBuilder.getFlowName());
         } catch (Exception e) {
             LOG.error(e.getMessage(), e);
index 12879dadda1c22db175238ea5b35d3002beb1fe8..fc331129eced6e12f7015e52bf901cdb34092474 100644 (file)
@@ -19,10 +19,10 @@ import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.Neutron_IPs;
+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.Neutron_IPs;
 import org.opendaylight.ovsdb.openstack.netvirt.MdsalHelper;
 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
@@ -1014,15 +1014,15 @@ public class OF13Provider implements ConfigInterface, NetworkingProvider {
             isLastPortinSubnet = false;
             if (isComputePort) {
                 isLastPortinSubnet = securityServicesManager.isLastPortinSubnet(node, intf);
-                srcAddressList = securityServicesManager.getIpAddressList(node, intf);
+                srcAddressList = securityServicesManager.getIpAddressList(intf);
                 if (null == srcAddressList) {
                     LOG.warn("programLocalRules: No Ip address assigned {}", intf);
                     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,17 +1033,75 @@ 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 {
             LOG.warn("programLocalRules: No DCHP port seen in  network of {}", intf);
         }
     }
+
+    /*
+     * The function is for the new compute node joining the existing network.
+     * When a new VM is instantiated in the new compute node, neutron port add
+     * event is generated. This event is processed only for that node. So,
+     * loop through all the ports of the same network and install unicast mac
+     * flow for the VM's created on the TEP of the destination node in src node.
+     * This function will be executed even for any new VM creation in an existing
+     * network. If a cache is maintained to optimize the below flow addition, it will
+     * work only for one unstack and restack. For the next unstack and restack,
+     * it will not work since the cache would have been already deleted.
+     */
+    private void programTunnelRulesInNewNode(NeutronNetwork network,
+                                             String networkType, String segmentationId,
+                                             InetAddress src, InetAddress dst,
+                                             Node srcBridgeNode, Node dstBridgeNode,
+                                             OvsdbTerminationPointAugmentation intf){
+        try {
+            long localPort = southbound.getOFPort(intf);
+            if(localPort != 0)
+            {
+                LOG.debug("Interface update details {}", intf);
+
+                /*
+                 * When a network is added and the TEP destination is not present in a
+                 * node C1, tunnelin and broadcast rules will not be programmed, since
+                 * OF port is not created. So, when a new node C2 joins and create a new
+                 * VM, the tunnelin and broadcast rule will not be present in C1.
+                 * So, handling it in the case below to make ping work.
+                 */
+                if(securityServicesManager.getNeutronPortFromDhcpIntf(intf) == null){
+                    programTunnelRules(networkType, segmentationId, src, dstBridgeNode, intf, true);
+                }
+
+                /*
+                 * FIX for 4208 - loop through all the ports and add the VM's
+                 * unicast mac rule of the destination node in the source node.
+                 * When a new node is added, it needs to configure the VM unicast mac
+                 * flow rules which were created before it was joined to an existing
+                 * network.
+                 */
+                List<OvsdbTerminationPointAugmentation> ports = southbound.getTerminationPointsOfBridge(dstBridgeNode);
+                for (OvsdbTerminationPointAugmentation port : ports) {
+                    if(network == tenantNetworkManager.getTenantNetwork(port)){
+                        programTunnelRules(networkType, segmentationId, dst, srcBridgeNode, port, false);
+                    }
+                    else{
+                        LOG.trace("Port {} is not part of network {}", port, network);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            LOG.error("Exception during handlingNeutron network add", e);
+        }
+    }
+
     @Override
     public boolean handleInterfaceUpdate(NeutronNetwork network, Node srcNode,
                                          OvsdbTerminationPointAugmentation intf) {
@@ -1060,7 +1118,7 @@ public class OF13Provider implements ConfigInterface, NetworkingProvider {
             programVlanRules(network, srcNode, intf);
         } else if (isTunnel(networkType)){
 
-            boolean sourceTunnelStatus;
+            boolean sourceTunnelStatus = false;
             boolean destTunnelStatus = false;
             for (Node dstNode : nodes.values()) {
                 InetAddress src = configurationService.getTunnelEndPoint(srcNode);
@@ -1080,6 +1138,8 @@ public class OF13Provider implements ConfigInterface, NetworkingProvider {
                     }
                     if (destTunnelStatus) {
                         programTunnelRules(networkType, segmentationId, src, dstBridgeNode, intf, false);
+                        programTunnelRulesInNewNode(network, networkType, segmentationId, src, dst,
+                                                    srcBridgeNode, dstBridgeNode, intf);
                     }
                 } else {
                     LOG.warn("Tunnel end-point configuration missing. Please configure it in OpenVSwitch Table. "
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 8ae8fab07d2ebf68d4e965c8f14f77799b89fee2..7aa754872c2980a41f47c64c9da198f67ff1d03a 100644 (file)
@@ -8,21 +8,23 @@
 
 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.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
-import org.opendaylight.neutron.spi.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;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefixBuilder;
 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.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
@@ -40,15 +42,23 @@ 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.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+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";
+    private static final int PORT_RANGE_MIN = 1;
+    private static final int PORT_RANGE_MAX = 65535;
 
     public EgressAclService() {
         super(Service.EGRESS_ACL);
@@ -59,11 +69,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;
         }
@@ -71,6 +80,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:
@@ -79,210 +89,153 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
              * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
              *
              */
-            if (portSecurityRule.getSecurityRuleEthertype().equals("IPv4")
+
+            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;
-                            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;
-                    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;
-                }
-               *//**
-               * 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;
+                    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 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;
+                if (write) {
+                    securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
+                } else {
+                    securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
                 }
-                  *//**
-                  * 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;
+            }
+        }
+    }
+
+    @Override
+    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();
+                try {
+                    InetAddress address = InetAddress.getByName(ipaddress);
+                    // TODO: remove this when ipv6 support is implemented
+                    if (address instanceof Inet6Address) {
+                        LOG.debug("Skipping ip address {}. IPv6 support is not yet implemented.", address);
+                        return;
+                    }
+                } catch (UnknownHostException e) {
+                    LOG.warn("Invalid ip address {}", ipaddress, e);
+                    return;
                 }
-                   *//**
-                   * 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 (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+                String prefixStr = portSecurityRule.getSecurityRuleRemoteIpPrefix();
+                try {
+                    IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(prefixStr);
+                    // TODO: remove this when ipv6 support is implemented
+                    if (ipPrefix.getIpv6Prefix() != null) {
+                        LOG.debug("Skipping ip prefix {}. IPv6 support is not yet implemented.", ipPrefix);
+                        return;
+                    }
+                } catch (IllegalArgumentException e) {
+                    LOG.warn("Invalid ip prefix {}", prefixStr, e);
+                    return;
                 }
-                LOG.debug("ACL Match combination not found for rule: {}", portSecurityRule);
-            }*/
+            }
+
+            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 programFixedSecurityAcl(Long dpid, String segmentationId, String attachedMac,
+    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
@@ -295,9 +248,19 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                  Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
             //Adds rule to check legitimate ip/mac pair for each packet from the vm
             for (Neutron_IPs srcAddress : srcAddressList) {
-                String addressWithPrefix = srcAddress.getIpAddress() + HOST_MASK;
-                egressAclAllowTrafficFromVmIpMacPair(dpid, localPort, attachedMac, addressWithPrefix,
-                                                     Constants.PROTO_VM_IP_MAC_MATCH_PRIORITY,write);
+                try {
+                    InetAddress address = InetAddress.getByName(srcAddress.getIpAddress());
+                    if (address instanceof Inet4Address) {
+                        String addressWithPrefix = srcAddress.getIpAddress() + HOST_MASK;
+                        egressAclAllowTrafficFromVmIpMacPair(dpid, localPort, attachedMac, addressWithPrefix,
+                                                             Constants.PROTO_VM_IP_MAC_MATCH_PRIORITY,write);
+                    } else {
+                        LOG.debug("Skipping IPv6 address {}. IPv6 support is not yet implemented.",
+                                  srcAddress.getIpAddress());
+                    }
+                } catch(UnknownHostException e) {
+                    LOG.warn("Invalid IP address {}", srcAddress.getIpAddress());
+                }
             }
         }
     }
@@ -336,13 +299,22 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                               NeutronSecurityRule portSecurityRule, String dstAddress,
                               boolean write, Integer protoPortMatchPriority) {
         MatchBuilder matchBuilder = new MatchBuilder();
-        String flowId = "Egress_Custom_Tcp" + segmentationId + "_" + srcMac + "_";
+        String flowId = "Egress_TCP_" + segmentationId + "_" + srcMac + "_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+
+        /* Custom TCP Match */
         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
-            flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+            flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
             matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
                                                      portSecurityRule.getSecurityRulePortMin());
         } else {
+            /* All TCP Match */
+            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+                    && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                            + portSecurityRule.getSecurityRulePortMax() + "_";
+                matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
+            }
             /*TODO TCP PortRange Match*/
 
         }
@@ -350,20 +322,68 @@ 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_";
+        flowId = flowId + "_Permit";
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
 
     }
+
+    /**
+     * Creates a egress match with src macaddress. If dest address is specified
+     * destination specific match will be created. Otherwise a match with a
+     * CIDR will be created.
+     * @param dpidLong the dpid
+     * @param segmentationId the segmentation id
+     * @param srcMac the source mac address.
+     * @param portSecurityRule the security rule in the SG
+     * @param dstAddress the source IP address
+     * @param write add or delete
+     * @param protoPortMatchPriority the protocol match priority
+     */
+    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 + "_";
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+        /*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,
+                    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);
+
+    }
+
     /**
      * Creates a egress match with src macaddress. If dest address is specified
      * destination specific match will be created. Otherwise a match with a
@@ -381,13 +401,22 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                               boolean write, Integer protoPortMatchPriority) {
 
         MatchBuilder matchBuilder = new MatchBuilder();
-        String flowId = "Eress_UDP" + segmentationId + "_" + srcMac + "_";
+        String flowId = "Egress_UDP_" + segmentationId + "_" + srcMac + "_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+
+        /* Custom UDP Match */
         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
-            flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+            flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
             matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
                                                      portSecurityRule.getSecurityRulePortMin());
         } else {
+            /* All UDP Match */
+            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+                    && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                    + portSecurityRule.getSecurityRulePortMax() + "_";
+                matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
+            }
             /*TODO UDP PortRange Match*/
 
         }
@@ -403,7 +432,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                         new Ipv4Prefix(portSecurityRule
                                                                        .getSecurityRuleRemoteIpPrefix()));
         }
-        flowId = flowId + "_Permit_";
+        flowId = flowId + "_Permit";
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
@@ -777,6 +806,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 2fe4ec5f77aa3904189d40ad8fc3ecbad2e68a12..2b9fb0ee01681b5fc9dcaeabcdc456f1c342eeab 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
 import java.math.BigInteger;
 import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
 import java.util.List;
 
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
@@ -42,8 +44,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14
 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 InboundNatService extends AbstractServiceInstance implements ConfigInterface, InboundNatProvider {
+    private static final Logger LOG = LoggerFactory.getLogger(InboundNatService.class);
     public static final Class<? extends NxmNxReg> REG_FIELD = NxmNxReg3.class;
 
     public InboundNatService() {
@@ -127,6 +132,20 @@ public class InboundNatService extends AbstractServiceInstance implements Config
         InstructionBuilder ib;
 
         MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+        String ipAddress = excludedCidr.substring(0, excludedCidr.indexOf("/"));
+        InetAddress inetAddress;
+        try {
+            inetAddress = InetAddress.getByName(ipAddress);
+        } catch (UnknownHostException e) {
+            return new Status(StatusCode.BADREQUEST);
+        }
+        if (inetAddress instanceof Inet6Address) {
+            // WORKAROUND: For now ipv6 is not supported
+            // TODO: implement ipv6 cidr case
+            LOG.debug("ipv6 cidr is not implemented yet. cidr {}",
+                      excludedCidr);
+            return new Status(StatusCode.NOTIMPLEMENTED);
+        }
         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(excludedCidr));
 
         // Goto Next Table
index c0f23c3f0b39c0f5dc39f1e9b230e2ff99ee9741..d33a1f450243fd4b31427ebfdf9d4a34fa8f3bc2 100644 (file)
@@ -8,21 +8,24 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
-import java.math.BigInteger;
-import java.util.List;
 
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
-import org.opendaylight.neutron.spi.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;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefixBuilder;
 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.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
@@ -40,12 +43,21 @@ 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.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+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;
 
     public IngressAclService() {
         super(Service.INGRESS_ACL);
@@ -56,11 +68,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;
         }
@@ -68,6 +80,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:
@@ -77,188 +90,142 @@ 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;
-                            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;
-                    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;
+                    programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
+                                            portSecurityRule, null, write);
                 }
-                  *//**
-                  * 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;
+                if (write) {
+                    securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
+                } else {
+                    securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
                 }
-                   *//**
-                   * 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;
+            }
+        }
+    }
+
+    @Override
+    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();
+                try {
+                    InetAddress address = InetAddress.getByName(ipaddress);
+                    // TODO: remove this when ipv6 support is implemented
+                    if (address instanceof Inet6Address) {
+                        LOG.debug("Skipping ip address {}. IPv6 support is not yet implemented.", address);
+                        return;
+                    }
+                } catch (UnknownHostException e) {
+                    LOG.warn("Invalid ip address {}", ipaddress, e);
+                    return;
                 }
-                    *//**
-                    * 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 (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+                String ipPrefixStr = portSecurityRule.getSecurityRuleRemoteIpPrefix();
+                try {
+                    IpPrefix ipPrefix = IpPrefixBuilder.getDefaultInstance(ipPrefixStr);
+                    // TODO: remove this when ipv6 support is implemented
+                    if (ipPrefix.getIpv6Prefix() != null) {
+                        LOG.debug("Skipping ip prefix {}. IPv6 support is not yet implemented.", ipPrefix);
+                        return;
+                    }
+                } catch (IllegalArgumentException e) {
+                    LOG.warn("Invalid ip prefix {}", ipPrefixStr, e);
+                    return;
                 }
-                     *//**
-                     * 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);
+            }
+
+            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 programFixedSecurityAcl(Long dpid, String segmentationId, String dhcpMacAddress,
+    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.
@@ -277,7 +244,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);
@@ -299,18 +266,27 @@ 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();
-        String flowId = "Ingress_Custom_Tcp" + segmentationId + "_" + dstMac + "_";
+        String flowId = "Ingress_TCP_" + segmentationId + "_" + dstMac + "_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+
+        /* Custom TCP Match*/
         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
-            flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+            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)
+                    && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                    + portSecurityRule.getSecurityRulePortMax() + "_";
+                matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
+            }
             /*TODO TCP PortRange Match*/
 
         }
@@ -328,7 +304,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         }
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-        flowId = flowId + "_Permit_";
+        flowId = flowId + "_Permit";
         syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
 
     }
@@ -346,16 +322,25 @@ 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 = "ingressAclUDP" + segmentationId + "_" + dstMac + "_";
+        String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+
+        /* Custom UDP Match */
         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
-            flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+            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)
+                    && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
+                    + portSecurityRule.getSecurityRulePortMax() + "_";
+                matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
+            }
             /*TODO TCP PortRange Match*/
 
         }
@@ -368,15 +353,66 @@ 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);
-        flowId = flowId + "_Permit_";
+        flowId = flowId + "_Permit";
         syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
 
     }
 
+    /**
+     * Creates a ingress match to the dst macaddress. If src address is specified
+     * source specific match will be created. Otherwise a match with a CIDR will
+     * be created.
+     * @param dpidLong the dpid
+     * @param segmentationId the segmentation id
+     * @param dstMac the destination mac address.
+     * @param portSecurityRule the security rule in the SG
+     * @param srcAddress the destination IP address
+     * @param write add or delete
+     * @param protoPortMatchPriority the protocol match priority
+     */
+    private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
+                                NeutronSecurityRule portSecurityRule, String srcAddress,
+                                boolean write, Integer protoPortMatchPriority) {
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+
+        /* 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);
+        } 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);
+    }
+
+
     public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
                                  Integer securityRulePortMin, Integer protoPortMatchPriority) {
 
@@ -576,6 +612,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
     public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
                                          boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
         MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
@@ -583,7 +620,6 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
                              .build());
         if (securityRuleIpPrefix != null) {
-            Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
             flowBuilder.setMatch(MatchUtils
                                  .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
                                  .build());
@@ -610,10 +646,11 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
 
         if (write) {
             // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
             InstructionsBuilder isb = new InstructionsBuilder();
             List<Instruction> instructionsList = Lists.newArrayList();
 
-            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
+            ib = this.getMutablePipelineInstructionBuilder();
             ib.setOrder(1);
             ib.setKey(new InstructionKey(0));
             instructionsList.add(ib.build());
@@ -700,6 +737,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 ce2eec801263f3741e6ac00b4a885a34c6c8f6ab..0eeddf214344e46c86fc57b2ca7d3df9488168bc 100644 (file)
@@ -9,6 +9,8 @@
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import org.opendaylight.ovsdb.openstack.netvirt.api.L2ForwardingProvider;
@@ -16,6 +18,7 @@ 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.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.inet.types.rev100924.Uri;
@@ -30,11 +33,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 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.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.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.ApplyActions;
 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;
@@ -42,14 +45,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-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;
 
-import com.google.common.collect.Lists;
-
 public class L2ForwardingService extends AbstractServiceInstance implements ConfigInterface, L2ForwardingProvider {
     private static final Logger LOG = LoggerFactory.getLogger(L2ForwardingService.class);
     public L2ForwardingService() {
@@ -72,50 +72,35 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
-        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "UcastOut_" + segmentationId + "_" + localPort + "_" + attachedMac;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
 
         if (write) {
-            // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-
             // Set the Output Port/Iface
-            InstructionUtils.createOutputPortInstructions(ib, dpidLong, localPort);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction setOutputPortInstruction =
+                    InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, localPort)
+                            .setOrder(0)
+                            .setKey(new InstructionKey(0))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, setOutputPortInstruction);
             writeFlow(flowBuilder, nodeBuilder);
         } else {
             removeFlow(flowBuilder, nodeBuilder);
         }
     }
+
     /*
      * (Table:2) Local VLAN unicast
      * Match: VLAN ID and dMAC
@@ -129,54 +114,36 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
-        flowBuilder.setMatch(
-                MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "VlanUcastOut_" + segmentationId + "_" + localPort + "_" + attachedMac;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
 
         if (write) {
-            // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-            List<Instruction> instructions_tmp = Lists.newArrayList();
-
             /* Strip vlan and store to tmp instruction space*/
-            InstructionUtils.createPopVlanInstructions(ib);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions_tmp.add(ib.build());
+            Instruction stripVlanInstruction = InstructionUtils.createPopVlanInstructions(new InstructionBuilder())
+                    .setOrder(0)
+                    .setKey(new InstructionKey(0))
+                    .build();
 
             // Set the Output Port/Iface
-            ib = new InstructionBuilder();
-            InstructionUtils.addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp);
-            ib.setOrder(1);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction setOutputPortInstruction =
+                    InstructionUtils.addOutputPortInstructions(new InstructionBuilder(), dpidLong, localPort,
+                            Collections.singletonList(stripVlanInstruction))
+                            .setOrder(1)
+                            .setKey(new InstructionKey(0))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, setOutputPortInstruction);
             writeFlow(flowBuilder, nodeBuilder);
         } else {
             removeFlow(flowBuilder, nodeBuilder);
@@ -184,33 +151,6 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
     }
 
 
-    /**
-     * Utility function used by the flooding logic to allow a flow to be resubmitted
-     * to the local port flooding rule, after being outputed to all available tunnel
-     * or VLAN egress ports.
-     */
-    private void appendResubmitLocalFlood(InstructionBuilder ib) {
-
-        //Update the ApplyActions instructions
-        ApplyActionsCase aac = (ApplyActionsCase) ib.getInstruction();
-        List<Action> actionList = aac.getApplyActions().getAction();
-
-        int index = actionList.size();
-        ActionBuilder ab = new ActionBuilder();
-        ab.setAction(ActionUtils.nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(ClassifierService.REG_FIELD).build(),
-                BigInteger.valueOf(ClassifierService.REG_VALUE_FROM_REMOTE)));
-        ab.setOrder(index);
-        ab.setKey(new ActionKey(index));
-        actionList.add(ab.build());
-
-        index++;
-        ab = new ActionBuilder();
-        ab.setAction(ActionUtils.nxResubmitAction(null, this.getTable()));
-        ab.setOrder(index);
-        ab.setKey(new ActionKey(index));
-        actionList.add(ab.build());
-    }
-
     /*
      * (Table:2) Local Broadcast Flood
      * Match: Tunnel ID and dMAC (::::FF:FF)
@@ -223,61 +163,45 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
-        MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_REMOTE));
-        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
-                new MacAddress("01:00:00:00:00:00")).build());
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.addNxRegMatch(matchBuilder,
+                new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_REMOTE));
+        MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+                new MacAddress("01:00:00:00:00:00"));
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "BcastOut_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(16384);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "BcastOut_" + segmentationId;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+                .setPriority(16384);
+
         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
-        // Instantiate the Builders for the OF Actions and Instructions
-        InstructionBuilder ib = new InstructionBuilder();
-        InstructionsBuilder isb = new InstructionsBuilder();
-        List<Instruction> instructions = Lists.newArrayList();
-        List<Instruction> existingInstructions = null;
-        if (flow != null) {
-            Instructions ins = flow.getInstructions();
-            if (ins != null) {
-                existingInstructions = ins.getInstruction();
-            }
-        }
+
+        // Retrieve the existing instructions
+        List<Instruction> existingInstructions = InstructionUtils.extractExistingInstructions(flow);
 
         if (write) {
             // Create output port list
-            createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
+            Instruction outputPortInstruction =
+                    createOutputPortInstructions(new InstructionBuilder(), dpidLong, localPort, existingInstructions)
+                            .setOrder(0)
+                            .setKey(new InstructionKey(0))
+                            .build();
 
-            /* Alternative method to address Bug 2004 is to make a call
-             * here to appendResubmitLocalFlood(ib) so that we send the
-             * flow back to the local flood rule.
-             */
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            /* Alternative method to address Bug 2004 is to use appendResubmitLocalFlood(ib) so that we send the
+             * flow back to the local flood rule. (See git history.) */
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
 
             writeFlow(flowBuilder, nodeBuilder);
         } else {
+            InstructionBuilder ib = new InstructionBuilder();
             boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong, localPort,
                     existingInstructions);
             if (flowRemove) {
@@ -285,15 +209,14 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
                 removeFlow(flowBuilder, nodeBuilder);
             } else {
                 /* Install instruction with new output port list*/
-                ib.setOrder(0);
-                ib.setKey(new InstructionKey(0));
-                instructions.add(ib.build());
-
-                // Add InstructionBuilder to the Instruction(s)Builder List
-                isb.setInstruction(instructions);
+                Instruction outputPortInstruction = ib
+                        .setOrder(0)
+                        .setKey(new InstructionKey(0))
+                        .build();
 
                 // Add InstructionsBuilder to FlowBuilder
-                flowBuilder.setInstructions(isb.build());
+                InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
+
                 writeFlow(flowBuilder, nodeBuilder);
             }
         }
@@ -313,78 +236,69 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
-        flowBuilder.setMatch(
-                MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
-                new MacAddress("01:00:00:00:00:00")).build());
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+                new MacAddress("01:00:00:00:00:00"));
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "VlanBcastOut_"+segmentationId+"_"+ethPort;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(16384);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "VlanBcastOut_" + segmentationId + "_" + ethPort;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+                .setPriority(16384);
         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
-        // Instantiate the Builders for the OF Actions and Instructions
-        List<Instruction> existingInstructions = null;
-        if (flow != null) {
-            Instructions ins = flow.getInstructions();
-            if (ins != null) {
-                existingInstructions = ins.getInstruction();
-            }
-        }
 
-        List<Instruction> instructions = Lists.newArrayList();
-        InstructionBuilder ib = new InstructionBuilder();
-        List<Action> actionList;
+        // Retrieve the existing instructions
+        List<Instruction> existingInstructions = InstructionUtils.extractExistingInstructions(flow);
+
         if (write) {
-            if (existingInstructions == null) {
+            List<Action> actionList;
+            if (existingInstructions == null || existingInstructions.isEmpty()) {
                 /* First time called there should be no instructions.
                  * We can simply add the output:ethPort first, followed by
                  * popVlan and then the local port. The next calls will append
                  * the rest of the local ports.
                  */
-                ActionBuilder ab = new ActionBuilder();
-                actionList = Lists.newArrayList();
-
-                ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + ethPort)));
-                ab.setOrder(0);
-                ab.setKey(new ActionKey(0));
-                actionList.add(ab.build());
-
-                ab.setAction(ActionUtils.popVlanAction());
-                ab.setOrder(1);
-                ab.setKey(new ActionKey(1));
-                actionList.add(ab.build());
-
-                ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)));
-                ab.setOrder(2);
-                ab.setKey(new ActionKey(2));
-                actionList.add(ab.build());
+                actionList = new ArrayList<>();
+
+                actionList.add(
+                        new ActionBuilder()
+                                .setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + ethPort)))
+                                .setOrder(0)
+                                .setKey(new ActionKey(0))
+                                .build());
+
+                actionList.add(
+                        new ActionBuilder()
+                                .setAction(ActionUtils.popVlanAction())
+                                .setOrder(1)
+                                .setKey(new ActionKey(1))
+                                .build());
+
+                actionList.add(
+                        new ActionBuilder()
+                                .setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)))
+                                .setOrder(2)
+                                .setKey(new ActionKey(2))
+                                .build());
             } else {
                 /* Subsequent calls require appending any new local ports for this tenant. */
                 Instruction in = existingInstructions.get(0);
                 actionList = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
 
                 NodeConnectorId ncid = new NodeConnectorId(nodeName + ":" + localPort);
+                final Uri nodeConnectorUri = new Uri(ncid);
                 boolean addNew = true;
 
                 /* Check if the port is already in the output list */
                 for (Action action : actionList) {
                     if (action.getAction() instanceof OutputActionCase) {
                         OutputActionCase opAction = (OutputActionCase) action.getAction();
-                        if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
+                        if (opAction.getOutputAction().getOutputNodeConnector().equals(nodeConnectorUri)) {
                             addNew = false;
                             break;
                         }
@@ -392,32 +306,29 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
                 }
 
                 if (addNew) {
-                    ActionBuilder ab = new ActionBuilder();
-
-                    ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)));
-                    ab.setOrder(actionList.size());
-                    ab.setKey(new ActionKey(actionList.size()));
-                    actionList.add(ab.build());
+                    actionList.add(
+                            new ActionBuilder()
+                                    .setAction(
+                                            ActionUtils.outputAction(new NodeConnectorId(nodeName + ":" + localPort)))
+                                    .setOrder(actionList.size())
+                                    .setKey(new ActionKey(actionList.size()))
+                                    .build());
                 }
             }
 
-            ApplyActionsBuilder aab = new ApplyActionsBuilder();
-            aab.setAction(actionList);
-            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            InstructionsBuilder isb = new InstructionsBuilder();
-            isb.setInstruction(instructions);
+            ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();
+            Instruction applyActionsInstruction =
+                    new InstructionBuilder()
+                            .setInstruction(new ApplyActionsCaseBuilder().setApplyActions(applyActions).build())
+                            .setOrder(0)
+                            .setKey(new InstructionKey(0))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, applyActionsInstruction);
             writeFlow(flowBuilder, nodeBuilder);
         } else {
-            //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
-            //                     localPort, existingInstructions);
+            InstructionBuilder ib = new InstructionBuilder();
             boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort, ethPort,
                     existingInstructions);
             if (flowRemove) {
@@ -425,16 +336,13 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
                 removeFlow(flowBuilder, nodeBuilder);
             } else {
                 /* Install instruction with new output port list*/
-                ib.setOrder(0);
-                ib.setKey(new InstructionKey(0));
-                instructions.add(ib.build());
-
-                // Add InstructionBuilder to the Instruction(s)Builder List
-                InstructionsBuilder isb = new InstructionsBuilder();
-                isb.setInstruction(instructions);
+                Instruction outputPortInstruction = ib
+                        .setOrder(0)
+                        .setKey(new InstructionKey(0))
+                        .build();
 
                 // Add InstructionsBuilder to FlowBuilder
-                flowBuilder.setInstructions(isb.build());
+                InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
                 writeFlow(flowBuilder, nodeBuilder);
             }
         }
@@ -442,43 +350,44 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
     private boolean removeOutputPortFromInstructions(InstructionBuilder ib, Long dpidLong, Long localPort,
                                                      Long ethPort, List<Instruction> instructions) {
-        List<Action> actionList = Lists.newArrayList();
+        List<Action> actionList = new ArrayList<>();
         boolean removeFlow = true;
 
-        if (instructions != null) {
+        if (instructions != null && !instructions.isEmpty()) {
             Instruction in = instructions.get(0);
             List<Action> oldActionList = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
             NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + localPort);
+            final Uri localNodeConnectorUri = new Uri(ncid);
             NodeConnectorId ncidEth = new NodeConnectorId(OPENFLOW + dpidLong + ":" + ethPort);
+            final Uri ethNodeConnectorUri = new Uri(ncidEth);
 
             // Remove the port from the output list
-            ActionBuilder ab = new ActionBuilder();
             int index = 2;
-            //for (ListIterator<Action> it = oldActionList.listIterator(oldActionList.size()); it.hasPrevious();) {
-            //    Action action = it.previous();
             for (Action action : oldActionList) {
                 if (action.getAction() instanceof OutputActionCase) {
                     OutputActionCase opAction = (OutputActionCase) action.getAction();
-                    if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncidEth))) {
+                    if (opAction.getOutputAction().getOutputNodeConnector().equals(ethNodeConnectorUri)) {
                         actionList.add(action);
-                    } else if (!opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
-                        ab.setAction(action.getAction());
-                        ab.setOrder(index);
-                        ab.setKey(new ActionKey(index));
-                        actionList.add(ab.build());
+                    } else if (!opAction.getOutputAction().getOutputNodeConnector().equals(localNodeConnectorUri)) {
+                        actionList.add(
+                                new ActionBuilder()
+                                        .setAction(action.getAction())
+                                        .setOrder(index)
+                                        .setKey(new ActionKey(index))
+                                        .build());
                         index++;
                     }
                 } else {
                     actionList.add(action);
                 }
             }
-            ApplyActionsBuilder aab = new ApplyActionsBuilder();
-            aab.setAction(actionList);
-            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+            ApplyActions applyActions = new ApplyActionsBuilder().setAction(actionList).build();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(applyActions).build());
         }
 
         if (actionList.size() > 2) {
             // Add InstructionBuilder to the Instruction(s)Builder List
+            // TODO This doesn't actually do anything
             InstructionsBuilder isb = new InstructionsBuilder();
             isb.setInstruction(instructions);
             removeFlow = false;
@@ -499,46 +408,28 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create Match(es) and Set them in the FlowBuilder Object
-        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+        flowBuilder.setMatch(
+                MatchUtils.createTunnelIDMatch(new MatchBuilder(), new BigInteger(segmentationId)).build());
 
         if (write) {
-            // Create the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-
             // Call the InstructionBuilder Methods Containing Actions
-            InstructionUtils.createDropInstructions(ib);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction dropInstruction = InstructionUtils.createDropInstructions(new InstructionBuilder())
+                    .setOrder(0)
+                    .setKey(new InstructionKey(0))
+                    .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, dropInstruction);
         }
 
-        String flowId = "LocalTableMiss_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(8192);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "LocalTableMiss_" + segmentationId;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+                .setPriority(8192);
         if (write) {
             writeFlow(flowBuilder, nodeBuilder);
         } else {
@@ -558,47 +449,29 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create Match(es) and Set them in the FlowBuilder Object
         flowBuilder.setMatch(
-                MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
+                MatchUtils.createVlanIdMatch(new MatchBuilder(), new VlanId(Integer.valueOf(segmentationId)),
+                        true).build());
 
         if (write) {
-            // Create the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-
             // Call the InstructionBuilder Methods Containing Actions
-            InstructionUtils.createDropInstructions(ib);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction dropInstruction = InstructionUtils.createDropInstructions(new InstructionBuilder())
+                    .setOrder(0)
+                    .setKey(new InstructionKey(0))
+                    .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, dropInstruction);
         }
 
-        String flowId = "LocalTableMiss_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(8192);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "LocalTableMiss_" + segmentationId;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+                .setPriority(8192);
         if (write) {
             writeFlow(flowBuilder, nodeBuilder);
         } else {
@@ -620,45 +493,29 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
-        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "TunnelOut_" + segmentationId + "_" + OFPortOut + "_" + attachedMac;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
 
         if (write) {
-            // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-
             // Set the Output Port/Iface
-            InstructionUtils.createOutputPortInstructions(ib, dpidLong, OFPortOut);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(1));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction outputPortInstruction =
+                    InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, OFPortOut)
+                            .setOrder(0)
+                            .setKey(new InstructionKey(1))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
 
             writeFlow(flowBuilder, nodeBuilder);
         } else {
@@ -679,44 +536,29 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
-        flowBuilder.setMatch(
-                MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null);
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "VlanOut_" + segmentationId + "_" + ethPort + "_" + attachedMac;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
 
         if (write) {
-            // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
             // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-            InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(1));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction outputPortInstruction =
+                    InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, ethPort)
+                            .setOrder(0)
+                            .setKey(new InstructionKey(1))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
 
             writeFlow(flowBuilder, nodeBuilder);
         } else {
@@ -736,59 +578,51 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
+        MatchBuilder matchBuilder = new MatchBuilder();
         // Match TunnelID
-        MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_LOCAL));
-        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+        MatchUtils.addNxRegMatch(matchBuilder,
+                new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_LOCAL));
+        MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
         // Match DMAC
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
-                new MacAddress("01:00:00:00:00:00")).build());
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+                new MacAddress("01:00:00:00:00:00"));
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "TunnelFloodOut_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setBarrier(true);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(16383);  // FIXME: change it back to 16384 once bug 3005 is fixed.
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "TunnelFloodOut_" + segmentationId;
+        final FlowId flowId = new FlowId(flowName);
+        flowBuilder
+                .setId(flowId)
+                .setBarrier(true)
+                .setTableId(getTable())
+                .setKey(new FlowKey(flowId))
+                .setPriority(16383)  // FIXME: change it back to 16384 once bug 3005 is fixed.
+                .setFlowName(flowName)
+                .setHardTimeout(0)
+                .setIdleTimeout(0);
 
         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
         // Instantiate the Builders for the OF Actions and Instructions
-        InstructionBuilder ib = new InstructionBuilder();
-        InstructionsBuilder isb = new InstructionsBuilder();
-        List<Instruction> instructions = Lists.newArrayList();
-        List<Instruction> existingInstructions = null;
-        if (flow != null) {
-            Instructions ins = flow.getInstructions();
-            if (ins != null) {
-                existingInstructions = ins.getInstruction();
-            }
-        }
+        List<Instruction> existingInstructions = InstructionUtils.extractExistingInstructions(flow);
 
         if (write) {
             // Set the Output Port/Iface
-            //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions);
-            createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction outputPortInstruction =
+                    createOutputPortInstructions(new InstructionBuilder(), dpidLong, OFPortOut, existingInstructions)
+                            .setOrder(0)
+                            .setKey(new InstructionKey(0))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
 
             writeFlow(flowBuilder, nodeBuilder);
         } else {
+            InstructionBuilder ib = new InstructionBuilder();
             /* remove port from action list */
             boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong,
                     OFPortOut, existingInstructions);
@@ -797,15 +631,13 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
                 removeFlow(flowBuilder, nodeBuilder);
             } else {
                 /* Install instruction with new output port list*/
-                ib.setOrder(0);
-                ib.setKey(new InstructionKey(0));
-                instructions.add(ib.build());
-
-                // Add InstructionBuilder to the Instruction(s)Builder List
-                isb.setInstruction(instructions);
+                Instruction instruction = ib
+                        .setOrder(0)
+                        .setKey(new InstructionKey(0))
+                        .build();
 
                 // Add InstructionsBuilder to FlowBuilder
-                flowBuilder.setInstructions(isb.build());
+                InstructionUtils.setFlowBuilderInstruction(flowBuilder, instruction);
                 writeFlow(flowBuilder, nodeBuilder);
             }
         }
@@ -824,50 +656,44 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create the OF Match using MatchBuilder
+        MatchBuilder matchBuilder = new MatchBuilder();
         // Match Vlan ID
-        flowBuilder.setMatch(
-                MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
+        MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true);
         // Match DMAC
-        flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
-                new MacAddress("01:00:00:00:00:00")).build());
+        MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"),
+                new MacAddress("01:00:00:00:00:00"));
+        flowBuilder.setMatch(matchBuilder.build());
 
-        String flowId = "VlanFloodOut_"+segmentationId+"_"+ethPort;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setBarrier(true);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(16384);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "VlanFloodOut_" + segmentationId + "_" + ethPort;
+        final FlowId flowId = new FlowId(flowName);
+        flowBuilder
+                .setId(flowId)
+                .setBarrier(true)
+                .setTableId(getTable())
+                .setKey(new FlowKey(flowId))
+                .setPriority(16384)
+                .setFlowName(flowName)
+                .setHardTimeout(0)
+                .setIdleTimeout(0);
 
         //ToDo: Is there something to be done with result of the call to getFlow?
-
         Flow flow = this.getFlow(flowBuilder, nodeBuilder);
-        // Instantiate the Builders for the OF Actions and Instructions
-        InstructionBuilder ib = new InstructionBuilder();
-        InstructionsBuilder isb = new InstructionsBuilder();
-        List<Instruction> instructions = Lists.newArrayList();
 
         if (write) {
             // Set the Output Port/Iface
-            InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction outputPortInstruction =
+                    InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, ethPort)
+                            .setOrder(0)
+                            .setKey(new InstructionKey(0))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
 
             writeFlow(flowBuilder, nodeBuilder);
         } else {
@@ -886,45 +712,28 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create Match(es) and Set them in the FlowBuilder Object
-        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+        flowBuilder.setMatch(
+                MatchUtils.createTunnelIDMatch(new MatchBuilder(), new BigInteger(segmentationId)).build());
 
         if (write) {
-            // Create the OF Actions and Instructions
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-
             // Call the InstructionBuilder Methods Containing Actions
-            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction mutablePipelineInstruction = getMutablePipelineInstructionBuilder()
+                    .setOrder(0)
+                    .setKey(new InstructionKey(0))
+                    .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, mutablePipelineInstruction);
         }
 
-        String flowId = "TunnelMiss_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(8192);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "TunnelMiss_" + segmentationId;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+                .setPriority(8192);
         if (write) {
             writeFlow(flowBuilder, nodeBuilder);
         } else {
@@ -945,47 +754,30 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
 
         String nodeName = OPENFLOW + dpidLong;
 
-        MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         // Create Match(es) and Set them in the FlowBuilder Object
         flowBuilder.setMatch(
-                MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId)), true).build());
+                MatchUtils.createVlanIdMatch(new MatchBuilder(), new VlanId(Integer.valueOf(segmentationId)),
+                        true).build());
 
         if (write) {
-            // Create the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-
             // Set the Output Port/Iface
-            InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(1));
-            instructions.add(ib.build());
-
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
+            Instruction outputPortInstruction =
+                    InstructionUtils.createOutputPortInstructions(new InstructionBuilder(), dpidLong, ethPort)
+                            .setOrder(0)
+                            .setKey(new InstructionKey(1))
+                            .build();
 
             // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
+            InstructionUtils.setFlowBuilderInstruction(flowBuilder, outputPortInstruction);
         }
 
-        String flowId = "VlanMiss_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(getTable());
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(8192);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
+        String flowName = "VlanMiss_" + segmentationId;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable())
+                .setPriority(8192);
         if (write) {
             writeFlow(flowBuilder, nodeBuilder);
         } else {
@@ -1007,7 +799,7 @@ public class L2ForwardingService extends AbstractServiceInstance implements Conf
         NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port);
         LOG.debug("createOutputPortInstructions() 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;
index d5389b12410705e98f6212afe1126a07894184e1..6b44c38d578df9d92d202f885aa98c942a6aab72 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
 import java.math.BigInteger;
 import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
 import java.util.List;
 
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
@@ -44,8 +46,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import com.google.common.collect.Lists;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class OutboundNatService extends AbstractServiceInstance implements OutboundNatProvider, ConfigInterface {
+    private static final Logger LOG = LoggerFactory.getLogger(OutboundNatService.class);
+
     public OutboundNatService() {
         super(Service.OUTBOUND_NAT);
     }
@@ -164,6 +170,20 @@ public class OutboundNatService extends AbstractServiceInstance implements Outbo
         InstructionBuilder ib;
 
         MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+        String ipAddress = excludedCidr.substring(0, excludedCidr.indexOf("/"));
+        InetAddress inetAddress;
+        try {
+            inetAddress = InetAddress.getByName(ipAddress);
+        } catch (UnknownHostException e) {
+            return new Status(StatusCode.BADREQUEST);
+        }
+        if (inetAddress instanceof Inet6Address) {
+            // WORKAROUND: For now ipv6 is not supported
+            // TODO: implement ipv6 cidr case
+            LOG.debug("ipv6 cidr is not implemented yet. cidr {}",
+                      excludedCidr);
+            return new Status(StatusCode.NOTIMPLEMENTED);
+        }
         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(excludedCidr));
 
         // Goto Next Table
index 38fc4702b73ce823047fd82d7b3131761fda313b..a8acadd9ede22d87a244fa8502d9caa4a1c8b9b0 100644 (file)
@@ -13,6 +13,7 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.List;
 
+import org.apache.commons.net.util.SubnetUtils;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
@@ -90,7 +91,8 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr
                       address);
             return new Status(StatusCode.NOTIMPLEMENTED);
         }
-        final String prefixString = address.getHostAddress() + "/" + mask;
+        SubnetUtils addressSubnetInfo = new SubnetUtils(address.getHostAddress() + "/" + mask);
+        final String prefixString = addressSubnetInfo.getInfo().getNetworkAddress() + "/" + mask;
         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString));
 
         // Set source Mac address
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 0ac0bc0884650f8d253a9b110e7b7069828575d6..aed4a647fe5732fc976215e32dc32cde994eab64 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.arp;
 
+import org.opendaylight.controller.liblldp.NetUtils;
 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.opendaylight.flow.service.rev130819.RemoveFlowInput;
@@ -26,6 +27,9 @@ public final class ArpResolverMetadata {
     private final boolean periodicRefresh;
     private RemoveFlowInput flowToRemove;
     private MacAddress gatewayMacAddress;
+    private boolean gatewayMacAddressResolved;
+    private int numberOfOutstandingArpRequests;
+    private static final int MAX_OUTSTANDING_ARP_REQUESTS = 2;
 
     public ArpResolverMetadata(final Long externalNetworkBridgeDpid,
             final Ipv4Address gatewayIpAddress, final Ipv4Address arpRequestSourceIp,
@@ -35,6 +39,9 @@ public final class ArpResolverMetadata {
         this.arpRequestSourceIp = arpRequestSourceIp;
         this.arpRequestSourceMacAddress = arpRequestMacAddress;
         this.periodicRefresh = periodicRefresh;
+        this.gatewayMacAddress = null;
+        this.gatewayMacAddressResolved = false;
+        this.numberOfOutstandingArpRequests = 0;
     }
 
     public RemoveFlowInput getFlowToRemove() {
@@ -53,6 +60,12 @@ public final class ArpResolverMetadata {
         return gatewayMacAddress;
     }
     public void setGatewayMacAddress(MacAddress gatewayMacAddress) {
+        if (gatewayMacAddress != null) {
+            gatewayMacAddressResolved = true;
+            numberOfOutstandingArpRequests = 0;
+        } else {
+            gatewayMacAddressResolved = false;
+        }
         this.gatewayMacAddress = gatewayMacAddress;
     }
 
@@ -62,10 +75,39 @@ public final class ArpResolverMetadata {
     public Ipv4Address getArpRequestSourceIp() {
         return arpRequestSourceIp;
     }
-    public MacAddress getArpRequestMacAddress() {
+    public MacAddress getArpRequestSourceMacAddress() {
         return arpRequestSourceMacAddress;
     }
 
+    /**
+     * This method is used to determine whether to use the broadcast MAC or the unicast MAC as the destination address
+     * for an ARP request packet based on whether one of the last MAX_OUTSTANDING_ARP_REQUESTS requests has been
+     * answered.
+     *
+     * A counter (numberOfOutstandingArpRequests) is maintained to track outstanding ARP requests.  This counter is
+     * incremented in this method and reset when setGatewayMacAddress() is called with an updated MAC address after an
+     * ARP reply is received. It is therefore expected that this method be called exactly once for each ARP request
+     * event, and not be called for other reasons, or it may result in more broadcast ARP request packets being sent
+     * than needed.
+     *
+     * @return Destination MAC address to be used in ARP request packet:  Either the unicast MAC or the broadcast MAC
+     * as described above.
+     */
+    public MacAddress getArpRequestDestMacAddress() {
+
+        numberOfOutstandingArpRequests++;
+
+        if (numberOfOutstandingArpRequests > MAX_OUTSTANDING_ARP_REQUESTS) {
+            gatewayMacAddressResolved = false;
+        }
+
+        if (gatewayMacAddressResolved) {
+            return gatewayMacAddress;
+        } else {
+            return ArpUtils.bytesToMac(NetUtils.getBroadcastMACAddr());
+        }
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
index 1030915e53a35df66f7f6e9267f9d335c4cf3189..8abc1251f3cfba1e11c5175964b2e8bccfdb34a0 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.liblldp.Ethernet;
 import org.opendaylight.controller.liblldp.NetUtils;
 import org.opendaylight.controller.liblldp.PacketException;
 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.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
@@ -69,7 +70,7 @@ public class ArpSender {
         NodeConnectorKey nodeConnectorKey = new NodeConnectorKey(createNodeConnectorId(OFPP_ALL,
                 nodeIid.firstKeyOf(Node.class, NodeKey.class).getId()));
         InstanceIdentifier<NodeConnector> egressNc = nodeIid.child(NodeConnector.class, nodeConnectorKey);
-        return sendArp(senderAddress, tpa, egressNc);
+        return sendArp(senderAddress, tpa, null, egressNc);
     }
 
     private NodeConnectorId createNodeConnectorId(String connectorId, NodeId nodeId) {
@@ -82,15 +83,15 @@ public class ArpSender {
      * @param senderAddress the addresses used in sender part of ARP packet
      * @param tpa the target protocol address, in this case IPv4 address for which MAC should be
      *        discovered
-     * @param egressNc the path to node connector from where the ARP packet will be sent
-     * @return future result about success of packet-out
+     * @param arpRequestDestMacAddress the destination MAC address to be used in the ARP packet or null if not known.
+     * @param egressNc the path to node connector from where the ARP packet will be sent  @return future result about success of packet-out
      */
     public ListenableFuture<RpcResult<Void>> sendArp(ArpMessageAddress senderAddress, Ipv4Address tpa,
-            InstanceIdentifier<NodeConnector> egressNc) {
+                                                     MacAddress arpRequestDestMacAddress, InstanceIdentifier<NodeConnector> egressNc) {
         checkNotNull(senderAddress);
         checkNotNull(tpa);
         checkNotNull(egressNc);
-        final Ethernet arpFrame = createArpFrame(senderAddress, tpa);
+        final Ethernet arpFrame = createArpFrame(senderAddress, tpa, arpRequestDestMacAddress);
         byte[] arpFrameAsBytes;
         try {
             arpFrameAsBytes = arpFrame.serialize();
@@ -113,10 +114,15 @@ public class ArpSender {
         return JdkFutureAdapters.listenInPoolThread(futureTransmitPacketResult);
     }
 
-    private Ethernet createArpFrame(ArpMessageAddress senderAddress, Ipv4Address tpa) {
+    private Ethernet createArpFrame(ArpMessageAddress senderAddress, Ipv4Address tpa, MacAddress arpRequestDestMacAddress) {
         byte[] senderMac = ArpUtils.macToBytes(senderAddress.getHardwareAddress());
         byte[] senderIp = ArpUtils.ipToBytes(senderAddress.getProtocolAddress());
-        byte[] targetMac = NetUtils.getBroadcastMACAddr();
+        byte[] targetMac;
+        if (arpRequestDestMacAddress != null) {
+            targetMac = ArpUtils.macToBytes(arpRequestDestMacAddress);
+        } else {
+            targetMac = NetUtils.getBroadcastMACAddr();
+        }
         byte[] targetIp = ArpUtils.ipToBytes(tpa);
         Ethernet arpFrame = new Ethernet().setSourceMACAddress(senderMac)
             .setDestinationMACAddress(targetMac)
index 7c2cfbebae8a3ab589561b4d89ec27bd831f686b..e74a7b60a7dad61ad5eebcea67d11fecbaabddc0 100644 (file)
@@ -89,7 +89,7 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                                         implements ConfigInterface, GatewayMacResolver,PacketProcessingListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(GatewayMacResolverService.class);
-    private static final short TABEL_FOR_ARP_FLOW = 0;
+    private static final short TABLE_FOR_ARP_FLOW = 0;
     private static final String ARP_REPLY_TO_CONTROLLER_FLOW_NAME = "GatewayArpReplyRouter";
     private static final int ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY = 10000;
     private static final Instruction SEND_TO_CONTROLLER_INSTRUCTION;
@@ -157,9 +157,9 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                                     }
 
                                     LOG.debug("Refresh Gateway Mac for gateway {} using source ip {} and mac {} for ARP request",
-                                            gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestMacAddress().getValue());
+                                            gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestSourceMacAddress().getValue());
 
-                                    sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestMacAddress());
+                                    sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestSourceMacAddress());
                                 }
                             }, 1, TimeUnit.SECONDS);
                         }
@@ -256,16 +256,24 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                 }
                 LOG.debug("Flow to route ARP Reply to Controller installed successfully : {}", flowIid);
 
+                ArpResolverMetadata gatewayArpMetadata = gatewayToArpMetadataMap.get(gatewayIp);
+                if (gatewayArpMetadata == null) {
+                    LOG.warn("No metadata found for gatewayIp: {}", gatewayIp);
+                    return;
+                }
+
                 //cache metadata
-                gatewayToArpMetadataMap.get(gatewayIp).setFlowToRemove(
-                        new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
+                gatewayArpMetadata.setFlowToRemove(new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
+
+                //get MAC DA for ARP packets
+                MacAddress arpRequestDestMacAddress = gatewayArpMetadata.getArpRequestDestMacAddress();
 
-                //Broadcast ARP request packets
+                //Send ARP request packets
                 for (NodeConnector egressNc : externalNetworkBridge.getNodeConnector()) {
                     KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> egressNcIid = nodeIid.child(
                             NodeConnector.class, new NodeConnectorKey(egressNc.getId()));
                     ListenableFuture<RpcResult<Void>> futureSendArpResult = arpSender.sendArp(
-                            senderAddress, gatewayIp, egressNcIid);
+                            senderAddress, gatewayIp, arpRequestDestMacAddress, egressNcIid);
                     Futures.addCallback(futureSendArpResult, logResult(gatewayIp, egressNcIid));
                 }
             }
@@ -304,7 +312,7 @@ public class GatewayMacResolverService extends AbstractServiceInstance
     private Flow createArpReplyToControllerFlow(final ArpMessageAddress senderAddress, final Ipv4Address ipForRequestedMac) {
         checkNotNull(senderAddress);
         checkNotNull(ipForRequestedMac);
-        FlowBuilder arpFlow = new FlowBuilder().setTableId(TABEL_FOR_ARP_FLOW)
+        FlowBuilder arpFlow = new FlowBuilder().setTableId(TABLE_FOR_ARP_FLOW)
             .setFlowName(ARP_REPLY_TO_CONTROLLER_FLOW_NAME)
             .setPriority(ARP_REPLY_TO_CONTROLLER_FLOW_PRIORITY)
             .setBufferId(OFConstants.OFP_NO_BUFFER)
index d6990521c53a6678a005be8deca41e9f996df4f2..9d9c97f6044f64f578753c29e134e2f32b565c70 100644 (file)
@@ -142,8 +142,9 @@ public class AbstractServiceInstanceTest {
 
         abstractServiceInstance.writeFlow(flowBuilder, nodeBuilder);
 
-        verify(transaction, times(2)).put(eq(LogicalDatastoreType.CONFIGURATION), any(InstanceIdentifier.class), any(DataObject.class), eq(true));
-        verify(commitFuture, times(1)).get();
+        //verify(transaction, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION), any(InstanceIdentifier.class), any(DataObject.class), eq(true));
+        //verify(transaction, times(1)).merge(eq(LogicalDatastoreType.CONFIGURATION), any(InstanceIdentifier.class), any(DataObject.class), eq(true));
+        //verify(commitFuture, times(1)).get();
     }
 
     /**
@@ -197,7 +198,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 4dff41cf635594196109ff8540cb3911ce57c790..a4ce294d9d5972560cf36d3a47bc7d63ea703fcf 100644 (file)
@@ -34,7 +34,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.MdsalHelper;
 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
index bf6774d19b8d8c9d95e7fedf05389f6aa098326f..c21b60fa0bbde363e34bdfde92fe71e68db7dfed 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;
@@ -22,45 +19,47 @@ import static org.mockito.Mockito.when;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.junit.Assert;
 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.mockito.Spy;
-import org.mockito.internal.matchers.Equality;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
-import org.opendaylight.neutron.spi.Neutron_IPs;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+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.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;
-import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
-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.MatchBuilder;
 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.model.match.types.rev131026.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.modules.junit4.PowerMockRunner;
 
 import com.google.common.util.concurrent.CheckedFuture;
 /**
  * Unit test for {@link EgressAclService}
  */
-@RunWith(MockitoJUnitRunner.class)
+@RunWith(PowerMockRunner.class)
 @SuppressWarnings("unchecked")
 public class EgressAclServiceTest {
 
     @InjectMocks private EgressAclService egressAclService = new EgressAclService();
-    @Spy private EgressAclService egressAclServiceSpy;
-    @Spy private MatchUtils matchUtil;
+    private EgressAclService egressAclServiceSpy;
 
     @Mock private DataBroker dataBroker;
     @Mock private PipelineOrchestrator orchestrator;
@@ -72,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";
@@ -86,10 +86,30 @@ 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;
+    private static final int PORT_RANGE_MIN = 1;
+    private static final int PORT_RANGE_MAX = 65535;
+    private static FlowBuilder flowBuilder;
+    private static NodeBuilder nodeBuilder;
+
+    private static Answer<Object> answer() {
+        return new Answer<Object>() {
+            @Override
+            public CheckedFuture<Void, TransactionCommitFailedException> answer(InvocationOnMock invocation)
+                    throws Throwable {
+                flowBuilder = (FlowBuilder) invocation.getArguments()[0];
+                nodeBuilder = (NodeBuilder) invocation.getArguments()[1];
+                return null;
+            }
+        };
+    }
 
     @Before
     public void setUp() {
-        egressAclServiceSpy = Mockito.spy(egressAclService);
+        egressAclServiceSpy = PowerMockito.spy(egressAclService);
 
         when(writeTransaction.submit()).thenReturn(commitFuture);
 
@@ -102,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();
@@ -118,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);
     }
 
     /**
@@ -246,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
@@ -272,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();
@@ -289,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();
@@ -301,15 +358,24 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramPortSecurityACLRuleAddTcp1() throws Exception {
         when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
-        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
-        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(20);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(20);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match=(TcpMatch) match.getLayer4Match();
+        Assert.assertEquals(20, layer4Match.getTcpDestinationPort().getValue().intValue());
+        int port=portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
@@ -318,15 +384,25 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramPortSecurityACLRuleRemoveTcp1() throws Exception {
         when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
-        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
-        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(30);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(30);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
-
-        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match = (TcpMatch) match.getLayer4Match();
+        Assert.assertEquals(30, layer4Match.getTcpDestinationPort().getValue().intValue());
+        int port=portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
@@ -335,16 +411,31 @@ public class EgressAclServiceTest {
     @Test
     public void testProgramPortSecurityACLRuleAddTcp2() throws Exception {
         when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
-        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
-        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
-        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(40);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(40);
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
-
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(4)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match=(TcpMatch) match.getLayer4Match();
+        int port=portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
@@ -355,14 +446,138 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
         when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
-        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match=(TcpMatch) match.getLayer4Match();
+        int port=portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
 
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+    /**
+     *  Test TCP add with port range (All TCP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddTcpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        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);
+        TcpMatch layer4Match=(TcpMatch) match.getLayer4Match();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+    }
 
-        verify(writeTransaction, times(2)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+    /**
+     *  Test TCP remove with port range (All TCP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveTcpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        Assert.assertEquals("Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                            PORT_RANGE_MAX + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test TCP add with port range (All TCP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddTcpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        String expectedFlowId1 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test TCP remove with port range (All TCP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveTcpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        String expectedFlowId1 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Egress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
@@ -374,16 +589,25 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
-     *  Test UDP add with port no and CIDR selected.
+     *  Test UDP remove with port no and CIDR selected.
      */
     @Test
     public void testProgramPortSecurityACLRuleRemoveUdp1() throws Exception {
@@ -391,12 +615,21 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
-
-        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
@@ -409,16 +642,33 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
-
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(4)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
-     *  Test UDP add with port no and remote SG selected.
+     *  Test UDP remove with port no and remote SG selected.
      */
     @Test
     public void testProgramPortSecurityACLRuleRemoveUdp2() throws Exception {
@@ -427,12 +677,263 @@ public class EgressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
 
-        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
 
-        verify(writeTransaction, times(2)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+    /**
+     *  Test UDP add with port (All UDP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddUdpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        Assert.assertEquals("Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                            PORT_RANGE_MAX + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test UDP remove with port (All UDP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveUdpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        Assert.assertEquals("Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                            PORT_RANGE_MAX + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test UDP add with port (All UDP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddUdpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        String expectedFlowId1 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test UDP remove with port (All UDP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveUdpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        egressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                     PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        String expectedFlowId1 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Egress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test ICMP add with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(10);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(10);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.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());
+        Assert.assertEquals(10, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        Assert.assertEquals("Egress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + type + "_" + code + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test ICMP remove with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(20);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(20);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.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());
+        Assert.assertEquals(20, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        Assert.assertEquals("Egress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + type + "_" + code + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test ICMP add with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(30);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(30);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.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());
+        Assert.assertEquals(30, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        String expectedFlowId1 = "Egress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + type + "_" + code + "_"
+                                + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Egress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + type + "_" + code + "_"
+                                + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test ICMP remove with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(40);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(40);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(egressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        egressAclServiceSpy.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());
+        Assert.assertEquals(40, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetSource().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        String expectedFlowId1 = "Egress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + type + "_" + code + "_"
+                                + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Egress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + type + "_" + code + "_"
+                                + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
@@ -442,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();
@@ -456,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();
@@ -468,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();
@@ -480,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();
@@ -493,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();
@@ -506,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();
@@ -519,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();
@@ -532,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();
@@ -545,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));
@@ -559,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();
@@ -571,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
@@ -587,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
@@ -603,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
@@ -619,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 6454c7ae4461c33c2464b1cd5d073f39cb357622..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;
@@ -22,39 +19,48 @@ import static org.mockito.Mockito.when;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.junit.Assert;
 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.mockito.Spy;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
-import org.opendaylight.neutron.spi.Neutron_IPs;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
 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.model.match.types.rev131026.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.modules.junit4.PowerMockRunner;
 
 import com.google.common.util.concurrent.CheckedFuture;
 
 /**
  * Unit test fort {@link IngressAclService}
  */
-@RunWith(MockitoJUnitRunner.class)
+@RunWith(PowerMockRunner.class)
 @SuppressWarnings("unchecked")
 public class IngressAclServiceTest {
 
     @InjectMocks private IngressAclService ingressAclService = new IngressAclService();
-    @Spy private IngressAclService ingressAclServiceSpy;
+    private IngressAclService ingressAclServiceSpy;
 
     @Mock private DataBroker dataBroker;
     @Mock private PipelineOrchestrator orchestrator;
@@ -65,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;
@@ -80,10 +87,30 @@ 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;
+    private static final int PORT_RANGE_MIN = 1;
+    private static final int PORT_RANGE_MAX = 65535;
+    private static FlowBuilder flowBuilder;
+    private static NodeBuilder nodeBuilder;
+
+    private static Answer<Object> answer() {
+        return new Answer<Object>() {
+            @Override
+            public CheckedFuture<Void, TransactionCommitFailedException> answer(InvocationOnMock invocation)
+                    throws Throwable {
+                flowBuilder = (FlowBuilder) invocation.getArguments()[0];
+                nodeBuilder = (NodeBuilder) invocation.getArguments()[1];
+                return null;
+            }
+        };
+    }
 
     @Before
     public void setUp() {
-        ingressAclServiceSpy = Mockito.spy(ingressAclService);
+        ingressAclServiceSpy = PowerMockito.spy(ingressAclService);
 
         when(writeTransaction.submit()).thenReturn(commitFuture);
 
@@ -95,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();
@@ -113,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);
     }
 
    /* *//**
@@ -242,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.
      */
@@ -252,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();
@@ -269,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();
@@ -282,15 +346,25 @@ public class IngressAclServiceTest {
     @Test
     public void testProgramPortSecurityACLRuleAddTcp1() throws Exception {
         when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
-        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
-        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(20);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(20);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match = (TcpMatch) match.getLayer4Match();
+        Assert.assertEquals(20, layer4Match.getTcpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
@@ -299,15 +373,25 @@ public class IngressAclServiceTest {
     @Test
     public void testProgramPortSecurityACLRuleRemoveTcp1() throws Exception {
         when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
-        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
-        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(15);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(15);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
-
-        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match = (TcpMatch) match.getLayer4Match();
+        Assert.assertEquals(15, layer4Match.getTcpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
@@ -320,12 +404,29 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
-
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(4)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match = (TcpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getTcpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
@@ -338,12 +439,143 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match = (TcpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getTcpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
 
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
 
-        verify(writeTransaction, times(2)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+    /**
+     *  Test TCP add with port (All TCP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddTcpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        Assert.assertEquals("Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                            PORT_RANGE_MAX + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test TCP remove with port (All TCP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveTcpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        Assert.assertEquals("Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                            PORT_RANGE_MAX + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test TCP add with port (All TCP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddTcpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        String expectedFlowId1 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                            PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN + "_" +
+                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test TCP remove with port (All TCP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveTcpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("tcp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof TcpMatch);
+        TcpMatch layer4Match = (TcpMatch) match.getLayer4Match();
+        String expectedFlowId1 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Ingress_TCP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + PORT_RANGE_MIN + "_" +
+                                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
@@ -355,16 +587,26 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
-     *  Test UDP add with port no and CIDR selected.
+     *  Test UDP remove with port no and CIDR selected.
      */
     @Test
     public void testProgramPortSecurityACLRuleRemoveUdp1() throws Exception {
@@ -372,12 +614,22 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
-
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
-
-        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(1)).submit();
-        verify(commitFuture, times(1)).get();
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        Assert.assertEquals("Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +
+                            "_" + port + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
     }
 
     /**
@@ -390,16 +642,33 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
-
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
-
-        verify(writeTransaction, times(4)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
-     *  Test UDP add with port no and remote SG selected.
+     *  Test UDP remove with port no and remote SG selected.
      */
     @Test
     public void testProgramPortSecurityACLRuleRemoveUdp2() throws Exception {
@@ -408,12 +677,263 @@ public class IngressAclServiceTest {
         when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
         when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
         when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        UdpMatch layer4Match = (UdpMatch) match.getLayer4Match();
+        Assert.assertEquals(50, layer4Match.getUdpDestinationPort().getValue().intValue());
+        int port = portSecurityRule.getSecurityRulePortMin();
+        String expectedFlowId1 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_1 +
+                "_Permit";
+        String expectedFlowId2 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + port + "_" + DEST_IP_2 +
+                "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
 
-        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+    /**
+     *  Test UDP add with ports (All UDP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddUdpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
 
-        verify(writeTransaction, times(2)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(2)).submit();
-        verify(commitFuture, times(2)).get();
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        Assert.assertEquals("Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN  + "_" +
+                            PORT_RANGE_MAX + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test UDP remove with ports (All UDP) and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveUdpAll1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        Assert.assertEquals("Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + PORT_RANGE_MIN  + "_" +
+                PORT_RANGE_MAX + "_0.0.0.0/24_Permit", flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test UDP add with ports (All UDP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddUdpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, true);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        String expectedFlowId1 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + PORT_RANGE_MIN + "_" +
+                        PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + PORT_RANGE_MIN + "_" +
+                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test UDP remove with ports (All UDP) and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveUdpAll2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("udp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(PORT_RANGE_MAX);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(PORT_RANGE_MIN);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        ingressAclServiceSpy.programPortSecurityGroup(DP_ID_LONG, SEGMENT_ID, MAC_ADDRESS, LOCAL_PORT, securityGroup,
+                                                      PORT_UUID, false);
+
+        Match match = flowBuilder.getMatch();
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+
+        Assert.assertTrue(match.getLayer4Match() instanceof UdpMatch);
+        String expectedFlowId1 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + PORT_RANGE_MIN + "_" +
+                        PORT_RANGE_MAX + "_" + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Ingress_UDP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + PORT_RANGE_MIN + "_" +
+                PORT_RANGE_MAX + "_" + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if (actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test ICMP add with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(10);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(10);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+        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());
+        Assert.assertEquals(10, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        Assert.assertEquals("Ingress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + type + "_" + code
+                            + "_0.0.0.0/24_Permit",
+                            flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test ICMP remove with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(20);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(20);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        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());
+        Assert.assertEquals(20, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        Assert.assertEquals("Ingress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS + "_" + type + "_" + code
+                            + "_0.0.0.0/24_Permit",
+                            flowBuilder.getFlowName());
+    }
+
+    /**
+     *  Test ICMP add with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(30);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(30);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer()).when(ingressAclServiceSpy, "writeFlow", any(FlowBuilder.class),
+                                             any(NodeBuilder.class));
+
+        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());
+        Assert.assertEquals(30, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        String expectedFlowId1 = "Ingress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + type + "_" + code + "_"
+                                + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Ingress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + type + "_" + code + "_"
+                                + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
+    }
+
+    /**
+     *  Test ICMP remove with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(40);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(40);
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+        PowerMockito.doAnswer(answer())
+        .when(ingressAclServiceSpy, "removeFlow", any(FlowBuilder.class), any(NodeBuilder.class));
+
+        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());
+        Assert.assertEquals(40, icmpv4Match.getIcmpv4Code().shortValue());
+        EthernetMatch ethMatch = match.getEthernetMatch();
+        Assert.assertEquals(MAC_ADDRESS, ethMatch.getEthernetDestination().getAddress().getValue());
+        Short type = portSecurityRule.getSecurityRulePortMin().shortValue();
+        Short code = portSecurityRule.getSecurityRulePortMax().shortValue();
+        String expectedFlowId1 = "Ingress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + type + "_" + code + "_"
+                                + DEST_IP_1 + "_Permit";
+        String expectedFlowId2 = "Ingress_ICMP_" + SEGMENT_ID + "_" + MAC_ADDRESS +"_" + type + "_" + code + "_"
+                                + DEST_IP_2 + "_Permit";
+        String actualFlowId = flowBuilder.getFlowName();
+        if(actualFlowId.equals(expectedFlowId1) || actualFlowId.equals(expectedFlowId2)) {
+            Assert.assertTrue(true);
+        } else {
+            Assert.assertTrue(false);
+        }
     }
 
     /**
@@ -423,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();
@@ -437,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();
@@ -449,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();
@@ -461,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();
@@ -473,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
@@ -489,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
@@ -505,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
@@ -521,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
@@ -537,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 7da9620049f5f800362b982d9c457938d6802236..75049d0d0e309d3f466bae15a6b5206749848ece 100644 (file)
@@ -19,9 +19,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>openstack.net-virt-sfc-api</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
+  <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,5 +39,30 @@ 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>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              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>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
index b16942a5e5a0658abbc1524ddfa04ee1670a1a24..0f4c9953167ea1466fe8fb42d3d86ba9b664f374 100644 (file)
@@ -3,19 +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: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;
         }
     }
+
+    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;
+                        }
+                    }
+                }
+            }
         }
     }
 }
index 63440723cc57f10248ff7c98e5d39fccc25b685b..a4c0e0998bf832075badf9cdb6e28ffb141f651a 100644 (file)
@@ -11,10 +11,17 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>openstack.net-virt-sfc-artifacts</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
+  <version>1.2.1-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <dependencyManagement>
index b43649aa802a03a9086e2a0b5102290aa4f961f6..88af585c31a214e3d897ab33831a8590e4b2c2cd 100644 (file)
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 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 INTERNAL
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
-    <artifactId>features-parent</artifactId>
+    <artifactId>odlparent-lite</artifactId>
     <version>1.6.0-SNAPSHOT</version>
     <relativePath/>
   </parent>
+
   <groupId>org.opendaylight.ovsdb</groupId>
-  <artifactId>openstack.net-virt-sfc-features</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
-  <name>${project.artifactId}</name>
+  <artifactId>openstack.net-virt-sfc-features-aggregator</artifactId>
+  <version>1.2.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
   <modelVersion>4.0.0</modelVersion>
   <prerequisites>
     <maven>3.1.1</maven>
   </prerequisites>
-  <properties>
-    <mdsal.model.version>0.8.0-SNAPSHOT</mdsal.model.version>
-    <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
-    <restconf.version>1.3.0-SNAPSHOT</restconf.version>
-    <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
-    <dlux.version>0.3.0-SNAPSHOT</dlux.version>
-    <configfile.directory>etc/opendaylight/karaf</configfile.directory>
-  </properties>
-  <dependencyManagement>
-    <dependencies>
-      <!-- project specific dependencies -->
-      <dependency>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>mdsal-artifacts</artifactId>
-        <version>${mdsal.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.netconf</groupId>
-        <artifactId>restconf-artifacts</artifactId>
-        <version>${restconf.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>features-yangtools</artifactId>
-      <classifier>features</classifier>
-      <version>${yangtools.version}</version>
-      <type>xml</type>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.mdsal.model</groupId>
-      <artifactId>features-mdsal-model</artifactId>
-      <version>${mdsal.model.version}</version>
-      <classifier>features</classifier>
-      <type>xml</type>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>features-mdsal</artifactId>
-      <classifier>features</classifier>
-      <version>${mdsal.version}</version>
-      <type>xml</type>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.netconf</groupId>
-      <artifactId>features-restconf</artifactId>
-      <classifier>features</classifier>
-      <version>${restconf.version}</version>
-      <type>xml</type>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.dlux</groupId>
-      <artifactId>features-dlux</artifactId>
-      <classifier>features</classifier>
-      <version>${dlux.version}</version>
-      <type>xml</type>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>openstack.net-virt-sfc-impl</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>openstack.net-virt-sfc-impl</artifactId>
-      <version>${project.version}</version>
-      <type>xml</type>
-      <classifier>config</classifier>
-    </dependency>
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>openstack.net-virt-sfc-api</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
+  <modules>
+    <module>production</module>
+    <module>test</module>
+  </modules>
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <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>
 </project>
diff --git a/openstack/net-virt-sfc/features/production/pom.xml b/openstack/net-virt-sfc/features/production/pom.xml
new file mode 100644 (file)
index 0000000..684d59a
--- /dev/null
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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 INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>features-parent</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+  <groupId>org.opendaylight.ovsdb</groupId>
+  <artifactId>openstack.net-virt-sfc-features</artifactId>
+  <version>1.2.1-SNAPSHOT</version>
+  <name>${project.artifactId}</name>
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.1.1</maven>
+  </prerequisites>
+  <properties>
+    <configfile.directory>etc/opendaylight/karaf</configfile.directory>
+    <dlux.version>0.3.0-SNAPSHOT</dlux.version>
+    <mdsal.model.version>0.8.0-SNAPSHOT</mdsal.model.version>
+    <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
+    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+    <restconf.version>1.3.0-SNAPSHOT</restconf.version>
+    <sfc.version>0.2.0-SNAPSHOT</sfc.version>
+    <yangtools.version>0.8.0-SNAPSHOT</yangtools.version>
+  </properties>
+  <dependencyManagement>
+    <dependencies>
+      <!-- project specific dependencies -->
+      <dependency>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>mdsal-artifacts</artifactId>
+        <version>${mdsal.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.netconf</groupId>
+        <artifactId>restconf-artifacts</artifactId>
+        <version>${restconf.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.ovsdb</groupId>
+        <artifactId>ovsdb-artifacts</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>features-yangtools</artifactId>
+      <classifier>features</classifier>
+      <version>${yangtools.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>features-mdsal-model</artifactId>
+      <version>${mdsal.model.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>features-mdsal</artifactId>
+      <classifier>features</classifier>
+      <version>${mdsal.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.netconf</groupId>
+      <artifactId>features-restconf</artifactId>
+      <classifier>features</classifier>
+      <version>${restconf.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.dlux</groupId>
+      <artifactId>features-dlux</artifactId>
+      <classifier>features</classifier>
+      <version>${dlux.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>features-ovsdb</artifactId>
+      <classifier>features</classifier>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin</artifactId>
+      <version>${openflowplugin.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>features-openflowplugin-extension</artifactId>
+      <version>${openflowplugin.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>features-sfc</artifactId>
+      <version>${sfc.version}</version>
+      <classifier>features</classifier>
+      <type>xml</type>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt-sfc-impl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt-sfc-impl</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>config</classifier>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt-sfc-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>southbound-features</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>features</classifier>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>utils.servicehelper</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/openstack/net-virt-sfc/features/production/src/main/features/features.xml b/openstack/net-virt-sfc/features/production/src/main/features/features.xml
new file mode 100644 (file)
index 0000000..7bdac12
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+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
+-->
+<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/{{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/{{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-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/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.southbound-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>
+    <feature version="${restconf.version}">odl-restconf</feature>
+  </feature>
+  <feature name='odl-ovsdb-sfc-ui' version='${project.version}' description='OpenDaylight :: ovsdb-sfc :: UI'>
+    <feature version="${project.version}">odl-ovsdb-sfc-rest</feature>
+    <feature version="${restconf.version}">odl-mdsal-apidocs</feature>
+    <feature version="${mdsal.version}">odl-mdsal-xsql</feature>
+    <feature version="${dlux.version}">odl-dlux-yangui</feature>
+  </feature>
+
+</features>
diff --git a/openstack/net-virt-sfc/features/test/pom.xml b/openstack/net-virt-sfc/features/test/pom.xml
new file mode 100644 (file)
index 0000000..f1c49bf
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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 INTERNAL
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>features-parent</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+  <groupId>org.opendaylight.ovsdb</groupId>
+  <artifactId>openstack.net-virt-sfc-features-test</artifactId>
+  <version>1.2.1-SNAPSHOT</version>
+  <name>${project.artifactId}</name>
+  <modelVersion>4.0.0</modelVersion>
+  <prerequisites>
+    <maven>3.1.1</maven>
+  </prerequisites>
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt-sfc-features</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>features</classifier>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.southbound-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/openstack/net-virt-sfc/features/test/src/main/features/features.xml b/openstack/net-virt-sfc/features/test/src/main/features/features.xml
new file mode 100644 (file)
index 0000000..0f8b724
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+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
+-->
+<features name="odl-ovsdb-sfc-test${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.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/{{VERSION}}</bundle>
+    <bundle>mvn:org.opendaylight.ovsdb/utils.southbound-utils/{{VERSION}}</bundle>
+    <feature version='${project.version}'>odl-ovsdb-sfc-ui</feature>
+  </feature>
+</features>
index 9c8652e73cb6976a96f76bc22b55ef3a1179dc9b..e3b09a1a0eaf24b1c67960dbd8780c92161d128e 100644 (file)
@@ -21,27 +21,170 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>openstack.net-virt-sfc-impl</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
+  <version>1.2.1-SNAPSHOT</version>
   <packaging>bundle</packaging>
+
+  <properties>
+    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+    <powermock.version>1.5.2</powermock.version>
+    <sfc.version>0.2.0-SNAPSHOT</sfc.version>
+    <sonar.jacoco.itReportPath>../it/target/jacoco-it.exec</sonar.jacoco.itReportPath>
+  </properties>
+
   <dependencies>
+    <!-- project specific dependencies -->
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>openstack.net-virt-sfc-api</artifactId>
       <version>${project.version}</version>
     </dependency>
-
-    <!-- Testing Dependencies -->
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>openstack.net-virt</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <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>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-openflow</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.servicehelper</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <!-- openflowplugin dependencies -->
+    <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>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin.model</groupId>
+      <artifactId>model-flow-service</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <!-- mdsal dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-topology</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>iana-if-type-2014-05-08</artifactId>
+    </dependency>
+    <!-- sfc dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>sfc-model</artifactId>
+      <version>${sfc.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.sfc</groupId>
+      <artifactId>sfc-provider</artifactId>
+      <version>${sfc.version}</version>
+    </dependency>
+    <!-- external dependencies -->
+    <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.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!-- testing dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
-
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.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>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Embed-Dependency>utils.mdsal-openflow;type=!pom;inline=false</Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+            <Export-Package>
+              org.opendaylight.ovsdb.openstack.netvirt.sfc
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <properties>
+            <property>
+              <name>listener</name>
+              <value>org.sonar.java.jacoco.JUnitListener</value>
+            </property>
+          </properties>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
index 402b72d8828a19334051ebbe07f668fdbcc416ee..a794e579218c8e05d2352cad7e5c369af812b445 100644 (file)
@@ -10,6 +10,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <required-capabilities>
     <capability>urn:opendaylight:params:xml:ns:yang:netvirt:sfc?module=netvirt-sfc&amp;revision=2014-12-10</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: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>
   </required-capabilities>
   <configuration>
 
@@ -18,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>
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/AbstractDataTreeListener.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/AbstractDataTreeListener.java
new file mode 100644 (file)
index 0000000..87a9db6
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, 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 java.util.Collection;
+
+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.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AbstractChangeListner implemented basic {@link AsyncDataChangeEvent} processing for
+ * netvirt-sfc data change listener.
+ */
+public abstract class AbstractDataTreeListener<T extends DataObject> implements INetvirtSfcDataProcessor<T> {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractDataTreeListener.class);
+    protected INetvirtSfcOF13Provider provider;
+    protected final Class<T> clazz;
+
+    public AbstractDataTreeListener(INetvirtSfcOF13Provider provider, Class<T> clazz) {
+        this.provider = Preconditions.checkNotNull(provider, "provider can not be null!");
+        this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+    }
+
+    @Override
+    public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
+        Preconditions.checkNotNull(changes, "Changes may not be null!");
+
+        LOG.info("Received Data Tree Changed ...", changes);
+        for (DataTreeModification<T> change : changes) {
+            final InstanceIdentifier<T> key = change.getRootPath().getRootIdentifier();
+            final DataObjectModification<T> mod = change.getRootNode();
+            LOG.info("Received Data Tree Changed Update of Type={} for Key={}", mod.getModificationType(), key);
+            switch (mod.getModificationType()) {
+                case DELETE:
+                    remove(key, mod.getDataBefore());
+                    break;
+                case SUBTREE_MODIFIED:
+                    update(key, mod.getDataBefore(), mod.getDataAfter());
+                    break;
+                case WRITE:
+                    if (mod.getDataBefore() == null) {
+                        add(key, mod.getDataAfter());
+                    } else {
+                        update(key, mod.getDataBefore(), mod.getDataAfter());
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+            }
+        }
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/INetvirtSfcDataProcessor.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/INetvirtSfcDataProcessor.java
new file mode 100644 (file)
index 0000000..5225b03
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, 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 org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * netvirt-sfc-dcl processor
+ * org.opendaylight.ovsdb.openstack.netvirt.sfc
+ */
+public interface INetvirtSfcDataProcessor<D extends DataObject> extends AutoCloseable, DataTreeChangeListener<D> {
+
+    /**
+     * Method removes DataObject which is identified by InstanceIdentifier.
+     *
+     * @param identifier - the whole path to DataObject
+     * @param del - DataObject for removing
+     */
+    void remove(InstanceIdentifier<D> identifier, D del);
+
+    /**
+     * Method updates the original DataObject to the update DataObject.
+     * Both are identified by same InstanceIdentifier.
+     *
+     * @param identifier - the whole path to DataObject
+     * @param original - original DataObject (for update)
+     * @param update - changed DataObject (contain updates)
+     */
+    void update(InstanceIdentifier<D> identifier, D original, D update);
+
+    /**
+     * Method adds the DataObject which is identified by InstanceIdentifier
+     * to device.
+     *
+     * @param identifier - the whole path to new DataObject
+     * @param add - new DataObject
+     */
+    void add(InstanceIdentifier<D> identifier, D add);
+
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/INetvirtSfcOF13Provider.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/INetvirtSfcOF13Provider.java
new file mode 100644 (file)
index 0000000..1853f8a
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 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
+ * @author Arun Yerra
+ */
+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 bridge - Service Function Forwarder
+     * @param acl - Access list includes rules that need to be installed in a SFF.
+     */
+    void addClassifierRules(Bridge bridge, Acl acl);
+    void addClassifierRules(Bridges bridges, Acl acl);
+
+    /**
+     * Method removes 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 acl - Access list includes rules that need to be installed in a SFF.
+     */
+    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);
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcAclListener.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcAclListener.java
new file mode 100644 (file)
index 0000000..7477669
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 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.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.utils.mdsal.utils.MdsalUtils;
+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;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Data tree listener for AccessList.
+ */
+public class NetvirtSfcAclListener extends AbstractDataTreeListener<Acl> {
+    private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcAclListener.class);
+    private ListenerRegistration<NetvirtSfcAclListener> listenerRegistration;
+
+    /**
+     * {@link NetvirtSfcAclListener} constructor.
+     * @param provider OpenFlow 1.3 Provider
+     * @param db MdSal {@link DataBroker}
+     */
+    public NetvirtSfcAclListener(final INetvirtSfcOF13Provider provider, final DataBroker db) {
+        super(provider, Acl.class);
+        Preconditions.checkNotNull(db, "DataBroker can not be null!");
+
+        registrationListener(db);
+    }
+
+    private void registrationListener(final DataBroker db) {
+        final DataTreeIdentifier<Acl> treeId =
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getIetfAclIid());
+        try {
+            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!");
+            throw new IllegalStateException("NetvirtSfcAccessListListener startup fail! System needs restart.", e);
+        }
+    }
+
+    @Override
+    public void close() {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.warn("Error while stopping IETF ACL ChangeListener: {}", e.getMessage());
+                LOG.debug("Error while stopping IETF ACL ChangeListener..", e);
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    @Override
+    public void remove(final InstanceIdentifier<Acl> identifier,
+                       final Acl removeDataObj) {
+        Preconditions.checkNotNull(removeDataObj, "Removed object can not be null!");
+        provider.removeClassifierRules(removeDataObj);
+    }
+
+    @Override
+    public void update(final InstanceIdentifier<Acl> identifier,
+                       final Acl original, final Acl update) {
+    }
+
+    @Override
+    public void add(final InstanceIdentifier<Acl> identifier,
+                    final Acl addDataObj) {
+        Preconditions.checkNotNull(addDataObj, "Added object can not be null!");
+        LOG.debug("Adding accesslist iid = {}, dataObj = {}", identifier, addDataObj);
+        provider.addClassifierRules(addDataObj);
+    }
+
+    public InstanceIdentifier<Acl> getIetfAclIid() {
+        return InstanceIdentifier.create(AccessLists.class).child(Acl.class);
+    }
+}
diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcClassifierListener.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/NetvirtSfcClassifierListener.java
new file mode 100644 (file)
index 0000000..1562a41
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 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.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.utils.mdsal.utils.MdsalUtils;
+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;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Data tree listener for Classifier.
+ *
+ * @author Arun Yerra
+ */
+public class NetvirtSfcClassifierListener extends AbstractDataTreeListener<Classifier> {
+    private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcClassifierListener.class);
+    private MdsalUtils mdsalUtils;
+    private ListenerRegistration<NetvirtSfcClassifierListener> listenerRegistration;
+
+    /**
+     * {@link NetvirtSfcClassifierListener} constructor.
+     * @param provider OpenFlow 1.3 Provider
+     * @param db MdSal {@link DataBroker}
+     */
+    public NetvirtSfcClassifierListener(final INetvirtSfcOF13Provider provider, final DataBroker db) {
+        super(provider, Classifier.class);
+        Preconditions.checkNotNull(db, "DataBroker can not be null!");
+        mdsalUtils = new MdsalUtils(db);
+        registrationListener(db);
+    }
+
+    private void registrationListener(final DataBroker db) {
+        final DataTreeIdentifier<Classifier> treeId =
+                new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getClassifierIid());
+        try {
+            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!");
+            throw new IllegalStateException("NetvirtSfcClassifierListener startup fail! System needs restart.", e);
+        }
+    }
+
+    @Override
+    public void close() {
+        if (listenerRegistration != null) {
+            try {
+                listenerRegistration.close();
+            } catch (final Exception e) {
+                LOG.warn("Error to stop Netvirt Classifier DataChange listener: {}", e.getMessage());
+            }
+            listenerRegistration = null;
+        }
+    }
+
+    @Override
+    public void remove(final InstanceIdentifier<Classifier> identifier,
+                       final Classifier removeDataObj) {
+        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.
+        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;
+        }
+
+        provider.removeClassifierRules(acl);
+    }
+
+    @Override
+    public void update(final InstanceIdentifier<Classifier> identifier,
+                       final Classifier original, final Classifier update) {
+        //TODO
+
+    }
+
+    @Override
+    public void add(final InstanceIdentifier<Classifier> identifier,
+                    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.
+        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;
+        }
+
+        provider.addClassifierRules(acl);
+    }
+
+    public InstanceIdentifier<Classifier> getClassifierIid() {
+        return InstanceIdentifier.create(Classifiers.class).child(Classifier.class);
+    }
+
+    private InstanceIdentifier<Acl> getIetfAclIid(String aclName) {
+        return InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(aclName));
+    }
+}
index e303a588b69012fa61e948b412eb75c308db6e1a..a77b8cf560f795bb44a5567279ec320160569cee 100644 (file)
 /*
- * Copyright © 2015 Red Hat, Inc. and others.  All rights reserved.
+ * Copyright © 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 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.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 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);
+
+        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);
+        classifierListener = new NetvirtSfcClassifierListener(provider, dataBroker);
+
+        addToPipeline(provider);
+        provider.setDependencies(null);
     }
 
     @Override
     public void close() throws Exception {
         LOG.info("NetvirtSfcProvider Closed");
+        aclListener.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/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..92ffcbd
--- /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(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) {
+
+    }
+
+    @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..0fa0398
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * 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.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.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.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.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 MdsalUtils mdsalUtils;
+    private SfcUtils sfcUtils;
+    private static final String VXGPE = "vxgpe";
+    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;
+    }
+
+    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 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 localIp = "";
+        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) {
+                localIp = southbound.getOtherConfig(ovsdbNode, OvsdbTables.OPENVSWITCH, TUNNEL_ENDPOINT_KEY);
+            }
+
+        }
+        return localIp.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;
+    }
+
+    private long getSfPort(Node bridgeNode, String sfPortName) {
+        return getOFPort(bridgeNode, sfPortName);
+    }
+
+    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);
+                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) {
+                    LOG.error("Interrupted while waiting for ofPort {}", portName, e);
+                }
+            }
+        }
+        return ofPort;
+    }
+
+    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..8ebc063
--- /dev/null
@@ -0,0 +1,577 @@
+/*
+ * 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 BigInteger getCookie(FlowID flowID) {
+        String cookieString = String.format("1110%02d%010d", flowID.value, cookieIndex++);
+        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 = 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) {
+            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 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(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) {
+                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+                MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+                        aceIp.getDestinationPortRange().getLowerPort().getValue());
+            } else {
+                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+                MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+                        aceIp.getDestinationPortRange().getLowerPort().getValue());
+            }
+        } 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 73a1db628a94767243dd054852b889ed86390a0d..34dfd96c547b3cbc0cd9c91212b70b39500754a9 100644 (file)
@@ -1,13 +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;
+
+public class NetvirtSfcModule extends AbstractNetvirtSfcModule {
+    private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcModule.class);
+    private BundleContext bundleContext;
 
-public class NetvirtSfcModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.AbstractNetvirtSfcModule {
-    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);
     }
 
@@ -18,9 +35,14 @@ public class NetvirtSfcModule extends org.opendaylight.yang.gen.v1.urn.opendayli
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        NetvirtSfcProvider provider = new NetvirtSfcProvider();
-        getBrokerDependency().registerProvider(provider);
-        return provider;
+        LOG.info("Netvirt SFC module initialization.");
+        NetvirtSfcProvider sfcProvider = new NetvirtSfcProvider(bundleContext);
+        sfcProvider.setOf13Provider(getOf13provider());
+        getBrokerDependency().registerProvider(sfcProvider);
+        return sfcProvider;
     }
 
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
 }
index 26e2fd5e53d972f13a020bc35b5d765826495519..276a14aa20b5561f3a20ab37114fdf3c03a1b4c3 100644 (file)
@@ -1,13 +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;
-public class NetvirtSfcModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.AbstractNetvirtSfcModuleFactory {
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
+
+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 8eb647929b7af3c7699d3f1a212ec16f55af3bf7..2f5d016da2cb08e2412da489d337465083113c1a 100644 (file)
@@ -4,7 +4,7 @@ module netvirt-sfc {
     prefix "netvirt-sfc";
 
     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-md-sal-binding { prefix mdsal; revision-date 2013-10-28;}
 
     description
         "Service definition for netvirt sfc project";
@@ -26,10 +26,14 @@ module netvirt-sfc {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity md-sal-binding:binding-broker-osgi-registry;
+                        config:required-identity mdsal:binding-broker-osgi-registry;
                     }
                 }
             }
+
+            leaf of13provider {
+                type string;
+            }
         }
     }
 }
index f3cb611a698d4f750daf4e2778af7897e48ceb88..ecc9c11f116fe42a1906e6762f2e8811fadcedac 100644 (file)
@@ -5,46 +5,87 @@
  * terms of the 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.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() {
         NetvirtSfcModule module = new NetvirtSfcModule(mock(ModuleIdentifier.class), mock(DependencyResolver.class));
-
         // ensure no exceptions on validation
         // currently this method is empty
         module.customValidation();
     }
 
+    @SuppressWarnings("unchecked")
     @Test
     public void testCreateInstance() throws Exception {
         // configure mocks
         DependencyResolver dependencyResolver = mock(DependencyResolver.class);
         BindingAwareBroker broker = mock(BindingAwareBroker.class);
-        when(dependencyResolver.resolveInstance(eq(BindingAwareBroker.class), any(ObjectName.class), any(JmxAttribute.class))).thenReturn(broker);
+        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(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
-        AutoCloseable closeable = module.getInstance();
+        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 7b8125361d542a73d72fbd5e5b79e03824072ee7..67b04335ea4996eb339b72c38423e5b922297b12 100644 (file)
@@ -12,32 +12,95 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
   <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>mdsal-it-parent</artifactId>
-    <version>1.3.0-SNAPSHOT</version>
-    <relativePath/>
+    <groupId>org.opendaylight.ovsdb</groupId>
+    <artifactId>it</artifactId>
+    <version>1.2.1-SNAPSHOT</version>
+    <relativePath>../../../commons/it</relativePath>
   </parent>
 
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>openstack.net-virt-sfc-it</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
-  <packaging>bundle</packaging>
+  <version>1.2.1-SNAPSHOT</version>
+  <packaging>jar</packaging>
 
   <properties>
-    <skipITs>false</skipITs>
     <karaf.distro.groupId>org.opendaylight.ovsdb</karaf.distro.groupId>
     <karaf.distro.artifactId>openstack.net-virt-sfc-karaf</karaf.distro.artifactId>
-    <karaf.distro.version>1.0.0-SNAPSHOT</karaf.distro.version>
+    <karaf.distro.version>${project.version}</karaf.distro.version>
     <karaf.distro.type>zip</karaf.distro.type>
-  </properties>
+   </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>${project.groupId}</groupId>
+        <artifactId>openstack.net-virt-sfc-artifacts</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
 
   <dependencies>
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>openstack.net-virt-sfc-features</artifactId>
+      <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>
       <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.southbound-utils</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>concepts</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.sonar-plugins.java</groupId>
+      <artifactId>sonar-jacoco-listeners</artifactId>
+      <scope>test</scope>
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <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>
+          <excludes>
+            <exclude>**/NetvirtSfcIT.java</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
 </project>
index d8a5a849f180699678efba657655a3cf8e1d64c7..e0066baf3dbdb9ad5abc6589767dc8b736edce8d 100644 (file)
  * terms of the 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 static org.junit.Assert.assertEquals;
+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 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.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.ServiceFunctionForwarderUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionPathUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionUtils;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
+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.cisco.params.xml.ns.yang.sfc.common.rev151017.SftType;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.SffsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.SffBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.Sfc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
+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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
+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.TopologyId;
+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.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;
 import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
 import org.ops4j.pax.exam.options.MavenUrlReference;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
@@ -24,10 +124,62 @@ import org.ops4j.pax.exam.spi.reactors.PerClass;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Maps;
+
 @RunWith(PaxExam.class)
 @ExamReactorStrategy(PerClass.class)
 public class NetvirtSfcIT extends AbstractMdsalTestBase {
     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcIT.class);
+    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 boolean ovsdb_wait = false;
+    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";
+    public static final String CONNECTION_TYPE_ACTIVE = "active";
+    public static final String CONNECTION_TYPE_PASSIVE = "passive";
+    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 OVSDB_WAIT = "ovsdb.wait";
+    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 = "sf1Dpl";
+    private static final String SF2DPLNAME = "sf2Dpl";
+    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 RULENAME= "httpRule";
+    private static final String SFCNAME = "sfc1";
+    private static final String SFCPATH = "SFC-Path";
+    private static final String SFCSF1NAME = "firewall-abstract";
+    private static final SftType SFCSF1TYPE = new SftType("firewall");
+    private static final int GPEPORT = 6633;
 
     @Override
     public String getModuleName() {
@@ -43,7 +195,7 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
     public MavenUrlReference getFeatureRepo() {
         return maven()
                 .groupId("org.opendaylight.ovsdb")
-                .artifactId("openstack.net-virt-sfc-features")
+                .artifactId("openstack.net-virt-sfc-features-test")
                 .classifier("features")
                 .type("xml")
                 .versionAsInProject();
@@ -51,20 +203,650 @@ public class NetvirtSfcIT extends AbstractMdsalTestBase {
 
     @Override
     public String getFeatureName() {
-        return "odl-ovsdb-sfc-ui";
+        return "odl-ovsdb-sfc-test";
+    }
+
+    @Configuration
+    @Override
+    public Option[] config() {
+        Option[] parentOptions = super.config();
+        Option[] propertiesOptions = getPropertiesOptions();
+        Option[] otherOptions = getOtherOptions();
+        Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
+        System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
+        System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
+        System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
+                otherOptions.length);
+        return options;
+    }
+
+    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()
+        };
+    }
+
+    public Option[] getPropertiesOptions() {
+        return new Option[] {
+                propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE,
+                        CONTROLLER_IPADDRESS, OVSDB_TRACE, OVSDB_WAIT),
+        };
     }
 
     @Override
     public Option getLoggingOption() {
-        Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
-                logConfiguration(NetvirtSfcIT.class),
-                LogLevel.INFO.name());
-        option = composite(option, super.getLoggingOption());
-        return option;
+        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.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());
+    }
+
+    protected String usage() {
+        return "Integration Test needs a valid connection configuration as follows :\n"
+                + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
+                + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
+    }
+
+    private void getProperties() {
+        Properties props = System.getProperties();
+        addressStr = props.getProperty(SERVER_IPADDRESS);
+        portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
+        connectionType = props.getProperty(CONNECTION_TYPE, "active");
+        LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
+                connectionType, addressStr, portStr);
+        if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
+            if (addressStr == null) {
+                fail(usage());
+            }
+        }
+        LOG.info("getProperties {}: {}", OVSDB_TRACE, props.getProperty(OVSDB_TRACE));
+        LOG.info("getProperties {}: {}", OVSDB_WAIT, props.getProperty(OVSDB_WAIT));
+        if (props.getProperty(OVSDB_WAIT).equals("true")) {
+            ovsdb_wait = true;
+        }
+    }
+
+    @Before
+    @Override
+    public void setup() {
+        if (setup.get()) {
+            LOG.info("Skipping setUp, already initialized");
+            return;
+        }
+
+        try {
+            Thread.sleep(1000);
+            super.setup();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        getProperties();
+
+        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);
+    }
+
+    private ProviderContext getProviderContext() {
+        ProviderContext providerContext = null;
+        for (int i=0; i < 60; i++) {
+            providerContext = getSession();
+            if (providerContext != null) {
+                break;
+            } else {
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        assertNotNull("providercontext should not be null", providerContext);
+        /* One more second to let the provider finish initialization */
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return providerContext;
+    }
+
+    private DataBroker getDatabroker(ProviderContext providerContext) {
+        DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
+        assertNotNull("dataBroker should not be null", dataBroker);
+        return dataBroker;
+    }
+
+    private Boolean getNetvirtTopology() {
+        LOG.info("getNetvirtTopology: looking for {}...", NETVIRT_TOPOLOGY_ID);
+        Boolean found = false;
+        final TopologyId topologyId = new TopologyId(new Uri(NETVIRT_TOPOLOGY_ID));
+        InstanceIdentifier<Topology> path =
+                InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
+        for (int i = 0; i < 60; i++) {
+            Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
+            if (topology != null) {
+                LOG.info("getNetvirtTopology: found {}...", NETVIRT_TOPOLOGY_ID);
+                found = true;
+                break;
+            } else {
+                LOG.info("getNetvirtTopology: still looking ({})...", i);
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return found;
     }
 
     @Test
-    public void testnetvirtsfcFeatureLoad() {
-        Assert.assertTrue(true);
+    public void testNetvirtSfcFeatureLoad() {
+        assertTrue(true);
+    }
+
+    private AccessListsBuilder accessListsBuilder() {
+        String ruleName = RULENAME;
+        String sfcName = SFCNAME;
+        MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
+        LOG.info("Matches: {}", matchesBuilder.build());
+        ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), sfcName);
+        AceBuilder accessListEntryBuilder =
+                aclUtils.aceBuilder(new AceBuilder(), ruleName, 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() throws InterruptedException {
+        testModel(accessListsBuilder(), AccessLists.class, 0);
+    }
+
+    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() throws InterruptedException {
+        testModel(classifiersBuilder(), Classifiers.class, 0);
+    }
+
+    private SfcBuilder netvirtSfcBuilder() {
+        return sfcUtils.sfcBuilder(new SfcBuilder(), "sfc");
+    }
+
+    @Test
+    public void testNetvirtSfcModel() throws InterruptedException {
+        testModel(netvirtSfcBuilder(), Sfc.class, 0);
+    }
+
+    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));
+        T 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 sf1DplName = SF1DPLNAME;
+        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, sf1Ip, sn1Name, bridge1Name, sf1Name, sf1DplName);
+        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 = SFCSF1NAME;
+        SftType sfType = SFCSF1TYPE;
+        String sfcName = SFCNAME;
+
+        SfcServiceFunctionBuilder sfcServiceFunctionBuilder = serviceFunctionChainUtils.sfcServiceFunctionBuilder(
+                new SfcServiceFunctionBuilder(), sf1Name, sfType);
+        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 = SFCPATH;
+        String sfcName = SFCNAME;
+        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, SF1DPLNAME, "internal", null, externalIds);
+        southboundUtils.addTerminationPoint(bridgeNode, "vm1", "internal");
+        southboundUtils.addTerminationPoint(bridgeNode, "vm2", "internal");
+        Map<String, String> options = Maps.newHashMap();
+        options.put("key", "flow");
+        options.put("remote_ip", "192.168.120.32");
+        southboundUtils.addTerminationPoint(bridgeNode, "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);
+
+        readwait();
+
+        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 testNetvirtSfc() 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);
+        ControllerEntry controllerEntry;
+        // 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);
+            String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
+            assertNotNull("Failed to get controller target", controllerTarget);
+            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 controllerEntry = bridge.getControllerEntry().iterator().next();
+            assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
+            if (controllerEntry.isIsConnected()) {
+                Assert.assertTrue(controllerEntry.isIsConnected());
+                break;
+            }
+            Thread.sleep(1000);
+        }
+
+        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 = "sfcIngressClass_" + "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() {
+        if (ovsdb_wait) {
+            LOG.warn("Waiting, kill with ps -ef | grep java, kill xxx... ");
+            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);
+    }
+}
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AclUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AclUtils.java
new file mode 100644 (file)
index 0000000..7657f2e
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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.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.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 extends AbstractUtils {
+    public MatchesBuilder matchesBuilder(MatchesBuilder matchesBuilder, int destPort) {
+        PortNumber portNumber = new PortNumber(destPort);
+        DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder()
+                .setLowerPort(portNumber)
+                .setUpperPort(portNumber);
+
+        AceIpBuilder aceIpBuilder = new AceIpBuilder()
+                .setDestinationPortRange(destinationPortRangeBuilder.build())
+                .setProtocol((short)6)
+                .setAceIpVersion(new AceIpv4Builder().build());
+
+        return matchesBuilder.setAceType(aceIpBuilder.build());
+    }
+
+    public ActionsBuilder actionsBuilder(ActionsBuilder actionsBuilder, Boolean permit) {
+        return actionsBuilder.setPacketHandling(new PermitBuilder().setPermit(permit).build());
+    }
+
+    public ActionsBuilder actionsBuilder(ActionsBuilder actionsBuilder, String sfcName) {
+        RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder().setSfcName(sfcName);
+
+        return actionsBuilder.addAugmentation(RedirectToSfc.class, redirectToSfcBuilder.build());
+    }
+
+    public AceBuilder aceBuilder(AceBuilder accessListEntryBuilder,
+                                 String ruleName,
+                                 MatchesBuilder matchesBuilder,
+                                 ActionsBuilder actionsBuilder) {
+        return accessListEntryBuilder
+                .setRuleName(ruleName)
+                .setMatches(matchesBuilder.build())
+                .setActions(actionsBuilder.build());
+    }
+
+    public AccessListEntriesBuilder accessListEntriesBuidler(AccessListEntriesBuilder accessListEntriesBuilder,
+                                                             AceBuilder aceBuilder) {
+        List<Ace> aceList = new ArrayList<>();
+        aceList.add(aceBuilder.build());
+
+        return accessListEntriesBuilder.setAce(aceList);
+    }
+
+    public AclBuilder aclBuilder(AclBuilder aclBuilder,
+                                 String aclName,
+                                 AccessListEntriesBuilder accessListEntriesBuilder) {
+        return aclBuilder
+                .setAclName(aclName)
+                .setAccessListEntries(accessListEntriesBuilder.build());
+    }
+
+    public AccessListsBuilder accesslistsbuilder(AccessListsBuilder accessListsBuilder,
+                                                 AclBuilder aclBuilder) {
+        List<Acl> aclList = new ArrayList<>();
+        aclList.add(aclBuilder.build());
+
+        return accessListsBuilder.setAcl(aclList);
+    }
+}
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ClassifierUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/ClassifierUtils.java
new file mode 100644 (file)
index 0000000..54d31db
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.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.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.ClassifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.SffsBuilder;
+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 extends AbstractUtils {
+    public SffBuilder sffBuilder(SffBuilder sffBuilder, String sffName) {
+        return sffBuilder.setName(sffName);
+    }
+
+    public SffsBuilder sffsBuilder(SffsBuilder sffsBuilder, SffBuilder sffBuilder) {
+        List<Sff> sffList = new ArrayList<>();
+        sffList.add(sffBuilder.build());
+        sffsBuilder.setSff(sffList);
+
+        return sffsBuilder;
+    }
+
+    public ClassifierBuilder classifierBuilder(ClassifierBuilder classifierBuilder,
+                                               String classifierName, String aclName,
+                                               SffsBuilder sffsBuilder) {
+        return classifierBuilder
+                .setName(classifierName)
+                .setAcl(aclName);
+    }
+
+    public ClassifiersBuilder ClassifiersBuilder(ClassifiersBuilder classifiersBuilder,
+                                                 ClassifierBuilder classifierBuilder) {
+        List<Classifier> classifierList = new ArrayList<>();
+        classifierList.add(classifierBuilder.build());
+        classifiersBuilder.setClassifier(classifierList);
+
+        return classifiersBuilder;
+    }
+}
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..560d340
--- /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.common.rev151017.SftType;
+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;
+
+public class ServiceFunctionChainUtils extends AbstractUtils {
+    public SfcServiceFunctionBuilder sfcServiceFunctionBuilder(SfcServiceFunctionBuilder sfcServiceFunctionBuilder,
+                                                               String name,
+                                                               SftType 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..7d04154
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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.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;
+
+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 sffDplName, String sfDplName) {
+        return sffSfDataPlaneLocatorBuilder
+                .setSfDplName(SfDataPlaneLocatorName.getDefaultInstance(sfDplName))
+                .setSffDplName(SffDataPlaneLocatorName.getDefaultInstance(sffDplName));
+    }
+
+    public ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder(
+            ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder,
+            SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder,
+            String sfName) {
+
+        return serviceFunctionDictionaryBuilder
+                .setName(SfName.getDefaultInstance(sfName))
+                .setSffSfDataPlaneLocator(sffSfDataPlaneLocatorBuilder.build());
+    }
+
+    public OvsBridgeBuilder ovsBridgeBuilder(OvsBridgeBuilder ovsBridgeBuilder, String bridgeName) {
+        return ovsBridgeBuilder.setBridgeName(bridgeName);
+    }
+
+    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 sfIp, String snName, String bridgeName, String sfName, String sfDplName) {
+
+        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(), sffDplName, sfDplName);
+        ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder =
+                serviceFunctionDictionaryBuilder(new ServiceFunctionDictionaryBuilder(),
+                        sffSfDataPlaneLocatorBuilder, sfName);
+        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..391c6f6
--- /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.common.rev151017.SftType;
+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.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,
+                                                         SftType 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, new SftType("firewall"));
+    }
+
+
+}
diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/SfcUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/SfcUtils.java
new file mode 100644 (file)
index 0000000..5b24ef4
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * 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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
+
+public class SfcUtils {
+    public SfcBuilder sfcBuilder(SfcBuilder sfcBuilder, String sfcName) {
+        return sfcBuilder.setName(sfcName);
+    }
+}
index e193631c16bac668e8de8a0209e01bb09dec7948..2119c4f54adfcc726c83c4307cf0691d959f234e 100644 (file)
@@ -17,13 +17,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>openstack.net-virt-sfc-karaf</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
+  <version>1.2.1-SNAPSHOT</version>
   <name>${project.artifactId}</name>
   <prerequisites>
     <maven>3.1.1</maven>
   </prerequisites>
   <properties>
-    <karaf.localFeature>odl-ovsdb-sfc-ui</karaf.localFeature>
+    <karaf.localFeature>odl-ovsdb-sfc-test</karaf.localFeature>
   </properties>
   <dependencyManagement>
     <dependencies>
@@ -47,7 +47,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
 
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>openstack.net-virt-sfc-features</artifactId>
+      <artifactId>openstack.net-virt-sfc-features-test</artifactId>
+      <version>${project.version}</version>
       <classifier>features</classifier>
       <type>xml</type>
       <scope>runtime</scope>
index 810b37be73d3a8f9a6d52748fda9e086abe7afc1..1abfc0383491173b086d930417754622355769bb 100644 (file)
@@ -9,7 +9,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
 
   <parent>
     <groupId>org.opendaylight.odlparent</groupId>
-    <artifactId>odlparent</artifactId>
+    <artifactId>odlparent-lite</artifactId>
     <version>1.6.0-SNAPSHOT</version>
     <relativePath/>
   </parent>
index f80c2c9d1589b35f03c15d030747e80264d309df..90823bd410dcdd080af0c2e73547e8859d3b1a20 100644 (file)
@@ -45,91 +45,45 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   </scm>
 
   <properties>
-    <networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
-    <ovsdb.utils.config.version>1.2.1-SNAPSHOT</ovsdb.utils.config.version>
-    <ovsdb.utils.servicehelper.version>1.2.1-SNAPSHOT</ovsdb.utils.servicehelper.version>
+    <neutron.model.version>0.6.0-SNAPSHOT</neutron.model.version>
     <powermock.version>1.5.2</powermock.version>
-    <sonar-jacoco-listeners.version>2.4</sonar-jacoco-listeners.version>
-    <root.directory>${env.PWD}</root.directory>
-    <sonar.jacoco.itReportPath>${root.directory}/target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
+    <sonar.jacoco.itReportPath>../net-virt-it/target/jacoco-it.exec</sonar.jacoco.itReportPath>
   </properties>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.opendaylight.mdsal</groupId>
-        <artifactId>mdsal-artifacts</artifactId>
-        <version>2.0.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.mdsal.model</groupId>
-        <artifactId>mdsal-model-artifacts</artifactId>
-        <version>0.8.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
   <dependencies>
+    <!-- project specific dependencies -->
     <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-config</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-common-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.neutron</groupId>
-      <artifactId>neutron-spi</artifactId>
-      <version>${networkconfig.neutron.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
+      <groupId>${project.groupId}</groupId>
       <artifactId>southbound-api</artifactId>
-      <version>1.2.1-SNAPSHOT</version>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
+      <groupId>${project.groupId}</groupId>
       <artifactId>utils.config</artifactId>
-      <version>${ovsdb.utils.config.version}</version>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
+      <groupId>${project.groupId}</groupId>
       <artifactId>utils.servicehelper</artifactId>
-      <version>${ovsdb.utils.servicehelper.version}</version>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>yang-common</artifactId>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.mdsal-utils</artifactId>
+      <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>concepts</artifactId>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>utils.neutron-utils</artifactId>
+      <version>${project.version}</version>
     </dependency>
+    <!-- neutron dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.neutron</groupId>
+      <artifactId>model</artifactId>
+      <version>${neutron.model.version}</version>
+    </dependency>
+    <!-- mdsal dependencies -->
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-inet-types</artifactId>
@@ -150,10 +104,23 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-yang-types</artifactId>
     </dependency>
+    <!-- external dependencies -->
+   <dependency>
+      <groupId>commons-net</groupId>
+      <artifactId>commons-net</artifactId>
+    </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.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
     </dependency>
+    <!-- testing dependencies -->
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
@@ -194,17 +161,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>junit</artifactId>
       <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.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
   <build>
     <plugins>
@@ -217,91 +173,25 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <Embed-Dependency>utils.config;type=!pom;inline=false</Embed-Dependency>
             <Embed-Transitive>true</Embed-Transitive>
             <Export-Package>
+              org.opendaylight.ovsdb.openstack.netvirt.translator,
               org.opendaylight.ovsdb.openstack.netvirt.api,
               org.opendaylight.ovsdb.openstack.netvirt
             </Export-Package>
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-failsafe-plugin</artifactId>
-        <configuration>
-          <!-- Specific to generate mapping between tests and covered code -->
-          <!--<argLine>${jacoco.agent.it.arg}</argLine>-->
-          <properties>
-            <property>
-              <name>listener</name>
-              <value>org.sonar.java.jacoco.JUnitListener</value>
-            </property>
-          </properties>
-          <!-- Let's put failsafe reports with surefire to have access to tests failures/success reports in sonar -->
-          <!--<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>-->
-        </configuration>
-      </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <!-- Specific to generate mapping between tests and covered code -->
-          <!--<argLine>${jacoco.agent.ut.arg}</argLine>-->
           <properties>
             <property>
               <name>listener</name>
               <value>org.sonar.java.jacoco.JUnitListener</value>
             </property>
           </properties>
-          <!-- Let's put failsafe reports with surefire to have access to tests failures/success reports in sonar -->
-          <!--<reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>-->
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>prepare-ut-agent</id>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-            <configuration>
-              <destFile>${sonar.jacoco.reportPath}</destFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>prepare-it-agent</id>
-            <goals>
-              <goal>prepare-agent-integration</goal>
-            </goals>
-            <configuration>
-              <append>true</append>
-              <destFile>${sonar.jacoco.itReportPath}</destFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>default-report</id>
-            <goals>
-              <goal>report</goal>
-            </goals>
-            <configuration>
-              <dataFile>${sonar.jacoco.reportPath}</dataFile>
-            </configuration>
-          </execution>
-          <execution>
-            <id>default-report-integration</id>
-            <goals>
-              <goal>report-integration</goal>
-            </goals>
-            <configuration>
-              <dataFile>${sonar.jacoco.itReportPath}</dataFile>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
     </plugins>
   </build>
-  </project>
+</project>
index 1848ad705fde9880cb4b6f19671ca5c1f62f6b6c..d503a8d55fb40b04b59a8dc09f2af5b16541fcfe 100644 (file)
@@ -34,6 +34,19 @@ public abstract class AbstractEvent {
 
     private HandlerType handlerType;
     private Action action;
+    private int transactionId;
+
+    public int getTransactionId() {
+        return transactionId;
+    }
+
+    private static int txId = 0;
+    private static int incTxId() {
+        return ++txId;
+    }
+    public static int getTxId() {
+        return txId;
+    }
 
     private AbstractEvent() {
         // this is private to force proper construction
@@ -42,6 +55,7 @@ public abstract class AbstractEvent {
     protected AbstractEvent(HandlerType handlerType, Action action) {
         this.handlerType = handlerType;
         this.action = action;
+        this.transactionId = incTxId();
     }
 
     public HandlerType getHandlerType() {
@@ -54,7 +68,8 @@ public abstract class AbstractEvent {
 
     @Override
     public String toString() {
-        return "AbstractEvent [handlerType=" + handlerType + " action=" + action + "]";
+        return "AbstractEvent [transactionId=" + transactionId
+                + " handlerType=" + handlerType + " action=" + action + "]";
     }
 
     @Override
index bc6bd51522cbd5b0727ea001c8e5eae754f49713..8a5915b2449c2bedfee1982af524158040e89641 100644 (file)
@@ -12,11 +12,82 @@ import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Hashtable;
 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.neutron.spi.*;
-import org.opendaylight.ovsdb.openstack.netvirt.api.*;
-import org.opendaylight.ovsdb.openstack.netvirt.impl.*;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFirewallInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFirewallPolicyInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFirewallRuleInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronFloatingIPInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerHealthMonitorInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerListenerInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerPoolInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronLoadBalancerPoolMemberInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronNetworkInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronPortInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronRouterInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronSecurityGroupInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronSecurityRuleInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.impl.NeutronSubnetInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallPolicyAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallRuleAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFloatingIPAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerPoolAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerPoolMemberAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronNetworkAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronPortAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronRouterAware;
+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.utils.neutron.utils.NeutronModelsDataStoreHelper;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -27,8 +98,8 @@ import org.slf4j.LoggerFactory;
 
 public class ConfigActivator implements BundleActivator {
     private static final Logger LOG = LoggerFactory.getLogger(ConfigActivator.class);
-    private List<ServiceRegistration<?>> registrations = new ArrayList<>();
-    private List<Object> services = new ArrayList<>();
+    private List<ServiceRegistration<?>> translatorCRUDRegistrations = new ArrayList<>();
+    private List<Pair<Object, ServiceRegistration>> servicesAndRegistrations = new ArrayList<>();
     private ProviderContext providerContext;
 
     public ConfigActivator(ProviderContext providerContext) {
@@ -38,6 +109,7 @@ public class ConfigActivator implements BundleActivator {
     @Override
     public void start(BundleContext context) throws Exception {
         LOG.info("ConfigActivator start:");
+        registerCRUDServiceProviders(context, this.providerContext);
 
         ConfigurationServiceImpl configurationService = new ConfigurationServiceImpl();
         registerService(context, new String[] {ConfigurationService.class.getName()},
@@ -100,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},
@@ -113,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);
 
@@ -134,10 +214,18 @@ public class ConfigActivator implements BundleActivator {
                 new String[] {OvsdbInventoryService.class.getName()}, null, ovsdbInventoryService);
 
         // Call .setDependencies() starting with the last service registered
-        for (int i = services.size() - 1; i >= 0; i--) {
-            Object service = services.get(i);
+        for (int i = servicesAndRegistrations.size() - 1; i >= 0; i--) {
+            Pair<Object, ServiceRegistration> serviceAndRegistration = servicesAndRegistrations.get(i);
+            Object service = serviceAndRegistration.getLeft();
+            ServiceRegistration<?> serviceRegistration = serviceAndRegistration.getRight();
+            LOG.info("Setting dependencies on service {}/{}, {}", i, servicesAndRegistrations.size(),
+                    service.getClass());
             if (service instanceof ConfigInterface) {
-                ((ConfigInterface) service).setDependencies(context, null);
+                ((ConfigInterface) service).setDependencies(
+                        serviceRegistration != null ? serviceRegistration.getReference() : null);
+                LOG.info("Dependencies set");
+            } else {
+                LOG.warn("Service isn't a ConfigInterface");
             }
         }
 
@@ -150,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);
@@ -159,9 +248,31 @@ public class ConfigActivator implements BundleActivator {
         trackService(context, RoutingProvider.class, neutronL3Adapter);
         trackService(context, L3ForwardingProvider.class, neutronL3Adapter);
         trackService(context, GatewayMacResolver.class, neutronL3Adapter);
+        trackService(context, IngressAclProvider.class, securityServices);
+        trackService(context, EgressAclProvider.class, securityServices);
 
         // We no longer need to track the services, avoid keeping references around
-        services.clear();
+        servicesAndRegistrations.clear();
+    }
+
+    private void registerCRUDServiceProviders(BundleContext context,
+            ProviderContext providerContext) {
+        LOG.debug("Registering CRUD service providers");
+        NeutronRouterInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronPortInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronSubnetInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronNetworkInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronSecurityGroupInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronSecurityRuleInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronFirewallInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronFirewallPolicyInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronFirewallRuleInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronLoadBalancerInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronLoadBalancerPoolInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronLoadBalancerListenerInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronLoadBalancerHealthMonitorInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronLoadBalancerPoolMemberInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
+        NeutronFloatingIPInterface.registerNewInterface(context, providerContext, translatorCRUDRegistrations);
     }
 
     private void trackService(BundleContext context, final Class<?> clazz, final ConfigInterface... dependents) {
@@ -204,11 +315,11 @@ public class ConfigActivator implements BundleActivator {
 
     private ServiceRegistration<?> registerService(BundleContext bundleContext, String[] interfaces,
                                                    Dictionary<String, Object> properties, Object impl) {
-        services.add(impl);
-        ServiceRegistration<?> serviceRegistration = bundleContext.registerService(interfaces, impl, properties);
-        if (serviceRegistration != null) {
-            registrations.add(serviceRegistration);
+        ServiceRegistration serviceRegistration = bundleContext.registerService(interfaces, impl, properties);
+        if (serviceRegistration == null) {
+            LOG.warn("Service registration for {} failed to return a ServiceRegistration instance", impl.getClass());
         }
+        servicesAndRegistrations.add(Pair.of(impl, serviceRegistration));
         return serviceRegistration;
     }
 }
index ef18425f1581fd1b5ab26b510b8ebf4e322c4dd0..2681edb15ba07a8822ba8cd5cd3709dd4277e5da 100644 (file)
@@ -8,10 +8,9 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt;
 
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 
 public interface ConfigInterface {
-    void setDependencies(BundleContext bundleContext, ServiceReference serviceReference);
+    void setDependencies(ServiceReference serviceReference);
     void setDependencies(Object impl);
 }
index 6b47771998a91e8aa817f2f9016ec9380186a01a..0b7881f31259d3f6b90773cd46933651b1697a15 100644 (file)
@@ -10,15 +10,14 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 
 import java.net.HttpURLConnection;
 
-import org.opendaylight.neutron.spi.INeutronFirewallAware;
-import org.opendaylight.neutron.spi.INeutronFirewallPolicyAware;
-import org.opendaylight.neutron.spi.INeutronFirewallRuleAware;
-import org.opendaylight.neutron.spi.NeutronFirewall;
-import org.opendaylight.neutron.spi.NeutronFirewallPolicy;
-import org.opendaylight.neutron.spi.NeutronFirewallRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewall;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallPolicy;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallPolicyAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFirewallRuleAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -171,7 +170,7 @@ public class FWaasHandler extends AbstractHandler
     /**
      * Process the event.
      *
-     * @param abstractEvent@see org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher
+     * @param abstractEvent new FWaas Event@see org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher
      */
     @Override
     public void processEvent(AbstractEvent abstractEvent) {
@@ -190,11 +189,10 @@ public class FWaasHandler extends AbstractHandler
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronFirewallAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index a8607595e46665a65f413ae9ce7c4945f48c0e6a..30e28ea438cfe4e0cdb284f262929ef744ec83c4 100644 (file)
@@ -10,13 +10,12 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 
 import java.net.HttpURLConnection;
 
-import org.opendaylight.neutron.spi.INeutronFloatingIPAware;
-import org.opendaylight.neutron.spi.NeutronFloatingIP;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFloatingIPAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -142,13 +141,12 @@ public class FloatingIPHandler extends AbstractHandler
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronFloatingIPAware.class.getName()), this);
         neutronL3Adapter =
                 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index 764ddc484e090bd203df768d4b7ec118bcf46ec9..e305fd340cea7ec7c2f12d89cd12cc793d82e2d1 100644 (file)
@@ -12,15 +12,15 @@ import java.net.HttpURLConnection;
 import java.util.List;
 import java.util.Map;
 
-import org.opendaylight.neutron.spi.INeutronLoadBalancerAware;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronLoadBalancer;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
@@ -29,7 +29,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheListener;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -166,6 +166,8 @@ public class LBaaSHandler extends AbstractHandler
     /**
      * Useful utility for extracting the loadbalancer instance
      * configuration from the neutron LB cache
+     * @param neutronLB neutron load balancer object
+     * @return returns load balancer configuration
      */
     public LoadBalancerConfiguration extractLBConfiguration(NeutronLoadBalancer neutronLB) {
         String loadBalancerName = neutronLB.getLoadBalancerName();
@@ -247,17 +249,15 @@ public class LBaaSHandler extends AbstractHandler
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         loadBalancerProvider =
                 (LoadBalancerProvider) ServiceHelper.getGlobalInstance(LoadBalancerProvider.class, this);
         nodeCacheManager =
                 (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
-        nodeCacheManager.cacheListenerAdded(
-                bundleContext.getServiceReference(INeutronLoadBalancerAware.class.getName()), this);
+        nodeCacheManager.cacheListenerAdded(serviceReference, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronLoadBalancerAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index da6ca5f752fed06858d7c74e12fc38903fa256ae..93b4ce626ecabb3b93fd2269bed9d627f8c08c1c 100755 (executable)
@@ -12,14 +12,14 @@ import java.net.HttpURLConnection;
 import java.util.List;
 import java.util.Map;
 
-import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolAware;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronLoadBalancer;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerCRUD;
+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.translator.iaware.INeutronLoadBalancerPoolAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
@@ -27,7 +27,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -194,6 +194,8 @@ public class LBaaSPoolHandler extends AbstractHandler
     /**
      * Useful utility for extracting the loadbalancer instance. With
      * each LB pool, we allow multiple VIP and LB to be instantiated.
+     * @param neutronLBPool Neutron load balancer pool object
+     * @return list of loadbalancer configuration of pool members
      */
     public List<LoadBalancerConfiguration> extractLBConfiguration(NeutronLoadBalancerPool neutronLBPool) {
         String poolProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
@@ -263,15 +265,14 @@ public class LBaaSPoolHandler extends AbstractHandler
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         loadBalancerProvider =
                 (LoadBalancerProvider) ServiceHelper.getGlobalInstance(LoadBalancerProvider.class, this);
         nodeCacheManager =
                 (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronLoadBalancerPoolAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index 4d3f3662bb4bebc805583f352fc952ed27d9b854..793f7ac0916cda17a53e61df08342d1c9888a079 100755 (executable)
@@ -12,15 +12,15 @@ import java.net.HttpURLConnection;
 import java.util.List;
 import java.util.Map;
 
-import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolMemberAware;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronLoadBalancer;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerPoolMemberAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
@@ -28,7 +28,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -191,6 +191,8 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
     /**
      * Useful utility for extracting the loadbalancer instance
      * configuration from the neutron LB cache based on member info
+     * @param neutronLBPoolMember Neutron LB pool member object
+     * @return load balancer configuration of the pool member
      */
     public LoadBalancerConfiguration extractLBConfiguration(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
         String memberID = neutronLBPoolMember.getID();
@@ -210,6 +212,10 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
             return null;
         }
         NeutronLoadBalancerPool neutronLBPool = neutronLBPoolCache.getNeutronLoadBalancerPool(memberPoolID);
+        if (neutronLBPool == null) {
+            LOG.debug("Neutron LB pool {} unavailable", memberPoolID);
+            return null;
+        }
         String memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
         if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_TCP) ||
                 memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) ||
@@ -272,15 +278,14 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         loadBalancerProvider =
                 (LoadBalancerProvider) ServiceHelper.getGlobalInstance(LoadBalancerProvider.class, this);
         nodeCacheManager =
                 (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronLoadBalancerPoolMemberAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
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 b867ef3200bc3fcd00b26c179548a8adce18fa50..cbd4d80162cebf28503ebbb81710494aa603baf2 100644 (file)
@@ -11,9 +11,9 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 import java.net.HttpURLConnection;
 import java.util.List;
 
-import org.opendaylight.neutron.spi.INeutronNetworkAware;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronNetworkAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
@@ -24,7 +24,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -55,8 +55,8 @@ public class NetworkHandler extends AbstractHandler implements INeutronNetworkAw
      */
     @Override
     public int canCreateNetwork(NeutronNetwork network) {
-        if (network.isShared()) {
-            LOG.error(" Network shared attribute not supported ");
+        if (network.isShared() && !network.getRouterExternal()) {
+            LOG.error("Shared attribute is only supported on external networks");
             return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
         }
 
@@ -89,8 +89,8 @@ public class NetworkHandler extends AbstractHandler implements INeutronNetworkAw
     @Override
     public int canUpdateNetwork(NeutronNetwork delta,
                                 NeutronNetwork original) {
-        if (delta.isShared()) {
-            LOG.error(" Network shared attribute not supported ");
+        if (delta.isShared() && !delta.getRouterExternal()) {
+            LOG.error("Shared attribute is only supported on external networks");
             return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
         }
 
@@ -194,7 +194,7 @@ public class NetworkHandler extends AbstractHandler implements INeutronNetworkAw
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         tenantNetworkManager =
                 (TenantNetworkManager) ServiceHelper.getGlobalInstance(TenantNetworkManager.class, this);
         bridgeConfigurationManager =
@@ -207,8 +207,7 @@ public class NetworkHandler extends AbstractHandler implements INeutronNetworkAw
                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronNetworkAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index c52c281256b636934febf1221638ad66721014c2..c0e48e37f5be97139d4400c8832217983381368f 100755 (executable)
@@ -8,16 +8,15 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt;
 
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronSubnet;
-import org.opendaylight.neutron.spi.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+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;
+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;
 
@@ -25,6 +24,9 @@ public class NeutronCacheUtils {
 
     /**
      * Look up in the NeutronPortsCRUD cache and return the MAC address for a corresponding IP address
+     * @param neutronPortsCache Reference to port cache to get existing port related data. This interface
+     * basically read data from the md-sal data store.
+     * @param subnetID subnet to which given port is attached
      * @param ipAddr IP address of a member or VM
      * @return MAC address registered with that IP address
      */
@@ -33,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();
                     }
@@ -58,6 +52,10 @@ public class NeutronCacheUtils {
     /**
      * Look up in the NeutronNetworkCRUD cache and NeutronSubnetCRUD cache for
      * extracting the provider segmentation_type and segmentation_id
+     * @param neutronNetworkCache Reference to neutron network cache to get existing network related data.
+     * This interface basically read data from the md-sal data store.
+     * @param neutronSubnetCache Reference to neutron subnet cache to get existing subnet related data.
+     * This interface basically read data from the md-sal data store.
      * @param subnetID Subnet UUID
      * @return {Type: ID} pair for that subnet ID
      */
@@ -80,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 ae4609ae96baefda1eeeca3841150f13bd89f533..88a9ebc073f14198d13633c1ee3d096644c1bca8 100644 (file)
@@ -8,15 +8,16 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt;
 
-import org.opendaylight.neutron.spi.NeutronFloatingIP;
-import org.opendaylight.neutron.spi.NeutronLoadBalancer;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronRouter;
-import org.opendaylight.neutron.spi.NeutronRouter_Interface;
-import org.opendaylight.neutron.spi.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+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;
 
 public class NorthboundEvent extends AbstractEvent {
@@ -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 40f2643858d72f89f6df82220a9e8a1b7abac91e..e374404ae52d615d17b36aa887f638bfea9fed7f 100644 (file)
@@ -11,8 +11,8 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 import java.net.HttpURLConnection;
 import java.util.List;
 
-import org.opendaylight.neutron.spi.INeutronPortAware;
-import org.opendaylight.neutron.spi.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronPortAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
@@ -22,7 +22,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -173,7 +173,7 @@ public class PortHandler extends AbstractHandler implements INeutronPortAware, C
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         nodeCacheManager =
                 (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
         neutronL3Adapter =
@@ -182,8 +182,7 @@ public class PortHandler extends AbstractHandler implements INeutronPortAware, C
                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronPortAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index 74d296f2c5128b9b15762f73a55d35311f726519..646693cd263950310ad51f608b252d49f9366816 100644 (file)
@@ -9,14 +9,20 @@
 package org.opendaylight.ovsdb.openstack.netvirt;
 
 import java.net.HttpURLConnection;
-
-import org.opendaylight.neutron.spi.INeutronSecurityGroupAware;
-import org.opendaylight.neutron.spi.INeutronSecurityRuleAware;
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
+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.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,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) {
@@ -81,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
@@ -104,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));
     }
 
     /**
@@ -124,20 +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(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronSecurityGroupAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
+        neutronPortCache =
+                (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        securityServicesManager =
+                (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
     }
 
     @Override
index 31a7ddb54dbaffbc33dec7a1a8169e4da7ed4571..95b77606a03a030c603183c18e11095a989ff521 100644 (file)
@@ -10,14 +10,13 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 
 import java.net.HttpURLConnection;
 
-import org.opendaylight.neutron.spi.INeutronRouterAware;
-import org.opendaylight.neutron.spi.NeutronRouter;
-import org.opendaylight.neutron.spi.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronRouterAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -217,13 +216,12 @@ public class RouterHandler extends AbstractHandler implements INeutronRouterAwar
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         neutronL3Adapter =
                 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronRouterAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index 8f21cb8902070819fbb1aebc0b4718dbe45d13b1..108a7680fef52f98e4006e4e4362b0c920853125 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 
 import java.util.List;
 
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.api.*;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
@@ -20,7 +20,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 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.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -219,7 +218,7 @@ public class SouthboundHandler extends AbstractHandler
             return;
         }
         SouthboundEvent ev = (SouthboundEvent) abstractEvent;
-        LOG.trace("processEvent: {}", ev);
+        LOG.trace("processEvent ({}): {}", ev, ev.getTransactionId());
         switch (ev.getType()) {
             case NODE:
                 processOvsdbNodeEvent(ev);
@@ -241,6 +240,7 @@ public class SouthboundHandler extends AbstractHandler
                 LOG.warn("Unable to process type {} action {} for node {}", ev.getType(), ev.getAction(), ev.getNode());
                 break;
         }
+        LOG.trace("processEvent exit ({}): {}", ev, ev.getTransactionId());
     }
 
     private void processOvsdbNodeEvent(SouthboundEvent ev) {
@@ -295,10 +295,8 @@ public class SouthboundHandler extends AbstractHandler
     private void processPortUpdate(Node node, OvsdbTerminationPointAugmentation port) {
         LOG.debug("processPortUpdate <{}> <{}>", node, port);
         NeutronNetwork network = tenantNetworkManager.getTenantNetwork(port);
-        if (network != null ){
-            if(!network.getRouterExternal()){
-                this.handleInterfaceUpdate(node, port);
-            }
+        if (network != null && !network.getRouterExternal()) {
+            this.handleInterfaceUpdate(node, port);
         }
     }
 
@@ -369,7 +367,7 @@ public class SouthboundHandler extends AbstractHandler
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         configurationService =
                 (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
         networkingProviderManager =
@@ -380,16 +378,14 @@ public class SouthboundHandler extends AbstractHandler
                 (BridgeConfigurationManager) ServiceHelper.getGlobalInstance(BridgeConfigurationManager.class, this);
         nodeCacheManager =
                 (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
-        nodeCacheManager.cacheListenerAdded(
-                bundleContext.getServiceReference(OvsdbInventoryListener.class.getName()), this);
+        nodeCacheManager.cacheListenerAdded(serviceReference, this);
         neutronL3Adapter =
                 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
         southbound =
                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(OvsdbInventoryListener.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
         ovsdbInventoryService =
                 (OvsdbInventoryService) ServiceHelper.getGlobalInstance(OvsdbInventoryService.class, this);
         ovsdbInventoryService.listenerAdded(this);
index c63d43c776d8d78af583e582f39a2ab701368424..c74d11d12c327d4ba54869c19cf3ea9ff376a4ad 100644 (file)
@@ -10,13 +10,12 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 
 import java.net.HttpURLConnection;
 
-import org.opendaylight.neutron.spi.INeutronSubnetAware;
-import org.opendaylight.neutron.spi.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSubnetAware;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -89,13 +88,12 @@ public class SubnetHandler extends AbstractHandler implements INeutronSubnetAwar
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         neutronL3Adapter =
                 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(INeutronSubnetAware.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
     }
 
     @Override
index 45d3018ba81fb71bef75c01931a37fa898c9563d..0d1b52cf75fa30772805efe3a6a7632dd1eda0aa 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.api;
 
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 
 import java.util.List;
@@ -74,7 +74,7 @@ public interface BridgeConfigurationManager {
      * For OpenFlow 1.3 the Integration Bridge is required and must have a physical device connected.
      * @param bridgeNode the {@link Node} that represents bridge
      * @param ovsdbNode the {@link Node} where the bridge is configured
-     * @param network the {@link org.opendaylight.neutron.spi.NeutronNetwork}
+     * @param network the {@link org.opendaylight.ovsdb.openstack.netvirt.translator}
      * @return True or False
      */
     boolean isNodeVlanReady(Node bridgeNode, Node ovsdbNode, NeutronNetwork network);
@@ -92,7 +92,7 @@ public interface BridgeConfigurationManager {
      * Returns true if the bridges required for the provider network type are created
      * If the bridges are not created, this method will attempt to create them
      * @param node the {@link Node} to query
-     * @param network the {@link org.opendaylight.neutron.spi.NeutronNetwork}
+     * @param network the {@link org.opendaylight.ovsdb.openstack.netvirt.translator}
      * @return True or False
      */
     boolean createLocalNetwork(Node node, NeutronNetwork network);
@@ -105,9 +105,9 @@ public interface BridgeConfigurationManager {
 
     /**
      * Returns the physical interface mapped to the given neutron physical network.
-     * @param node
-     * @param physicalNetwork
-     * @return
+     * @param node the {@link Node} to query
+     * @param physicalNetwork neutron physical network
+     * @return name of the physical interface
      */
     String getPhysicalInterfaceName(Node node, String physicalNetwork);
 
@@ -117,4 +117,14 @@ public interface BridgeConfigurationManager {
      * @return a List in the format {eth1, eth2} given bridge_mappings=physnet1:eth1,physnet2:eth2
      */
     List<String> getAllPhysicalInterfaceNames(Node node);
+
+   /*
+     * Return br-ex interface configured in the bridge_mappings.
+     * Return null if br-ex is not configured in bridge_mappings.
+     * @param node the {@link Node} to query
+     * @param externalNetwork
+     * @return the interface as a string like eth3 given bridge_mappings=br-ex:eth3
+   */
+     String getExternalInterfaceName (Node node, String externalNetwork);
+
 }
index b1beb944227541c20a7d105eaa08dc9f0ac90feb..209530b0ed4abe92547aafaa06b8cc1a29b047ad 100644 (file)
@@ -22,52 +22,57 @@ import org.apache.commons.lang3.tuple.Pair;
 public interface ConfigurationService {
 
     /**
-     * Returns the name configured name of the Integration Bridge
+     * @return the name configured name of the Integration Bridge
      */
     String getIntegrationBridgeName();
 
     /**
      * Configures the name of the Integration Bridge
+     * @param integrationBridgeName name of integration bridge
      */
     void setIntegrationBridgeName(String integrationBridgeName);
 
     /**
-     * Returns the name configured name of the Network Bridge
+     * @return the name configured name of the Network Bridge
      */
     String getNetworkBridgeName();
 
     /**
      * Configures the name of the Network Bridge
+     * @param networkBridgeName Name of the network bridge
      */
     void setNetworkBridgeName(String networkBridgeName);
 
     /**
-     * Returns the name configured name of the ExternalBridge
+     * @return the name configured name of the ExternalBridge
      */
     String getExternalBridgeName();
 
     /**
      * Configures the name of the External Bridge
+     * @param externalBridgeName Name of external bridge
      */
     void setExternalBridgeName(String externalBridgeName);
 
     /**
-     * Returns the key used to access the Tunnel Endpoint configuration from Open vSwitch
+     * @return the key used to access the Tunnel Endpoint configuration from Open vSwitch
      */
     String getTunnelEndpointKey();
 
     /**
      * Sets the key used to access the Tunnel Endpoint configuration from Open vSwitch
+     * @param tunnelEndpointKey key of tunnel end point
      */
     void setTunnelEndpointKey(String tunnelEndpointKey);
 
     /**
-     * Returns a Map of patch port names where the key is a tuple of source bridge and destination bridge
+     * @return a Map of patch port names where the key is a tuple of source bridge and destination bridge
      */
     Map<Pair<String, String>, String> getPatchPortNames();
 
     /**
      * Sets the Map of source/destination bridges to patch port name
+     * @param patchPortNames Map of source/destination bridges to patch port name
      */
     void setPatchPortNames(Map<Pair<String, String>, String> patchPortNames);
 
@@ -80,22 +85,24 @@ public interface ConfigurationService {
     String getPatchPortName(Pair portTuple);
 
     /**
-     * Returns the key used to access the Tunnel Endpoint configuration from Open vSwitch
+     * @return the key used to access the Tunnel Endpoint configuration from Open vSwitch
      */
     String getProviderMappingsKey();
 
     /**
      * Sets the key used to access the Tunnel Endpoint configuration from Open vSwitch
+     * @param providerMappingsKey provide mapping key
      */
     void setProviderMappingsKey(String providerMappingsKey);
 
     /**
-     * Gets the default provider mapping
+     * @return Gets the default provider mapping
      */
     String getDefaultProviderMapping();
 
     /**
      * Sets the default provider mapping
+     * @param providerMapping provider mapping
      */
     void setDefaultProviderMapping(String providerMapping);
 
@@ -134,4 +141,6 @@ public interface ConfigurationService {
      * @return the MacAddress to use for the default gateway; or null if none is configured.
      */
     String getDefaultGatewayMacAddress(Node node);
+
+    boolean isUserSpaceEnabled();
 }
index 2335078062023480a5e687c0cca95158c162b4c1..069fd6c24dcc967a41a259bfed8efbd15b8b4c05 100644 (file)
@@ -8,10 +8,11 @@
 
 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 org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.Neutron_IPs;
+import java.util.List;
 
 /**
  *  This interface allows egress Port Security flows to be written to devices.
@@ -19,21 +20,35 @@ import org.opendaylight.neutron.spi.Neutron_IPs;
 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 fixed egress ACL rules that will be associated with the VM port when a vm is spawned.
+     * 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 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,8 +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 4fb38991f0def9f90316a57791963048b456b93a..a96d78b4b57937847b604baab67439c71bf12e8e 100644 (file)
@@ -31,15 +31,17 @@ public interface GatewayMacResolver {
      * periodicRefresh flag.
      * @param externalNetworkBridgeDpid This bridge will be used for sending ARP request
      * @param gatewayIp ARP request will be send for this ip address
+     * @param sourceIpAddress Source IP address for the ARP request (localhost)
+     * @param sourceMacAddress Source MAC address for the ARP request (localhost)
      * @param periodicRefresh Do you want to periodically refresh the gateway mac?
-     * @return
+     * @return ListenableFuture that contains the mac address of gateway ip.
      */
     public ListenableFuture<MacAddress> resolveMacAddress( final Long externalNetworkBridgeDpid, final Ipv4Address gatewayIp,
             final Ipv4Address sourceIpAddress, final MacAddress sourceMacAddress, final Boolean periodicRefresh);
 
     /**
      * Method will stop the periodic refresh of the given gateway ip address.
-     * @param gatewayIp
+     * @param gatewayIp Gateway IP Address
      */
     public void stopPeriodicRefresh(final Ipv4Address gatewayIp);
 }
index 28d5d7ce1b12e1e11ec13360f73687e164271b3f..6121adaf1b7e48d9608996f902e1572b8c9ee6a3 100644 (file)
@@ -8,10 +8,9 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.api;
 
-import java.util.List;
-
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.Neutron_IPs;
+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;
 
 /**
  *  This interface allows ingress Port Security flows to be written to devices.
@@ -19,19 +18,33 @@ import org.opendaylight.neutron.spi.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,7 +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;
     }
index 953a0b17f256cc0063930aa1457e177b338b6f0e..791e07aeac811c11945e363bb85501ba53d093db 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.api;
 
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 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;
@@ -19,27 +19,37 @@ import org.osgi.framework.ServiceReference;
 public interface NetworkingProvider {
 
     /**
-     * Returns the name of the NetworkingProvider
+     * @return the name of the NetworkingProvider
      */
     String getName();
 
     /**
-     * Return true if the provider supports Network Service Instances
+     * @return true if the provider supports Network Service Instances
      */
     boolean supportsServices();
 
     /**
-     * Return true if the provider supports per-tenant or "static" tunneling
+     * @return true if the provider supports per-tenant or "static" tunneling
      */
     boolean hasPerTenantTunneling();
 
     /**
      * Handle Interface Update Callback Method
+     * @param network Neutron Network attached to the interface
+     * @param source Source node where interface is attached
+     * @param intf Termination point attached to the node
+     * @return true if interface update handled successfully
      */
     boolean handleInterfaceUpdate(NeutronNetwork network, Node source, OvsdbTerminationPointAugmentation intf);
 
     /**
      * Handle Interface Delete Callback Method
+     * @param tunnelType Type of the tunnel (e.g. vxlan)
+     * @param network Neutron Network associated with the removed interface
+     * @param source Source node where interface was attached
+     * @param intf Termination point associated to the deleted interface
+     * @param isLastInstanceOnNode is last interface attached to the node ?
+     * @return true if interface delete handled successfully
      */
     boolean handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node source,
                                   OvsdbTerminationPointAugmentation intf, boolean isLastInstanceOnNode);
@@ -49,11 +59,13 @@ public interface NetworkingProvider {
      * This method provides a set of common functionalities to initialize the Flow rules of an OVSDB node
      * that are Openflow Version specific. Hence we have this method in addition to the following
      * Openflow Node specific initialization method.
+     * @param node Node on which flow rules are going to be installed
      */
     void initializeFlowRules(Node node);
 
     /**
      * Initialize the Flow rules for a given OpenFlow node
+     * @param openflowNode Node on which flow rules are going to be installed
      */
     void initializeOFFlowRules(Node openflowNode);
 }
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 ba51303731c327da8b5f31faa9658e551a556494..f6dcea1a857e373585a926764eb709ca5c4f5c4a 100644 (file)
@@ -8,14 +8,15 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.api;
 
-import java.util.List;
-
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.Neutron_IPs;
+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;
 
+import java.util.List;
+
 /**
  * Open vSwitch isolates Tenant Networks using VLANs on the Integration Bridge.
  * This class manages the provisioning of these VLANs
@@ -43,6 +44,14 @@ public interface SecurityServicesManager {
      */
     NeutronPort getDhcpServerPort(OvsdbTerminationPointAugmentation intf);
 
+    /**
+      * Check if the given interface corresponds to a DHCP server port.
+      *
+      * @param intf the intf
+      * @return Return the DHCP neutron port
+      */
+    NeutronPort getNeutronPortFromDhcpIntf(OvsdbTerminationPointAugmentation intf);
+
     /**
      * Is the port a compute port.
      *
@@ -68,17 +77,31 @@ public interface SecurityServicesManager {
     boolean isLastPortinBridge(Node node, OvsdbTerminationPointAugmentation intf);
     /**
      * Returns the  list of ip address assigned to the interface.
-     * @param node The node to which the intf is connected.
      * @param intf the intf
      * @return the list of ip address associated with the vm
      */
-    List<Neutron_IPs> getIpAddressList(Node node, OvsdbTerminationPointAugmentation intf);
+    List<Neutron_IPs> getIpAddressList(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  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 7a8f6e6a593255e785777a743b0ea77d6993c657..6805837e7dff92b2b517b19a8548f1ef679c29e1 100644 (file)
@@ -11,6 +11,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.OvsdbNodeAugmentation;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
@@ -31,11 +32,13 @@ 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);
     String getOsdbNodeExternalIdsValue(OvsdbNodeAugmentation ovsdbNodeAugmentation, String key);
-    boolean addBridge(Node ovsdbNode, String bridgeName, String target);
+    boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
+                      final Class<? extends DatapathTypeBase> dpType);
     boolean deleteBridge(Node ovsdbNode);
     OvsdbBridgeAugmentation readBridge(Node node, String name);
     Node readBridgeNode(Node node, String name);
index 482a6077bbcc3d82992fe94ab0a1947312b52529..ff6200a138fdae4979942a338fa7c34df3c02091 100644 (file)
@@ -8,8 +8,8 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.api;
 
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
 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;
 
@@ -55,16 +55,22 @@ public interface TenantNetworkManager {
 
     /**
      * Get the Neutron Network ID for a given Segmentation ID
+     * @param segmentationId segmentation id of the neutron network
+     * @return Neutron network id associated with the given segmentation id
      */
     String getNetworkId(String segmentationId);
 
     /**
      * Network Created Callback
+     * @param node target node
+     * @param networkId Id of neutron network
+     * @return vlan assigned to the network
      */
     int networkCreated(Node node, String networkId);
 
     /**
      * Network Deleted Callback
+     * @param id Id of the neutron network
      */
     void networkDeleted(String id);
     NeutronNetwork getTenantNetwork(OvsdbTerminationPointAugmentation terminationPointAugmentation);
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/UuidUtils.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/UuidUtils.java
deleted file mode 100644 (file)
index ef64fd1..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2013, 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.api;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.UUID;
-
-/**
- * Utilities for validating and converting OpenStack UUID's
- */
-public final class UuidUtils {
-
-    /**
-     * Neutron UUID identifier length.
-     */
-    private static final int UUID_LEN = 36;
-
-    /**
-     * Tenant id length when keystone identifier is used in neutron.
-     */
-    private static final int KEYSTONE_ID_LEN = 32;
-
-    /**
-     * UUID version number position.
-     */
-    private static final int UUID_VERSION_POS = 12;
-
-    /**
-     * UUID time-low field byte length in hex.
-     */
-    private static final int UUID_TIME_LOW = 8;
-
-    /**
-     * UUID time-mid field byte length in hex.
-     */
-    private static final int UUID_TIME_MID = 4;
-
-    /**
-     * UUID time-high and version field byte length in hex.
-     */
-    private static final int UUID_TIME_HIGH_VERSION = 4;
-
-    /**
-     * UUID clock sequence field byte length in hex.
-     */
-    private static final int UUID_CLOCK_SEQ = 4;
-
-    /**
-     * UUID node field byte length in hex.
-     */
-    private static final int UUID_NODE = 12;
-
-    /**
-     * UUID time field byte length in hex.
-     */
-    private static final int UUID_TIME_LEN = (UUID_TIME_LOW +
-                                              UUID_TIME_MID + UUID_TIME_HIGH_VERSION);
-
-    private static final Logger LOG = LoggerFactory.getLogger(UuidUtils.class);
-
-    /**
-     * Private constructor (utility class).
-     */
-    private UuidUtils() {
-        // Nothing to do
-    }
-
-    /**
-     * Convert neutron object id to  key syntax.
-     *
-     * @param neutronID neutron object id.
-     * @return key in compliance to  object key.
-     */
-    public static String convertNeutronIDToKey(String neutronID) {
-        String key;
-        if (neutronID == null) {
-            return null;
-        }
-
-        LOG.trace(" neutronID - {}, length - {} ",
-                     neutronID, neutronID.length());
-        if (!isValidNeutronID(neutronID)) {
-            return null;
-        }
-
-        if (neutronID.length() == UUID_LEN) {
-            key = convertUUIDToKey(neutronID);
-        } else if (neutronID.length() == KEYSTONE_ID_LEN) {
-            key = convertKeystoneIDToKey(neutronID);
-        } else {
-            key = neutronID;
-        }
-        return key;
-    }
-
-    /**
-     * Verify the validity of neutron object identifiers.
-     *
-     * @param id neutron object id.
-     * @return {@code true} neutron identifier is valid.
-     *         {@code false} neutron identifier is invalid.
-     */
-    public static boolean isValidNeutronID(String id) {
-        if (id == null) {
-            return false;
-        }
-        boolean isValid;
-        LOG.trace("id - {}, length - {} ", id, id.length());
-        /**
-         * check the string length
-         * if length is 36 its a uuid do uuid validation
-         * if length is 32 it can be tenant id form keystone
-         * if its less than 32  can be valid  ID
-         */
-        if (id.length() == UUID_LEN) {
-            try {
-                UUID fromUUID = UUID.fromString(id);
-                String toUUID = fromUUID.toString();
-                isValid = toUUID.equalsIgnoreCase(id);
-            } catch(IllegalArgumentException e) {
-                LOG.error(" IllegalArgumentExecption for id - {} ", id, e);
-                isValid = false;
-            }
-        } else {
-            isValid = (id.length() > 0) && (id.length() <= KEYSTONE_ID_LEN);
-        }
-        return isValid;
-    }
-
-    /**
-     * Convert UUID to  key syntax.
-     *
-     * @param id neutron object UUID.
-     * @return key in compliance to  object key.
-     */
-    private static String convertUUIDToKey(String id) {
-
-        String key;
-        if (id == null) {
-            return null;
-        }
-        LOG.trace("id - {}, length - {} ", id, id.length());
-        /**
-         * ID must be less than 32 bytes,
-         * Shorten UUID string length from 36 to 31 as follows:
-         * delete UUID Version and hyphen (see RFC4122) field in the UUID
-         */
-        try {
-            StringBuilder tKey = new StringBuilder();
-            // remove all the '-'
-            for (String retkey: id.split("-")) {
-                tKey.append(retkey);
-            }
-            // remove the version byte
-            tKey.deleteCharAt(UUID_VERSION_POS);
-            key = tKey.toString();
-        } catch(IllegalArgumentException ile) {
-            LOG.error(" Invalid UUID - {} ", id, ile);
-            key = null;
-        }
-        return key;
-    }
-
-    /**
-     * Convert string id to  key syntax.
-     *
-     * @param id neutron object id.
-     * @return key in compliance to  object key.
-     */
-    private static String convertKeystoneIDToKey(String id) {
-        String key = null;
-        if (id == null) {
-            return null;
-        }
-
-        /**
-         * tenant ID if given from openstack keystone does not follow the
-         * generic UUID syntax, convert the ID to UUID format for validation
-         * and reconvert it to  key
-         */
-
-        LOG.trace(" id - {}, length - {} ", id, id.length());
-        try {
-            StringBuilder tKey = new StringBuilder();
-            String tmpStr = id.substring(0, UUID_TIME_LOW);
-            tKey.append(tmpStr);
-            tKey.append("-");
-            tmpStr = id.substring(UUID_TIME_LOW,
-                                  (UUID_TIME_LOW + UUID_TIME_MID));
-            tKey.append(tmpStr);
-            tKey.append("-");
-            tmpStr = id.substring((UUID_TIME_LOW + UUID_TIME_MID),
-                                  UUID_TIME_LEN);
-            tKey.append(tmpStr);
-            tKey.append("-");
-            tmpStr = id.substring(UUID_TIME_LEN,
-                                  (UUID_TIME_LEN + UUID_CLOCK_SEQ));
-            tKey.append(tmpStr);
-            tKey.append("-");
-            tmpStr = id.substring((UUID_TIME_LEN + UUID_CLOCK_SEQ),
-                                  (UUID_TIME_LEN + UUID_CLOCK_SEQ + UUID_NODE));
-            tKey.append(tmpStr);
-
-            tmpStr = tKey.toString();
-            UUID fromUUID = UUID.fromString(tmpStr);
-            String toUUID = fromUUID.toString();
-            if (toUUID.equalsIgnoreCase(tmpStr)) {
-                key = convertUUIDToKey(tmpStr);
-            }
-        } catch(IndexOutOfBoundsException ibe) {
-            LOG.error(" Exception! Invalid UUID - {} ", id, ibe);
-            key = null;
-        } catch (IllegalArgumentException iae) {
-            LOG.error(" Exception! Invalid object ID - {} ", id, iae);
-            key = null;
-        }
-        return key;
-    }
-
-}
index bc40093955545c17c1e73b8af2728f9f0a016d38..d59f53601734280d497669f225369496a3d40f84 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.impl;
 
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
@@ -19,8 +19,12 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbTables;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+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.DatapathTypeNetdev;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeSystem;
 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.ManagerEntry;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 
 import com.google.common.base.Preconditions;
@@ -29,11 +33,11 @@ import com.google.common.collect.Lists;
 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 org.apache.commons.lang3.tuple.ImmutablePair;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -199,6 +203,34 @@ public class BridgeConfigurationManagerImpl implements BridgeConfigurationManage
         return isCreated;
     }
 
+
+
+    @Override
+    public String getExternalInterfaceName (Node node, String extNetwork) {
+        String phyIf = null;
+        String providerMaps = southbound.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
+                configurationService.getProviderMappingsKey());
+        if (providerMaps != null) {
+            for (String map : providerMaps.split(",")) {
+                String[] pair = map.split(":");
+                if (pair[0].equals(extNetwork)) {
+                    phyIf = pair[1];
+                    break;
+                }
+            }
+        }
+        if (phyIf == null) {
+            LOG.error("External interface not found for Node: {}, Network {}",
+                    node, extNetwork);
+        }
+        else {
+            LOG.info("External interface found for Node: {}, Network {} is {}",node,extNetwork,phyIf);
+        }
+        return phyIf;
+    }
+
+
+
     @Override
     public String getPhysicalInterfaceName (Node node, String physicalNetwork) {
         String phyIf = null;
@@ -377,8 +409,15 @@ public class BridgeConfigurationManagerImpl implements BridgeConfigurationManage
                 LOG.error("Add Port {} to Bridge {} failed", portNameExt, brExt);
                 return false;
             }
+            String extNetName = getExternalInterfaceName(extBridgeNode, brExt);
+            if ( extNetName != null) {
+                if (!addPortToBridge(extBridgeNode, brExt, extNetName)) {
+                    LOG.error("Add External Port {} to Bridge {} failed", extNetName, brExt);
+                    return false;
+                }
+            LOG.info("Add External Port {} to Ext Bridge {} success", extNetName, brExt);
+            }
         }
-
         /* For vlan network types add physical port to br-int. */
         if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
             String phyNetName = this.getPhysicalInterfaceName(bridgeNode, network.getProviderPhysicalNetwork());
@@ -388,7 +427,7 @@ public class BridgeConfigurationManagerImpl implements BridgeConfigurationManage
             }
         }
 
-        LOG.debug("createBridges: node: {}, status: success", bridgeNode);
+        LOG.info("createBridges: node: {}, status: success", bridgeNode);
         return true;
     }
 
@@ -447,7 +486,11 @@ public class BridgeConfigurationManagerImpl implements BridgeConfigurationManage
         boolean rv = true;
         if ((!southbound.isBridgeOnOvsdbNode(ovsdbNode, bridgeName)) ||
                 (southbound.getBridgeFromConfig(ovsdbNode, bridgeName) == null)) {
-            rv = southbound.addBridge(ovsdbNode, bridgeName, getControllerTarget(ovsdbNode));
+            Class<? extends DatapathTypeBase> dpType = null;
+            if (configurationService.isUserSpaceEnabled()) {
+                dpType = DatapathTypeNetdev.class;
+            }
+            rv = southbound.addBridge(ovsdbNode, bridgeName, getControllersFromOvsdbNode(ovsdbNode), dpType);
         }
         return rv;
     }
@@ -492,42 +535,70 @@ public class BridgeConfigurationManagerImpl implements BridgeConfigurationManage
         return openFlowPort;
     }
 
-    private String getControllerTarget(Node node) {
-        String setControllerStr = null;
-        short openflowPort = Constants.OPENFLOW_PORT;
-        //Look at user configuration.
-        //TODO: In case we move to config subsystem to expose these user facing parameter,
-        // we will have to modify this code.
+    private List<String> getControllersFromOvsdbNode(Node node) {
+        List<String> controllersStr = new ArrayList<>();
 
         String controllerIpStr = getControllerIPAddress();
-
-        if(controllerIpStr == null){
-            // Check if ovsdb node has connection info
+        if (controllerIpStr != null) {
+            // If codepath makes it here, the ip address to be used was explicitly provided.
+            // Being so, also fetch openflowPort provided via ConfigProperties.
+            controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                    + ":" + controllerIpStr + ":" + getControllerOFPort());
+        } else {
+            // Check if ovsdb node has manager entries
             OvsdbNodeAugmentation ovsdbNodeAugmentation = southbound.extractOvsdbNode(node);
             if (ovsdbNodeAugmentation != null) {
-                ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
-                if(connectionInfo != null && connectionInfo.getLocalIp() != null) {
-                    controllerIpStr = new String(connectionInfo.getLocalIp().getValue());
-                }else{
-                    LOG.warn("Ovsdb Node does not contains connection info : {}", node);
+                List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
+                if (managerEntries != null && !managerEntries.isEmpty()) {
+                    for (ManagerEntry managerEntry : managerEntries) {
+                        if (managerEntry == null || managerEntry.getTarget() == null) {
+                            continue;
+                        }
+                        String[] tokens = managerEntry.getTarget().getValue().split(":");
+                        if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
+                            controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                                    + ":" + tokens[1] + ":" + getControllerOFPort());
+                        } else if (tokens[0].equalsIgnoreCase("ptcp")) {
+                            ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
+                            if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
+                                controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
+                                controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                                        + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
+                            } else {
+                                LOG.warn("Ovsdb Node does not contain connection info: {}", node);
+                            }
+                        } else {
+                            LOG.trace("Skipping manager entry {} for node {}",
+                                    managerEntry.getTarget(), node.getNodeId().getValue());
+                        }
+                    }
+                } else {
+                    LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
                 }
             }
-        }else {
-            openflowPort = getControllerOFPort();
         }
 
-        if(controllerIpStr == null) {
-            // Neither user provided ip nor ovsdb node has controller ip, Lets use local machine ip address
+        if (controllersStr.isEmpty()) {
+            // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
             LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
             controllerIpStr = getLocalControllerHostIpAddress();
+            if (controllerIpStr != null) {
+                controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
+                        + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
+            }
         }
-        if(controllerIpStr != null){
-            LOG.debug("Targe OpenFlow Controller found : {}", controllerIpStr);
-            setControllerStr = Constants.OPENFLOW_CONNECTION_PROTOCOL + ":" + controllerIpStr + ":" + openflowPort;
-        }else {
+
+        if (controllersStr.isEmpty()) {
             LOG.warn("Failed to determine OpenFlow controller ip address");
+        } else if (LOG.isDebugEnabled()) {
+            controllerIpStr = "";
+            for (String currControllerIpStr : controllersStr) {
+                controllerIpStr += " " + currControllerIpStr;
+            }
+            LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
         }
-        return setControllerStr;
+
+        return controllersStr;
     }
 
     private String getLocalControllerHostIpAddress() {
@@ -551,7 +622,7 @@ public class BridgeConfigurationManagerImpl implements BridgeConfigurationManage
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         configurationService =
                 (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
         networkingProviderManager =
index 1692dad4fa07e3accdbb44f4acf476bcba713f15..c9691fce72a395d4c0db83e6f8a7e013ffd27430 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -179,7 +179,13 @@ public class ConfigurationServiceImpl implements ConfigurationService, ConfigInt
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public boolean isUserSpaceEnabled() {
+        final String enabledPropertyStr = ConfigProperties.getProperty(this.getClass(), "ovsdb.userspace.enabled");
+        return enabledPropertyStr != null && enabledPropertyStr.equalsIgnoreCase("yes");
+    }
+
+    @Override
+    public void setDependencies(ServiceReference serviceReference) {
         southbound =
                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
     }
index 1c5f3e90a371db628b4ae147ae847a4b2f54dad1..75132f90c1a33d38b0b354cf75ac0f9243e0a92c 100644 (file)
@@ -14,7 +14,6 @@ import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -86,6 +85,7 @@ public class EventDispatcherImpl implements EventDispatcher, ConfigInterface {
     }
 
     private void dispatchEvent(AbstractEvent ev) {
+        LOG.trace("dispatchEvent: Processing (id={}): {}", ev.getTransactionId(), ev);
         AbstractHandler handler = handlers[ev.getHandlerType().ordinal()];
         if (handler == null) {
             LOG.warn("event dispatcher found no handler for {}", ev);
@@ -93,14 +93,17 @@ public class EventDispatcherImpl implements EventDispatcher, ConfigInterface {
         }
 
         handler.processEvent(ev);
+        LOG.trace("dispatchEvent: Done processing (id={}): {}", ev.getTransactionId(), ev);
     }
 
     public void eventHandlerAdded(final ServiceReference ref, AbstractHandler handler){
         Long pid = (Long) ref.getProperty(org.osgi.framework.Constants.SERVICE_ID);
         Object handlerTypeObject = ref.getProperty(Constants.EVENT_HANDLER_TYPE_PROPERTY);
         if (!(handlerTypeObject instanceof AbstractEvent.HandlerType)){
+            // The exception should give us a stacktrace
             LOG.error("Abstract handler reg failed to provide a valid handler type: {} ref: {} handler: {}",
-                    handlerTypeObject, ref.getClass().getName(), handler.getClass().getName());
+                    handlerTypeObject, ref.getClass().getName(), handler.getClass().getName(),
+                    new IllegalArgumentException("Missing handler type"));
             return;
         }
         AbstractEvent.HandlerType handlerType = (AbstractEvent.HandlerType) handlerTypeObject;
@@ -141,7 +144,7 @@ public class EventDispatcherImpl implements EventDispatcher, ConfigInterface {
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {}
+    public void setDependencies(ServiceReference serviceReference) {}
 
     @Override
     public void setDependencies(Object impl) {}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtils.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtils.java
deleted file mode 100644 (file)
index 9420bbf..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.openstack.netvirt.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-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;
-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.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MdsalUtils {
-    private static final Logger LOG = LoggerFactory.getLogger(MdsalUtils.class);
-    private DataBroker databroker = null;
-
-    /**
-     * Class constructor setting the data broker.
-     *
-     * @param dataBroker the {@link org.opendaylight.controller.md.sal.binding.api.DataBroker}
-     */
-    public MdsalUtils(DataBroker dataBroker) {
-        this.databroker = dataBroker;
-    }
-
-    /**
-     * Executes delete as a blocking transaction.
-     *
-     * @param store {@link LogicalDatastoreType} which should be modified
-     * @param path {@link InstanceIdentifier} to read from
-     * @param <D> the data object type
-     * @return the result of the request
-     */
-    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();
-            result = true;
-        } catch (TransactionCommitFailedException e) {
-            LOG.warn("Failed to delete {} ", path, e);
-        }
-        return result;
-    }
-
-    /**
-     * Executes merge as a blocking transaction.
-     *
-     * @param logicalDatastoreType {@link LogicalDatastoreType} which should be modified
-     * @param path {@link InstanceIdentifier} for path to read
-     * @param <D> the data object type
-     * @return the result of the request
-     */
-    public <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean merge(
-            final LogicalDatastoreType logicalDatastoreType, final InstanceIdentifier<D> path, D data)  {
-        boolean result = false;
-        final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
-        transaction.merge(logicalDatastoreType, path, data, true);
-        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
-        try {
-            future.checkedGet();
-            result = true;
-        } catch (TransactionCommitFailedException e) {
-            LOG.warn("Failed to merge {} ", path, e);
-        }
-        return result;
-    }
-
-    /**
-     * Executes put as a blocking transaction.
-     *
-     * @param logicalDatastoreType {@link LogicalDatastoreType} which should be modified
-     * @param path {@link InstanceIdentifier} for path to read
-     * @param <D> the data object type
-     * @return the result of the request
-     */
-    public <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean put(
-            final LogicalDatastoreType logicalDatastoreType, final InstanceIdentifier<D> path, D data)  {
-        boolean result = false;
-        final WriteTransaction transaction = databroker.newWriteOnlyTransaction();
-        transaction.put(logicalDatastoreType, path, data, true);
-        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
-        try {
-            future.checkedGet();
-            result = true;
-        } catch (TransactionCommitFailedException e) {
-            LOG.warn("Failed to put {} ", path, e);
-        }
-        return result;
-    }
-
-    /**
-     * Executes read as a blocking transaction.
-     *
-     * @param store {@link LogicalDatastoreType} to read
-     * @param path {@link InstanceIdentifier} for path to read
-     * @param <D> the data object type
-     * @return the result as the data object requested
-     */
-    public <D extends org.opendaylight.yangtools.yang.binding.DataObject> D read(
-            final LogicalDatastoreType store, final InstanceIdentifier<D> path)  {
-        D result = null;
-        final ReadOnlyTransaction transaction = databroker.newReadOnlyTransaction();
-        Optional<D> optionalDataObject;
-        CheckedFuture<Optional<D>, ReadFailedException> future = transaction.read(store, path);
-        try {
-            optionalDataObject = future.checkedGet();
-            if (optionalDataObject.isPresent()) {
-                result = optionalDataObject.get();
-            } else {
-                LOG.debug("{}: Failed to read {}",
-                        Thread.currentThread().getStackTrace()[1], path);
-            }
-        } catch (ReadFailedException e) {
-            LOG.warn("Failed to read {} ", path, e);
-        }
-        transaction.close();
-        return result;
-    }
-}
index 32727ce7272699ac7ab7268cf5883eb1e4e34ef0..dfcfdaa8cc5d464b58781ddff5741b89b82ac1eb 100644 (file)
@@ -8,48 +8,68 @@
 
 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.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronFloatingIP;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronRouter;
-import org.opendaylight.neutron.spi.NeutronRouter_Interface;
-import org.opendaylight.neutron.spi.NeutronSubnet;
-import org.opendaylight.neutron.spi.Neutron_IPs;
 import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
-import org.opendaylight.ovsdb.openstack.netvirt.api.*;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+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.translator.iaware.impl.NeutronIAwareUtil;
+import org.opendaylight.ovsdb.utils.neutron.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.BundleContext;
-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.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,
@@ -65,12 +85,14 @@ 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;
     private volatile ArpProvider arpProvider;
     private volatile RoutingProvider routingProvider;
     private volatile GatewayMacResolver gatewayMacResolver;
+    private volatile SecurityServicesManager securityServicesManager;
 
     private class FloatIpData {
         // br-int of node where floating ip is associated with tenant port
@@ -98,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<>();
@@ -159,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
@@ -198,6 +362,8 @@ public class NeutronL3Adapter implements ConfigInterface {
      */
     public void handleNeutronPortEvent(final NeutronPort neutronPort, Action action) {
         LOG.debug("Neutron port {} event : {}", action, neutronPort.toString());
+
+        this.processSecurityGroupUpdate(neutronPort);
         if (!this.enabled) {
             return;
         }
@@ -234,14 +400,16 @@ public class NeutronL3Adapter implements ConfigInterface {
         if (neutronPort.getDeviceOwner().equalsIgnoreCase(OWNER_ROUTER_INTERFACE) ||
             neutronPort.getDeviceOwner().equalsIgnoreCase(OWNER_ROUTER_INTERFACE_DISTRIBUTED)) {
 
-            for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
-                NeutronRouter_Interface neutronRouterInterface =
+            if (neutronPort.getFixedIPs() != null) {
+                for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
+                    NeutronRouter_Interface neutronRouterInterface =
                         new NeutronRouter_Interface(neutronIP.getSubnetUUID(), neutronPort.getPortUUID());
-                // id of router interface to be same as subnet
-                neutronRouterInterface.setID(neutronIP.getSubnetUUID());
-                neutronRouterInterface.setTenantID(neutronPort.getTenantID());
+                    // id of router interface to be same as subnet
+                    neutronRouterInterface.setID(neutronIP.getSubnetUUID());
+                    neutronRouterInterface.setTenantID(neutronPort.getTenantID());
 
-                this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
+                    this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
+                }
             }
         } else {
             // We made it here, port is not used as a router interface. If this is not a delete action, make sure that
@@ -253,11 +421,11 @@ public class NeutronL3Adapter implements ConfigInterface {
                 for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
                     NeutronRouter_Interface neutronRouterInterface =
                             subnetIdToRouterInterfaceCache.get(neutronIP.getSubnetUUID());
-                   if (neutronRouterInterface != null) {
-                       this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
-                   }
-               }
-           }
+                    if (neutronRouterInterface != null) {
+                        this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
+                    }
+                }
+            }
             this.updateL3ForNeutronPort(neutronPort, isDelete);
         }
     }
@@ -302,15 +470,24 @@ public class NeutronL3Adapter implements ConfigInterface {
             boolean currPortShouldBeDeleted = false;
             // Note: delete in this case only applies to 1)router interface delete and 2)ports on the same subnet
             if (isDelete) {
-                for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
-                    if (neutronRouterInterface.getSubnetUUID().equalsIgnoreCase(neutronIP.getSubnetUUID())) {
-                        currPortShouldBeDeleted = true;
-                        break;
+                if (neutronPort.getFixedIPs() != null) {
+                    for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
+                        if (neutronRouterInterface.getSubnetUUID().equalsIgnoreCase(neutronIP.getSubnetUUID())) {
+                            currPortShouldBeDeleted = true;
+                            break;
+                        }
                     }
                 }
             }
             this.updateL3ForNeutronPort(neutronPort, currPortShouldBeDeleted);
         }
+
+        if (isDelete) {
+            /*
+             *  Bug 4277: Remove the router interface cache only after deleting the neutron port l3 flows.
+             */
+            this.cleanupRouterCache(neutronRouterInterface);
+        }
     }
 
     /**
@@ -320,7 +497,7 @@ public class NeutronL3Adapter implements ConfigInterface {
      * way around) on OpenFlow Table 100.
      *
      * @param actionIn the {@link org.opendaylight.ovsdb.openstack.netvirt.api.Action} action to be handled.
-     * @param neutronFloatingIP An {@link org.opendaylight.neutron.spi.NeutronFloatingIP} instance of NeutronFloatingIP object.
+     * @param neutronFloatingIP An {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP} instance of NeutronFloatingIP object.
      */
     public void handleNeutronFloatingIPEvent(final NeutronFloatingIP neutronFloatingIP,
                                              Action actionIn) {
@@ -368,7 +545,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());
@@ -385,7 +562,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());
@@ -395,13 +572,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);
         }
     }
@@ -416,16 +593,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();
@@ -476,7 +647,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;
@@ -523,7 +694,7 @@ public class NeutronL3Adapter implements ConfigInterface {
      * Process the event.
      *
      * @param action the {@link org.opendaylight.ovsdb.openstack.netvirt.api.Action} action to be handled.
-     * @param neutronNetwork An {@link org.opendaylight.neutron.spi.NeutronNetwork} instance of NeutronFloatingIP object.
+     * @param neutronNetwork An {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork} instance of NeutronFloatingIP object.
      */
     public void handleNeutronNetworkEvent(final NeutronNetwork neutronNetwork, Action action) {
         LOG.debug("neutronNetwork {}: network: {}", action, neutronNetwork);
@@ -538,7 +709,7 @@ public class NeutronL3Adapter implements ConfigInterface {
      * @param bridgeNode An instance of Node object.
      * @param intf An {@link org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105
      * .OvsdbTerminationPointAugmentation} instance of OvsdbTerminationPointAugmentation object.
-     * @param neutronNetwork An {@link org.opendaylight.neutron.spi.NeutronNetwork} instance of NeutronNetwork
+     * @param neutronNetwork An {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork} instance of NeutronNetwork
      * object.
      * @param action the {@link org.opendaylight.ovsdb.openstack.netvirt.api.Action} action to be handled.
      */
@@ -560,8 +731,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);
             }
 
@@ -632,7 +802,9 @@ public class NeutronL3Adapter implements ConfigInterface {
             if (dpid == null) {
                 continue;
             }
-
+            if (neutronPort.getFixedIPs() == null) {
+                continue;
+            }
             for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
                 final String tenantIpStr = neutronIP.getIpAddress();
                 if (tenantIpStr.isEmpty()) {
@@ -645,42 +817,73 @@ public class NeutronL3Adapter implements ConfigInterface {
 
                 // Configure distributed ARP responder
                 if (flgDistributedARPEnabled) {
-                    programStaticArpStage1(dpid, providerSegmentationId, tenantMac, tenantIpStr, action);
+                    // Arp rule is only needed when segmentation exists in the given node (bug 4752).
+                    boolean arpNeeded = tenantNetworkManager.isTenantNetworkPresentInNode(node, providerSegmentationId);
+                    final Action actionForNode = arpNeeded ? action : Action.DELETE;
+                    programStaticArpStage1(dpid, providerSegmentationId, tenantMac, tenantIpStr, actionForNode);
                 }
             }
         }
     }
 
+    private void processSecurityGroupUpdate(NeutronPort neutronPort) {
+        LOG.trace("processSecurityGroupUpdate:" + neutronPort);
+        /**
+         * Get updated data and original data for the the changed. Identify the security groups that got
+         * added and removed and call the appropriate providers for updating the flows.
+         */
+        try {
+            NeutronPort originalPort = neutronPort.getOriginalPort();
+            if (null == originalPort) {
+                LOG.debug("processSecurityGroupUpdate: originalport is empty");
+                return;
+            }
+            List<NeutronSecurityGroup> addedGroup = getsecurityGroupChanged(neutronPort,
+                                                                            neutronPort.getOriginalPort());
+            List<NeutronSecurityGroup> deletedGroup = getsecurityGroupChanged(neutronPort.getOriginalPort(),
+                                                                              neutronPort);
+
+            if (null != addedGroup && !addedGroup.isEmpty()) {
+                securityServicesManager.syncSecurityGroup(neutronPort,addedGroup,true);
+            }
+            if (null != deletedGroup && !deletedGroup.isEmpty()) {
+                securityServicesManager.syncSecurityGroup(neutronPort,deletedGroup,false);
+            }
+
+        } catch (Exception e) {
+            LOG.error("Exception in processSecurityGroupUpdate", e);
+        }
+    }
+
+    private List<NeutronSecurityGroup> getsecurityGroupChanged(NeutronPort port1, NeutronPort port2) {
+        LOG.trace("getsecurityGroupChanged:" + "Port1:" + port1 + "Port2" + port2);
+        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) {
+                if (securityGroup1.getID().equals(securityGroup2.getID())) {
+                    iterator.remove();
+                }
+            }
+        }
+        return list1;
+    }
+
     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,
@@ -806,13 +1009,7 @@ public class NeutronL3Adapter implements ConfigInterface {
             }
         }
 
-        // Keep cache for finding router's mac from network uuid -- remove
-        //
-        if (isDelete) {
-            networkIdToRouterMacCache.remove(neutronNetwork.getNetworkUUID());
-            networkIdToRouterIpListCache.remove(neutronNetwork.getNetworkUUID());
-            subnetIdToRouterInterfaceCache.remove(subnet.getSubnetUUID());
-        }
+        // Keep cache for finding router's mac from network uuid -- NOTE: remove is done later, via cleanupRouterCache()
     }
 
     private void programFlowForNetworkFromExternal(final Node node,
@@ -912,41 +1109,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,
@@ -981,34 +1159,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,
@@ -1041,37 +1202,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,
@@ -1106,33 +1250,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,
@@ -1153,34 +1280,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) {
@@ -1260,6 +1370,9 @@ public class NeutronL3Adapter implements ConfigInterface {
     }
 
     private NeutronSubnet getExternalNetworkSubnet(NeutronPort gatewayPort){
+        if (gatewayPort.getFixedIPs() == null) {
+            return null;
+        }
         for (Neutron_IPs neutronIPs : gatewayPort.getFixedIPs()) {
             String subnetUUID = neutronIPs.getSubnetUUID();
             NeutronSubnet extSubnet = neutronSubnetCache.getSubnet(subnetUUID);
@@ -1274,6 +1387,21 @@ public class NeutronL3Adapter implements ConfigInterface {
         return null;
     }
 
+     private void cleanupRouterCache(final NeutronRouter_Interface neutronRouterInterface) {
+         /*
+          *  Fix for 4277
+          *  Remove the router cache only after deleting the neutron
+          *  port l3 flows.
+          */
+         final NeutronPort neutronPort = neutronPortCache.getPort(neutronRouterInterface.getPortUUID());
+
+         if (neutronPort != null) {
+             networkIdToRouterMacCache.remove(neutronPort.getNetworkUUID());
+             networkIdToRouterIpListCache.remove(neutronPort.getNetworkUUID());
+             subnetIdToRouterInterfaceCache.remove(neutronRouterInterface.getSubnetUUID());
+         }
+     }
+
     public void triggerGatewayMacResolver(final Node node, final NeutronPort gatewayPort ){
 
         Preconditions.checkNotNull(node);
@@ -1286,7 +1414,8 @@ public class NeutronL3Adapter implements ConfigInterface {
 
                 // TODO: address IPv6 case.
                 if (externalSubnet != null &&
-                    externalSubnet.getIpVersion() == 4) {
+                    externalSubnet.getIpVersion() == 4 &&
+                    gatewayPort.getFixedIPs() != null) {
                     LOG.info("Trigger MAC resolution for gateway ip {} on Node {}",externalSubnet.getGatewayIP(),node.getNodeId());
                     ListenableFuture<MacAddress> gatewayMacAddress =
                         gatewayMacResolver.resolveMacAddress(getDpidForExternalBridge(node),
@@ -1334,7 +1463,7 @@ public class NeutronL3Adapter implements ConfigInterface {
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         tenantNetworkManager =
                 (TenantNetworkManager) ServiceHelper.getGlobalInstance(TenantNetworkManager.class, this);
         configurationService =
@@ -1355,6 +1484,8 @@ public class NeutronL3Adapter implements ConfigInterface {
                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
         gatewayMacResolver =
                 (GatewayMacResolver) ServiceHelper.getGlobalInstance(GatewayMacResolver.class, this);
+        securityServicesManager =
+                (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
         initL3AdapterMembers();
     }
 
@@ -1366,6 +1497,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) {
@@ -1379,5 +1512,6 @@ public class NeutronL3Adapter implements ConfigInterface {
         }else if (impl instanceof GatewayMacResolver) {
             gatewayMacResolver = (GatewayMacResolver)impl;
         }
+        populateL3ForwardingCaches();
     }
 }
index b6b36a57cf1fb0921baf526a3f05407d77905d81..574331d6b784a33e395241e2ade0eeb2175d82fc 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,7 +66,7 @@ public class NodeCacheManagerImpl extends AbstractHandler implements NodeCacheMa
         }
         nodeCache.put(nodeId, node);
 
-        LOG.debug("processNodeUpdate: {} Node type {} {}: {}",
+        LOG.debug("processNodeUpdate: size= {}, Node type= {}, action= {}, node= {}",
                 nodeCache.size(),
                 southbound.getBridge(node) != null ? "BridgeNode" : "OvsdbNode",
                 action == Action.ADD ? "ADD" : "UPDATE",
@@ -164,14 +164,27 @@ 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(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         southbound =
                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
         eventDispatcher =
                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
-        eventDispatcher.eventHandlerAdded(
-                bundleContext.getServiceReference(NodeCacheManager.class.getName()), this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
+        populateNodeCache();
     }
 
     @Override
index eb4bbeb803dfa731c3edcbb0c2a7b5ead3ef3392..d64e7fd520cb7ac702c40e0d46ddb6b3576d294d 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.MultiTenantAwareRouter;
 
 import java.net.InetAddress;
 import java.util.UUID;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -83,7 +83,7 @@ public class OpenstackRouter implements MultiTenantAwareRouter, ConfigInterface
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
 
     }
 
index 99af88140020b7303a5d7813efea1b398b96037d..481da49b4fa2f78a30b24265b81c85b9e12e077f 100644 (file)
@@ -8,7 +8,9 @@
 package org.opendaylight.ovsdb.openstack.netvirt.impl;
 
 import com.google.common.collect.Sets;
+
 import java.util.Set;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
@@ -16,6 +18,15 @@ import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryService;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryListener;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.impl.NeutronFloatingIPChangeListener;
+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;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 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.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
@@ -23,7 +34,6 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -62,6 +72,7 @@ public class OvsdbInventoryServiceImpl implements ConfigInterface, OvsdbInventor
     @Override
     public void providersReady() {
         ovsdbDataChangeListener.start();
+        initializeNeutronModelsDataChangeListeners(dataBroker);
         initializeNetvirtTopology();
     }
 
@@ -70,7 +81,7 @@ public class OvsdbInventoryServiceImpl implements ConfigInterface, OvsdbInventor
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {}
+    public void setDependencies(ServiceReference serviceReference) {}
 
     @Override
     public void setDependencies(Object impl) {}
@@ -85,4 +96,17 @@ public class OvsdbInventoryServiceImpl implements ConfigInterface, OvsdbInventor
             LOG.error("Error initializing netvirt topology");
         }
     }
+
+    private void initializeNeutronModelsDataChangeListeners(
+            DataBroker db) {
+        new NeutronNetworkChangeListener(db);
+        new NeutronSubnetChangeListener(db);
+        new NeutronPortChangeListener(db);
+        new NeutronRouterChangeListener(db);
+        new NeutronFloatingIPChangeListener(db);
+        new NeutronLoadBalancerPoolChangeListener(db);
+        new NeutronLoadBalancerPoolMemberChangeListener(db);
+        new NeutronSecurityRuleDataChangeListener(db);
+    }
+
 }
index 687534940e9d2e4e8c0a39b27d15bbdab1797404..e7a4e370c1ffb1e1feb0d048d746f2e84dbc6ff3 100644 (file)
@@ -8,7 +8,6 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.impl;
 
-import java.util.HashMap;
 import java.util.Map;
 
 import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
@@ -18,7 +17,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryService;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -82,7 +81,7 @@ public class ProviderNetworkManagerImpl implements ConfigInterface, NetworkingPr
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         ovsdbInventoryService =
                 (OvsdbInventoryService) ServiceHelper.getGlobalInstance(OvsdbInventoryService.class, this);
     }
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..e77eca2
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * 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);
+        if (port == null) {
+            LOG.debug("In portAdded no neutron port found:" + " portUuid:" + portUuid);
+            return;
+        }
+        processPortAdded(securityGroupUuid,port);
+    }
+
+    @Override
+    public void portRemoved(String securityGroupUuid, String portUuid) {
+        LOG.debug("In portRemoved securityGroupUuid:" + securityGroupUuid + " portUuid:" + portUuid);
+        NeutronPort port = neutronPortCache.getPort(portUuid);
+        if (port == null) {
+            LOG.debug("In portRemoved no neutron port found:" + " portUuid:" + portUuid);
+            return;
+        }
+        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) {
+                if (port.getFixedIPs() == null) {
+                    continue;
+                }
+                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) {
+                if (port.getFixedIPs() == null) {
+                    continue;
+                }
+                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 9bdc326b62bbf398bcdd82e8f4da4acfade25969..f59980e36fdf2ae475f790dfd96fd478b2e593cc 100644 (file)
@@ -8,33 +8,42 @@
 
 package org.opendaylight.ovsdb.openstack.netvirt.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.NeutronSubnet;
-import org.opendaylight.neutron.spi.Neutron_IPs;
 import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
+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.IngressAclProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class SecurityServicesImpl implements ConfigInterface, SecurityServicesManager {
     private static final Logger LOG = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
     private volatile INeutronPortCRUD neutronPortCache;
     private volatile INeutronSubnetCRUD neutronSubnetCache;
     private volatile Southbound southbound;
+    private volatile INeutronNetworkCRUD neutronNetworkCache;
+    private volatile ConfigurationService configurationService;
+    private volatile IngressAclProvider ingressAclProvider;
+    private volatile EgressAclProvider egressAclProvider;
 
     @Override
     public boolean isPortSecurityReady(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
@@ -70,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;
@@ -123,6 +132,10 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
             /* Get all the ports in the subnet and identify the dhcp port*/
             String subnetUuid = fixedIps.iterator().next().getSubnetUUID();
             NeutronSubnet neutronSubnet = neutronSubnetCache.getSubnet(subnetUuid);
+            if (neutronSubnet == null) {
+                LOG.error("getDHCPServerPort: No subnet is found for " + subnetUuid);
+                return null;
+            }
             List<NeutronPort> ports = neutronSubnet.getPortsInSubnet();
             for (NeutronPort port : ports) {
                 if (port.getDeviceOwner().contains("dhcp")) {
@@ -133,9 +146,33 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
             LOG.error("getDHCPServerPort:getDHCPServerPort failed due to ", e);
             return null;
         }
-
         return null;
+    }
 
+    @Override
+    public NeutronPort getNeutronPortFromDhcpIntf(
+            OvsdbTerminationPointAugmentation terminationPointAugmentation) {
+        if (neutronPortCache == null) {
+            LOG.error("getNeutronPortFromDhcpIntf: neutron port is null");
+            return null;
+        }
+        String neutronPortId = southbound.getInterfaceExternalIdsValue(
+                terminationPointAugmentation,
+                Constants.EXTERNAL_ID_INTERFACE_ID);
+        if (neutronPortId == null) {
+            return null;
+        }
+        NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
+        if (neutronPort == null) {
+            LOG.error("getNeutronPortFromDhcpIntf: neutron port of {} is not found", neutronPortId);
+            return null;
+        }
+        /* if the current port is a DHCP port, return true*/
+        if (neutronPort.getDeviceOwner().contains("dhcp")) {
+            LOG.trace("getNeutronPortFromDhcpIntf: neutronPort is a dhcp port", neutronPort );
+            return neutronPort;
+        }
+        return null;
     }
 
     @Override
@@ -247,8 +284,7 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
     }
 
     @Override
-    public List<Neutron_IPs> getIpAddressList(Node node,
-                                          OvsdbTerminationPointAugmentation terminationPointAugmentation) {
+    public List<Neutron_IPs> getIpAddressList(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
         if (neutronPortCache == null) {
             LOG.error("getIpAddress: neutron port is null");
             return null;
@@ -268,8 +304,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 {
@@ -279,14 +315,18 @@ 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());
+                            if (neutronPort.getFixedIPs() != null) {
+                                vmListForSecurityGroup.addAll(neutronPort.getFixedIPs());
+                            }
                         }
                     }
                 }
@@ -302,9 +342,157 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void syncSecurityGroup(NeutronPort port, List<NeutronSecurityGroup> securityGroupList, boolean write) {
+        LOG.trace("syncSecurityGroup:" + securityGroupList + " Write:" + write);
+        if (null != port && null != port.getSecurityGroups()) {
+            Node node = getNode(port);
+            if (node == null) {
+                return;
+            }
+            NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(port.getNetworkUUID());
+            if (neutronNetwork == null) {
+                return;
+            }
+            String segmentationId = neutronNetwork.getProviderSegmentationID();
+            OvsdbTerminationPointAugmentation intf = getInterface(node, port);
+            if (intf == null) {
+                return;
+            }
+            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 (dpid == 0L) {
+                return;
+            }
+            String neutronPortId = southbound.getInterfaceExternalIdsValue(intf,
+                                                                           Constants.EXTERNAL_ID_INTERFACE_ID);
+            if (neutronPortId == null) {
+                LOG.debug("syncSecurityGroup: No neutronPortId seen in {}", intf);
+                return;
+            }
+            for (NeutronSecurityGroup securityGroupInPort:securityGroupList) {
+                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);
+            if (node == null) {
+                return;
+            }
+            NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(port.getNetworkUUID());
+            if (neutronNetwork == null) {
+                return;
+            }
+            String segmentationId = neutronNetwork.getProviderSegmentationID();
+            OvsdbTerminationPointAugmentation intf = getInterface(node, port);
+            if (intf == null) {
+                return;
+            }
+            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 (dpid == 0L) {
+                return;
+            }
+            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);
+            }
+        }
+    }
+
+    private long getDpidOfIntegrationBridge(Node node) {
+        LOG.trace("getDpidOfIntegrationBridge:" + node);
+        long dpid = 0L;
+        if (southbound.getBridgeName(node).equals(configurationService.getIntegrationBridgeName())) {
+            dpid = getDpid(node);
+        }
+        if (dpid == 0L) {
+            LOG.warn("getDpidOfIntegerationBridge: dpid not found: {}", node);
+        }
+        return dpid;
+    }
+
+    private long getDpid(Node node) {
+        LOG.trace("getDpid" + node);
+        long dpid = southbound.getDataPathId(node);
+        if (dpid == 0) {
+            LOG.warn("getDpid: dpid not found: {}", node);
+        }
+        return dpid;
+    }
+
+    private Node getNode(NeutronPort port) {
+        LOG.trace("getNode:Port" + port);
+        List<Node> toplogyNodes = southbound.readOvsdbTopologyNodes();
+
+        for (Node topologyNode : toplogyNodes) {
+            try {
+                Node node = southbound.getBridgeNode(topologyNode,Constants.INTEGRATION_BRIDGE);
+                List<OvsdbTerminationPointAugmentation> ovsdbPorts = southbound.getTerminationPointsOfBridge(node);
+                for (OvsdbTerminationPointAugmentation ovsdbPort : ovsdbPorts) {
+                    String uuid = southbound.getInterfaceExternalIdsValue(ovsdbPort,
+                                                            Constants.EXTERNAL_ID_INTERFACE_ID);
+                    if (null != uuid && uuid.equals(port.getID())) {
+                        return node;
+                    }
+                }
+            } catch (Exception e) {
+                LOG.error("Exception during handlingNeutron network delete", e);
+            }
+        }
+        LOG.info("no node found for port:" + port);
+        return null;
+    }
+
+    private OvsdbTerminationPointAugmentation getInterface(Node node, NeutronPort port) {
+        LOG.trace("getInterface:Node:" + node + " Port:" + port);
+        try {
+            List<OvsdbTerminationPointAugmentation> ovsdbPorts = southbound.getTerminationPointsOfBridge(node);
+            for (OvsdbTerminationPointAugmentation ovsdbPort : ovsdbPorts) {
+                String uuid = southbound.getInterfaceExternalIdsValue(ovsdbPort,
+                                                                      Constants.EXTERNAL_ID_INTERFACE_ID);
+                if (null != uuid && uuid.equals(port.getID())) {
+                    return ovsdbPort;
+                }
+            }
+        } catch (Exception e) {
+            LOG.error("Exception during handlingNeutron network delete", e);
+        }
+        LOG.info("no interface found for node: " + node + " port:" + port);
+        return null;
+    }
+
+    @Override
+    public void setDependencies(ServiceReference serviceReference) {
         southbound =
                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
+        neutronNetworkCache =
+                (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
+        configurationService =
+                (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
     }
 
     @Override
@@ -313,9 +501,10 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
             neutronPortCache = (INeutronPortCRUD)impl;
         } else if (impl instanceof INeutronSubnetCRUD) {
             neutronSubnetCache = (INeutronSubnetCRUD) impl;
-        }
-        else if (impl instanceof INeutronSubnetCRUD) {
-            neutronSubnetCache = (INeutronSubnetCRUD) impl;
+        } else if (impl instanceof IngressAclProvider) {
+            ingressAclProvider = (IngressAclProvider) impl;
+        } else if (impl instanceof EgressAclProvider) {
+            egressAclProvider = (EgressAclProvider) impl;
         }
     }
 }
index 22934ea40965811109523cd7fe0f8dcfc4b02e6e..fb7f8e1224e599a0b2ceca4ab9aa35763812a7df 100644 (file)
@@ -20,19 +20,12 @@ import org.opendaylight.ovsdb.openstack.netvirt.MdsalHelper;
 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbTables;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 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.DatapathTypeNetdev;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
-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.OvsdbNodeAugmentation;
-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.OvsdbTerminationPointAugmentation;
-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.*;
 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.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;
@@ -70,9 +63,9 @@ import com.google.common.collect.ImmutableBiMap;
  */
 public class SouthboundImpl implements Southbound {
     private static final Logger LOG = LoggerFactory.getLogger(SouthboundImpl.class);
-    private DataBroker databroker = null;
+    private final DataBroker databroker;
     private static final String PATCH_PORT_TYPE = "patch";
-    private MdsalUtils mdsalUtils = null;
+    private final MdsalUtils mdsalUtils;
 
     /**
      * Class constructor setting the data broker.
@@ -128,6 +121,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);
@@ -165,10 +173,11 @@ public class SouthboundImpl implements Southbound {
         return value;
     }
 
-    public boolean addBridge(Node ovsdbNode, String bridgeName, String target) {
-        boolean result = false;
+    public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
+                             final Class<? extends DatapathTypeBase> dpType) {
+        boolean result;
 
-        LOG.info("addBridge: node: {}, bridgeName: {}, target: {}", ovsdbNode, bridgeName, target);
+        LOG.info("addBridge: node: {}, bridgeName: {}, controller(s): {}", ovsdbNode, bridgeName, controllersStr);
         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
         if (connectionInfo != null) {
             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
@@ -177,12 +186,22 @@ public class SouthboundImpl implements Southbound {
             NodeId bridgeNodeId = MdsalHelper.createManagedNodeId(bridgeIid);
             bridgeNodeBuilder.setNodeId(bridgeNodeId);
             OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
-            ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(target));
+            ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(controllersStr));
             ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
             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 (dpType != null) {
+                ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
+            }
             if (isOvsdbNodeDpdk(ovsdbNode)) {
                 ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
             }
@@ -197,11 +216,10 @@ public class SouthboundImpl implements Southbound {
     }
 
     public boolean deleteBridge(Node ovsdbNode) {
-        boolean result = false;
         InstanceIdentifier<Node> bridgeIid =
                 MdsalHelper.createInstanceIdentifier(ovsdbNode.getNodeId());
 
-        result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid);
+        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid);
         LOG.info("deleteBridge node: {}, bridgeName: {} result : {}", ovsdbNode, ovsdbNode.getNodeId(),result);
         return result;
     }
@@ -224,6 +242,9 @@ public class SouthboundImpl implements Southbound {
         Node ovsdbNode = node;
         if (extractNodeAugmentation(ovsdbNode) == null) {
             ovsdbNode = readOvsdbNode(node);
+            if (ovsdbNode == null) {
+                return null;
+            }
         }
         Node bridgeNode = null;
         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
@@ -236,15 +257,12 @@ public class SouthboundImpl implements Southbound {
     }
 
     public Node getBridgeNode(Node node, String bridgeName) {
-        Node bridgeNode = null;
         OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
         if (bridge != null && bridge.getBridgeName().getValue().equals(bridgeName)) {
-                bridgeNode = node;
+            return node;
         } else {
-            bridgeNode = readBridgeNode(node, bridgeName);
+            return readBridgeNode(node, bridgeName);
         }
-
-        return bridgeNode;
     }
 
     public String getBridgeUuid(Node node, String name) {
@@ -262,35 +280,24 @@ public class SouthboundImpl implements Southbound {
         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
     }
 
-    private void setControllerForBridge(Node ovsdbNode, String bridgeName, String targetString) {
-        ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
-        if (connectionInfo != null) {
-            for (ControllerEntry controllerEntry: createControllerEntries(targetString)) {
-                InstanceIdentifier<ControllerEntry> iid =
-                        MdsalHelper.createInstanceIdentifier(ovsdbNode.getKey(), bridgeName)
-                                .augmentation(OvsdbBridgeAugmentation.class)
-                                .child(ControllerEntry.class, controllerEntry.getKey());
-
-                boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, controllerEntry);
-                LOG.info("addController: result: {}", result);
+    private List<ControllerEntry> createControllerEntries(List<String> controllersStr) {
+        List<ControllerEntry> controllerEntries = new ArrayList<>();
+        if (controllersStr != null) {
+            for (String controllerStr : controllersStr) {
+                ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
+                controllerEntryBuilder.setTarget(new Uri(controllerStr));
+                controllerEntries.add(controllerEntryBuilder.build());
             }
         }
-    }
-
-    private List<ControllerEntry> createControllerEntries(String targetString) {
-        List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
-        ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
-        controllerEntryBuilder.setTarget(new Uri(targetString));
-        controllerEntries.add(controllerEntryBuilder.build());
         return controllerEntries;
     }
 
     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;
     }
 
@@ -353,7 +360,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();
@@ -407,8 +414,8 @@ public class SouthboundImpl implements Southbound {
     /**
      * Method read ports from bridge node. Method will check if the provided node
      * has the ports details, if not, it will read from Operational data store.
-     * @param node
-     * @return
+     * @param node Target bridge to getch termination points from.
+     * @return List of termination points on the given bridge
      */
     public List<OvsdbTerminationPointAugmentation> getTerminationPointsOfBridge(Node node) {
         List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(node);
@@ -446,7 +453,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());
@@ -455,7 +462,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){
@@ -475,7 +482,7 @@ public class SouthboundImpl implements Southbound {
         if(operNode != null){
             return extractTerminationPointAugmentations(operNode);
         }
-        return new ArrayList<OvsdbTerminationPointAugmentation>();
+        return new ArrayList<>();
     }
 
     public String getInterfaceExternalIdsValue(
@@ -526,7 +533,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()));
@@ -559,7 +566,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);
     }
@@ -583,7 +590,9 @@ public class SouthboundImpl implements Southbound {
             OvsdbNodeAugmentation ovsdbNode = extractNodeAugmentation(node);
             if (ovsdbNode == null) {
                 Node nodeFromReadOvsdbNode = readOvsdbNode(node);
-                ovsdbNode = extractNodeAugmentation(nodeFromReadOvsdbNode);
+                if (nodeFromReadOvsdbNode != null) {
+                    ovsdbNode = extractNodeAugmentation(nodeFromReadOvsdbNode);
+                }
             }
             if (ovsdbNode != null && ovsdbNode.getOpenvswitchExternalIds() != null) {
                 for (OpenvswitchExternalIds openvswitchExternalIds : ovsdbNode.getOpenvswitchExternalIds()) {
@@ -632,7 +641,9 @@ public class SouthboundImpl implements Southbound {
                 OvsdbNodeAugmentation ovsdbNode = extractNodeAugmentation(node);
                 if (ovsdbNode == null) {
                     Node nodeFromReadOvsdbNode = readOvsdbNode(node);
-                    ovsdbNode = extractNodeAugmentation(nodeFromReadOvsdbNode);
+                    if (nodeFromReadOvsdbNode != null) {
+                        ovsdbNode = extractNodeAugmentation(nodeFromReadOvsdbNode);
+                    }
                 }
                 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
                     for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
@@ -681,7 +692,7 @@ public class SouthboundImpl implements Southbound {
     public String getOptionsValue(List<Options> options, String key) {
         String value = null;
         for (Options option : options) {
-            if (option.getKey().equals(key)) {
+            if (option.getOption().equals(key)) {
                 value = option.getValue();
             }
         }
@@ -693,8 +704,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 63364b6f7358bf72cded59ef4905eaa6e83c5a55..6cb1f144fcbc26ed7546735e4f147c5ca77deba6 100644 (file)
@@ -9,11 +9,13 @@
 package org.opendaylight.ovsdb.openstack.netvirt.impl;
 
 import com.google.common.base.Preconditions;
+
 import java.util.List;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
@@ -22,7 +24,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -172,7 +174,7 @@ public class TenantNetworkManagerImpl implements ConfigInterface, TenantNetworkM
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         vlanConfigurationCache =
                 (VlanConfigurationCache) ServiceHelper.getGlobalInstance(VlanConfigurationCache.class, this);
         southbound =
index 4a491537fcbfe144c349275e4619e7c12933f877..ead275b352c79e0d78a7bcda218cd66273128a67 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import com.google.common.collect.Maps;
 import java.util.List;
 import java.util.Map;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -112,7 +112,7 @@ public class VlanConfigurationCacheImpl implements ConfigInterface, VlanConfigur
     }
 
     @Override
-    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+    public void setDependencies(ServiceReference serviceReference) {
         tenantNetworkManager =
                 (TenantNetworkManager) ServiceHelper.getGlobalInstance(TenantNetworkManager.class, this);
         southbound =
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/INeutronObject.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/INeutronObject.java
new file mode 100644 (file)
index 0000000..4e3076c
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+/**
+ * This class contains behaviour common to Neutron configuration objects
+ */
+public interface INeutronObject {
+
+    String getID();
+
+    void setID(String id);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewall.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewall.java
new file mode 100644 (file)
index 0000000..e72187f
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Firewall as a service
+ * (FWaaS) bindings. See OpenStack Network API
+ * v2.0 Reference for description of  the fields:
+ * Implemented fields are as follows:
+ *
+ * id                 uuid-str
+ * tenant_id          uuid-str
+ * name               String
+ * description        String
+ * admin_state_up     Bool
+ * status             String
+ * shared             Bool
+ * firewall_policy_id uuid-str
+ * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
+ *
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFirewall implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String firewallUUID;
+
+    @XmlElement (name = "tenant_id")
+    String firewallTenantID;
+
+    @XmlElement (name = "name")
+    String firewallName;
+
+    @XmlElement (name = "description")
+    String firewallDescription;
+
+    @XmlElement (defaultValue = "true", name = "admin_state_up")
+    Boolean firewallAdminStateIsUp;
+
+    @XmlElement (name = "status")
+    String firewallStatus;
+
+    @XmlElement (defaultValue = "false", name = "shared")
+    Boolean firewallIsShared;
+
+    @XmlElement (name = "firewall_policy_id")
+    String neutronFirewallPolicyID;
+
+    public String getID() {
+        return firewallUUID;
+    }
+
+    public void setID(String id) {
+        firewallUUID = id;
+    }
+
+    // @deprecated use getID()
+    public String getFirewallUUID() {
+        return firewallUUID;
+    }
+
+    // @deprecated use setID()
+    public void setFirewallUUID(String firewallUUID) {
+        this.firewallUUID = firewallUUID;
+    }
+
+    public String getFirewallTenantID() {
+        return firewallTenantID;
+    }
+
+    public void setFirewallTenantID(String firewallTenantID) {
+        this.firewallTenantID = firewallTenantID;
+    }
+
+    public String getFirewallName() {
+        return firewallName;
+    }
+
+    public void setFirewallName(String firewallName) {
+        this.firewallName = firewallName;
+    }
+
+    public String getFirewallDescription() {
+        return firewallDescription;
+    }
+
+    public void setFirewallDescription(String firewallDescription) {
+        this.firewallDescription = firewallDescription;
+    }
+
+    public Boolean getFirewallAdminStateIsUp() {
+        return firewallAdminStateIsUp;
+    }
+
+    public void setFirewallAdminStateIsUp(Boolean firewallAdminStateIsUp) {
+        this.firewallAdminStateIsUp = firewallAdminStateIsUp;
+    }
+
+    public String getFirewallStatus() {
+        return firewallStatus;
+    }
+
+    public void setFirewallStatus(String firewallStatus) {
+        this.firewallStatus = firewallStatus;
+    }
+
+    public Boolean getFirewallIsShared() {
+        return firewallIsShared;
+    }
+
+    public void setFirewallIsShared(Boolean firewallIsShared) {
+        this.firewallIsShared = firewallIsShared;
+    }
+
+    public String getFirewallPolicyID() {
+        return neutronFirewallPolicyID;
+    }
+
+    public void setNeutronFirewallPolicyID(String firewallPolicy) {
+        this.neutronFirewallPolicyID = firewallPolicy;
+    }
+
+    public NeutronFirewall extractFields(List<String> fields) {
+        NeutronFirewall ans = new NeutronFirewall();
+        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;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronFirewall{" +
+            "firewallUUID='" + firewallUUID + '\'' +
+            ", firewallTenantID='" + firewallTenantID + '\'' +
+            ", firewallName='" + firewallName + '\'' +
+            ", firewallDescription='" + firewallDescription + '\'' +
+            ", firewallAdminStateIsUp=" + firewallAdminStateIsUp +
+            ", firewallStatus='" + firewallStatus + '\'' +
+            ", firewallIsShared=" + firewallIsShared +
+            ", firewallRulePolicyID=" + neutronFirewallPolicyID +
+            '}';
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallPolicy.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallPolicy.java
new file mode 100644 (file)
index 0000000..5a6efb8
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Firewall as a service
+ * (FWaaS) bindings. See OpenStack Network API
+ * v2.0 Reference for description of  the fields.
+ * The implemented fields are as follows:
+ *
+ * id             uuid-str
+ * tenant_id      uuid-str
+ * name           String
+ * description    String
+ * shared         Boolean
+ * firewall_rules List
+ * audited        Boolean
+ * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
+ *
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFirewallPolicy implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String firewallPolicyUUID;
+
+    @XmlElement (name = "tenant_id")
+    String firewallPolicyTenantID;
+
+    @XmlElement (name = "name")
+    String firewallPolicyName;
+
+    @XmlElement (name = "description")
+    String firewallPolicyDescription;
+
+    @XmlElement (defaultValue = "false", name = "shared")
+    Boolean firewallPolicyIsShared;
+
+    @XmlElement (name = "firewall_rules")
+    List<String> firewallPolicyRules;
+
+    @XmlElement (defaultValue = "false", name = "audited")
+    Boolean firewallPolicyIsAudited;
+
+    public Boolean getFirewallPolicyIsAudited() {
+        return firewallPolicyIsAudited;
+    }
+
+    public void setFirewallPolicyIsAudited(Boolean firewallPolicyIsAudited) {
+        this.firewallPolicyIsAudited = firewallPolicyIsAudited;
+    }
+
+    public void setFirewallPolicyRules(List<String> firewallPolicyRules) {
+        this.firewallPolicyRules = firewallPolicyRules;
+    }
+
+    public List<String> getFirewallPolicyRules() {
+        return firewallPolicyRules;
+    }
+
+    public Boolean getFirewallPolicyIsShared() {
+        return firewallPolicyIsShared;
+    }
+
+    public void setFirewallPolicyIsShared(Boolean firewallPolicyIsShared) {
+        this.firewallPolicyIsShared = firewallPolicyIsShared;
+    }
+
+    public String getFirewallPolicyDescription() {
+        return firewallPolicyDescription;
+    }
+
+    public void setFirewallPolicyDescription(String firewallPolicyDescription) {
+        this.firewallPolicyDescription = firewallPolicyDescription;
+    }
+
+    public String getFirewallPolicyName() {
+        return firewallPolicyName;
+    }
+
+    public void setFirewallPolicyName(String firewallPolicyName) {
+        this.firewallPolicyName = firewallPolicyName;
+    }
+
+    public String getFirewallPolicyTenantID() {
+        return firewallPolicyTenantID;
+    }
+
+    public void setFirewallPolicyTenantID(String firewallPolicyTenantID) {
+        this.firewallPolicyTenantID = firewallPolicyTenantID;
+    }
+
+    public String getID() {
+        return firewallPolicyUUID;
+    }
+
+    public void setID(String id) {
+        firewallPolicyUUID = id;
+    }
+
+    // @deprecated use getID()
+    public String getFirewallPolicyUUID() {
+        return firewallPolicyUUID;
+    }
+
+    // @deprecated use setID()
+    public void setFirewallPolicyUUID(String firewallPolicyUUID) {
+        this.firewallPolicyUUID = firewallPolicyUUID;
+    }
+
+    public NeutronFirewallPolicy extractFields(List<String> fields) {
+        NeutronFirewallPolicy ans = new NeutronFirewallPolicy();
+        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;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronFirewallPolicy{" +
+            "firewallPolicyUUID='" + firewallPolicyUUID + '\'' +
+            ", firewallPolicyTenantID='" + firewallPolicyTenantID + '\'' +
+            ", firewallPolicyName='" + firewallPolicyName + '\'' +
+            ", firewallPolicyDescription='" + firewallPolicyDescription + '\'' +
+            ", firewallPolicyIsShared=" + firewallPolicyIsShared +
+            ", firewallPolicyRules=" + firewallPolicyRules +
+            ", firewallPolicyIsAudited='" + firewallPolicyIsAudited + '\'' +
+            '}';
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallRule.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFirewallRule.java
new file mode 100644 (file)
index 0000000..e198cb1
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * 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.openstack.netvirt.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Firewall as a service
+ * (FWaaS) bindings. See OpenStack Network API
+ * v2.0 Reference for description of  the fields.
+ * The implemented fields are as follows:
+ *
+ * tenant_id               uuid-str
+ * name                    String
+ * description             String
+ * admin_state_up          Bool
+ * status                  String
+ * shared                  Bool
+ * firewall_policy_id      uuid-str
+ * protocol                String
+ * ip_version              Integer
+ * source_ip_address       String (IP addr or CIDR)
+ * destination_ip_address  String (IP addr or CIDR)
+ * source_port             Integer
+ * destination_port        Integer
+ * position                Integer
+ * action                  String
+ * enabled                 Bool
+ * id                      uuid-str
+ * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
+ *
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFirewallRule implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String firewallRuleUUID;
+
+    @XmlElement(name = "tenant_id")
+    String firewallRuleTenantID;
+
+    @XmlElement(name = "name")
+    String firewallRuleName;
+
+    @XmlElement(name = "description")
+    String firewallRuleDescription;
+
+    @XmlElement(name = "status")
+    String firewallRuleStatus;
+
+    @XmlElement(defaultValue = "false", name = "shared")
+    Boolean firewallRuleIsShared;
+
+    @XmlElement(name = "firewall_policy_id")
+    String firewallRulePolicyID;
+
+    @XmlElement(name = "protocol")
+    String firewallRuleProtocol;
+
+    @XmlElement(name = "ip_version")
+    Integer firewallRuleIpVer;
+
+    @XmlElement(name = "source_ip_address")
+    String firewallRuleSrcIpAddr;
+
+    @XmlElement(name = "destination_ip_address")
+    String firewallRuleDstIpAddr;
+
+    @XmlElement(name = "source_port")
+    Integer firewallRuleSrcPort;
+
+    @XmlElement(name = "destination_port")
+    Integer firewallRuleDstPort;
+
+    @XmlElement(name = "position")
+    Integer firewallRulePosition;
+
+    @XmlElement(name = "action")
+    String firewallRuleAction;
+
+    @XmlElement(name = "enabled")
+    Boolean firewallRuleIsEnabled;
+
+    public Boolean getFirewallRuleIsEnabled() {
+        return firewallRuleIsEnabled;
+    }
+
+    public void setFirewallRuleIsEnabled(Boolean firewallRuleIsEnabled) {
+        this.firewallRuleIsEnabled = firewallRuleIsEnabled;
+    }
+
+    public String getFirewallRuleAction() {
+        return firewallRuleAction;
+    }
+
+    public void setFirewallRuleAction(String firewallRuleAction) {
+        this.firewallRuleAction = firewallRuleAction;
+    }
+
+    public Integer getFirewallRulePosition() {
+        return firewallRulePosition;
+    }
+
+    public void setFirewallRulePosition(Integer firewallRulePosition) {
+        this.firewallRulePosition = firewallRulePosition;
+    }
+
+    public Integer getFirewallRuleDstPort() {
+        return firewallRuleDstPort;
+    }
+
+    public void setFirewallRuleDstPort(Integer firewallRuleDstPort) {
+        this.firewallRuleDstPort = firewallRuleDstPort;
+    }
+
+    public Integer getFirewallRuleSrcPort() {
+        return firewallRuleSrcPort;
+    }
+
+    public void setFirewallRuleSrcPort(Integer firewallRuleSrcPort) {
+        this.firewallRuleSrcPort = firewallRuleSrcPort;
+    }
+
+    public String getFirewallRuleDstIpAddr() {
+        return firewallRuleDstIpAddr;
+    }
+
+    public void setFirewallRuleDstIpAddr(String firewallRuleDstIpAddr) {
+        this.firewallRuleDstIpAddr = firewallRuleDstIpAddr;
+    }
+
+    public String getFirewallRuleSrcIpAddr() {
+        return firewallRuleSrcIpAddr;
+    }
+
+    public void setFirewallRuleSrcIpAddr(String firewallRuleSrcIpAddr) {
+        this.firewallRuleSrcIpAddr = firewallRuleSrcIpAddr;
+    }
+
+    public Integer getFirewallRuleIpVer() {
+        return firewallRuleIpVer;
+    }
+
+    public void setFirewallRuleIpVer(Integer firewallRuleIpVer) {
+        this.firewallRuleIpVer = firewallRuleIpVer;
+    }
+
+    public String getFirewallRuleProtocol() {
+        return firewallRuleProtocol;
+    }
+
+    public void setFirewallRuleProtocol(String firewallRuleProtocol) {
+        this.firewallRuleProtocol = firewallRuleProtocol;
+    }
+
+    public String getFirewallRulePolicyID() {
+        return firewallRulePolicyID;
+    }
+
+    public void setFirewallRulesPolicyID(String firewallRulePolicyID) {
+        this.firewallRulePolicyID = firewallRulePolicyID;
+    }
+
+    public Boolean getFirewallRuleIsShared() {
+        return firewallRuleIsShared;
+    }
+
+    public void setFirewallRuleIsShared(Boolean firewallRuleIsShared) {
+        this.firewallRuleIsShared = firewallRuleIsShared;
+    }
+
+    public String getFirewallRuleStatus() {
+        return firewallRuleStatus;
+    }
+
+    public void setFirewallRuleStatus(String firewallRuleStatus) {
+        this.firewallRuleStatus = firewallRuleStatus;
+    }
+
+    public String getFirewallRuleDescription() {
+        return firewallRuleDescription;
+    }
+
+    public void setFirewallRuleDescription(String firewallRuleDescription) {
+        this.firewallRuleDescription = firewallRuleDescription;
+    }
+
+    public String getFirewallRuleName() {
+        return firewallRuleName;
+    }
+
+    public void setFirewallRuleName(String firewallRuleName) {
+        this.firewallRuleName = firewallRuleName;
+    }
+
+    public String getFirewallRuleTenantID() {
+        return firewallRuleTenantID;
+    }
+
+    public void setFirewallRuleTenantID(String firewallRuleTenantID) {
+        this.firewallRuleTenantID = firewallRuleTenantID;
+    }
+
+    public String getID() {
+        return firewallRuleUUID;
+    }
+
+    public void setID(String id) {
+        firewallRuleUUID = id;
+    }
+
+    // @deprecated use getID()
+    public String getFirewallRuleUUID() {
+        return firewallRuleUUID;
+    }
+
+    // @deprecated use setID()
+    public void setFireWallRuleID(String firewallRuleUUID) {
+        this.firewallRuleUUID = firewallRuleUUID;
+    }
+
+    public NeutronFirewallRule extractFields(List<String> fields) {
+        NeutronFirewallRule ans = new NeutronFirewallRule();
+        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;
+            }
+
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "firewallPolicyRules{" +
+            "firewallRuleUUID='" + firewallRuleUUID + '\'' +
+            ", firewallRuleTenantID='" + firewallRuleTenantID + '\'' +
+            ", firewallRuleName='" + firewallRuleName + '\'' +
+            ", firewallRuleDescription='" + firewallRuleDescription + '\'' +
+            ", firewallRuleStatus='" + firewallRuleStatus + '\'' +
+            ", firewallRuleIsShared=" + firewallRuleIsShared +
+            ", firewallRulePolicyID=" + firewallRulePolicyID +
+            ", firewallRuleProtocol='" + firewallRuleProtocol + '\'' +
+            ", firewallRuleIpVer=" + firewallRuleIpVer +
+            ", firewallRuleSrcIpAddr='" + firewallRuleSrcIpAddr + '\'' +
+            ", firewallRuleDstIpAddr='" + firewallRuleDstIpAddr + '\'' +
+            ", firewallRuleSrcPort=" + firewallRuleSrcPort +
+            ", firewallRuleDstPort=" + firewallRuleDstPort +
+            ", firewallRulePosition=" + firewallRulePosition +
+            ", firewallRuleAction='" + firewallRuleAction + '\'' +
+            ", firewallRuleIsEnabled=" + firewallRuleIsEnabled +
+            '}';
+    }
+
+    public void initDefaults() {
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFloatingIP.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronFloatingIP.java
new file mode 100644 (file)
index 0000000..3b1e4ff
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFloatingIP implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name = "id")
+    String floatingIPUUID;
+
+    @XmlElement (name = "floating_network_id")
+    String floatingNetworkUUID;
+
+    @XmlElement (name = "port_id")
+    String portUUID;
+
+    @XmlElement (name = "fixed_ip_address")
+    String fixedIPAddress;
+
+    @XmlElement (name = "floating_ip_address")
+    String floatingIPAddress;
+
+    @XmlElement (name = "tenant_id")
+    String tenantUUID;
+
+    @XmlElement (name="router_id")
+    String routerUUID;
+
+    @XmlElement (name="status")
+    String status;
+
+    public NeutronFloatingIP() {
+    }
+
+    public String getID() {
+        return floatingIPUUID;
+    }
+
+    public void setID(String id) {
+        floatingIPUUID = id;
+    }
+
+    // @deprecated use getID()
+    public String getFloatingIPUUID() {
+        return floatingIPUUID;
+    }
+
+    // @deprecated use setID()
+    public void setFloatingIPUUID(String floatingIPUUID) {
+        this.floatingIPUUID = floatingIPUUID;
+    }
+
+    public String getFloatingNetworkUUID() {
+        return floatingNetworkUUID;
+    }
+
+    public void setFloatingNetworkUUID(String floatingNetworkUUID) {
+        this.floatingNetworkUUID = floatingNetworkUUID;
+    }
+
+    public String getPortUUID() {
+        return portUUID;
+    }
+
+    public String getRouterUUID() {
+        return routerUUID;
+    }
+
+    public void setPortUUID(String portUUID) {
+        this.portUUID = portUUID;
+    }
+
+    public String getFixedIPAddress() {
+        return fixedIPAddress;
+    }
+
+    public void setFixedIPAddress(String fixedIPAddress) {
+        this.fixedIPAddress = fixedIPAddress;
+    }
+
+    public String getFloatingIPAddress() {
+        return floatingIPAddress;
+    }
+
+    public void setFloatingIPAddress(String floatingIPAddress) {
+        this.floatingIPAddress = floatingIPAddress;
+    }
+
+    public String getTenantUUID() {
+        return tenantUUID;
+    }
+
+    public void setTenantUUID(String tenantUUID) {
+        this.tenantUUID = tenantUUID;
+    }
+
+    public void setRouterUUID(String routerUUID) {
+        this.routerUUID = routerUUID;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackFloatingIPs object with only the selected fields
+     * populated
+     */
+
+    public NeutronFloatingIP extractFields(List<String> fields) {
+        NeutronFloatingIP ans = new NeutronFloatingIP();
+        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;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronFloatingIP{" +
+            "fipUUID='" + floatingIPUUID + '\'' +
+            ", fipFloatingNetworkId='" + floatingNetworkUUID + '\'' +
+            ", fipPortUUID='" + portUUID + '\'' +
+            ", fipFixedIPAddress='" + fixedIPAddress + '\'' +
+            ", fipFloatingIPAddress=" + floatingIPAddress +
+            ", fipTenantId='" + tenantUUID + '\'' +
+            ", fipRouterId='" + routerUUID + '\'' +
+            ", fipStatus='" + status + '\'' +
+            '}';
+    }
+
+    public void initDefaults() {
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancer.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancer.java
new file mode 100644 (file)
index 0000000..0316006
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Load Balancer as a service
+ * (LBaaS) bindings. See OpenStack Network API
+ * v2.0 Reference for description of  the fields:
+ * Implemented fields are as follows:
+ *
+ * id                 uuid-str
+ * tenant_id          uuid-str
+ * name               String
+ * description        String
+ * status             String
+ * vip_address        IP address
+ * vip_subnet         uuid-str
+ * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancer implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String loadBalancerID;
+
+    @XmlElement (name = "tenant_id")
+    String loadBalancerTenantID;
+
+    @XmlElement (name = "name")
+    String loadBalancerName;
+
+    @XmlElement (name = "description")
+    String loadBalancerDescription;
+
+    @XmlElement (name = "status")
+    String loadBalancerStatus;
+
+    @XmlElement (name = "admin_state_up")
+    Boolean loadBalancerAdminStateUp;
+
+    @XmlElement (name = "vip_address")
+    String loadBalancerVipAddress;
+
+    @XmlElement (name = "vip_subnet_id")
+    String loadBalancerVipSubnetID;
+
+    public String getID() {
+        return loadBalancerID;
+    }
+
+    public void setID(String id) {
+        loadBalancerID = id;
+    }
+
+    // @deprecated use getID()
+    public String getLoadBalancerID() {
+        return loadBalancerID;
+    }
+
+    // @deprecated use setID()
+    public void setLoadBalancerID(String loadBalancerID) {
+        this.loadBalancerID = loadBalancerID;
+    }
+
+    public String getLoadBalancerTenantID() {
+        return loadBalancerTenantID;
+    }
+
+    public void setLoadBalancerTenantID(String loadBalancerTenantID) {
+        this.loadBalancerTenantID = loadBalancerTenantID;
+    }
+
+    public String getLoadBalancerName() {
+        return loadBalancerName;
+    }
+
+    public void setLoadBalancerName(String loadBalancerName) {
+        this.loadBalancerName = loadBalancerName;
+    }
+
+    public String getLoadBalancerDescription() {
+        return loadBalancerDescription;
+    }
+
+    public void setLoadBalancerDescription(String loadBalancerDescription) {
+        this.loadBalancerDescription = loadBalancerDescription;
+    }
+
+    public String getLoadBalancerStatus() {
+        return loadBalancerStatus;
+    }
+
+    public void setLoadBalancerStatus(String loadBalancerStatus) {
+        this.loadBalancerStatus = loadBalancerStatus;
+    }
+
+    public Boolean getLoadBalancerAdminStateUp() {
+        return loadBalancerAdminStateUp;
+    }
+
+    public void setLoadBalancerAdminStateUp(Boolean loadBalancerAdminStateUp) {
+        this.loadBalancerAdminStateUp = loadBalancerAdminStateUp;
+    }
+
+    public String getLoadBalancerVipAddress() {
+        return loadBalancerVipAddress;
+    }
+
+    public void setLoadBalancerVipAddress(String loadBalancerVipAddress) {
+        this.loadBalancerVipAddress = loadBalancerVipAddress;
+    }
+
+    public String getLoadBalancerVipSubnetID() {
+        return loadBalancerVipSubnetID;
+    }
+
+    public void setLoadBalancerVipSubnetID(String loadBalancerVipSubnetID) {
+        this.loadBalancerVipSubnetID = loadBalancerVipSubnetID;
+    }
+
+    public NeutronLoadBalancer extractFields(List<String> fields) {
+        NeutronLoadBalancer ans = new NeutronLoadBalancer();
+        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;
+    }
+
+    @Override public String toString() {
+        return "NeutronLoadBalancer{" +
+                "loadBalancerID='" + loadBalancerID + '\'' +
+                ", loadBalancerTenantID='" + loadBalancerTenantID + '\'' +
+                ", loadBalancerName='" + loadBalancerName + '\'' +
+                ", loadBalancerDescription='" + loadBalancerDescription + '\'' +
+                ", loadBalancerStatus='" + loadBalancerStatus + '\'' +
+                ", loadBalancerAdminStateUp='" + loadBalancerAdminStateUp + '\'' +
+                ", loadBalancerVipAddress='" + loadBalancerVipAddress + '\'' +
+                ", loadBalancerVipSubnetID='" + loadBalancerVipSubnetID + '\'' +
+                '}';
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerHealthMonitor.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerHealthMonitor.java
new file mode 100644 (file)
index 0000000..af55dbe
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Load Balancer as a service
+ * (LBaaS) bindings. See OpenStack Network API
+ * v2.0 Reference for description of  the fields:
+ * Implemented fields are as follows:
+ *
+ *
+ * id                 uuid-str
+ * tenant_id          uuid-str
+ * type               String
+ * delay              Integer
+ * timeout            Integer
+ * max_retries        Integer
+ * http_method        String
+ * url_path           String
+ * expected_codes     String
+ * admin_state_up     Boolean
+ * status             String
+ * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerHealthMonitor
+    implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String loadBalancerHealthMonitorID;
+
+    @XmlElement (name = "tenant_id")
+    String loadBalancerHealthMonitorTenantID;
+
+    @XmlElement (name = "type")
+    String loadBalancerHealthMonitorType;
+
+    @XmlElement (name = "delay")
+    Integer loadBalancerHealthMonitorDelay;
+
+    @XmlElement (name = "timeout")
+    Integer loadBalancerHealthMonitorTimeout;
+
+    @XmlElement (name = "max_retries")
+    Integer loadBalancerHealthMonitorMaxRetries;
+
+    @XmlElement (name = "http_method")
+    String loadBalancerHealthMonitorHttpMethod;
+
+    @XmlElement (name = "url_path")
+    String loadBalancerHealthMonitorUrlPath;
+
+    @XmlElement (name = "expected_codes")
+    String loadBalancerHealthMonitorExpectedCodes;
+
+    @XmlElement (defaultValue = "true", name = "admin_state_up")
+    Boolean loadBalancerHealthMonitorAdminStateIsUp;
+
+    @XmlElement (name = "pools")
+    List<Neutron_ID> loadBalancerHealthMonitorPools;
+
+    public String getID() {
+        return loadBalancerHealthMonitorID;
+    }
+
+    public void setID(String id) {
+        loadBalancerHealthMonitorID = id;
+    }
+
+    // @deprecated use getID()
+    public String getLoadBalancerHealthMonitorID() {
+        return loadBalancerHealthMonitorID;
+    }
+
+    // @deprecated use setID()
+    public void setLoadBalancerHealthMonitorID(String loadBalancerHealthMonitorID) {
+        this.loadBalancerHealthMonitorID = loadBalancerHealthMonitorID;
+    }
+
+    public String getLoadBalancerHealthMonitorTenantID() {
+        return loadBalancerHealthMonitorTenantID;
+    }
+
+    public void setLoadBalancerHealthMonitorTenantID(String loadBalancerHealthMonitorTenantID) {
+        this.loadBalancerHealthMonitorTenantID = loadBalancerHealthMonitorTenantID;
+    }
+
+    public String getLoadBalancerHealthMonitorType() {
+        return loadBalancerHealthMonitorType;
+    }
+
+    public void setLoadBalancerHealthMonitorType(String loadBalancerHealthMonitorType) {
+        this.loadBalancerHealthMonitorType = loadBalancerHealthMonitorType;
+    }
+
+    public Integer getLoadBalancerHealthMonitorDelay() {
+        return loadBalancerHealthMonitorDelay;
+    }
+
+    public void setLoadBalancerHealthMonitorDelay(Integer loadBalancerHealthMonitorDelay) {
+        this.loadBalancerHealthMonitorDelay = loadBalancerHealthMonitorDelay;
+    }
+
+    public Integer getLoadBalancerHealthMonitorTimeout() {
+        return loadBalancerHealthMonitorTimeout;
+    }
+
+    public void setLoadBalancerHealthMonitorTimeout(Integer loadBalancerHealthMonitorTimeout) {
+        this.loadBalancerHealthMonitorTimeout = loadBalancerHealthMonitorTimeout;
+    }
+
+    public Integer getLoadBalancerHealthMonitorMaxRetries() {
+        return loadBalancerHealthMonitorMaxRetries;
+    }
+
+    public void setLoadBalancerHealthMonitorMaxRetries(Integer loadBalancerHealthMonitorMaxRetries) {
+        this.loadBalancerHealthMonitorMaxRetries = loadBalancerHealthMonitorMaxRetries;
+    }
+
+    public String getLoadBalancerHealthMonitorHttpMethod() {
+        return loadBalancerHealthMonitorHttpMethod;
+    }
+
+    public void setLoadBalancerHealthMonitorHttpMethod(String loadBalancerHealthMonitorHttpMethod) {
+        this.loadBalancerHealthMonitorHttpMethod = loadBalancerHealthMonitorHttpMethod;
+    }
+
+    public String getLoadBalancerHealthMonitorUrlPath() {
+        return loadBalancerHealthMonitorUrlPath;
+    }
+
+    public void setLoadBalancerHealthMonitorUrlPath(String loadBalancerHealthMonitorUrlPath) {
+        this.loadBalancerHealthMonitorUrlPath = loadBalancerHealthMonitorUrlPath;
+    }
+
+    public String getLoadBalancerHealthMonitorExpectedCodes() {
+        return loadBalancerHealthMonitorExpectedCodes;
+    }
+
+    public void setLoadBalancerHealthMonitorExpectedCodes(String loadBalancerHealthMonitorExpectedCodes) {
+        this.loadBalancerHealthMonitorExpectedCodes = loadBalancerHealthMonitorExpectedCodes;
+    }
+
+    public Boolean getLoadBalancerHealthMonitorAdminStateIsUp() {
+        return loadBalancerHealthMonitorAdminStateIsUp;
+    }
+
+    public void setLoadBalancerHealthMonitorAdminStateIsUp(Boolean loadBalancerHealthMonitorAdminStateIsUp) {
+        this.loadBalancerHealthMonitorAdminStateIsUp = loadBalancerHealthMonitorAdminStateIsUp;
+    }
+
+    public List<Neutron_ID> getLoadBalancerHealthMonitorPools() {
+        return loadBalancerHealthMonitorPools;
+    }
+
+    public void setLoadBalancerHealthMonitorPools(List<Neutron_ID> loadBalancerHealthMonitorPools) {
+        this.loadBalancerHealthMonitorPools = loadBalancerHealthMonitorPools;
+    }
+
+    public NeutronLoadBalancerHealthMonitor extractFields(List<String> fields) {
+        NeutronLoadBalancerHealthMonitor ans = new NeutronLoadBalancerHealthMonitor();
+        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;
+    }
+
+    @Override public String toString() {
+        return "NeutronLoadBalancerHealthMonitor{" +
+                "loadBalancerHealthMonitorID='" + loadBalancerHealthMonitorID + '\'' +
+                ", loadBalancerHealthMonitorTenantID='" + loadBalancerHealthMonitorTenantID + '\'' +
+                ", loadBalancerHealthMonitorType='" + loadBalancerHealthMonitorType + '\'' +
+                ", loadBalancerHealthMonitorDelay=" + loadBalancerHealthMonitorDelay +
+                ", loadBalancerHealthMonitorTimeout=" + loadBalancerHealthMonitorTimeout +
+                ", loadBalancerHealthMonitorMaxRetries=" + loadBalancerHealthMonitorMaxRetries +
+                ", loadBalancerHealthMonitorHttpMethod='" + loadBalancerHealthMonitorHttpMethod + '\'' +
+                ", loadBalancerHealthMonitorUrlPath='" + loadBalancerHealthMonitorUrlPath + '\'' +
+                ", loadBalancerHealthMonitorExpectedCodes='" + loadBalancerHealthMonitorExpectedCodes + '\'' +
+                ", loadBalancerHealthMonitorAdminStateIsUp=" + loadBalancerHealthMonitorAdminStateIsUp +
+                '}';
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerListener.java
new file mode 100644 (file)
index 0000000..38101ad
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Load Balancer as a service
+ * (LBaaS) bindings. See OpenStack Network API
+ * v2.0 Reference for description of  the fields:
+ * Implemented fields are as follows:
+ *
+ * id                 uuid-str
+ * default_pool_id    String
+ * tenant_id          uuid-str
+ * name               String
+ * description        String
+ * shared             Bool
+ * protocol           String
+ * protocol_port      String
+ * load_balancer_id   String
+ * admin_state_up     Boolean
+ * status             String
+ *
+ * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerListener
+    implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String loadBalancerListenerID;
+
+    @XmlElement (name = "default_pool_id")
+    String neutronLoadBalancerListenerDefaultPoolID;
+
+    @XmlElement (name = "connection_limit")
+    Integer neutronLoadBalancerListenerConnectionLimit;
+
+    @XmlElement (name = "tenant_id")
+    String loadBalancerListenerTenantID;
+
+    @XmlElement (name = "name")
+    String loadBalancerListenerName;
+
+    @XmlElement (name = "description")
+    String loadBalancerListenerDescription;
+
+    @XmlElement (defaultValue = "true", name = "admin_state_up")
+    Boolean loadBalancerListenerAdminStateIsUp;
+
+    @XmlElement (name = "protocol")
+    String neutronLoadBalancerListenerProtocol;
+
+    @XmlElement (name = "protocol_port")
+    String neutronLoadBalancerListenerProtocolPort;
+
+    @XmlElement (name = "load_balancers")
+    List<Neutron_ID> neutronLoadBalancerListenerLoadBalancerIDs;
+
+    public String getID() {
+        return loadBalancerListenerID;
+    }
+
+    public void setID(String id) {
+        loadBalancerListenerID = id;
+    }
+
+    // @deprecated use getID()
+    public String getLoadBalancerListenerID() {
+        return loadBalancerListenerID;
+    }
+
+    // @deprecated use setID()
+    public void setLoadBalancerListenerID(String loadBalancerListenerID) {
+        this.loadBalancerListenerID = loadBalancerListenerID;
+    }
+
+    public String getLoadBalancerListenerTenantID() {
+        return loadBalancerListenerTenantID;
+    }
+
+    public void setLoadBalancerListenerTenantID(String loadBalancerListenerTenantID) {
+        this.loadBalancerListenerTenantID = loadBalancerListenerTenantID;
+    }
+
+    public String getLoadBalancerListenerName() {
+        return loadBalancerListenerName;
+    }
+
+    public void setLoadBalancerListenerName(String loadBalancerListenerName) {
+        this.loadBalancerListenerName = loadBalancerListenerName;
+    }
+
+    public String getLoadBalancerListenerDescription() {
+        return loadBalancerListenerDescription;
+    }
+
+    public void setLoadBalancerListenerDescription(String loadBalancerListenerDescription) {
+        this.loadBalancerListenerDescription = loadBalancerListenerDescription;
+    }
+
+    public Boolean getLoadBalancerListenerAdminStateIsUp() {
+        return loadBalancerListenerAdminStateIsUp;
+    }
+
+    public void setLoadBalancerListenerAdminStateIsUp(Boolean loadBalancerListenerAdminStateIsUp) {
+        this.loadBalancerListenerAdminStateIsUp = loadBalancerListenerAdminStateIsUp;
+    }
+
+    public String getNeutronLoadBalancerListenerProtocol() {
+        return neutronLoadBalancerListenerProtocol;
+    }
+
+    public void setNeutronLoadBalancerListenerProtocol(String neutronLoadBalancerListenerProtocol) {
+        this.neutronLoadBalancerListenerProtocol = neutronLoadBalancerListenerProtocol;
+    }
+
+    public String getNeutronLoadBalancerListenerProtocolPort() {
+        return neutronLoadBalancerListenerProtocolPort;
+    }
+
+    public void setNeutronLoadBalancerListenerProtocolPort(String neutronLoadBalancerListenerProtocolPort) {
+        this.neutronLoadBalancerListenerProtocolPort = neutronLoadBalancerListenerProtocolPort;
+    }
+
+    public String getNeutronLoadBalancerListenerDefaultPoolID() {
+        return neutronLoadBalancerListenerDefaultPoolID;
+    }
+
+    public void setNeutronLoadBalancerListenerDefaultPoolID(String neutronLoadBalancerListenerDefaultPoolID) {
+        this.neutronLoadBalancerListenerDefaultPoolID = neutronLoadBalancerListenerDefaultPoolID;
+    }
+
+    public Integer getNeutronLoadBalancerListenerConnectionLimit() {
+        return neutronLoadBalancerListenerConnectionLimit;
+    }
+
+    public void setNeutronLoadBalancerListenerConnectionLimit(Integer neutronLoadBalancerListenerConnectionLimit) {
+        this.neutronLoadBalancerListenerConnectionLimit = neutronLoadBalancerListenerConnectionLimit;
+    }
+
+    public List<Neutron_ID> getNeutronLoadBalancerListenerLoadBalancerIDs() {
+        return neutronLoadBalancerListenerLoadBalancerIDs;
+    }
+
+    public void setNeutronLoadBalancerListenerLoadBalancerIDs(List<Neutron_ID> neutronLoadBalancerListenerLoadBalancerIDs) {
+        this.neutronLoadBalancerListenerLoadBalancerIDs = neutronLoadBalancerListenerLoadBalancerIDs;
+    }
+
+    public NeutronLoadBalancerListener extractFields(List<String> fields) {
+        NeutronLoadBalancerListener ans = new NeutronLoadBalancerListener();
+        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;
+    }
+
+    @Override public String toString() {
+        return "NeutronLoadBalancerListener{" +
+                "loadBalancerListenerID='" + loadBalancerListenerID + '\'' +
+                ", neutronLoadBalancerListenerDefaultPoolID='" + neutronLoadBalancerListenerDefaultPoolID + '\'' +
+                ", neutronLoadBalancerListenerConnectionLimit='" + neutronLoadBalancerListenerConnectionLimit + '\'' +
+                ", loadBalancerListenerTenantID='" + loadBalancerListenerTenantID + '\'' +
+                ", loadBalancerListenerName='" + loadBalancerListenerName + '\'' +
+                ", loadBalancerListenerDescription='" + loadBalancerListenerDescription + '\'' +
+                ", loadBalancerListenerAdminStateIsUp=" + loadBalancerListenerAdminStateIsUp +
+                ", neutronLoadBalancerListenerProtocol='" + neutronLoadBalancerListenerProtocol + '\'' +
+                ", neutronLoadBalancerListenerProtocolPort='" + neutronLoadBalancerListenerProtocolPort + '\'' +
+                '}';
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPool.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPool.java
new file mode 100644 (file)
index 0000000..195b82a
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Load Balancer as a service
+ * (LBaaS) bindings. See OpenStack Network API
+ * v2.0 Reference for description of  the fields:
+ * Implemented fields are as follows:
+ *
+ * id                 uuid-str
+ * tenant_id          uuid-str
+ * name               String
+ * description        String
+ * protocol           String
+ * lb_algorithm       String
+ * healthmonitor_id   String
+ * admin_state_up     Bool
+ * status             String
+ * members            List &lt;NeutronLoadBalancerPoolMember&gt;
+ * http://docs.openstack.org/api/openstack-network/2.0/openstack-network.pdf
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerPool implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String loadBalancerPoolID;
+
+    @XmlElement (name = "tenant_id")
+    String loadBalancerPoolTenantID;
+
+    @XmlElement (name = "name")
+    String loadBalancerPoolName;
+
+    @XmlElement (name = "description")
+    String loadBalancerPoolDescription;
+
+    @XmlElement (name = "protocol")
+    String loadBalancerPoolProtocol;
+
+    @XmlElement (name = "lb_algorithm")
+    String loadBalancerPoolLbAlgorithm;
+
+    @XmlElement (name = "healthmonitor_id")
+    String neutronLoadBalancerPoolHealthMonitorID;
+
+    @XmlElement (defaultValue = "true", name = "admin_state_up")
+    Boolean loadBalancerPoolAdminStateIsUp;
+
+    @XmlElement(name = "listeners")
+    List<Neutron_ID> loadBalancerPoolListeners;
+
+    @XmlElement(name = "session_persistence")
+    NeutronLoadBalancer_SessionPersistence loadBalancerPoolSessionPersistence;
+
+    @XmlElement(name = "members")
+    List<NeutronLoadBalancerPoolMember> loadBalancerPoolMembers;
+
+    public NeutronLoadBalancerPool() {
+    }
+
+    public String getID() {
+        return loadBalancerPoolID;
+    }
+
+    public void setID(String id) {
+        loadBalancerPoolID = id;
+    }
+
+    // @deprecated use getID()
+    public String getLoadBalancerPoolID() {
+        return loadBalancerPoolID;
+    }
+
+    // @deprecated use setID()
+    public void setLoadBalancerPoolID(String loadBalancerPoolID) {
+        this.loadBalancerPoolID = loadBalancerPoolID;
+    }
+
+    public String getLoadBalancerPoolTenantID() {
+        return loadBalancerPoolTenantID;
+    }
+
+    public void setLoadBalancerPoolTenantID(String loadBalancerPoolTenantID) {
+        this.loadBalancerPoolTenantID = loadBalancerPoolTenantID;
+    }
+
+    public String getLoadBalancerPoolName() {
+        return loadBalancerPoolName;
+    }
+
+    public void setLoadBalancerPoolName(String loadBalancerPoolName) {
+        this.loadBalancerPoolName = loadBalancerPoolName;
+    }
+
+    public String getLoadBalancerPoolDescription() {
+        return loadBalancerPoolDescription;
+    }
+
+    public void setLoadBalancerPoolDescription(String loadBalancerPoolDescription) {
+        this.loadBalancerPoolDescription = loadBalancerPoolDescription;
+    }
+
+    public String getLoadBalancerPoolProtocol() {
+        return loadBalancerPoolProtocol;
+    }
+
+    public void setLoadBalancerPoolProtocol(String loadBalancerPoolProtocol) {
+        this.loadBalancerPoolProtocol = loadBalancerPoolProtocol;
+    }
+
+    public String getLoadBalancerPoolLbAlgorithm() {
+        return loadBalancerPoolLbAlgorithm;
+    }
+
+    public void setLoadBalancerPoolLbAlgorithm(String loadBalancerPoolLbAlgorithm) {
+        this.loadBalancerPoolLbAlgorithm = loadBalancerPoolLbAlgorithm;
+    }
+
+    public String getNeutronLoadBalancerPoolHealthMonitorID() {
+        return neutronLoadBalancerPoolHealthMonitorID;
+    }
+
+    public void setNeutronLoadBalancerPoolHealthMonitorID(String neutronLoadBalancerPoolHealthMonitorID) {
+        this.neutronLoadBalancerPoolHealthMonitorID = neutronLoadBalancerPoolHealthMonitorID;
+    }
+
+    public Boolean getLoadBalancerPoolAdminIsStateIsUp() {
+        return loadBalancerPoolAdminStateIsUp;
+    }
+
+    public void setLoadBalancerPoolAdminStateIsUp(Boolean loadBalancerPoolAdminStateIsUp) {
+        this.loadBalancerPoolAdminStateIsUp = loadBalancerPoolAdminStateIsUp;
+    }
+
+    public NeutronLoadBalancer_SessionPersistence getLoadBalancerPoolSessionPersistence() {
+        return loadBalancerPoolSessionPersistence;
+    }
+
+    public void setLoadBalancerSessionPersistence(NeutronLoadBalancer_SessionPersistence loadBalancerPoolSessionPersistence) {
+        this.loadBalancerPoolSessionPersistence = loadBalancerPoolSessionPersistence;
+    }
+
+    public List<Neutron_ID> getLoadBalancerPoolListeners() {
+        return loadBalancerPoolListeners;
+    }
+
+    public void setLoadBalancerPoolListeners(List<Neutron_ID> loadBalancerPoolListeners) {
+        this.loadBalancerPoolListeners = loadBalancerPoolListeners;
+    }
+
+    public List<NeutronLoadBalancerPoolMember> getLoadBalancerPoolMembers() {
+        /*
+         * Update the pool_id of the member to that this.loadBalancerPoolID
+         */
+        if (loadBalancerPoolMembers != null) {
+            for (NeutronLoadBalancerPoolMember member: loadBalancerPoolMembers) {
+                member.setPoolID(loadBalancerPoolID);
+            }
+            return loadBalancerPoolMembers;
+        }
+        return loadBalancerPoolMembers;
+    }
+
+    public void setLoadBalancerPoolMembers(List<NeutronLoadBalancerPoolMember> loadBalancerPoolMembers) {
+        this.loadBalancerPoolMembers = loadBalancerPoolMembers;
+    }
+
+    public void addLoadBalancerPoolMember(NeutronLoadBalancerPoolMember loadBalancerPoolMember) {
+        this.loadBalancerPoolMembers.add(loadBalancerPoolMember);
+    }
+
+    public void removeLoadBalancerPoolMember(NeutronLoadBalancerPoolMember loadBalancerPoolMember) {
+        this.loadBalancerPoolMembers.remove(loadBalancerPoolMember);
+    }
+
+    public NeutronLoadBalancerPool extractFields(List<String> fields) {
+        NeutronLoadBalancerPool ans = new NeutronLoadBalancerPool();
+        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;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronLoadBalancerPool{" +
+            "id='" + loadBalancerPoolID + '\'' +
+            ", tenantID='" + loadBalancerPoolTenantID + '\'' +
+            ", name='" + loadBalancerPoolName + '\'' +
+            ", description='" + loadBalancerPoolDescription + '\'' +
+            ", protocol=" + loadBalancerPoolProtocol +'\''+
+            ", lbAlgorithm='" + loadBalancerPoolLbAlgorithm + '\'' +
+            ", healthmonitorID=" + neutronLoadBalancerPoolHealthMonitorID +
+            ", adminStateUp=" + loadBalancerPoolAdminStateIsUp +
+// todo: add loadBalancerPoolMembers as joined string
+            '}';
+    }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPoolMember.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancerPoolMember.java
new file mode 100644 (file)
index 0000000..d36487f
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import java.io.Serializable;
+import java.util.List;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronLoadBalancerPoolMember
+    implements Serializable, INeutronObject {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * TODO: Plumb into LBaaS Pool. Members are nested underneath Pool CRUD.
+     */
+    @XmlElement (name = "id")
+    String poolMemberID;
+
+    @XmlElement (name = "tenant_id")
+    String poolMemberTenantID;
+
+    @XmlElement (name = "address")
+    String poolMemberAddress;
+
+    @XmlElement (name = "protocol_port")
+    Integer poolMemberProtoPort;
+
+    @XmlElement (name = "admin_state_up")
+    Boolean poolMemberAdminStateIsUp;
+
+    @XmlElement (name = "weight")
+    Integer poolMemberWeight;
+
+    @XmlElement (name = "subnet_id")
+    String poolMemberSubnetID;
+
+    String poolID;
+
+    public NeutronLoadBalancerPoolMember() {
+    }
+
+    @XmlTransient
+    public String getPoolID() {
+        return poolID;
+    }
+
+    public void setPoolID(String poolID) {
+        this.poolID = poolID;
+    }
+
+    public String getID() {
+        return poolMemberID;
+    }
+
+    public void setID(String id) {
+        poolMemberID = id;
+    }
+
+    // @deprecated use getID()
+    public String getPoolMemberID() {
+        return poolMemberID;
+    }
+
+    // @deprecated use setID()
+    public void setPoolMemberID(String poolMemberID) {
+        this.poolMemberID = poolMemberID;
+    }
+
+    public String getPoolMemberTenantID() {
+        return poolMemberTenantID;
+    }
+
+    public void setPoolMemberTenantID(String poolMemberTenantID) {
+        this.poolMemberTenantID = poolMemberTenantID;
+    }
+
+    public String getPoolMemberAddress() {
+        return poolMemberAddress;
+    }
+
+    public void setPoolMemberAddress(String poolMemberAddress) {
+        this.poolMemberAddress = poolMemberAddress;
+    }
+
+    public Integer getPoolMemberProtoPort() {
+        return poolMemberProtoPort;
+    }
+
+    public void setPoolMemberProtoPort(Integer poolMemberProtoPort) {
+        this.poolMemberProtoPort = poolMemberProtoPort;
+    }
+
+    public Boolean getPoolMemberAdminStateIsUp() {
+        return poolMemberAdminStateIsUp;
+    }
+
+    public void setPoolMemberAdminStateIsUp(Boolean poolMemberAdminStateIsUp) {
+        this.poolMemberAdminStateIsUp = poolMemberAdminStateIsUp;
+    }
+
+    public Integer getPoolMemberWeight() {
+        return poolMemberWeight;
+    }
+
+    public void setPoolMemberWeight(Integer poolMemberWeight) {
+        this.poolMemberWeight = poolMemberWeight;
+    }
+
+    public String getPoolMemberSubnetID() {
+        return poolMemberSubnetID;
+    }
+
+    public void setPoolMemberSubnetID(String poolMemberSubnetID) {
+        this.poolMemberSubnetID = poolMemberSubnetID;
+    }
+
+    public NeutronLoadBalancerPoolMember extractFields(List<String> fields) {
+        NeutronLoadBalancerPoolMember ans = new NeutronLoadBalancerPoolMember();
+        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;
+    }
+    @Override public String toString() {
+        return "NeutronLoadBalancerPoolMember{" +
+                "poolMemberID='" + poolMemberID + '\'' +
+                ", poolID='" + poolID + '\'' +
+                ", poolMemberTenantID='" + poolMemberTenantID + '\'' +
+                ", poolMemberAddress='" + poolMemberAddress + '\'' +
+                ", poolMemberProtoPort=" + poolMemberProtoPort +
+                ", poolMemberAdminStateIsUp=" + poolMemberAdminStateIsUp +
+                ", poolMemberWeight=" + poolMemberWeight +
+                ", poolMemberSubnetID='" + poolMemberSubnetID + '\'' +
+                '}';
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancer_SessionPersistence.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronLoadBalancer_SessionPersistence.java
new file mode 100644 (file)
index 0000000..7d3d63c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronLoadBalancer_SessionPersistence implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name = "cookie_name")
+    String cookieName;
+
+    @XmlElement(name = "type")
+    String type;
+
+    public NeutronLoadBalancer_SessionPersistence() {
+    }
+
+    public NeutronLoadBalancer_SessionPersistence(String cookieName, String type) {
+        this.cookieName = cookieName;
+        this.type = type;
+    }
+
+    public String getCookieName() {
+        return cookieName;
+    }
+
+    public void setCookieName(String cookieName) {
+        this.cookieName = cookieName;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
+
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronNetwork.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronNetwork.java
new file mode 100644 (file)
index 0000000..1e008ec
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "network")
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronNetwork implements Serializable, INeutronObject {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement (name = "id")
+    String networkUUID;
+
+    @XmlElement (name = "name")
+    String networkName;
+
+    @XmlElement (defaultValue = "true", name = "admin_state_up")
+    Boolean adminStateUp;
+
+    @XmlElement (defaultValue = "false", name = "shared")
+    Boolean shared;
+
+    @XmlElement (name = "tenant_id")
+    String tenantID;
+
+    //    @XmlElement (defaultValue = "false", name = "router:external")
+    @XmlElement (defaultValue="false", namespace="router", name="external")
+    Boolean routerExternal;
+
+    //    @XmlElement (defaultValue = "flat", name = "provider:network_type")
+    @XmlElement (namespace="provider", name="network_type")
+    String providerNetworkType;
+
+    //    @XmlElement (name = "provider:physical_network")
+    @XmlElement (namespace="provider", name="physical_network")
+    String providerPhysicalNetwork;
+
+    //    @XmlElement (name = "provider:segmentation_id")
+    @XmlElement (namespace="provider", name="segmentation_id")
+    String providerSegmentationID;
+
+    @XmlElement (name = "status")
+    String status;
+
+    @XmlElement (name="segments")
+    List<NeutronNetwork_Segment> segments;
+
+    @XmlElement (name="vlan_transparent")
+    Boolean vlanTransparent;
+
+    @XmlElement (name="mtu")
+    Integer mtu;
+
+    /* This attribute lists the ports associated with an instance
+     * which is needed for determining if that instance can be deleted
+     */
+
+    public NeutronNetwork() {
+    }
+
+    public void initDefaults() {
+        if (status == null) {
+            status = "ACTIVE";
+        }
+        if (adminStateUp == null) {
+            adminStateUp = true;
+        }
+        if (shared == null) {
+            shared = false;
+        }
+        if (routerExternal == null) {
+            routerExternal = false;
+        }
+        if (providerNetworkType == null) {
+            providerNetworkType = "flat";
+        }
+    }
+
+    public String getID() { return networkUUID; }
+
+    public void setID(String id) { this.networkUUID = id; }
+
+    public String getNetworkUUID() {
+        return networkUUID;
+    }
+
+    public void setNetworkUUID(String networkUUID) {
+        this.networkUUID = networkUUID;
+    }
+
+    public String getNetworkName() {
+        return networkName;
+    }
+
+    public void setNetworkName(String networkName) {
+        this.networkName = networkName;
+    }
+
+    public boolean isAdminStateUp() {
+        return adminStateUp;
+    }
+
+    public Boolean getAdminStateUp() { return adminStateUp; }
+
+    public void setAdminStateUp(boolean newValue) {
+        adminStateUp = newValue;
+    }
+
+    public boolean isShared() { return shared; }
+
+    public Boolean getShared() { return shared; }
+
+    public void setShared(boolean newValue) {
+        shared = newValue;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    public boolean isRouterExternal() { return routerExternal; }
+
+    public Boolean getRouterExternal() { return routerExternal; }
+
+    public void setRouterExternal(boolean newValue) {
+        routerExternal = newValue;
+    }
+
+    public String getProviderNetworkType() {
+        return providerNetworkType;
+    }
+
+    public void setProviderNetworkType(String providerNetworkType) {
+        this.providerNetworkType = providerNetworkType;
+    }
+
+    public String getProviderPhysicalNetwork() {
+        return providerPhysicalNetwork;
+    }
+
+    public void setProviderPhysicalNetwork(String providerPhysicalNetwork) {
+        this.providerPhysicalNetwork = providerPhysicalNetwork;
+    }
+
+    public String getProviderSegmentationID() {
+        return providerSegmentationID;
+    }
+
+    public void setProviderSegmentationID(String providerSegmentationID) {
+        this.providerSegmentationID = providerSegmentationID;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public void setSegments(List<NeutronNetwork_Segment> segments) {
+        this.segments = segments;
+    }
+
+    public List<NeutronNetwork_Segment> getSegments() {
+        return segments;
+    }
+
+    public Boolean getVlanTransparent() {
+        return vlanTransparent;
+    }
+
+    public void setVlanTransparent(Boolean input) {
+        this.vlanTransparent = input;
+    }
+
+    public Integer getMtu() {
+        return mtu;
+    }
+
+    public void setMtu(Integer input) {
+        mtu = input;
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackNetworks object with only the selected fields
+     * populated
+     */
+
+    public NeutronNetwork extractFields(List<String> fields) {
+        NeutronNetwork ans = new NeutronNetwork();
+        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 "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;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronNetwork [networkUUID=" + networkUUID + ", networkName=" + networkName + ", adminStateUp="
+                + adminStateUp + ", shared=" + shared + ", tenantID=" + tenantID + ", routerExternal=" + routerExternal
+                + ", providerNetworkType=" + providerNetworkType + ", providerPhysicalNetwork="
+                + providerPhysicalNetwork + ", providerSegmentationID=" + providerSegmentationID + ", status=" + status
+                + ", segments = " + segments + "]";
+    }
+}
+
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronNetwork_Segment.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronNetwork_Segment.java
new file mode 100644 (file)
index 0000000..2246f89
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "network")
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronNetwork_Segment implements Serializable {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    private static final long serialVersionUID = 1L;
+
+    //    @XmlElement (defaultValue="flat", name="provider:network_type")
+    @XmlElement (defaultValue="flat", namespace="provider", name="network_type")
+    String providerNetworkType;
+
+    //    @XmlElement (name="provider:physical_network")
+    @XmlElement (namespace="provider", name="physical_network")
+    String providerPhysicalNetwork;
+
+    //    @XmlElement (name="provider:segmentation_id")
+    @XmlElement (namespace="provider", name="segmentation_id")
+    String providerSegmentationID;
+
+    public NeutronNetwork_Segment() {
+    }
+
+    public String getProviderNetworkType() {
+        return providerNetworkType;
+    }
+
+    public void setProviderNetworkType(String providerNetworkType) {
+        this.providerNetworkType = providerNetworkType;
+    }
+
+    public String getProviderPhysicalNetwork() {
+        return providerPhysicalNetwork;
+    }
+
+    public void setProviderPhysicalNetwork(String providerPhysicalNetwork) {
+        this.providerPhysicalNetwork = providerPhysicalNetwork;
+    }
+
+    public String getProviderSegmentationID() {
+        return providerSegmentationID;
+    }
+
+    public void setProviderSegmentationID(String providerSegmentationID) {
+        this.providerSegmentationID = providerSegmentationID;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronNetwork_Segment [ " +
+               ", providerNetworkType=" + providerNetworkType +
+               ", providerPhysicalNetwork=" + providerPhysicalNetwork +
+               ", providerSegmentationID=" + providerSegmentationID + "]";
+    }
+}
+
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort.java
new file mode 100644 (file)
index 0000000..b77e411
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronPort implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name = "id")
+    String portUUID;
+
+    @XmlElement (name = "network_id")
+    String networkUUID;
+
+    @XmlElement (name = "name")
+    String name;
+
+    @XmlElement (defaultValue = "true", name = "admin_state_up")
+    Boolean adminStateUp;
+
+    @XmlElement (name = "status")
+    String status;
+
+    @XmlElement (name = "mac_address")
+    String macAddress;
+
+    @XmlElement (name = "fixed_ips")
+    List<Neutron_IPs> fixedIPs;
+
+    @XmlElement (name = "device_id")
+    String deviceID;
+
+    @XmlElement (name = "device_owner")
+    String deviceOwner;
+
+    @XmlElement (name = "tenant_id")
+    String tenantID;
+
+    @XmlElement (name = "security_groups")
+    List<NeutronSecurityGroup> securityGroups;
+
+    @XmlElement (name = "allowed_address_pairs")
+    List<NeutronPort_AllowedAddressPairs> allowedAddressPairs;
+
+    //@XmlElement (name = "binding:host_id")
+    @XmlElement (namespace = "binding", name = "host_id")
+    String bindinghostID;
+
+    //@XmlElement (name = "binding:vnic_type")
+    @XmlElement (namespace = "binding", name = "vnic_type")
+    String bindingvnicType;
+
+    //@XmlElement (name = "binding:vif_type")
+    @XmlElement (namespace = "binding", name = "vif_type")
+    String bindingvifType;
+
+    //@XmlElement (name = "binding:vif_details")
+    @XmlElement (namespace = "binding", name = "vif_details")
+    List<NeutronPort_VIFDetail> vifDetails;
+
+    @XmlElement (name = "extra_dhcp_opts")
+    List<NeutronPort_ExtraDHCPOption> extraDHCPOptions;
+
+    NeutronPort originalPort;
+
+    public NeutronPort() {
+    }
+
+    public String getID() { return portUUID; }
+
+    public void setID(String id) { this.portUUID = id; }
+
+    public String getPortUUID() {
+        return portUUID;
+    }
+
+    public void setPortUUID(String portUUID) {
+        this.portUUID = portUUID;
+    }
+
+    public String getNetworkUUID() {
+        return networkUUID;
+    }
+
+    public void setNetworkUUID(String networkUUID) {
+        this.networkUUID = networkUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isAdminStateUp() {
+        if (adminStateUp == null) {
+            return true;
+        }
+        return adminStateUp;
+    }
+
+    public Boolean getAdminStateUp() { return adminStateUp; }
+
+    public void setAdminStateUp(Boolean newValue) {
+            adminStateUp = newValue;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getMacAddress() {
+        return macAddress;
+    }
+
+    public void setMacAddress(String macAddress) {
+        this.macAddress = macAddress;
+    }
+
+    public List<Neutron_IPs> getFixedIPs() {
+        return fixedIPs;
+    }
+
+    public void setFixedIPs(List<Neutron_IPs> fixedIPs) {
+        this.fixedIPs = fixedIPs;
+    }
+
+    public String getDeviceID() {
+        return deviceID;
+    }
+
+    public void setDeviceID(String deviceID) {
+        this.deviceID = deviceID;
+    }
+
+    public String getDeviceOwner() {
+        return deviceOwner;
+    }
+
+    public void setDeviceOwner(String deviceOwner) {
+        this.deviceOwner = deviceOwner;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    public List<NeutronSecurityGroup> getSecurityGroups() {
+        return securityGroups;
+    }
+
+    public void setSecurityGroups(List<NeutronSecurityGroup> securityGroups) {
+        this.securityGroups = securityGroups;
+    }
+
+    public List<NeutronPort_AllowedAddressPairs> getAllowedAddressPairs() {
+        return allowedAddressPairs;
+    }
+
+    public void setAllowedAddressPairs(List<NeutronPort_AllowedAddressPairs> allowedAddressPairs) {
+        this.allowedAddressPairs = allowedAddressPairs;
+    }
+
+    public List<NeutronPort_ExtraDHCPOption> getExtraDHCPOptions() {
+        return extraDHCPOptions;
+    }
+
+    public void setExtraDHCPOptions(List<NeutronPort_ExtraDHCPOption> extraDHCPOptions) {
+        this.extraDHCPOptions = extraDHCPOptions;
+    }
+
+    public List<NeutronPort_VIFDetail> getVIFDetail() {
+        return vifDetails;
+    }
+
+    public void setVIFDetail(List<NeutronPort_VIFDetail> vifDetails) {
+        this.vifDetails = vifDetails;
+    }
+
+    public String getBindinghostID() {
+      return bindinghostID;
+    }
+
+    public void setBindinghostID(String bindinghostID) {
+      this.bindinghostID = bindinghostID;
+    }
+
+    public String getBindingvnicType() {
+        return bindingvnicType;
+    }
+
+    public void setBindingvnicType(String bindingvnicType) {
+        this.bindingvnicType = bindingvnicType;
+    }
+
+    public String getBindingvifType() {
+        return bindingvifType;
+    }
+
+    public void setBindingvifType(String bindingvifType) {
+        this.bindingvifType = bindingvifType;
+    }
+
+    public NeutronPort getOriginalPort() {
+        return originalPort;
+    }
+
+
+    public void setOriginalPort(NeutronPort originalPort) {
+        this.originalPort = originalPort;
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackPorts object with only the selected fields
+     * populated
+     */
+
+    public NeutronPort extractFields(List<String> fields) {
+        NeutronPort ans = new NeutronPort();
+        for (String field: fields) {
+            if ("id".equals(field)) {
+                ans.setPortUUID(this.getPortUUID());
+            }
+            if ("network_id".equals(field)) {
+                ans.setNetworkUUID(this.getNetworkUUID());
+            }
+            if ("name".equals(field)) {
+                ans.setName(this.getName());
+            }
+            if ("admin_state_up".equals(field)) {
+                ans.setAdminStateUp(this.getAdminStateUp());
+            }
+            if ("status".equals(field)) {
+                ans.setStatus(this.getStatus());
+            }
+            if ("mac_address".equals(field)) {
+                ans.setMacAddress(this.getMacAddress());
+            }
+            if ("fixed_ips".equals(field)) {
+                ans.setFixedIPs(new ArrayList<>(this.getFixedIPs()));
+            }
+            if ("device_id".equals(field)) {
+                ans.setDeviceID(this.getDeviceID());
+            }
+            if ("device_owner".equals(field)) {
+                ans.setDeviceOwner(this.getDeviceOwner());
+            }
+            if ("tenant_id".equals(field)) {
+                ans.setTenantID(this.getTenantID());
+            }
+            if ("security_groups".equals(field)) {
+                ans.setSecurityGroups(new ArrayList<>(this.getSecurityGroups()));
+            }
+        }
+        return ans;
+    }
+
+    public void initDefaults() {
+        adminStateUp = true;
+        if (status == null) {
+            status = "ACTIVE";
+        }
+        if (fixedIPs == null) {
+            fixedIPs = new ArrayList<>();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronPort [portUUID=" + portUUID + ", networkUUID=" + networkUUID + ", name=" + name
+                + ", adminStateUp=" + adminStateUp + ", status=" + status + ", macAddress=" + macAddress
+                + ", fixedIPs=" + fixedIPs + ", deviceID=" + deviceID + ", deviceOwner=" + deviceOwner + ", tenantID="
+                + tenantID + ", securityGroups=" + securityGroups
+                + ", bindinghostID=" + bindinghostID + ", bindingvnicType=" + bindingvnicType
+                + ", bindingvnicType=" + bindingvnicType + "]";
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_AllowedAddressPairs.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_AllowedAddressPairs.java
new file mode 100644 (file)
index 0000000..65448d0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronPort_AllowedAddressPairs implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement (name = "port_id")
+    String portID;
+
+    @XmlElement (name = "mac_address")
+    String macAddress;
+
+    @XmlElement (name = "ip_address")
+    String ipAddress;
+
+    public NeutronPort_AllowedAddressPairs() {
+    }
+
+    public NeutronPort_AllowedAddressPairs(String portID, String macAddress, String ipAddress) {
+        this.portID = portID;
+        this.macAddress = macAddress;
+        this.ipAddress = ipAddress;
+    }
+
+    public String getPortID() { return(portID); }
+
+    public void setPortID(String portID) { this.portID = portID; }
+
+    public String getMacAddress() { return(macAddress); }
+
+    public void setMacAddress(String macAddress) { this.macAddress = macAddress; }
+
+    public String getIpAddress() { return(ipAddress); }
+
+    public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_ExtraDHCPOption.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_ExtraDHCPOption.java
new file mode 100644 (file)
index 0000000..554fac1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronPort_ExtraDHCPOption implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement (name = "opt_value")
+    String value;
+
+    @XmlElement (name = "opt_name")
+    String name;
+
+    public NeutronPort_ExtraDHCPOption() {
+    }
+
+    public NeutronPort_ExtraDHCPOption(String value, String name) {
+        this.value = value;
+        this.name = name;
+    }
+
+    public String getValue() { return(value); }
+
+    public void setValue(String value) { this.value = value; }
+
+    public String getName() { return(name); }
+
+    public void setName(String name) { this.name = name; }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_VIFDetail.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronPort_VIFDetail.java
new file mode 100644 (file)
index 0000000..c485259
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronPort_VIFDetail implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement (name = "port_filter")
+    Boolean portFilter;
+
+    @XmlElement (name = "ovs_hybrid_plug")
+    Boolean ovsHybridPlug;
+
+    public NeutronPort_VIFDetail() {
+    }
+
+    public NeutronPort_VIFDetail(Boolean portFilter, Boolean ovsHybridPlug) {
+        this.portFilter = portFilter;
+        this.ovsHybridPlug = ovsHybridPlug;
+    }
+
+    public Boolean getPortFilter() { return(portFilter); }
+
+    public void setPortFilter(Boolean portFilter) { this.portFilter = portFilter; }
+
+    public Boolean getOvsHybridPlug() { return(ovsHybridPlug); }
+
+    public void setOvsHybridPlug(Boolean ovsHybridPlug) { this.ovsHybridPlug = ovsHybridPlug; }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter.java
new file mode 100644 (file)
index 0000000..a37a188
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouter implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+    @XmlElement (name = "id")
+    String routerUUID;
+
+    @XmlElement (name = "name")
+    String name;
+
+    @XmlElement (defaultValue = "true", name = "admin_state_up")
+    Boolean adminStateUp;
+
+    @XmlElement (name = "status")
+    String status;
+
+    @XmlElement (name = "tenant_id")
+    String tenantID;
+
+    @XmlElement (name = "external_gateway_info", nillable = true)
+    NeutronRouter_NetworkReference externalGatewayInfo;
+
+    @XmlElement (name = "distributed")
+    Boolean distributed;
+
+    @XmlElement (name = "gw_port_id", nillable = true)
+    String gatewayPortId;
+
+    @XmlElement (name = "routes")
+    List<String> routes;
+
+    /* Holds a map of OpenStackRouterInterfaces by subnet UUID
+     * used for internal mapping to DOVE
+     */
+    Map<String, NeutronRouter_Interface> interfaces;
+
+    public NeutronRouter() {
+        interfaces = new HashMap<>();
+    }
+
+    public String getID() { return routerUUID; }
+
+    public void setID(String id) { this.routerUUID = id; }
+
+    public String getRouterUUID() {
+        return routerUUID;
+    }
+
+    public void setRouterUUID(String routerUUID) {
+        this.routerUUID = routerUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isAdminStateUp() {
+        if (adminStateUp == null) {
+            return true;
+        }
+        return adminStateUp;
+    }
+
+    public Boolean getAdminStateUp() { return adminStateUp; }
+
+    public void setAdminStateUp(Boolean newValue) {
+        adminStateUp = newValue;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    public NeutronRouter_NetworkReference getExternalGatewayInfo() {
+        return externalGatewayInfo;
+    }
+
+    public void setExternalGatewayInfo(NeutronRouter_NetworkReference externalGatewayInfo) {
+        this.externalGatewayInfo = externalGatewayInfo;
+    }
+
+    public Boolean getDistributed() {
+        return distributed;
+    }
+
+    public void setDistributed(Boolean distributed) {
+        this.distributed = distributed;
+    }
+
+    public String getGatewayPortId() {
+        return gatewayPortId;
+    }
+
+    public void setGatewayPortId(String gatewayPortId) {
+        this.gatewayPortId = gatewayPortId;
+    }
+
+    public List<String> getRoutes() {
+        return routes;
+    }
+
+    public void setRoutes(List<String> routes) {
+        this.routes = routes;
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackRouters object with only the selected fields
+     * populated
+     */
+    public NeutronRouter extractFields(List<String> fields) {
+        NeutronRouter ans = new NeutronRouter();
+        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;
+    }
+
+    public void setInterfaces(Map<String, NeutronRouter_Interface> input) {
+        interfaces = input;
+    }
+
+    public Map<String, NeutronRouter_Interface> getInterfaces() {
+        return interfaces;
+    }
+
+    public void addInterface(String s, NeutronRouter_Interface i) {
+        interfaces.put(s, i);
+    }
+
+    public void removeInterface(String s) {
+        interfaces.remove(s);
+    }
+
+    public void initDefaults() {
+        adminStateUp = true;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronRouter [" +
+            "id=" + routerUUID +
+            ", name=" + name +
+            ", adminStateUp=" + adminStateUp +
+            ", status=" + status +
+            ", tenantID=" + tenantID +
+            ", external_gateway_info=" + externalGatewayInfo +
+            ", distributed=" + distributed +
+            ", gw_port_id=" + gatewayPortId +
+            ", routes=" + routes +
+            ", interfaces=" + interfaces +
+            "]";
+    }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter_Interface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter_Interface.java
new file mode 100644 (file)
index 0000000..9749533
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronRouter_Interface implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name = "subnet_id")
+    String subnetUUID;
+
+    @XmlElement (name = "port_id")
+    String portUUID;
+
+    @XmlElement (name = "id")
+    String id;
+
+    @XmlElement (name = "tenant_id")
+    String tenantID;
+
+    public NeutronRouter_Interface() {
+    }
+
+    public NeutronRouter_Interface(String subnetUUID, String portUUID) {
+        this.subnetUUID = subnetUUID;
+        this.portUUID = portUUID;
+    }
+
+    public String getSubnetUUID() {
+        return subnetUUID;
+    }
+
+    public void setSubnetUUID(String subnetUUID) {
+        this.subnetUUID = subnetUUID;
+    }
+
+    public String getPortUUID() {
+        return portUUID;
+    }
+
+    public void setPortUUID(String portUUID) {
+        this.portUUID = portUUID;
+    }
+
+    public String getID() {
+        return id;
+    }
+
+    public void setID(String id) {
+        this.id = id;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronRouterInterface [" +
+            "subnetUUID=" + subnetUUID +
+            ", portUUID=" + portUUID +
+            ", id=" + id +
+            ", tenantID=" + tenantID + "]";
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter_NetworkReference.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronRouter_NetworkReference.java
new file mode 100644 (file)
index 0000000..ddc2217
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouter_NetworkReference implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name = "network_id")
+    String networkID;
+
+    @XmlElement(name = "enable_snat")
+    Boolean enableSNAT;
+
+    @XmlElement(name = "external_fixed_ips")
+    List<Neutron_IPs> externalFixedIPs;
+
+    public NeutronRouter_NetworkReference() {
+    }
+
+    public String getNetworkID() {
+        return networkID;
+    }
+
+    public void setNetworkID(String networkID) {
+        this.networkID = networkID;
+    }
+
+    public Boolean getEnableSNAT() {
+        return enableSNAT;
+    }
+
+    public void setEnableSNAT(Boolean enableSNAT) {
+        this.enableSNAT = enableSNAT;
+    }
+
+    public List<Neutron_IPs> getExternalFixedIPs() {
+        return externalFixedIPs;
+    }
+
+    public void setExternalFixedIPs(List<Neutron_IPs> externalFixedIPs) {
+        this.externalFixedIPs = externalFixedIPs;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronRouterNetworkReference [networkID=" + networkID +
+            " enableSNAT=" + enableSNAT +
+            " externalFixedIPs=" + externalFixedIPs + "]";
+    }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityGroup.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityGroup.java
new file mode 100644 (file)
index 0000000..9f898b8
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * OpenStack Neutron v2.0 Security Group bindings.
+ * See OpenStack Network API v2.0 Reference for description of
+ * annotated attributes. The current fields are as follows:
+ * <p>
+ * id                   uuid-str unique ID for the security group.
+ * name                 String name of the security group.
+ * description          String name of the security group.
+ * tenant_id            uuid-str Owner of security rule..
+ * security_group_rules List&lt;NeutronSecurityRule&gt; nested RO in the sec group.
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSecurityGroup implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String securityGroupUUID;
+
+    @XmlElement(name = "name")
+    String securityGroupName;
+
+    @XmlElement(name = "description")
+    String securityGroupDescription;
+
+    @XmlElement(name = "tenant_id")
+    String securityGroupTenantID;
+
+    @XmlElement(name = "security_group_rules")
+    List<NeutronSecurityRule> neutronSecurityRule;
+
+    public NeutronSecurityGroup() {
+        neutronSecurityRule = new ArrayList<>();
+
+    }
+
+    public String getID() {
+        return securityGroupUUID;
+    }
+
+    public void setID(String id) {
+        securityGroupUUID = id;
+    }
+
+    // @deprecated use getID()
+    public String getSecurityGroupUUID() {
+        return securityGroupUUID;
+    }
+
+    // @deprecated use setID()
+    public void setSecurityGroupUUID(String securityGroupUUID) {
+        this.securityGroupUUID = securityGroupUUID;
+    }
+
+    public String getSecurityGroupName() {
+        return securityGroupName;
+    }
+
+    public void setSecurityGroupName(String securityGroupName) {
+        this.securityGroupName = securityGroupName;
+    }
+
+    public String getSecurityGroupDescription() {
+        return securityGroupDescription;
+    }
+
+    public void setSecurityGroupDescription(String securityGroupDescription) {
+        this.securityGroupDescription = securityGroupDescription;
+    }
+
+    public String getSecurityGroupTenantID() {
+        return securityGroupTenantID;
+    }
+
+    public void setSecurityGroupTenantID(String securityGroupTenantID) {
+        this.securityGroupTenantID = securityGroupTenantID;
+    }
+
+    // Rules In Group
+    public List<NeutronSecurityRule> getSecurityRules() {
+        return neutronSecurityRule;
+    }
+
+    public void setSecurityRules(List<NeutronSecurityRule> neutronSecurityRule) {
+        this.neutronSecurityRule = neutronSecurityRule;
+    }
+
+    public NeutronSecurityGroup extractFields(List<String> fields) {
+        NeutronSecurityGroup ans = new NeutronSecurityGroup ();
+        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;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronSecurityGroup{" +
+                "securityGroupUUID='" + securityGroupUUID + '\'' +
+                ", securityGroupName='" + securityGroupName + '\'' +
+                ", securityGroupDescription='" + securityGroupDescription + '\'' +
+                ", securityGroupTenantID='" + securityGroupTenantID + '\'' +
+                ", securityRules=" + neutronSecurityRule + "]";
+    }
+
+    public void initDefaults() {
+        //TODO verify no defaults values are nessecary required.
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityRule.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSecurityRule.java
new file mode 100644 (file)
index 0000000..b8b9228
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014 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.translator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * See OpenStack Network API v2.0 Reference for description of
+ * annotated attributes. The current fields are as follows:
+ * <p>
+ * id                uuid (String) UUID for the security group rule.
+ * security_rule_id  uuid (String) The security group to associate rule.
+ * direction         String Direction the VM traffic  (ingress/egress).
+ * security_group_id The security group to associate rule with.
+ * protocol          String IP Protocol (icmp, tcp, udp, etc).
+ * port_range_min    Integer Port at start of range
+ * port_range_max    Integer Port at end of range
+ * ethertype         String ethertype in L2 packet (IPv4, IPv6, etc)
+ * remote_ip_prefix  String (IP cidr) CIDR for address range.
+ * remote_group_id   uuid-str Source security group to apply to rule.
+ * tenant_id         uuid-str Owner of security rule. Admin only outside tenant.
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSecurityRule implements Serializable, INeutronObject {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String securityRuleUUID;
+
+    @XmlElement(name = "direction")
+    String securityRuleDirection;
+
+    @XmlElement(name = "protocol")
+    String securityRuleProtocol;
+
+    @XmlElement(name = "port_range_min")
+    Integer securityRulePortMin;
+
+    @XmlElement(name = "port_range_max")
+    Integer securityRulePortMax;
+
+    @XmlElement(name = "ethertype")
+    String securityRuleEthertype;
+
+    @XmlElement(name = "remote_ip_prefix")
+    String securityRuleRemoteIpPrefix;
+
+    @XmlElement(name = "remote_group_id")
+    String securityRemoteGroupID;
+
+    @XmlElement(name = "security_group_id")
+    String securityRuleGroupID;
+
+    @XmlElement(name = "tenant_id")
+    String securityRuleTenantID;
+
+    public NeutronSecurityRule() {
+    }
+
+    public String getID() {
+        return securityRuleUUID;
+    }
+
+    public void setID(String id) {
+        securityRuleUUID = id;
+    }
+
+    // @deprecated use getID()
+    public String getSecurityRuleUUID() {
+        return securityRuleUUID;
+    }
+
+    // @deprecated use setID()
+    public void setSecurityRuleUUID(String securityRuleUUID) {
+        this.securityRuleUUID = securityRuleUUID;
+    }
+
+    public String getSecurityRuleDirection() {
+        return securityRuleDirection;
+    }
+
+    public void setSecurityRuleDirection(String securityRuleDirection) {
+        this.securityRuleDirection = securityRuleDirection;
+    }
+
+    public String getSecurityRuleProtocol() {
+        return securityRuleProtocol;
+    }
+
+    public void setSecurityRuleProtocol(String securityRuleProtocol) {
+        this.securityRuleProtocol = securityRuleProtocol;
+    }
+
+    public Integer getSecurityRulePortMin() {
+        return securityRulePortMin;
+    }
+
+    public void setSecurityRulePortMin(Integer securityRulePortMin) {
+        this.securityRulePortMin = securityRulePortMin;
+    }
+
+    public Integer getSecurityRulePortMax() {
+        return securityRulePortMax;
+    }
+
+    public void setSecurityRulePortMax(Integer securityRulePortMax) {
+        this.securityRulePortMax = securityRulePortMax;
+    }
+
+    public String getSecurityRuleEthertype() {
+        return securityRuleEthertype;
+    }
+
+    public void setSecurityRuleEthertype(String securityRuleEthertype) {
+        this.securityRuleEthertype = securityRuleEthertype;
+    }
+
+    public String getSecurityRuleRemoteIpPrefix() {
+        return securityRuleRemoteIpPrefix;
+    }
+
+    public void setSecurityRuleRemoteIpPrefix(String securityRuleRemoteIpPrefix) {
+        this.securityRuleRemoteIpPrefix = securityRuleRemoteIpPrefix;
+    }
+
+    public String getSecurityRemoteGroupID() {
+        return securityRemoteGroupID;
+    }
+
+    public void setSecurityRemoteGroupID(String securityRemoteGroupID) {
+        this.securityRemoteGroupID = securityRemoteGroupID;
+    }
+
+    public String getSecurityRuleGroupID() {
+        return securityRuleGroupID;
+    }
+
+    public void setSecurityRuleGroupID(String securityRuleGroupID) {
+        this.securityRuleGroupID = securityRuleGroupID;
+    }
+
+    public String getSecurityRuleTenantID() {
+        return securityRuleTenantID;
+    }
+
+    public void setSecurityRuleTenantID(String securityRuleTenantID) {
+        this.securityRuleTenantID = securityRuleTenantID;
+    }
+
+    public NeutronSecurityRule extractFields(List<String> fields) {
+        NeutronSecurityRule ans = new NeutronSecurityRule();
+        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;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronSecurityRule{" +
+            "securityRuleUUID='" + securityRuleUUID + '\'' +
+            ", securityRuleDirection='" + securityRuleDirection + '\'' +
+            ", securityRuleProtocol='" + securityRuleProtocol + '\'' +
+            ", securityRulePortMin=" + securityRulePortMin +
+            ", securityRulePortMax=" + securityRulePortMax +
+            ", securityRuleEthertype='" + securityRuleEthertype + '\'' +
+            ", securityRuleRemoteIpPrefix='" + securityRuleRemoteIpPrefix + '\'' +
+            ", securityRemoteGroupID=" + securityRemoteGroupID +
+            ", securityRuleGroupID='" + securityRuleGroupID + '\'' +
+            ", securityRuleTenantID='" + securityRuleTenantID + '\'' +
+            '}';
+    }
+
+    public void initDefaults() {
+        //TODO verify no defaults values are nessecary required.
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnet.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnet.java
new file mode 100644 (file)
index 0000000..1b7e8c9
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.net.util.SubnetUtils;
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.NeutronCRUDInterfaces;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSubnet implements Serializable, INeutronObject {
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(NeutronCRUDInterfaces.class);
+
+    private static final long serialVersionUID = 1L;
+    private static final int IPV4_VERSION = 4;
+    private static final int IPV6_VERSION = 6;
+    private static final int IPV6_LENGTH = 128;
+    private static final int IPV6_LENGTH_BYTES = 8;
+    private static final long IPV6_LSB_MASK = 0x000000FF;
+    private static final int IPV6_BYTE_OFFSET = 7;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name = "id")
+    String subnetUUID;
+
+    @XmlElement (name = "network_id")
+    String networkUUID;
+
+    @XmlElement (name = "name")
+    String name;
+
+    @XmlElement (defaultValue = "4", name = "ip_version")
+    Integer ipVersion;
+
+    @XmlElement (name = "cidr")
+    String cidr;
+
+    @XmlElement (name = "gateway_ip")
+    String gatewayIP;
+
+    @XmlElement (name = "dns_nameservers")
+    List<String> dnsNameservers;
+
+    @XmlElement (name = "allocation_pools")
+    List<NeutronSubnetIPAllocationPool> allocationPools;
+
+    @XmlElement (name = "host_routes")
+    List<NeutronSubnet_HostRoute> hostRoutes;
+
+    @XmlElement (defaultValue = "true", name = "enable_dhcp")
+    Boolean enableDHCP;
+
+    @XmlElement (name = "tenant_id")
+    String tenantID;
+
+    @XmlElement (name = "ipv6_address_mode", nillable = true)
+    String ipV6AddressMode;
+
+    @XmlElement (name = "ipv6_ra_mode", nillable = true)
+    String ipV6RaMode;
+
+    /* stores the OpenStackPorts associated with an instance
+     * used to determine if that instance can be deleted.
+     *
+     * @deprecated, will be removed in Boron
+     */
+
+    List<NeutronPort> myPorts;
+
+    public NeutronSubnet() {
+        myPorts = new ArrayList<>();
+    }
+
+    // @deprecated - will be removed in Boron
+    public void setPorts(List<NeutronPort> arg) {
+        myPorts = arg;
+    }
+
+    public String getID() { return subnetUUID; }
+
+    public void setID(String id) { this.subnetUUID = id; }
+
+    public String getSubnetUUID() {
+        return subnetUUID;
+    }
+
+    public void setSubnetUUID(String subnetUUID) {
+        this.subnetUUID = subnetUUID;
+    }
+
+    public String getNetworkUUID() {
+        return networkUUID;
+    }
+
+    public void setNetworkUUID(String networkUUID) {
+        this.networkUUID = networkUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getIpVersion() {
+        return ipVersion;
+    }
+
+    public void setIpVersion(Integer ipVersion) {
+        this.ipVersion = ipVersion;
+    }
+
+    public String getCidr() {
+        return cidr;
+    }
+
+    public void setCidr(String cidr) {
+        this.cidr = cidr;
+    }
+
+    public String getGatewayIP() {
+        return gatewayIP;
+    }
+
+    public void setGatewayIP(String gatewayIP) {
+        this.gatewayIP = gatewayIP;
+    }
+
+    public List<String> getDnsNameservers() {
+        return dnsNameservers;
+    }
+
+    public void setDnsNameservers(List<String> dnsNameservers) {
+        this.dnsNameservers = dnsNameservers;
+    }
+
+    public List<NeutronSubnetIPAllocationPool> getAllocationPools() {
+        return allocationPools;
+    }
+
+    public void setAllocationPools(List<NeutronSubnetIPAllocationPool> allocationPools) {
+        this.allocationPools = allocationPools;
+    }
+
+    public List<NeutronSubnet_HostRoute> getHostRoutes() {
+        return hostRoutes;
+    }
+
+    public void setHostRoutes(List<NeutronSubnet_HostRoute> hostRoutes) {
+        this.hostRoutes = hostRoutes;
+    }
+
+    public boolean isEnableDHCP() {
+        if (enableDHCP == null) {
+            return true;
+        }
+        return enableDHCP;
+    }
+
+    public Boolean getEnableDHCP() { return enableDHCP; }
+
+    public void setEnableDHCP(Boolean newValue) {
+            enableDHCP = newValue;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    public String getIpV6AddressMode() { return ipV6AddressMode; }
+
+    public void setIpV6AddressMode(String ipV6AddressMode) { this.ipV6AddressMode = ipV6AddressMode; }
+
+    public String getIpV6RaMode() { return ipV6RaMode; }
+
+    public void setIpV6RaMode(String ipV6RaMode) { this.ipV6RaMode = ipV6RaMode; }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackSubnets object with only the selected fields
+     * populated
+     */
+
+    public NeutronSubnet extractFields(List<String> fields) {
+        NeutronSubnet ans = new NeutronSubnet();
+        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;
+    }
+
+    // @deprecated - will be removed in Boron
+    public List<NeutronPort> getPortsInSubnet() {
+        return myPorts;
+    }
+
+    // @deprecated - will be removed in Boron
+    public List<NeutronPort> getPortsInSubnet(String ignore) {
+       List<NeutronPort> answer = new ArrayList<>();
+       for (NeutronPort port : myPorts) {
+           if (!port.getDeviceOwner().equalsIgnoreCase(ignore)) {
+                answer.add(port);
+            }
+        }
+        return answer;
+    }
+
+    /* test to see if the cidr address used to define this subnet
+     * is a valid network address (an necessary condition when creating
+     * a new subnet)
+     */
+    public boolean isValidCIDR() {
+        // fix for Bug 2290 - need to wrap the existing test as
+        // IPv4 because SubnetUtils doesn't support IPv6
+        if (ipVersion == IPV4_VERSION) {
+            try {
+                SubnetUtils util = new SubnetUtils(cidr);
+                SubnetInfo info = util.getInfo();
+                if (!info.getNetworkAddress().equals(info.getAddress())) {
+                    return false;
+                }
+            } catch (IllegalArgumentException e) {
+                LOGGER.warn("Failure in isValidCIDR()", e);
+                return false;
+            }
+            return true;
+        }
+        if (ipVersion == IPV6_VERSION) {
+            // fix for Bug2290 - this is custom code because no classes
+            // with ODL-friendly licenses have been found
+            // extract address (in front of /) and length (after /)
+            String[] parts = cidr.split("/");
+            if (parts.length != 2) {
+                return false;
+            }
+            try {
+                int length = Integer.parseInt(parts[1]);
+                //TODO?: limit check on length
+                // convert to byte array
+                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) {
+                        return(false);
+                    }
+                }
+                return(true);
+            } catch (UnknownHostException e) {
+                LOGGER.warn("Failure in isValidCIDR()", e);
+                return(false);
+            }
+        }
+        return false;
+    }
+
+    /* test to see if the gateway IP specified overlaps with specified
+     * allocation pools (an error condition when creating a new subnet
+     * or assigning a gateway IP)
+     */
+    public boolean gatewayIP_Pool_overlap() {
+        for (NeutronSubnetIPAllocationPool pool : allocationPools) {
+            if (ipVersion == IPV4_VERSION && pool.contains(gatewayIP)) {
+                return true;
+            }
+            if (ipVersion == IPV6_VERSION && pool.containsV6(gatewayIP)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean initDefaults() {
+        if (enableDHCP == null) {
+            enableDHCP = true;
+        }
+        if (ipVersion == null) {
+            ipVersion = IPV4_VERSION;
+        }
+        dnsNameservers = new ArrayList<>();
+        if (hostRoutes == null) {
+            hostRoutes = new ArrayList<>();
+        }
+        if (allocationPools == null) {
+            allocationPools = new ArrayList<>();
+            if (ipVersion == IPV4_VERSION) {
+                try {
+                    SubnetUtils util = new SubnetUtils(cidr);
+                    SubnetInfo info = util.getInfo();
+                    if (gatewayIP == null || ("").equals(gatewayIP)) {
+                        gatewayIP = info.getLowAddress();
+                    }
+                    if (allocationPools.size() < 1) {
+                        NeutronSubnetIPAllocationPool source =
+                            new NeutronSubnetIPAllocationPool(info.getLowAddress(),
+                                    info.getHighAddress());
+                        allocationPools = source.splitPool(gatewayIP);
+                    }
+                } catch (IllegalArgumentException e) {
+                    LOGGER.warn("Failure in initDefault()", e);
+                    return false;
+                }
+            }
+            if (ipVersion == IPV6_VERSION) {
+                String[] parts = cidr.split("/");
+                if (parts.length != 2) {
+                    return false;
+                }
+                try {
+                    int length = Integer.parseInt(parts[1]);
+                    BigInteger lowAddress_bi = NeutronSubnetIPAllocationPool.convertV6(parts[0]);
+                    String lowAddress = NeutronSubnetIPAllocationPool.bigIntegerToIP(lowAddress_bi.add(BigInteger.ONE));
+                    BigInteger mask = BigInteger.ONE.shiftLeft(length).subtract(BigInteger.ONE);
+                    String highAddress = NeutronSubnetIPAllocationPool.bigIntegerToIP(lowAddress_bi.add(mask).subtract(BigInteger.ONE));
+                    if (gatewayIP == null || ("").equals(gatewayIP)) {
+                        gatewayIP = lowAddress;
+                    }
+                    if (allocationPools.size() < 1) {
+                        NeutronSubnetIPAllocationPool source =
+                            new NeutronSubnetIPAllocationPool(lowAddress,
+                                    highAddress);
+                        allocationPools = source.splitPoolV6(gatewayIP);
+                    }
+                } catch (Exception e) {
+                    LOGGER.warn("Failure in initDefault()", e);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /* this method tests to see if the supplied IPv4 address
+     * is valid for this subnet or not
+     */
+    public boolean isValidIP(String ipAddress) {
+        if (ipVersion == IPV4_VERSION) {
+            try {
+                SubnetUtils util = new SubnetUtils(cidr);
+                SubnetInfo info = util.getInfo();
+                return info.isInRange(ipAddress);
+            } catch (IllegalArgumentException e) {
+                LOGGER.warn("Failure in isValidIP()", e);
+                return false;
+            }
+        }
+
+        if (ipVersion == IPV6_VERSION) {
+            String[] parts = cidr.split("/");
+            try {
+                int length = Integer.parseInt(parts[1]);
+                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)))) !=
+                        ((((int) ipBytes[i/IPV6_LENGTH_BYTES]) & IPV6_LSB_MASK) & (1 << (IPV6_BYTE_OFFSET-(i%IPV6_LENGTH_BYTES))))) {
+                        return(false);
+                    }
+                }
+                return(true);
+            } catch (UnknownHostException e) {
+                LOGGER.warn("Failure in isValidIP()", e);
+                return(false);
+            }
+        }
+        return false;
+    }
+
+    /* method to get the lowest available address of the subnet.
+     * go through all the allocation pools and keep the lowest of their
+     * low addresses.
+     */
+    public String getLowAddr() {
+        String ans = null;
+        for (NeutronSubnetIPAllocationPool pool : allocationPools) {
+            if (ans == null) {
+                ans = pool.getPoolStart();
+            } else {
+                if (ipVersion == IPV4_VERSION &&
+                        NeutronSubnetIPAllocationPool.convert(pool.getPoolStart()) <
+                                NeutronSubnetIPAllocationPool.convert(ans)) {
+                    ans = pool.getPoolStart();
+                }
+                if (ipVersion == IPV6_VERSION &&
+                        NeutronSubnetIPAllocationPool.convertV6(pool.getPoolStart()).compareTo(
+                                NeutronSubnetIPAllocationPool.convertV6(ans)) < 0) {
+                    ans = pool.getPoolStart();
+                }
+            }
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronSubnet [subnetUUID=" + subnetUUID + ", networkUUID=" + networkUUID + ", name=" + name
+                + ", ipVersion=" + ipVersion + ", cidr=" + cidr + ", gatewayIP=" + gatewayIP + ", dnsNameservers="
+                + dnsNameservers + ", allocationPools=" + allocationPools + ", hostRoutes=" + hostRoutes
+                + ", enableDHCP=" + enableDHCP + ", tenantID=" + tenantID
+                + ", ipv6AddressMode=" + ipV6AddressMode
+                + ", ipv6RaMode=" + ipV6RaMode + "]";
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnetIPAllocationPool.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnetIPAllocationPool.java
new file mode 100644 (file)
index 0000000..c3cc051
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronSubnetIPAllocationPool implements Serializable {
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(NeutronSubnetIPAllocationPool.class);
+
+    private static final long serialVersionUID = 1L;
+
+    private static final int BYTE_LENGTH = 8;
+    private static final int IPV4_DOTTED_QUADS = 4;
+    private static final int IPV4_DOTTED_QUAD_OFFSET = 3;
+    private static final int IPV4_DOTTED_QUAD_MASK = 255;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name = "start")
+    String poolStart;
+
+    @XmlElement(name = "end")
+    String poolEnd;
+
+    public NeutronSubnetIPAllocationPool() {
+    }
+
+    public NeutronSubnetIPAllocationPool(String lowAddress, String highAddress) {
+        poolStart = lowAddress;
+        poolEnd = highAddress;
+    }
+
+    public String getPoolStart() {
+        return poolStart;
+    }
+
+    public void setPoolStart(String poolStart) {
+        this.poolStart = poolStart;
+    }
+
+    public String getPoolEnd() {
+        return poolEnd;
+    }
+
+    public void setPoolEnd(String poolEnd) {
+        this.poolEnd = poolEnd;
+    }
+
+    /**
+     * This method determines if this allocation pool contains the
+     * input IPv4 address
+     *
+     * @param inputString
+     *            IPv4 address in dotted decimal format
+     * @return a boolean on whether the pool contains the address or not
+     */
+
+    public boolean contains(String inputString) {
+        long inputIP = convert(inputString);
+        long startIP = convert(poolStart);
+        long endIP = convert(poolEnd);
+        return (inputIP >= startIP && inputIP <= endIP);
+    }
+
+    /**
+     * This static method converts the supplied IPv4 address to a long
+     * integer for comparison
+     *
+     * @param inputString
+     *            IPv4 address in dotted decimal format
+     * @return high-endian representation of the IPv4 address as a long.
+     *          This method will return 0 if the input is null.
+     */
+
+    static long convert(String inputString) {
+        long ans = 0;
+        if (inputString != null) {
+            String[] parts = inputString.split("\\.");
+            for (String part: parts) {
+                ans <<= BYTE_LENGTH;
+                ans |= Integer.parseInt(part);
+            }
+        }
+        return ans;
+    }
+
+    /**
+     * This method determines if this allocation pool contains the
+     * input IPv4 address
+     *
+     * @param inputString
+     *            IPv4 address in dotted decimal format
+     * @return a boolean on whether the pool contains the address or not
+     */
+
+    public boolean containsV6(String inputString) {
+        BigInteger inputIP = convertV6(inputString);
+        BigInteger startIP = convertV6(poolStart);
+        BigInteger endIP = convertV6(poolEnd);
+        return (inputIP.compareTo(startIP) >= 0 && inputIP.compareTo(endIP) <= 0);
+    }
+
+    /**
+     * This static method converts the supplied IPv4 address to a long
+     * integer for comparison
+     *
+     * @param inputString
+     *            IPv6 address in dotted decimal format
+     * @return high-endian representation of the IPv4 address as a BigInteger.
+     *          This method will return 0 if the input is null.
+     */
+
+    static BigInteger convertV6(String inputString) {
+        if (inputString == null) {
+            return BigInteger.ZERO;
+        }
+        try {
+            return new BigInteger(InetAddress.getByName(inputString).getAddress());
+        } catch (Exception e) {
+            LOGGER.error("convertV6 error", e);
+            return BigInteger.ZERO;
+        }
+    }
+
+    /**
+     * This static method converts the supplied high-ending long back
+     * into a dotted decimal representation of an IPv4 address
+     *
+     * @param l
+     *            high-endian representation of the IPv4 address as a long
+     * @return IPv4 address in dotted decimal format
+     */
+    static String longToIP(long input) {
+        int part;
+        long ipLong = input;
+        String[] parts = new String[IPV4_DOTTED_QUADS];
+        for (part = 0; part < IPV4_DOTTED_QUADS; part++) {
+            parts[IPV4_DOTTED_QUAD_OFFSET-part] = String.valueOf(ipLong & IPV4_DOTTED_QUAD_MASK);
+            ipLong >>= BYTE_LENGTH;
+        }
+        return join(parts,".");
+    }
+
+    /**
+     * This static method converts the supplied high-ending long back
+     * into a dotted decimal representation of an IPv4 address
+     *
+     * @param l
+     *            high-endian representation of the IPv4 address as a long
+     * @return IPv4 address in dotted decimal format
+     */
+    static String bigIntegerToIP(BigInteger b) {
+        try {
+            return Inet6Address.getByAddress(b.toByteArray()).getHostAddress();
+        } catch (Exception e) {
+            LOGGER.error("bigIntegerToIP", e);
+            return "ERROR";
+        }
+    }
+
+    /*
+     * helper routine used by longToIP
+     */
+    public static String join(String r[],String separator)
+    {
+        if (r.length == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        int i;
+        for(i = 0;i < r.length - 1;i++) {
+            sb.append(r[i]);
+            sb.append(separator);
+        }
+        return sb.toString() + r[i];
+    }
+
+    /*
+     * This method splits the current instance by removing the supplied
+     * parameter.
+     *
+     * If the parameter is either the low or high address,
+     * then that member is adjusted and a list containing just this instance
+     * is returned.
+     *
+     * If the parameter is in the middle of the pool, then
+     * create two new instances, one ranging from low to parameter-1
+     * the other ranging from parameter+1 to high
+     */
+    public List<NeutronSubnetIPAllocationPool> splitPool(String ipAddress) {
+        List<NeutronSubnetIPAllocationPool> ans = new ArrayList<>();
+        long gIP = NeutronSubnetIPAllocationPool.convert(ipAddress);
+        long sIP = NeutronSubnetIPAllocationPool.convert(poolStart);
+        long eIP = NeutronSubnetIPAllocationPool.convert(poolEnd);
+        long i;
+        NeutronSubnetIPAllocationPool p = new NeutronSubnetIPAllocationPool();
+        boolean poolStarted = false;
+        for (i = sIP; i <= eIP; i++) {
+            if (i == sIP) {
+                if (i != gIP) {
+                    p.setPoolStart(poolStart);
+                    poolStarted = true;
+                } else {
+                    //FIX for bug 533
+                    p.setPoolStart(NeutronSubnetIPAllocationPool.longToIP(i+1));
+                }
+            }
+            if (i == eIP) {
+                if (i != gIP) {
+                    p.setPoolEnd(poolEnd);
+                } else {
+                    p.setPoolEnd(NeutronSubnetIPAllocationPool.longToIP(i-1));
+                }
+                ans.add(p);
+            }
+            if (i != sIP && i != eIP) {
+                if (i != gIP) {
+                    if (!poolStarted) {
+                        p.setPoolStart(NeutronSubnetIPAllocationPool.longToIP(i));
+                        poolStarted = true;
+                    }
+                } else {
+                    p.setPoolEnd(NeutronSubnetIPAllocationPool.longToIP(i-1));
+                    poolStarted = false;
+                    ans.add(p);
+                    p = new NeutronSubnetIPAllocationPool();
+                    // Fix for 2120
+                    p.setPoolStart(NeutronSubnetIPAllocationPool.longToIP(i+1));
+                    poolStarted = true;
+                }
+            }
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronSubnetIPAllocationPool [" +
+            "start=" + poolStart +
+            ", end=" + poolEnd + "]";
+    }
+
+    /*
+     * This method splits the current instance by removing the supplied
+     * parameter.
+     *
+     * If the parameter is either the low or high address,
+     * then that member is adjusted and a list containing just this instance
+     * is returned.
+     new *
+     * If the parameter is in the middle of the pool, then
+     * create two new instances, one ranging from low to parameter-1
+     * the other ranging from parameter+1 to high
+     * If the pool is a single address, return null
+     */
+    public List<NeutronSubnetIPAllocationPool> splitPoolV6(String ipAddress) {
+        List<NeutronSubnetIPAllocationPool> ans = new ArrayList<>();
+        BigInteger gIP = NeutronSubnetIPAllocationPool.convertV6(ipAddress);
+        BigInteger sIP = NeutronSubnetIPAllocationPool.convertV6(poolStart);
+        BigInteger eIP = NeutronSubnetIPAllocationPool.convertV6(poolEnd);
+        if (gIP.compareTo(sIP) == 0 && gIP.compareTo(eIP) < 0) {
+            NeutronSubnetIPAllocationPool p = new NeutronSubnetIPAllocationPool();
+            p.setPoolStart(NeutronSubnetIPAllocationPool.bigIntegerToIP(sIP.add(BigInteger.ONE)));
+            p.setPoolEnd(poolEnd);
+            ans.add(p);
+            return(ans);
+        }
+        if (gIP.compareTo(eIP) == 0 && gIP.compareTo(sIP) > 0) {
+            NeutronSubnetIPAllocationPool p = new NeutronSubnetIPAllocationPool();
+            p.setPoolStart(poolStart);
+            p.setPoolEnd(NeutronSubnetIPAllocationPool.bigIntegerToIP(eIP.subtract(BigInteger.ONE)));
+            ans.add(p);
+            return(ans);
+        }
+        if (gIP.compareTo(eIP) < 0 && gIP.compareTo(sIP) > 0) {
+            NeutronSubnetIPAllocationPool p = new NeutronSubnetIPAllocationPool();
+            p.setPoolStart(poolStart);
+            p.setPoolEnd(NeutronSubnetIPAllocationPool.bigIntegerToIP(gIP.subtract(BigInteger.ONE)));
+            ans.add(p);
+            NeutronSubnetIPAllocationPool p2 = new NeutronSubnetIPAllocationPool();
+            p2.setPoolStart(NeutronSubnetIPAllocationPool.bigIntegerToIP(gIP.add(BigInteger.ONE)));
+            p2.setPoolEnd(poolEnd);
+            ans.add(p2);
+            return ans;
+        }
+        return null;
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnet_HostRoute.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/NeutronSubnet_HostRoute.java
new file mode 100644 (file)
index 0000000..49743fe
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronSubnet_HostRoute implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name = "destination")
+    String destination;
+
+    @XmlElement(name = "nexthop")
+    String nextHop;
+
+    /**
+     *  HostRoute constructor
+     */
+    public NeutronSubnet_HostRoute() { }
+
+    @Override
+    public String toString() {
+        return "NeutronSubnetHostRoute [" +
+            "destination=" + destination +
+            ", nextHop=" + nextHop + "]";
+    }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/Neutron_ID.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/Neutron_ID.java
new file mode 100644 (file)
index 0000000..acdae12
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Neutron_ID implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name = "id")
+    String uuid;
+
+    public Neutron_ID() { }
+
+    public Neutron_ID(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getID() {
+        return uuid;
+    }
+
+    public void setID(String uuid) {
+        this.uuid = uuid;
+    }
+
+    @Override
+    public String toString() {
+        return "Neutron_ID{" + "id='" + uuid + '\'' + "}";
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/Neutron_IPs.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/Neutron_IPs.java
new file mode 100644 (file)
index 0000000..41b8981
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Neutron_IPs implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name = "ip_address")
+    String ipAddress;
+
+    @XmlElement(name = "subnet_id")
+    String subnetUUID;
+
+    public Neutron_IPs() { }
+
+    public Neutron_IPs(String uuid) {
+        subnetUUID = uuid;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public String getSubnetUUID() {
+        return subnetUUID;
+    }
+
+    public void setSubnetUUID(String subnetUUID) {
+        this.subnetUUID = subnetUUID;
+    }
+
+    @Override
+    public String toString() {
+        return "Neutron_IPs{" +
+               "ipAddress='" + ipAddress + '\'' +
+               ", subnetUUID='" + subnetUUID + '\'' + "}";
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallCRUD.java
new file mode 100644 (file)
index 0000000..51b4021
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewall;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Firewall objects
+ */
+
+public interface INeutronFirewallCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     *Firewall object exists
+     *
+     * @param uuid
+     *            UUID of the Firewall object
+     * @return boolean
+     */
+
+    boolean neutronFirewallExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Firewall object exists
+     *
+     * @param uuid
+     *            UUID of the Firewall object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewall}
+     *          OpenStackFirewall class
+     */
+
+    NeutronFirewall getNeutronFirewall(String uuid);
+
+    /**
+     * Applications call this interface method to return all Firewall objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronFirewall> getAllNeutronFirewalls();
+
+    /**
+     * Applications call this interface method to add a Firewall object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronFirewall(NeutronFirewall input);
+
+    /**
+     * Applications call this interface method to remove a Neutron Firewall object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Firewall object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronFirewall(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Firewall object
+     *
+     * @param uuid
+     *            identifier of the Firewall object
+     * @param delta
+     *            OpenStackFirewall object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronFirewall(String uuid, NeutronFirewall delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the Firewall object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronFirewallInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallPolicyCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallPolicyCRUD.java
new file mode 100644 (file)
index 0000000..6993dfb
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallPolicy;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Firewall Policy objects
+ *
+ */
+
+public interface INeutronFirewallPolicyCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     *FirewallPolicy object exists
+     *
+     * @param uuid
+     *            UUID of the Firewall Policy object
+     * @return boolean
+     */
+
+    boolean neutronFirewallPolicyExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * FirewallPolicy object exists
+     *
+     * @param uuid
+     *            UUID of the Firewall Policy object
+     * @return {@link NeutronFirewallPolicy}
+     *          OpenStackFirewallPolicy class
+     */
+
+    NeutronFirewallPolicy getNeutronFirewallPolicy(String uuid);
+
+    /**
+     * Applications call this interface method to return all Firewall Policy objects
+     *
+     * @return List of OpenStack Firewall Policy objects
+     */
+
+    List<NeutronFirewallPolicy> getAllNeutronFirewallPolicies();
+
+    /**
+     * Applications call this interface method to add a Firewall Policy object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronFirewallPolicy(NeutronFirewallPolicy input);
+
+    /**
+     * Applications call this interface method to remove a Neutron FirewallPolicy object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Firewall Policy object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronFirewallPolicy(String uuid);
+
+    /**
+     * Applications call this interface method to edit a FirewallPolicy object
+     *
+     * @param uuid
+     *            identifier of the Firewall Policy object
+     * @param delta
+     *            OpenStackFirewallPolicy object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronFirewallPolicy(String uuid, NeutronFirewallPolicy delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the Firewall Policy object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronFirewallPolicyInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallRuleCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFirewallRuleCRUD.java
new file mode 100644 (file)
index 0000000..e3cce62
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallRule;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Firewall Rule objects
+ *
+ */
+
+public interface INeutronFirewallRuleCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     *FirewallRule object exists
+     *
+     * @param uuid
+     *            UUID of the Firewall Rule object
+     * @return boolean
+     */
+
+    boolean neutronFirewallRuleExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * FirewallRule object exists
+     *
+     * @param uuid
+     *            UUID of the Firewall Rule object
+     * @return {@link NeutronFirewallRule}
+     *          OpenStackFirewall Rule class
+     */
+
+    NeutronFirewallRule getNeutronFirewallRule(String uuid);
+
+    /**
+     * Applications call this interface method to return all Firewall Rule objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronFirewallRule> getAllNeutronFirewallRules();
+
+    /**
+     * Applications call this interface method to add a Firewall Rule object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronFirewallRule(NeutronFirewallRule input);
+
+    /**
+     * Applications call this interface method to remove a Neutron FirewallRule object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Firewall Rule object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronFirewallRule(String uuid);
+
+    /**
+     * Applications call this interface method to edit a FirewallRule object
+     *
+     * @param uuid
+     *            identifier of the Firewall Rule object
+     * @param delta
+     *            OpenStackFirewallRule object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronFirewallRule(String uuid, NeutronFirewallRule delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the Firewall Rule object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronFirewallRuleInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFloatingIPCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronFloatingIPCRUD.java
new file mode 100644 (file)
index 0000000..73ee3c4
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
+
+/**
+ * This interface defines the methods for CRUD of NB FloatingIP objects
+ *
+ */
+
+public interface INeutronFloatingIPCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * FloatingIP object exists
+     *
+     * @param uuid
+     *            UUID of the FloatingIP object
+     * @return boolean
+     */
+
+    boolean floatingIPExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * FloatingIP object exists
+     *
+     * @param uuid
+     *            UUID of the FloatingIP object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP}
+     *          OpenStack FloatingIP class
+     */
+
+    NeutronFloatingIP getFloatingIP(String uuid);
+
+    /**
+     * Applications call this interface method to return all FloatingIP objects
+     *
+     * @return a Set of OpenStackFloatingIPs objects
+     */
+
+    List<NeutronFloatingIP> getAllFloatingIPs();
+
+    /**
+     * Applications call this interface method to add a FloatingIP object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackFloatingIP object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addFloatingIP(NeutronFloatingIP input);
+
+    /**
+     * Applications call this interface method to remove a FloatingIP object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the FloatingIP object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeFloatingIP(String uuid);
+
+    /**
+     * Applications call this interface method to edit a FloatingIP object
+     *
+     * @param uuid
+     *            identifier of the FloatingIP object
+     * @param delta
+     *            OpenStackFloatingIP object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateFloatingIP(String uuid, NeutronFloatingIP delta);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerCRUD.java
new file mode 100644 (file)
index 0000000..7fc23c1
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack LoadBalancer objects
+ *
+ */
+
+public interface INeutronLoadBalancerCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     *LoadBalancer object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancer object
+     * @return boolean
+     */
+
+    boolean neutronLoadBalancerExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * LoadBalancer object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancer object
+     * @return {@link NeutronLoadBalancer}
+     *          OpenStackLoadBalancer class
+     */
+
+    NeutronLoadBalancer getNeutronLoadBalancer(String uuid);
+
+    /**
+     * Applications call this interface method to return all LoadBalancer objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronLoadBalancer> getAllNeutronLoadBalancers();
+
+    /**
+     * Applications call this interface method to add a LoadBalancer object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronLoadBalancer(NeutronLoadBalancer input);
+
+    /**
+     * Applications call this interface method to remove a Neutron LoadBalancer object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the LoadBalancer object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronLoadBalancer(String uuid);
+
+    /**
+     * Applications call this interface method to edit a LoadBalancer object
+     *
+     * @param uuid
+     *            identifier of the LoadBalancer object
+     * @param delta
+     *            OpenStackLoadBalancer object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronLoadBalancer(String uuid, NeutronLoadBalancer delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the LoadBalancer object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronLoadBalancerInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerHealthMonitorCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerHealthMonitorCRUD.java
new file mode 100644 (file)
index 0000000..98f781f
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerHealthMonitor;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack LoadBalancerHealthMonitor objects
+ *
+ */
+
+public interface INeutronLoadBalancerHealthMonitorCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     *LoadBalancerHealthMonitor object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancerHealthMonitor object
+     * @return boolean
+     */
+
+    boolean neutronLoadBalancerHealthMonitorExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * LoadBalancerHealthMonitor object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancerHealthMonitor object
+     * @return {@link NeutronLoadBalancerHealthMonitor}
+     *          OpenStackLoadBalancerHealthMonitor class
+     */
+
+    NeutronLoadBalancerHealthMonitor getNeutronLoadBalancerHealthMonitor(String uuid);
+
+    /**
+     * Applications call this interface method to return all LoadBalancerHealthMonitor objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronLoadBalancerHealthMonitor> getAllNeutronLoadBalancerHealthMonitors();
+
+    /**
+     * Applications call this interface method to add a LoadBalancerHealthMonitor object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronLoadBalancerHealthMonitor(NeutronLoadBalancerHealthMonitor input);
+
+    /**
+     * Applications call this interface method to remove a Neutron LoadBalancerHealthMonitor object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the LoadBalancerHealthMonitor object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronLoadBalancerHealthMonitor(String uuid);
+
+    /**
+     * Applications call this interface method to edit a LoadBalancerHealthMonitor object
+     *
+     * @param uuid
+     *            identifier of the LoadBalancerHealthMonitor object
+     * @param delta
+     *            OpenStackLoadBalancerHealthMonitor object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronLoadBalancerHealthMonitor(String uuid, NeutronLoadBalancerHealthMonitor delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the LoadBalancerHealthMonitor object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronLoadBalancerHealthMonitorInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerListenerCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerListenerCRUD.java
new file mode 100644 (file)
index 0000000..b771368
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerListener;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack LoadBalancerListener objects
+ *
+ */
+
+public interface INeutronLoadBalancerListenerCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     *LoadBalancerListener object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancerListener object
+     * @return boolean
+     */
+
+    boolean neutronLoadBalancerListenerExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * LoadBalancerListener object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancerListener object
+     * @return {@link NeutronLoadBalancerListener}
+     *          OpenStackLoadBalancerListener class
+     */
+
+    NeutronLoadBalancerListener getNeutronLoadBalancerListener(String uuid);
+
+    /**
+     * Applications call this interface method to return all LoadBalancerListener objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronLoadBalancerListener> getAllNeutronLoadBalancerListeners();
+
+    /**
+     * Applications call this interface method to add a LoadBalancerListener object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronLoadBalancerListener(NeutronLoadBalancerListener input);
+
+    /**
+     * Applications call this interface method to remove a Neutron LoadBalancerListener object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the LoadBalancerListener object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronLoadBalancerListener(String uuid);
+
+    /**
+     * Applications call this interface method to edit a LoadBalancerListener object
+     *
+     * @param uuid
+     *            identifier of the LoadBalancerListener object
+     * @param delta
+     *            OpenStackLoadBalancerListener object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronLoadBalancerListener(String uuid, NeutronLoadBalancerListener delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the LoadBalancerListener object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronLoadBalancerListenerInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerPoolCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerPoolCRUD.java
new file mode 100644 (file)
index 0000000..93185b3
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack LoadBalancerPool objects
+ *
+ */
+
+public interface INeutronLoadBalancerPoolCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     *LoadBalancerPool object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancerPool object
+     * @return boolean
+     */
+
+    boolean neutronLoadBalancerPoolExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * LoadBalancerPool object exists
+     *
+     * @param uuid
+     *            UUID of the LoadBalancerPool object
+     * @return {@link NeutronLoadBalancerPool}
+     *          OpenStackLoadBalancerPool class
+     */
+
+    NeutronLoadBalancerPool getNeutronLoadBalancerPool(String uuid);
+
+    /**
+     * Applications call this interface method to return all LoadBalancerPool objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronLoadBalancerPool> getAllNeutronLoadBalancerPools();
+
+    /**
+     * Applications call this interface method to add a LoadBalancerPool object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronLoadBalancerPool(NeutronLoadBalancerPool input);
+
+    /**
+     * Applications call this interface method to remove a Neutron LoadBalancerPool object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the LoadBalancerPool object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronLoadBalancerPool(String uuid);
+
+    /**
+     * Applications call this interface method to edit a LoadBalancerPool object
+     *
+     * @param uuid
+     *            identifier of the LoadBalancerPool object
+     * @param delta
+     *            OpenStackLoadBalancerPool object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronLoadBalancerPool(String uuid, NeutronLoadBalancerPool delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the LoadBalancerPool object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronLoadBalancerPoolInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerPoolMemberCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronLoadBalancerPoolMemberCRUD.java
new file mode 100644 (file)
index 0000000..a0b47f2
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+
+public interface INeutronLoadBalancerPoolMemberCRUD {
+
+    /**
+     * Applications call this interface method to determine if a particular
+     *NeutronLoadBalancerPoolMember object exists
+     *
+     * @param uuid
+     *            UUID of the NeutronLoadBalancerPoolMember object
+     * @return boolean
+     */
+
+    boolean neutronLoadBalancerPoolMemberExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * NeutronLoadBalancerPoolMember object exists
+     *
+     * @param uuid
+     *            UUID of the NeutronLoadBalancerPoolMember object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember}
+     *          OpenStackNeutronLoadBalancerPoolMember class
+     */
+
+    NeutronLoadBalancerPoolMember getNeutronLoadBalancerPoolMember(String uuid);
+
+    /**
+     * Applications call this interface method to return all NeutronLoadBalancerPoolMember objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronLoadBalancerPoolMember> getAllNeutronLoadBalancerPoolMembers();
+
+    /**
+     * Applications call this interface method to add a NeutronLoadBalancerPoolMember object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember input);
+
+    /**
+     * Applications call this interface method to remove a Neutron NeutronLoadBalancerPoolMember object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the NeutronLoadBalancerPoolMember object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronLoadBalancerPoolMember(String uuid);
+
+    /**
+     * Applications call this interface method to edit a NeutronLoadBalancerPoolMember object
+     *
+     * @param uuid
+     *            identifier of the NeutronLoadBalancerPoolMember object
+     * @param delta
+     *            OpenStackNeutronLoadBalancerPoolMember object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronLoadBalancerPoolMember(String uuid, NeutronLoadBalancerPoolMember delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid
+     *            identifier of the NeutronLoadBalancerPoolMember object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronLoadBalancerPoolMemberInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronNetworkCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronNetworkCRUD.java
new file mode 100644 (file)
index 0000000..8714666
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+
+/**
+ * This interface defines the methods for CRUD of NB network objects
+ *
+ */
+
+public interface INeutronNetworkCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Network object exists
+     *
+     * @param uuid
+     *            UUID of the Network object
+     * @return boolean
+     */
+
+    boolean networkExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Network object exists
+     *
+     * @param uuid
+     *            UUID of the Network object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork}
+     *          OpenStack Network class
+     */
+
+    NeutronNetwork getNetwork(String uuid);
+
+    /**
+     * Applications call this interface method to return all Network objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    List<NeutronNetwork> getAllNetworks();
+
+    /**
+     * Applications call this interface method to add a Network object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNetwork(NeutronNetwork input);
+
+    /**
+     * Applications call this interface method to remove a Network object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the network object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNetwork(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Network object
+     *
+     * @param uuid
+     *            identifier of the network object
+     * @param delta
+     *            OpenStackNetwork object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNetwork(String uuid, NeutronNetwork delta);
+
+    /**
+     * Applications call this interface method to determine if a Network object
+     * is use
+     *
+     * @param netUUID
+     *            identifier of the network object
+     *
+     * @return boolean on whether the network is in use or not
+     */
+
+    boolean networkInUse(String netUUID);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronPortCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronPortCRUD.java
new file mode 100644 (file)
index 0000000..f7d5271
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+
+/**
+ * This interface defines the methods for CRUD of NB Port objects
+ *
+ */
+
+public interface INeutronPortCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Port object exists
+     *
+     * @param uuid
+     *            UUID of the Port object
+     * @return boolean
+     */
+
+    boolean portExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Port object exists
+     *
+     * @param uuid
+     *            UUID of the Port object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort}
+     *          OpenStack Port class
+     */
+
+    NeutronPort getPort(String uuid);
+
+    /**
+     * Applications call this interface method to return all Port objects
+     *
+     * @return List of OpenStackPorts objects
+     */
+
+    List<NeutronPort> getAllPorts();
+
+    /**
+     * Applications call this interface method to add a Port object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackPort object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addPort(NeutronPort input);
+
+    /**
+     * Applications call this interface method to remove a Port object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Port object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removePort(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Port object
+     *
+     * @param uuid
+     *            identifier of the Port object
+     * @param delta
+     *            OpenStackPort object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updatePort(String uuid, NeutronPort delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param macAddress
+     *            mac Address to be tested
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     *
+     * @deprecated - will be removed in Boron
+     */
+
+    boolean macInUse(String macAddress);
+
+    /**
+     * Applications call this interface method to retrieve the port associated with
+     * the gateway address of a subnet
+     *
+     * @param subnetUUID
+     *            identifier of the subnet
+     * @return OpenStackPorts object if the port exists and null if it does not
+     *
+     * @deprecated - will be removed in Boron
+     */
+
+    NeutronPort getGatewayPort(String subnetUUID);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronRouterCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronRouterCRUD.java
new file mode 100644 (file)
index 0000000..c2fcc3c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
+
+/**
+ * This interface defines the methods for CRUD of NB Router objects
+ *
+ */
+
+public interface INeutronRouterCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Router object exists
+     *
+     * @param uuid
+     *            UUID of the Router object
+     * @return boolean
+     */
+
+    boolean routerExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Router object exists
+     *
+     * @param uuid
+     *            UUID of the Router object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter}
+     *          OpenStack Router class
+     */
+
+    NeutronRouter getRouter(String uuid);
+
+    /**
+     * Applications call this interface method to return all Router objects
+     *
+     * @return List of OpenStackRouters objects
+     */
+
+    List<NeutronRouter> getAllRouters();
+
+    /**
+     * Applications call this interface method to add a Router object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackRouter object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addRouter(NeutronRouter input);
+
+    /**
+     * Applications call this interface method to remove a Router object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Router object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeRouter(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Router object
+     *
+     * @param uuid
+     *            identifier of the Router object
+     * @param delta
+     *            OpenStackRouter object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateRouter(String uuid, NeutronRouter delta);
+
+    /**
+     * Applications call this interface method to check if a router is in use
+     *
+     * @param routerUUID
+     *            identifier of the Router object
+     * @return boolean on whether the router is in use or not
+     */
+
+    boolean routerInUse(String routerUUID);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSecurityGroupCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSecurityGroupCRUD.java
new file mode 100644 (file)
index 0000000..0fa139e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Security Group objects
+ */
+
+public interface INeutronSecurityGroupCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Security Group object exists
+     *
+     * @param uuid UUID of the Security Group object
+     * @return boolean
+     */
+
+    boolean neutronSecurityGroupExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Security Group object exists
+     *
+     * @param uuid UUID of the Security Group object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup}
+     * OpenStack Security Group class
+     */
+
+    NeutronSecurityGroup getNeutronSecurityGroup(String uuid);
+
+    /**
+     * Applications call this interface method to return all Security Group objects
+     *
+     * @return List of OpenStackSecurity Groups objects
+     */
+
+    List<NeutronSecurityGroup> getAllNeutronSecurityGroups();
+
+    /**
+     * Applications call this interface method to add a Security Group object to the
+     * concurrent map
+     *
+     * @param input OpenStackSecurity Group object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronSecurityGroup(NeutronSecurityGroup input);
+
+    /**
+     * Applications call this interface method to remove a Neutron Security Group object to the
+     * concurrent map
+     *
+     * @param uuid identifier for the security group object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronSecurityGroup(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Security Group object
+     *
+     * @param uuid  identifier of the security group object
+     * @param delta OpenStackSecurity Group object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid identifier of the security group object
+     * @return boolean on whether the Security Groups is already in use
+     */
+
+    boolean neutronSecurityGroupInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSecurityRuleCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSecurityRuleCRUD.java
new file mode 100644 (file)
index 0000000..42fbadc
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Security Rule objects
+ */
+
+public interface INeutronSecurityRuleCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Security Rule object exists
+     *
+     * @param uuid UUID of theSecurity Rule object
+     * @return boolean
+     */
+
+    boolean neutronSecurityRuleExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Security Rule object exists
+     *
+     * @param uuid UUID of the security rule object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule}
+     * OpenStackSecurity Rule class
+     */
+
+    NeutronSecurityRule getNeutronSecurityRule(String uuid);
+
+    /**
+     * Applications call this interface method to return all Security Rule objects
+     *
+     * @return List of OpenStack SecurityRules objects
+     */
+
+    List<NeutronSecurityRule> getAllNeutronSecurityRules();
+
+    /**
+     * Applications call this interface method to add a Security Rule object to the
+     * concurrent map
+     *
+     * @param input OpenStack security rule object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addNeutronSecurityRule(NeutronSecurityRule input);
+
+    /**
+     * Applications call this interface method to remove a Neutron Security Rule object to the
+     * concurrent map
+     *
+     * @param uuid identifier for the security rule object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeNeutronSecurityRule(String uuid);
+
+    /**
+     * Applications call this interface method to edit aSecurity Rule object
+     *
+     * @param uuid  identifier of the security rule object
+     * @param delta OpenStackSecurity Rule object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid identifier of the security rule object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    boolean neutronSecurityRuleInUse(String uuid);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSubnetCRUD.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/INeutronSubnetCRUD.java
new file mode 100644 (file)
index 0000000..b96646a
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud;
+
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
+
+/**
+ * This interface defines the methods for CRUD of NB Subnet objects
+ *
+ */
+
+public interface INeutronSubnetCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Subnet object exists
+     *
+     * @param uuid
+     *            UUID of the Subnet object
+     * @return boolean
+     */
+
+    boolean subnetExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Subnet object exists
+     *
+     * @param uuid
+     *            UUID of the Subnet object
+     * @return {@link org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet}
+     *          OpenStack Subnet class
+     */
+
+    NeutronSubnet getSubnet(String uuid);
+
+    /**
+     * Applications call this interface method to return all Subnet objects
+     *
+     * @return List of OpenStackSubnets objects
+     */
+
+    List<NeutronSubnet> getAllSubnets();
+
+    /**
+     * Applications call this interface method to add a Subnet object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackSubnet object
+     * @return boolean on whether the object was added or not
+     */
+
+    boolean addSubnet(NeutronSubnet input);
+
+    /**
+     * Applications call this interface method to remove a Subnet object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Subnet object
+     * @return boolean on whether the object was removed or not
+     */
+
+    boolean removeSubnet(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Subnet object
+     *
+     * @param uuid
+     *            identifier of the Subnet object
+     * @param delta
+     *            OpenStackSubnet object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    boolean updateSubnet(String uuid, NeutronSubnet delta);
+
+    /**
+     * Applications call this interface method to determine if a Subnet object
+     * is use
+     *
+     * @param subnetUUID
+     *            identifier of the subnet object
+     *
+     * @return boolean on whether the subnet is in use or not
+     *
+     * @deprecated - will be removed in Boron
+     */
+
+    boolean subnetInUse(String subnetUUID);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/NeutronCRUDInterfaces.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/NeutronCRUDInterfaces.java
new file mode 100644 (file)
index 0000000..4f61e51
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronCRUDInterfaces {
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(NeutronCRUDInterfaces.class);
+
+    private INeutronNetworkCRUD networkInterface;
+    private INeutronSubnetCRUD subnetInterface;
+    private INeutronPortCRUD portInterface;
+    private INeutronRouterCRUD routerInterface;
+    private INeutronFloatingIPCRUD fipInterface;
+    private INeutronSecurityGroupCRUD sgInterface;
+    private INeutronSecurityRuleCRUD srInterface;
+    private INeutronFirewallCRUD fwInterface;
+    private INeutronFirewallPolicyCRUD fwpInterface;
+    private INeutronFirewallRuleCRUD fwrInterface;
+    private INeutronLoadBalancerCRUD lbInterface;
+    private INeutronLoadBalancerPoolCRUD lbpInterface;
+    private INeutronLoadBalancerListenerCRUD lblInterface;
+    private INeutronLoadBalancerHealthMonitorCRUD lbhmInterface;
+    private INeutronLoadBalancerPoolMemberCRUD lbpmInterface;
+    public NeutronCRUDInterfaces() {
+    }
+
+    public INeutronNetworkCRUD getNetworkInterface() {
+        return networkInterface;
+    }
+
+    public INeutronSubnetCRUD getSubnetInterface() {
+        return subnetInterface;
+    }
+
+    public INeutronPortCRUD getPortInterface() {
+        return portInterface;
+    }
+
+    public INeutronRouterCRUD getRouterInterface() {
+        return routerInterface;
+    }
+
+    public INeutronFloatingIPCRUD getFloatingIPInterface() {
+        return fipInterface;
+    }
+
+    public INeutronSecurityGroupCRUD getSecurityGroupInterface() {
+        return sgInterface;
+    }
+
+    public INeutronSecurityRuleCRUD getSecurityRuleInterface() {
+        return srInterface;
+    }
+
+    public INeutronFirewallCRUD getFirewallInterface() {
+        return fwInterface;
+    }
+
+    public INeutronFirewallPolicyCRUD getFirewallPolicyInterface() {
+        return fwpInterface;
+    }
+
+    public INeutronFirewallRuleCRUD getFirewallRuleInterface() {
+        return fwrInterface;
+    }
+
+    public INeutronLoadBalancerCRUD getLoadBalancerInterface() {
+        return lbInterface;
+    }
+
+    public INeutronLoadBalancerPoolCRUD getLoadBalancerPoolInterface() {
+        return lbpInterface;
+    }
+
+    public INeutronLoadBalancerListenerCRUD getLoadBalancerListenerInterface() {
+        return lblInterface;
+    }
+
+    public INeutronLoadBalancerHealthMonitorCRUD getLoadBalancerHealthMonitorInterface() {
+        return lbhmInterface;
+    }
+
+    public INeutronLoadBalancerPoolMemberCRUD getLoadBalancerPoolMemberInterface() {
+        return lbpmInterface;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronNetworkCRUD(Object obj) {
+        networkInterface = (INeutronNetworkCRUD) getInstances(INeutronNetworkCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronSubnetCRUD(Object obj) {
+        subnetInterface = (INeutronSubnetCRUD) getInstances(INeutronSubnetCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronPortCRUD(Object obj) {
+        portInterface = (INeutronPortCRUD) getInstances(INeutronPortCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronRouterCRUD(Object obj) {
+        routerInterface = (INeutronRouterCRUD) getInstances(INeutronRouterCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronFloatingIPCRUD(Object obj) {
+        fipInterface = (INeutronFloatingIPCRUD) getInstances(INeutronFloatingIPCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronSecurityGroupCRUD(Object obj) {
+        sgInterface = (INeutronSecurityGroupCRUD) getInstances(INeutronSecurityGroupCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronSecurityRuleCRUD(Object obj) {
+        srInterface = (INeutronSecurityRuleCRUD) getInstances(INeutronSecurityRuleCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronFirewallCRUD(Object obj) {
+        fwInterface = (INeutronFirewallCRUD) getInstances(INeutronFirewallCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronFirewallPolicyCRUD(Object obj) {
+        fwpInterface = (INeutronFirewallPolicyCRUD) getInstances(INeutronFirewallPolicyCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronFirewallRuleCRUD(Object obj) {
+        fwrInterface = (INeutronFirewallRuleCRUD) getInstances(INeutronFirewallRuleCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronLoadBalancerCRUD(Object obj) {
+        lbInterface = (INeutronLoadBalancerCRUD) getInstances(INeutronLoadBalancerCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronLoadBalancerPoolCRUD(Object obj) {
+        lbpInterface = (INeutronLoadBalancerPoolCRUD) getInstances(INeutronLoadBalancerPoolCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronLoadBalancerListenerCRUD(Object obj) {
+        lblInterface = (INeutronLoadBalancerListenerCRUD) getInstances(INeutronLoadBalancerListenerCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronLoadBalancerHealthMonitorCRUD(Object obj) {
+        lbhmInterface = (INeutronLoadBalancerHealthMonitorCRUD) getInstances(INeutronLoadBalancerHealthMonitorCRUD.class, obj);
+        return this;
+    }
+
+    public NeutronCRUDInterfaces fetchINeutronLoadBalancerPoolMemberCRUD(Object obj) {
+        lbpmInterface = (INeutronLoadBalancerPoolMemberCRUD) getInstances(INeutronLoadBalancerPoolMemberCRUD.class, obj);
+        return this;
+    }
+
+    public Object getInstances(Class<?> clazz, Object bundle) {
+        try {
+            BundleContext bCtx = FrameworkUtil.getBundle(bundle.getClass()).getBundleContext();
+
+            ServiceReference<?>[] services = null;
+            services = bCtx.getServiceReferences(clazz.getName(), null);
+            if (services != null) {
+                return bCtx.getService(services[0]);
+            }
+        } catch (Exception e) {
+            LOGGER.error("Error in getInstances", e);
+        }
+        return null;
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/AbstractNeutronInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/AbstractNeutronInterface.java
new file mode 100644 (file)
index 0000000..841e6bf
--- /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.openstack.netvirt.translator.crud.impl;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.ExecutionException;
+
+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;
+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.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.INeutronObject;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+
+
+public abstract class AbstractNeutronInterface<T extends DataObject, S extends INeutronObject> implements AutoCloseable {
+    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNeutronInterface.class);
+    private static final int DEDASHED_UUID_LENGTH = 32;
+    private static final int DEDASHED_UUID_START = 0;
+    private static final int DEDASHED_UUID_DIV1 = 8;
+    private static final int DEDASHED_UUID_DIV2 = 12;
+    private static final int DEDASHED_UUID_DIV3 = 16;
+    private static final int DEDASHED_UUID_DIV4 = 20;
+
+    private DataBroker db;
+
+    AbstractNeutronInterface(ProviderContext providerContext) {
+        this.db = providerContext.getSALService(DataBroker.class);
+    }
+
+    public DataBroker getDataBroker() {
+        return db;
+    }
+
+    protected abstract InstanceIdentifier<T> createInstanceIdentifier(T item);
+
+    protected abstract T toMd(S neutronObject);
+
+    protected abstract T toMd(String uuid);
+
+    protected <B extends org.opendaylight.yangtools.yang.binding.DataObject> B readMd(InstanceIdentifier<B> path) {
+        B result = null;
+        final ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction();
+        CheckedFuture<Optional<B>, ReadFailedException> future = transaction.read(LogicalDatastoreType.CONFIGURATION, path);
+        if (future != null) {
+            try {
+                result = future.checkedGet().orNull();
+            } catch (ReadFailedException e) {
+                LOGGER.warn("Failed to read {}", path, e);
+            }
+        }
+        transaction.close();
+        return result;
+    }
+
+    protected boolean addMd(S neutronObject) {
+        // TODO think about adding existence logic
+        return updateMd(neutronObject);
+    }
+
+    protected boolean updateMd(S neutronObject) {
+        WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
+        T item = toMd(neutronObject);
+        InstanceIdentifier<T> iid = createInstanceIdentifier(item);
+        transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item,true);
+        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
+        try {
+            future.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOGGER.warn("Transation failed ",e);
+            return false;
+        }
+        return true;
+    }
+
+    protected boolean removeMd(T item) {
+        WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
+        InstanceIdentifier<T> iid = createInstanceIdentifier(item);
+        transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
+        CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
+        try {
+            future.get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOGGER.warn("Transation failed ",e);
+            return false;
+        }
+        return true;
+    }
+
+    protected Uuid toUuid(String uuid) {
+        Preconditions.checkNotNull(uuid);
+        Uuid result;
+        try {
+            result = new Uuid(uuid);
+        } catch(IllegalArgumentException e) {
+            // OK... someone didn't follow RFC 4122... lets try this the hard way
+            String dedashed = uuid.replace("-", "");
+            if(dedashed.length() == DEDASHED_UUID_LENGTH) {
+                String redashed = dedashed.substring(DEDASHED_UUID_START, DEDASHED_UUID_DIV1)
+                        + "-"
+                        + dedashed.substring(DEDASHED_UUID_DIV1, DEDASHED_UUID_DIV2)
+                        + "-"
+                        + dedashed.substring(DEDASHED_UUID_DIV2, DEDASHED_UUID_DIV3)
+                        + "-"
+                        + dedashed.substring(DEDASHED_UUID_DIV3, DEDASHED_UUID_DIV4)
+                        + "-"
+                        + dedashed.substring(DEDASHED_UUID_DIV4, DEDASHED_UUID_LENGTH);
+                result = new Uuid(redashed);
+            } else {
+                throw e;
+            }
+        }
+        return result;
+    }
+
+    // this method uses reflection to update an object from it's delta.
+
+    protected boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for(Method toMethod: methods){
+            if(toMethod.getDeclaringClass().equals(target.getClass())
+                    && toMethod.getName().startsWith("set")){
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[])null);
+                    if(value != null){
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    LOGGER.error("Error in overwrite", e);
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void close() throws Exception {
+        // TODO Auto-generated method stub
+
+    }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallInterface.java
new file mode 100644 (file)
index 0000000..485eb8b
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.INeutronObject;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewall;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronFirewallCRUD;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class NeutronFirewallInterface extends AbstractNeutronInterface implements INeutronFirewallCRUD {
+
+    NeutronFirewallInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronFirewallInterface neutronFirewallInterface = new NeutronFirewallInterface(providerContext);
+        ServiceRegistration<INeutronFirewallCRUD> neutronFirewallInterfaceRegistration = context.registerService(INeutronFirewallCRUD.class, neutronFirewallInterface, null);
+        if(neutronFirewallInterfaceRegistration != null) {
+            registrations.add(neutronFirewallInterfaceRegistration);
+        }
+    }
+
+    @Override
+    public boolean neutronFirewallExists(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public NeutronFirewall getNeutronFirewall(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<NeutronFirewall> getAllNeutronFirewalls() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean addNeutronFirewall(NeutronFirewall input) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean removeNeutronFirewall(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean updateNeutronFirewall(String uuid, NeutronFirewall delta) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean neutronFirewallInUse(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected InstanceIdentifier createInstanceIdentifier(DataObject item) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected DataObject toMd(INeutronObject neutronObject) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected DataObject toMd(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallPolicyInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallPolicyInterface.java
new file mode 100644 (file)
index 0000000..514a1dc
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.INeutronObject;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallPolicy;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronFirewallPolicyCRUD;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ */
+
+public class NeutronFirewallPolicyInterface extends AbstractNeutronInterface implements INeutronFirewallPolicyCRUD {
+
+    NeutronFirewallPolicyInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronFirewallPolicyExists(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public NeutronFirewallPolicy getNeutronFirewallPolicy(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<NeutronFirewallPolicy> getAllNeutronFirewallPolicies() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean addNeutronFirewallPolicy(NeutronFirewallPolicy input) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean removeNeutronFirewallPolicy(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean updateNeutronFirewallPolicy(String uuid,
+            NeutronFirewallPolicy delta) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean neutronFirewallPolicyInUse(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected InstanceIdentifier createInstanceIdentifier(DataObject item) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected DataObject toMd(INeutronObject neutronObject) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected DataObject toMd(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronFirewallPolicyInterface neutronFirewallPolicyInterface = new NeutronFirewallPolicyInterface(providerContext);
+        ServiceRegistration<INeutronFirewallPolicyCRUD> neutronFirewallPolicyInterfaceRegistration = context.registerService(INeutronFirewallPolicyCRUD.class, neutronFirewallPolicyInterface, null);
+        if(neutronFirewallPolicyInterfaceRegistration != null) {
+            registrations.add(neutronFirewallPolicyInterfaceRegistration);
+        }
+    }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallRuleInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFirewallRuleInterface.java
new file mode 100644 (file)
index 0000000..f056d18
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.INeutronObject;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronFirewallRuleCRUD;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class NeutronFirewallRuleInterface extends AbstractNeutronInterface implements INeutronFirewallRuleCRUD {
+
+    NeutronFirewallRuleInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronFirewallRuleExists(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public NeutronFirewallRule getNeutronFirewallRule(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<NeutronFirewallRule> getAllNeutronFirewallRules() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean addNeutronFirewallRule(NeutronFirewallRule input) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean removeNeutronFirewallRule(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean updateNeutronFirewallRule(String uuid,
+            NeutronFirewallRule delta) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean neutronFirewallRuleInUse(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected InstanceIdentifier createInstanceIdentifier(DataObject item) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected DataObject toMd(INeutronObject neutronObject) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected DataObject toMd(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronFirewallRuleInterface neutronFirewallRuleInterface = new NeutronFirewallRuleInterface(providerContext);
+        ServiceRegistration<INeutronFirewallRuleCRUD> neutronFirewallRuleInterfaceRegistration = context.registerService(INeutronFirewallRuleCRUD.class, neutronFirewallRuleInterface, null);
+        if(neutronFirewallRuleInterfaceRegistration != null) {
+            registrations.add(neutronFirewallRuleInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFloatingIPInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronFloatingIPInterface.java
new file mode 100644 (file)
index 0000000..c417e6e
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronFloatingIPCRUD;
+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.neutron.l3.rev150712.floatingips.attributes.Floatingips;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.floatingips.attributes.floatingips.Floatingip;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.floatingips.attributes.floatingips.FloatingipBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronFloatingIPInterface extends AbstractNeutronInterface<Floatingip, NeutronFloatingIP> implements INeutronFloatingIPCRUD {
+    private static final Logger LOGGER = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);
+
+    NeutronFloatingIPInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    // IfNBFloatingIPCRUD interface methods
+
+    @Override
+    public boolean floatingIPExists(String uuid) {
+        Floatingip fip = readMd(createInstanceIdentifier(toMd(uuid)));
+        return (fip != null);
+    }
+
+    @Override
+    public NeutronFloatingIP getFloatingIP(String uuid) {
+        Floatingip fip = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (fip == null) {
+            return null;
+        }
+        return fromMd(fip);
+    }
+
+    @Override
+    public List<NeutronFloatingIP> getAllFloatingIPs() {
+        Set<NeutronFloatingIP> allIPs = new HashSet<>();
+        Floatingips fips = readMd(createInstanceIdentifier());
+        if (fips != null) {
+            for (Floatingip fip: fips.getFloatingip()) {
+                allIPs.add(fromMd(fip));
+            }
+        }
+        LOGGER.debug("Exiting getAllFloatingIPs, Found {} FloatingIPs", allIPs.size());
+        List<NeutronFloatingIP> ans = new ArrayList<>();
+        ans.addAll(allIPs);
+        return ans;
+    }
+
+    @Override
+    public boolean addFloatingIP(NeutronFloatingIP input) {
+        if (floatingIPExists(input.getID())) {
+            return false;
+        }
+        return addMd(input);
+    }
+
+    @Override
+    public boolean removeFloatingIP(String uuid) {
+        NeutronFloatingIP fip = getFloatingIP(uuid);
+        if (fip == null) {
+            return false;
+        }
+        return removeMd(toMd(uuid));
+    }
+
+    @Override
+    public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {
+        NeutronFloatingIP target = getFloatingIP(uuid);
+        if (target == null) {
+            return false;
+        }
+        delta.setPortUUID(target.getPortUUID());
+        delta.setFixedIPAddress(target.getFixedIPAddress());
+        return updateMd(delta);
+    }
+
+    @Override
+    protected Floatingip toMd(String uuid) {
+        FloatingipBuilder floatingipBuilder = new FloatingipBuilder();
+        floatingipBuilder.setUuid(toUuid(uuid));
+        return floatingipBuilder.build();
+    }
+
+    @Override
+    protected Floatingip toMd(NeutronFloatingIP floatingIp) {
+        FloatingipBuilder floatingipBuilder = new FloatingipBuilder();
+        if (floatingIp.getFixedIPAddress() != null) {
+            floatingipBuilder.setFixedIpAddress(new IpAddress(floatingIp.getFixedIPAddress().toCharArray()));
+        }
+        if(floatingIp.getFloatingIPAddress() != null) {
+            floatingipBuilder.setFloatingIpAddress(new IpAddress(floatingIp.getFloatingIPAddress().toCharArray()));
+        }
+        if (floatingIp.getFloatingNetworkUUID() != null) {
+            floatingipBuilder.setFloatingNetworkId(toUuid(floatingIp.getFloatingNetworkUUID()));
+        }
+        if (floatingIp.getPortUUID() != null) {
+            floatingipBuilder.setPortId(toUuid(floatingIp.getPortUUID()));
+        }
+        if (floatingIp.getRouterUUID() != null) {
+            floatingipBuilder.setRouterId(toUuid(floatingIp.getRouterUUID()));
+        }
+        if (floatingIp.getStatus() != null) {
+            floatingipBuilder.setStatus(floatingIp.getStatus());
+        }
+        if (floatingIp.getTenantUUID() != null) {
+            floatingipBuilder.setTenantId(toUuid(floatingIp.getTenantUUID()));
+        }
+        if (floatingIp.getID() != null) {
+            floatingipBuilder.setUuid(toUuid(floatingIp.getID()));
+        }
+        else {
+            LOGGER.warn("Attempting to write neutron floating IP without UUID");
+        }
+        return floatingipBuilder.build();
+    }
+
+    protected NeutronFloatingIP fromMd(Floatingip fip) {
+        NeutronFloatingIP result = new NeutronFloatingIP();
+        result.setID(String.valueOf(fip.getUuid().getValue()));
+        if (fip.getFloatingNetworkId() != null) {
+            result.setFloatingNetworkUUID(String.valueOf(fip.getFloatingNetworkId().getValue()));
+        }
+        if (fip.getPortId() != null) {
+            result.setPortUUID(String.valueOf(fip.getPortId().getValue()));
+        }
+        if (fip.getFixedIpAddress() != null ) {
+            result.setFixedIPAddress(String.valueOf(fip.getFixedIpAddress().getValue()));
+        }
+        if (fip.getFloatingIpAddress() != null) {
+            result.setFloatingIPAddress(String.valueOf(fip.getFloatingIpAddress().getValue()));
+        }
+        if (fip.getTenantId() != null) {
+            result.setTenantUUID(String.valueOf(fip.getTenantId().getValue()));
+        }
+        if (fip.getRouterId() != null) {
+            result.setRouterUUID(String.valueOf(fip.getRouterId().getValue()));
+        }
+        result.setStatus(fip.getStatus());
+        return result;
+    }
+
+    @Override
+    protected InstanceIdentifier<Floatingip> createInstanceIdentifier(
+            Floatingip item) {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Floatingips.class)
+                .child(Floatingip.class,item.getKey());
+    }
+
+    protected InstanceIdentifier<Floatingips> createInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Floatingips.class);
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronFloatingIPInterface neutronFloatingIPInterface = new NeutronFloatingIPInterface(providerContext);
+        ServiceRegistration<INeutronFloatingIPCRUD> neutronFloatingIPInterfaceRegistration = context.registerService(INeutronFloatingIPCRUD.class, neutronFloatingIPInterface, null);
+        if (neutronFloatingIPInterfaceRegistration != null) {
+            registrations.add(neutronFloatingIPInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerHealthMonitorInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerHealthMonitorInterface.java
new file mode 100644 (file)
index 0000000..8f6cf29
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerHealthMonitor;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerHealthMonitorCRUD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.Healthmonitors;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class NeutronLoadBalancerHealthMonitorInterface extends AbstractNeutronInterface<Healthmonitors, NeutronLoadBalancerHealthMonitor> implements INeutronLoadBalancerHealthMonitorCRUD {
+
+    NeutronLoadBalancerHealthMonitorInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronLoadBalancerHealthMonitorExists(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public NeutronLoadBalancerHealthMonitor getNeutronLoadBalancerHealthMonitor(
+            String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<NeutronLoadBalancerHealthMonitor> getAllNeutronLoadBalancerHealthMonitors() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean addNeutronLoadBalancerHealthMonitor(
+            NeutronLoadBalancerHealthMonitor input) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean removeNeutronLoadBalancerHealthMonitor(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean updateNeutronLoadBalancerHealthMonitor(String uuid,
+            NeutronLoadBalancerHealthMonitor delta) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean neutronLoadBalancerHealthMonitorInUse(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected InstanceIdentifier<Healthmonitors> createInstanceIdentifier(
+            Healthmonitors item) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Healthmonitors toMd(NeutronLoadBalancerHealthMonitor neutronObject) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Healthmonitors toMd(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronLoadBalancerHealthMonitorInterface neutronLoadBalancerHealthMonitorInterface = new NeutronLoadBalancerHealthMonitorInterface(providerContext);
+        ServiceRegistration<INeutronLoadBalancerHealthMonitorCRUD> neutronLoadBalancerHealthMonitorInterfaceRegistration = context.registerService(INeutronLoadBalancerHealthMonitorCRUD.class, neutronLoadBalancerHealthMonitorInterface, null);
+        if(neutronLoadBalancerHealthMonitorInterfaceRegistration != null) {
+            registrations.add(neutronLoadBalancerHealthMonitorInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerInterface.java
new file mode 100644 (file)
index 0000000..058607d
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerCRUD;
+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.neutron.lbaasv2.rev150712.lbaas.attributes.Loadbalancers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.loadbalancers.Loadbalancer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.loadbalancers.LoadbalancerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO: Migrate this to consume the MD-SAL data store, so that it can read all the data from data store.
+ * No need to worry about the write/update related methods here. OVSDB net-virt will use these CRUD Interface
+ * only for reading. We will cleanup these interface/methods later.
+ */
+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<>();
+
+
+    NeutronLoadBalancerInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronLoadBalancerExists(String uuid) {
+        return loadBalancerDB.containsKey(uuid);
+    }
+
+    @Override
+    public NeutronLoadBalancer getNeutronLoadBalancer(String uuid) {
+        if (!neutronLoadBalancerExists(uuid)) {
+            LOGGER.debug("No LoadBalancer Have Been Defined");
+            return null;
+        }
+        return loadBalancerDB.get(uuid);
+    }
+
+    @Override
+    public List<NeutronLoadBalancer> getAllNeutronLoadBalancers() {
+        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<>();
+        ans.addAll(allLoadBalancers);
+        return ans;
+    }
+
+    @Override
+    public boolean addNeutronLoadBalancer(NeutronLoadBalancer input) {
+        if (neutronLoadBalancerExists(input.getID())) {
+            return false;
+        }
+        loadBalancerDB.putIfAbsent(input.getID(), input);
+        //TODO: add code to find INeutronLoadBalancerAware services and call newtorkCreated on them
+        return true;
+    }
+
+    @Override
+    public boolean removeNeutronLoadBalancer(String uuid) {
+        if (!neutronLoadBalancerExists(uuid)) {
+            return false;
+        }
+        loadBalancerDB.remove(uuid);
+        //TODO: add code to find INeutronLoadBalancerAware services and call newtorkDeleted on them
+        return true;
+    }
+
+    @Override
+    public boolean updateNeutronLoadBalancer(String uuid, NeutronLoadBalancer delta) {
+        if (!neutronLoadBalancerExists(uuid)) {
+            return false;
+        }
+        NeutronLoadBalancer target = loadBalancerDB.get(uuid);
+        return overwrite(target, delta);
+    }
+
+    @Override
+    public boolean neutronLoadBalancerInUse(String loadBalancerUUID) {
+        return !neutronLoadBalancerExists(loadBalancerUUID);
+    }
+
+    @Override
+    protected Loadbalancer toMd(String uuid) {
+        LoadbalancerBuilder loadBalancersBuilder = new LoadbalancerBuilder();
+        loadBalancersBuilder.setUuid(toUuid(uuid));
+        return loadBalancersBuilder.build();
+    }
+
+    @Override
+    protected InstanceIdentifier<Loadbalancer> createInstanceIdentifier(
+            Loadbalancer loadBalancer) {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Loadbalancers.class)
+                .child(Loadbalancer.class, loadBalancer.getKey());
+    }
+
+    @Override
+    protected Loadbalancer toMd(NeutronLoadBalancer loadBalancer) {
+        LoadbalancerBuilder loadBalancersBuilder = new LoadbalancerBuilder();
+        loadBalancersBuilder.setAdminStateUp(loadBalancer.getLoadBalancerAdminStateUp());
+        if (loadBalancer.getLoadBalancerDescription() != null) {
+            loadBalancersBuilder.setDescr(loadBalancer.getLoadBalancerDescription());
+        }
+        if (loadBalancer.getLoadBalancerName() != null) {
+            loadBalancersBuilder.setName(loadBalancer.getLoadBalancerName());
+        }
+        if (loadBalancer.getLoadBalancerStatus() != null) {
+            loadBalancersBuilder.setStatus(loadBalancer.getLoadBalancerStatus());
+        }
+        if (loadBalancer.getLoadBalancerTenantID() != null) {
+            loadBalancersBuilder.setTenantId(toUuid(loadBalancer.getLoadBalancerTenantID()));
+        }
+        if (loadBalancer.getLoadBalancerVipAddress() != null) {
+            loadBalancersBuilder.setVipAddress(new IpAddress(loadBalancer.getLoadBalancerVipAddress().toCharArray()));
+        }
+        if (loadBalancer.getLoadBalancerVipSubnetID() != null) {
+            loadBalancersBuilder.setVipSubnetId(toUuid(loadBalancer.getLoadBalancerVipSubnetID()));
+        }
+        if (loadBalancer.getID() != null) {
+            loadBalancersBuilder.setUuid(toUuid(loadBalancer.getID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron load balancer without UUID");
+        }
+        return loadBalancersBuilder.build();
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronLoadBalancerInterface neutronLoadBalancerInterface = new NeutronLoadBalancerInterface(providerContext);
+        ServiceRegistration<INeutronLoadBalancerCRUD> neutronLoadBalancerInterfaceRegistration = context.registerService(INeutronLoadBalancerCRUD.class, neutronLoadBalancerInterface, null);
+        if(neutronLoadBalancerInterfaceRegistration != null) {
+            registrations.add(neutronLoadBalancerInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerListenerInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerListenerInterface.java
new file mode 100644 (file)
index 0000000..1d16029
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerListener;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerListenerCRUD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.Listeners;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class NeutronLoadBalancerListenerInterface extends AbstractNeutronInterface<Listeners, NeutronLoadBalancerListener> implements INeutronLoadBalancerListenerCRUD {
+
+    NeutronLoadBalancerListenerInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronLoadBalancerListenerExists(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public NeutronLoadBalancerListener getNeutronLoadBalancerListener(
+            String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<NeutronLoadBalancerListener> getAllNeutronLoadBalancerListeners() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean addNeutronLoadBalancerListener(
+            NeutronLoadBalancerListener input) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean removeNeutronLoadBalancerListener(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean updateNeutronLoadBalancerListener(String uuid,
+            NeutronLoadBalancerListener delta) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean neutronLoadBalancerListenerInUse(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected InstanceIdentifier<Listeners> createInstanceIdentifier(
+            Listeners item) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Listeners toMd(NeutronLoadBalancerListener neutronObject) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Listeners toMd(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronLoadBalancerListenerInterface neutronLoadBalancerListenerInterface = new NeutronLoadBalancerListenerInterface(providerContext);
+        ServiceRegistration<INeutronLoadBalancerListenerCRUD> neutronLoadBalancerListenerInterfaceRegistration = context.registerService(INeutronLoadBalancerListenerCRUD.class, neutronLoadBalancerListenerInterface, null);
+        if(neutronLoadBalancerListenerInterfaceRegistration != null) {
+            registrations.add(neutronLoadBalancerListenerInterfaceRegistration);
+        }
+    }
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerPoolInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerPoolInterface.java
new file mode 100644 (file)
index 0000000..6b0c382
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer_SessionPersistence;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_ID;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerPoolCRUD;
+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.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.ProtocolTcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.Pools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.Pool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.PoolBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.pool.attributes.SessionPersistenceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+/**
+ * TODO: Migrate this to consume the MD-SAL data store, so that it can read all the data from data store.
+ * No need to worry about the write/update related methods here. OVSDB net-virt will use these CRUD Interface
+ * only for reading. We will cleanup these interface/methods later.
+ */
+
+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<>();
+
+    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(ProtocolTcp.class,"TCP")
+            .build();
+
+    NeutronLoadBalancerPoolInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronLoadBalancerPoolExists(String uuid) {
+        return loadBalancerPoolDB.containsKey(uuid);
+    }
+
+    @Override
+    public NeutronLoadBalancerPool getNeutronLoadBalancerPool(String uuid) {
+        if (!neutronLoadBalancerPoolExists(uuid)) {
+            LOGGER.debug("No LoadBalancerPool has Been Defined");
+            return null;
+        }
+        return loadBalancerPoolDB.get(uuid);
+    }
+
+    @Override
+    public List<NeutronLoadBalancerPool> getAllNeutronLoadBalancerPools() {
+        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<>();
+        ans.addAll(allLoadBalancerPools);
+        return ans;
+    }
+
+    @Override
+    public boolean addNeutronLoadBalancerPool(NeutronLoadBalancerPool input) {
+        if (neutronLoadBalancerPoolExists(input.getID())) {
+            return false;
+        }
+        loadBalancerPoolDB.putIfAbsent(input.getID(), input);
+        //TODO: add code to find INeutronLoadBalancerPoolAware services and call newtorkCreated on them
+        return true;
+    }
+
+    @Override
+    public boolean removeNeutronLoadBalancerPool(String uuid) {
+        if (!neutronLoadBalancerPoolExists(uuid)) {
+            return false;
+        }
+        loadBalancerPoolDB.remove(uuid);
+        //TODO: add code to find INeutronLoadBalancerPoolAware services and call newtorkDeleted on them
+        return true;
+    }
+
+    @Override
+    public boolean updateNeutronLoadBalancerPool(String uuid, NeutronLoadBalancerPool delta) {
+        if (!neutronLoadBalancerPoolExists(uuid)) {
+            return false;
+        }
+        NeutronLoadBalancerPool target = loadBalancerPoolDB.get(uuid);
+        return overwrite(target, delta);
+    }
+
+    @Override
+    public boolean neutronLoadBalancerPoolInUse(String loadBalancerPoolUUID) {
+        return !neutronLoadBalancerPoolExists(loadBalancerPoolUUID);
+    }
+
+    @Override
+    protected Pool toMd(String uuid) {
+        PoolBuilder poolsBuilder = new PoolBuilder();
+        poolsBuilder.setUuid(toUuid(uuid));
+        return poolsBuilder.build();
+    }
+
+    @Override
+    protected InstanceIdentifier<Pool> createInstanceIdentifier(Pool pools) {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Pools.class)
+                .child(Pool.class, pools.getKey());
+    }
+
+    @Override
+    protected Pool toMd(NeutronLoadBalancerPool pool) {
+        PoolBuilder poolBuilder = new PoolBuilder();
+        poolBuilder.setAdminStateUp(pool.getLoadBalancerPoolAdminIsStateIsUp());
+        if (pool.getLoadBalancerPoolDescription() != null) {
+            poolBuilder.setDescr(pool.getLoadBalancerPoolDescription());
+        }
+        if (pool.getNeutronLoadBalancerPoolHealthMonitorID() != null) {
+            poolBuilder.setHealthmonitorId(toUuid(pool.getNeutronLoadBalancerPoolHealthMonitorID()));
+        }
+        if (pool.getLoadBalancerPoolLbAlgorithm() != null) {
+            poolBuilder.setLbAlgorithm(pool.getLoadBalancerPoolLbAlgorithm());
+        }
+        if (pool.getLoadBalancerPoolListeners() != null) {
+            List<Uuid> listListener = new ArrayList<>();
+            for (Neutron_ID neutron_id : pool.getLoadBalancerPoolListeners()) {
+                listListener.add(toUuid(neutron_id.getID()));
+            }
+            poolBuilder.setListeners(listListener);
+        }
+        // because members are another container, we don't want to copy
+        // it over, so just skip it here
+        if (pool.getLoadBalancerPoolName() != null) {
+            poolBuilder.setName(pool.getLoadBalancerPoolName());
+        }
+        if (pool.getLoadBalancerPoolProtocol() != null) {
+            ImmutableBiMap<String, Class<? extends ProtocolBase>> mapper =
+                PROTOCOL_MAP.inverse();
+            poolBuilder.setProtocol(mapper.get(pool.getLoadBalancerPoolProtocol()));
+        }
+        if (pool.getLoadBalancerPoolSessionPersistence() != null) {
+            NeutronLoadBalancer_SessionPersistence sessionPersistence = pool.getLoadBalancerPoolSessionPersistence();
+            SessionPersistenceBuilder sessionPersistenceBuilder = new SessionPersistenceBuilder();
+            sessionPersistenceBuilder.setCookieName(sessionPersistence.getCookieName());
+            sessionPersistenceBuilder.setType(sessionPersistence.getType());
+            poolBuilder.setSessionPersistence(sessionPersistenceBuilder.build());
+        }
+        if (pool.getLoadBalancerPoolTenantID() != null) {
+            poolBuilder.setTenantId(toUuid(pool.getLoadBalancerPoolTenantID()));
+        }
+        if (pool.getID() != null) {
+            poolBuilder.setUuid(toUuid(pool.getID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron load balancer pool without UUID");
+        }
+        return poolBuilder.build();
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronLoadBalancerPoolInterface neutronLoadBalancerPoolInterface = new NeutronLoadBalancerPoolInterface(providerContext);
+        ServiceRegistration<INeutronLoadBalancerPoolCRUD> neutronLoadBalancerPoolInterfaceRegistration = context.registerService(INeutronLoadBalancerPoolCRUD.class, neutronLoadBalancerPoolInterface, null);
+        if(neutronLoadBalancerPoolInterfaceRegistration != null) {
+            registrations.add(neutronLoadBalancerPoolInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerPoolMemberInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronLoadBalancerPoolMemberInterface.java
new file mode 100644 (file)
index 0000000..2e6aa92
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronLoadBalancerPoolMemberCRUD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.pool.Members;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+public class NeutronLoadBalancerPoolMemberInterface extends
+        AbstractNeutronInterface<Members, NeutronLoadBalancerPoolMember> implements INeutronLoadBalancerPoolMemberCRUD {
+
+    NeutronLoadBalancerPoolMemberInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronLoadBalancerPoolMemberExists(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public NeutronLoadBalancerPoolMember getNeutronLoadBalancerPoolMember(
+            String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<NeutronLoadBalancerPoolMember> getAllNeutronLoadBalancerPoolMembers() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean addNeutronLoadBalancerPoolMember(
+            NeutronLoadBalancerPoolMember input) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean removeNeutronLoadBalancerPoolMember(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean updateNeutronLoadBalancerPoolMember(String uuid,
+            NeutronLoadBalancerPoolMember delta) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean neutronLoadBalancerPoolMemberInUse(String uuid) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected InstanceIdentifier<Members> createInstanceIdentifier(Members item) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Members toMd(NeutronLoadBalancerPoolMember neutronObject) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Members toMd(String uuid) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronLoadBalancerPoolMemberInterface neutronLoadBalancerPoolMemberInterface = new NeutronLoadBalancerPoolMemberInterface(providerContext);
+        ServiceRegistration<INeutronLoadBalancerPoolMemberCRUD> neutronLoadBalancerPoolMemberInterfaceRegistration = context.registerService(INeutronLoadBalancerPoolMemberCRUD.class, neutronLoadBalancerPoolMemberInterface, null);
+        if(neutronLoadBalancerPoolMemberInterfaceRegistration != null) {
+            registrations.add(neutronLoadBalancerPoolMemberInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronNetworkInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronNetworkInterface.java
new file mode 100644 (file)
index 0000000..55c2aa6
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork_Segment;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
+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.ext.rev150712.NetworkL3Extension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.ext.rev150712.NetworkL3ExtensionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtensionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.neutron.networks.network.Segments;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.neutron.networks.network.SegmentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+public class NeutronNetworkInterface extends AbstractNeutronInterface<Network,NeutronNetwork> implements INeutronNetworkCRUD {
+    private static final Logger LOGGER = LoggerFactory.getLogger(NeutronNetworkInterface.class);
+
+    private static final ImmutableBiMap<Class<? extends NetworkTypeBase>,String> NETWORK_MAP
+            = new ImmutableBiMap.Builder<Class<? extends NetworkTypeBase>,String>()
+            .put(NetworkTypeFlat.class,"flat")
+            .put(NetworkTypeGre.class,"gre")
+            .put(NetworkTypeVlan.class,"vlan")
+            .put(NetworkTypeVxlan.class,"vxlan")
+            .build();
+
+    NeutronNetworkInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    // IfNBNetworkCRUD methods
+
+    @Override
+    public boolean networkExists(String uuid) {
+        Network network = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (network == null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public NeutronNetwork getNetwork(String uuid) {
+        Network network = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (network == null) {
+            return null;
+        }
+        return fromMd(network);
+    }
+
+    @Override
+    public List<NeutronNetwork> getAllNetworks() {
+        Set<NeutronNetwork> allNetworks = new HashSet<>();
+        Networks networks = readMd(createInstanceIdentifier());
+        if (networks != null) {
+            for (Network network: networks.getNetwork()) {
+                allNetworks.add(fromMd(network));
+            }
+        }
+        LOGGER.debug("Exiting getAllNetworks, Found {} OpenStackNetworks", allNetworks.size());
+        List<NeutronNetwork> ans = new ArrayList<>();
+        ans.addAll(allNetworks);
+        return ans;
+    }
+
+    @Override
+    public boolean addNetwork(NeutronNetwork input) {
+        if (networkExists(input.getID())) {
+            return false;
+        }
+        addMd(input);
+        return true;
+    }
+
+    @Override
+    public boolean removeNetwork(String uuid) {
+        if (!networkExists(uuid)) {
+            return false;
+        }
+        return removeMd(toMd(uuid));
+    }
+
+    @Override
+    public boolean updateNetwork(String uuid, NeutronNetwork delta) {
+        if (!networkExists(uuid)) {
+            return false;
+        }
+/* note: because what we get is *not* a delta but (at this point) the updated
+ * object, this is much simpler - just replace the value and update the mdsal
+ * with it */
+        updateMd(delta);
+        return true;
+    }
+
+    @Override
+    public boolean networkInUse(String netUUID) {
+        if (!networkExists(netUUID)) {
+            return true;
+        }
+        return false;
+    }
+
+    protected NeutronNetwork fromMd(Network network) {
+        NeutronNetwork result = new NeutronNetwork();
+        result.setAdminStateUp(network.isAdminStateUp());
+        result.setNetworkName(network.getName());
+        result.setShared(network.isShared());
+        result.setStatus(network.getStatus());
+// todo remove '-' chars as tenant id doesn't use them
+        result.setTenantID(network.getTenantId().getValue());
+        result.setID(network.getUuid().getValue());
+
+        NetworkL3Extension l3Extension = network.getAugmentation(NetworkL3Extension.class);
+        result.setRouterExternal(l3Extension.isExternal());
+
+        NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
+        result.setProviderPhysicalNetwork(providerExtension.getPhysicalNetwork());
+        result.setProviderSegmentationID(providerExtension.getSegmentationId());
+        result.setProviderNetworkType(NETWORK_MAP.get(providerExtension.getNetworkType()));
+        List<NeutronNetwork_Segment> segments = new ArrayList<>();
+        if (providerExtension.getSegments() != null) {
+            for (Segments segment: providerExtension.getSegments()) {
+                NeutronNetwork_Segment neutronSegment = new NeutronNetwork_Segment();
+                neutronSegment.setProviderPhysicalNetwork(segment.getPhysicalNetwork());
+                neutronSegment.setProviderSegmentationID(segment.getSegmentationId());
+                neutronSegment.setProviderNetworkType(NETWORK_MAP.get(segment.getNetworkType()));
+                segments.add(neutronSegment);
+            }
+        }
+        result.setSegments(segments);
+        return result;
+    }
+
+    private void fillExtensions(NetworkBuilder networkBuilder,
+                                NeutronNetwork network) {
+        NetworkL3ExtensionBuilder l3ExtensionBuilder = new NetworkL3ExtensionBuilder();
+        if (network.getRouterExternal() != null) {
+            l3ExtensionBuilder.setExternal(network.getRouterExternal());
+        }
+
+        NetworkProviderExtensionBuilder providerExtensionBuilder = new NetworkProviderExtensionBuilder();
+        if (network.getProviderPhysicalNetwork() != null) {
+            providerExtensionBuilder.setPhysicalNetwork(network.getProviderPhysicalNetwork());
+        }
+        if (network.getProviderSegmentationID() != null) {
+            providerExtensionBuilder.setSegmentationId(network.getProviderSegmentationID());
+        }
+        if (network.getProviderNetworkType() != null) {
+            ImmutableBiMap<String, Class<? extends NetworkTypeBase>> mapper =
+                NETWORK_MAP.inverse();
+            providerExtensionBuilder.setNetworkType(mapper.get(network.getProviderNetworkType()));
+        }
+        if (network.getSegments() != null) {
+            List<Segments> segments = new ArrayList<>();
+            long count = 0;
+            for( NeutronNetwork_Segment segment : network.getSegments()) {
+                count++;
+                SegmentsBuilder segmentsBuilder = new SegmentsBuilder();
+                if (segment.getProviderPhysicalNetwork() != null) {
+                    segmentsBuilder.setPhysicalNetwork(segment.getProviderPhysicalNetwork());
+                }
+                if (segment.getProviderSegmentationID() != null) {
+                    segmentsBuilder.setSegmentationId(segment.getProviderSegmentationID());
+                }
+                if (segment.getProviderNetworkType() != null) {
+                    ImmutableBiMap<String, Class<? extends NetworkTypeBase>> mapper =
+                        NETWORK_MAP.inverse();
+                    segmentsBuilder.setNetworkType(mapper.get(segment.getProviderNetworkType()));
+                }
+                segmentsBuilder.setSegmentationIndex(count);
+                segments.add(segmentsBuilder.build());
+            }
+            providerExtensionBuilder.setSegments(segments);
+        }
+        if (network.getProviderSegmentationID() != null) {
+            providerExtensionBuilder.setSegmentationId(network.getProviderSegmentationID());
+        }
+
+        networkBuilder.addAugmentation(NetworkL3Extension.class,
+                                       l3ExtensionBuilder.build());
+        networkBuilder.addAugmentation(NetworkProviderExtension.class,
+                                       providerExtensionBuilder.build());
+    }
+
+    protected Network toMd(NeutronNetwork network) {
+        NetworkBuilder networkBuilder = new NetworkBuilder();
+        fillExtensions(networkBuilder, network);
+
+        networkBuilder.setAdminStateUp(network.getAdminStateUp());
+        if (network.getNetworkName() != null) {
+            networkBuilder.setName(network.getNetworkName());
+        }
+        if (network.getShared() != null) {
+            networkBuilder.setShared(network.getShared());
+        }
+        if (network.getStatus() != null) {
+            networkBuilder.setStatus(network.getStatus());
+        }
+        if (network.getTenantID() != null) {
+            networkBuilder.setTenantId(toUuid(network.getTenantID()));
+        }
+        if (network.getNetworkUUID() != null) {
+            networkBuilder.setUuid(toUuid(network.getNetworkUUID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron network without UUID");
+        }
+        return networkBuilder.build();
+    }
+
+    protected Network toMd(String uuid) {
+        NetworkBuilder networkBuilder = new NetworkBuilder();
+        networkBuilder.setUuid(toUuid(uuid));
+        return networkBuilder.build();
+    }
+
+    @Override
+    protected InstanceIdentifier<Network> createInstanceIdentifier(Network network) {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Networks.class)
+                .child(Network.class,network.getKey());
+    }
+
+    protected InstanceIdentifier<Networks> createInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Networks.class);
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronNetworkInterface neutronNetworkInterface = new NeutronNetworkInterface(providerContext);
+        ServiceRegistration<INeutronNetworkCRUD> neutronNetworkInterfaceRegistration = context.registerService(INeutronNetworkCRUD.class, neutronNetworkInterface, null);
+        if(neutronNetworkInterfaceRegistration != null) {
+            registrations.add(neutronNetworkInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronPortInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronPortInterface.java
new file mode 100644 (file)
index 0000000..08f0c41
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort_AllowedAddressPairs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort_ExtraDHCPOption;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort_VIFDetail;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+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.crud.INeutronSecurityGroupCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.NeutronCRUDInterfaces;
+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.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtensionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.binding.attributes.VifDetails;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.binding.attributes.VifDetailsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.AllowedAddressPairsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.ExtraDhcpOpts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.ExtraDhcpOptsBuilder;
+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.port.attributes.FixedIpsBuilder;
+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.PortBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronPortInterface extends AbstractNeutronInterface<Port, NeutronPort> implements INeutronPortCRUD {
+    private static final Logger LOGGER = LoggerFactory.getLogger(NeutronPortInterface.class);
+
+    NeutronPortInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    // IfNBPortCRUD methods
+
+    @Override
+    public boolean portExists(String uuid) {
+        Port port = readMd(createInstanceIdentifier(toMd(uuid)));
+        return port != null;
+    }
+
+    @Override
+    public NeutronPort getPort(String uuid) {
+        Port port = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (port == null) {
+            return null;
+        }
+        return fromMd(port);
+    }
+
+    @Override
+    public List<NeutronPort> getAllPorts() {
+        Set<NeutronPort> allPorts = new HashSet<>();
+        Ports ports = readMd(createInstanceIdentifier());
+        if (ports != null) {
+            for (Port port : ports.getPort()) {
+                allPorts.add(fromMd(port));
+            }
+        }
+        LOGGER.debug("Exiting getAllPorts, Found {} OpenStackPorts", allPorts.size());
+        List<NeutronPort> ans = new ArrayList<>();
+        ans.addAll(allPorts);
+        return ans;
+    }
+
+    @Override
+    public boolean addPort(NeutronPort input) {
+        if (portExists(input.getID())) {
+            return false;
+        }
+        addMd(input);
+        return true;
+    }
+
+    @Override
+    public boolean removePort(String uuid) {
+        if (!portExists(uuid)) {
+            return false;
+        }
+        return removeMd(toMd(uuid));
+    }
+
+    @Override
+    public boolean updatePort(String uuid, NeutronPort delta) {
+        if (!portExists(uuid)) {
+            return false;
+        }
+        updateMd(delta);
+        return true;
+    }
+
+    // @deprecated, will be removed in Boron
+    @Override
+    public boolean macInUse(String macAddress) {
+        return false;
+    }
+
+    // @deprecated, will be removed in Boron
+    @Override
+    public NeutronPort getGatewayPort(String subnetUUID) {
+        return null;
+    }
+
+    @Override
+    protected InstanceIdentifier<Port> createInstanceIdentifier(Port port) {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Ports.class)
+                .child(Port.class, port.getKey());
+    }
+
+    protected InstanceIdentifier<Ports> createInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Ports.class);
+    }
+
+    protected void addExtensions(Port port, NeutronPort result) {
+        PortBindingExtension binding = port.getAugmentation(PortBindingExtension.class);
+        result.setBindinghostID(binding.getHostId());
+        if (binding.getVifDetails() != null) {
+            List<NeutronPort_VIFDetail> details = new ArrayList<>();
+            for (VifDetails vifDetail : binding.getVifDetails()) {
+                NeutronPort_VIFDetail detail = new NeutronPort_VIFDetail();
+                detail.setPortFilter(vifDetail.isPortFilter());
+                detail.setOvsHybridPlug(vifDetail.isOvsHybridPlug());
+                details.add(detail);
+            }
+            result.setVIFDetail(details);
+        }
+        result.setBindingvifType(binding.getVifType());
+        result.setBindingvnicType(binding.getVnicType());
+    }
+
+    protected NeutronPort fromMd(Port port) {
+        NeutronPort result = new NeutronPort();
+        result.setAdminStateUp(port.isAdminStateUp());
+        if (port.getAllowedAddressPairs() != null) {
+            List<NeutronPort_AllowedAddressPairs> pairs = new ArrayList<>();
+            for (AllowedAddressPairs mdPair : port.getAllowedAddressPairs()) {
+                NeutronPort_AllowedAddressPairs pair = new NeutronPort_AllowedAddressPairs();
+                pair.setIpAddress(mdPair.getIpAddress());
+                pair.setMacAddress(mdPair.getMacAddress());
+                pair.setPortID(mdPair.getPortId());
+                pairs.add(pair);
+            }
+            result.setAllowedAddressPairs(pairs);
+        }
+        result.setDeviceID(port.getDeviceId());
+        result.setDeviceOwner(port.getDeviceOwner());
+        if (port.getExtraDhcpOpts() != null) {
+            List<NeutronPort_ExtraDHCPOption> options = new ArrayList<>();
+            for (ExtraDhcpOpts opt : port.getExtraDhcpOpts()) {
+                NeutronPort_ExtraDHCPOption arg = new NeutronPort_ExtraDHCPOption();
+                arg.setName(opt.getOptName());
+                arg.setValue(opt.getOptValue());
+                options.add(arg);
+            }
+            result.setExtraDHCPOptions(options);
+        }
+        if (port.getFixedIps() != null) {
+            List<Neutron_IPs> ips = new ArrayList<>();
+            for (FixedIps mdIP : port.getFixedIps()) {
+                Neutron_IPs ip = new Neutron_IPs();
+                ip.setIpAddress(String.valueOf(mdIP.getIpAddress().getValue()));
+                ip.setSubnetUUID(mdIP.getSubnetId().getValue());
+                ips.add(ip);
+            }
+            result.setFixedIPs(ips);
+        }
+        result.setMacAddress(port.getMacAddress());
+        result.setName(port.getName());
+        result.setNetworkUUID(String.valueOf(port.getNetworkId().getValue()));
+        if (port.getSecurityGroups() != null) {
+            Set<NeutronSecurityGroup> allGroups = new HashSet<>();
+            NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces().fetchINeutronSecurityGroupCRUD(this);
+            INeutronSecurityGroupCRUD sgIf = interfaces.getSecurityGroupInterface();
+            for (Uuid sgUuid : port.getSecurityGroups()) {
+                NeutronSecurityGroup secGroup = sgIf.getNeutronSecurityGroup(sgUuid.getValue());
+                if (secGroup != null) {
+                    allGroups.add(sgIf.getNeutronSecurityGroup(sgUuid.getValue()));
+                }
+            }
+            List<NeutronSecurityGroup> groups = new ArrayList<>();
+            groups.addAll(allGroups);
+            result.setSecurityGroups(groups);
+        }
+        result.setStatus(port.getStatus());
+        if (port.getTenantId() != null) {
+            result.setTenantID(String.valueOf(port.getTenantId().getValue()).replace("-", ""));
+        }
+        result.setPortUUID(String.valueOf(port.getUuid().getValue()));
+        addExtensions(port, result);
+        return result;
+    }
+
+    @Override
+    protected Port toMd(NeutronPort neutronPort) {
+        PortBindingExtensionBuilder bindingBuilder = new PortBindingExtensionBuilder();
+        if (neutronPort.getBindinghostID() != null) {
+            bindingBuilder.setHostId(neutronPort.getBindinghostID());
+        }
+        if (neutronPort.getVIFDetail() != null) {
+            List<VifDetails> listVifDetail = new ArrayList<>();
+            for (NeutronPort_VIFDetail detail: neutronPort.getVIFDetail()) {
+                VifDetailsBuilder vifDetailsBuilder = new VifDetailsBuilder();
+                if (detail.getPortFilter() != null) {
+                    vifDetailsBuilder.setPortFilter(detail.getPortFilter());
+                }
+                if (detail.getOvsHybridPlug() != null) {
+                    vifDetailsBuilder.setOvsHybridPlug(detail.getOvsHybridPlug());
+                }
+                listVifDetail.add(vifDetailsBuilder.build());
+            }
+            bindingBuilder.setVifDetails(listVifDetail);
+        }
+        if (neutronPort.getBindingvifType() != null) {
+            bindingBuilder.setVifType(neutronPort.getBindingvifType());
+        }
+        if (neutronPort.getBindingvnicType() != null) {
+            bindingBuilder.setVnicType(neutronPort.getBindingvnicType());
+        }
+
+        PortBuilder portBuilder = new PortBuilder();
+        portBuilder.addAugmentation(PortBindingExtension.class,
+                                    bindingBuilder.build());
+        portBuilder.setAdminStateUp(neutronPort.isAdminStateUp());
+        if(neutronPort.getAllowedAddressPairs() != null) {
+            List<AllowedAddressPairs> listAllowedAddressPairs = new ArrayList<>();
+            for (NeutronPort_AllowedAddressPairs allowedAddressPairs : neutronPort.getAllowedAddressPairs()) {
+                    AllowedAddressPairsBuilder allowedAddressPairsBuilder = new AllowedAddressPairsBuilder();
+                    allowedAddressPairsBuilder.setIpAddress(allowedAddressPairs.getIpAddress());
+                    allowedAddressPairsBuilder.setMacAddress(allowedAddressPairs.getMacAddress());
+                    allowedAddressPairsBuilder.setPortId(allowedAddressPairs.getPortID());
+                    listAllowedAddressPairs.add(allowedAddressPairsBuilder.build());
+            }
+            portBuilder.setAllowedAddressPairs(listAllowedAddressPairs);
+        }
+        if (neutronPort.getDeviceID() != null) {
+            portBuilder.setDeviceId(neutronPort.getDeviceID());
+        }
+        if (neutronPort.getDeviceOwner() != null) {
+        portBuilder.setDeviceOwner(neutronPort.getDeviceOwner());
+        }
+        if (neutronPort.getExtraDHCPOptions() != null) {
+            List<ExtraDhcpOpts> listExtraDHCPOptions = new ArrayList<>();
+            for (NeutronPort_ExtraDHCPOption extraDHCPOption : neutronPort.getExtraDHCPOptions()) {
+                ExtraDhcpOptsBuilder extraDHCPOptsBuilder = new ExtraDhcpOptsBuilder();
+                extraDHCPOptsBuilder.setOptName(extraDHCPOption.getName());
+                extraDHCPOptsBuilder.setOptValue(extraDHCPOption.getValue());
+                listExtraDHCPOptions.add(extraDHCPOptsBuilder.build());
+            }
+            portBuilder.setExtraDhcpOpts(listExtraDHCPOptions);
+        }
+        if (neutronPort.getFixedIPs() != null) {
+            List<FixedIps> listNeutronIPs = new ArrayList<>();
+            for (Neutron_IPs neutron_IPs : neutronPort.getFixedIPs()) {
+                FixedIpsBuilder fixedIpsBuilder = new FixedIpsBuilder();
+                fixedIpsBuilder.setIpAddress(new IpAddress(neutron_IPs.getIpAddress().toCharArray()));
+                fixedIpsBuilder.setSubnetId(toUuid(neutron_IPs.getSubnetUUID()));
+                listNeutronIPs.add(fixedIpsBuilder.build());
+            }
+            portBuilder.setFixedIps(listNeutronIPs);
+        }
+        if (neutronPort.getMacAddress() != null) {
+            portBuilder.setMacAddress(neutronPort.getMacAddress());
+        }
+        if (neutronPort.getName() != null) {
+        portBuilder.setName(neutronPort.getName());
+        }
+        if (neutronPort.getNetworkUUID() != null) {
+        portBuilder.setNetworkId(toUuid(neutronPort.getNetworkUUID()));
+        }
+        if (neutronPort.getSecurityGroups() != null) {
+            List<Uuid> listSecurityGroups = new ArrayList<>();
+            for (NeutronSecurityGroup neutronSecurityGroup : neutronPort.getSecurityGroups()) {
+                listSecurityGroups.add(toUuid(neutronSecurityGroup.getID()));
+            }
+            portBuilder.setSecurityGroups(listSecurityGroups);
+        }
+        if (neutronPort.getStatus() != null) {
+            portBuilder.setStatus(neutronPort.getStatus());
+        }
+        if (neutronPort.getTenantID() != null) {
+            portBuilder.setTenantId(toUuid(neutronPort.getTenantID()));
+        }
+        if (neutronPort.getPortUUID() != null) {
+            portBuilder.setUuid(toUuid(neutronPort.getPortUUID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron port without UUID");
+        }
+        return portBuilder.build();
+    }
+
+    @Override
+    protected Port toMd(String uuid) {
+        PortBuilder portBuilder = new PortBuilder();
+        portBuilder.setUuid(toUuid(uuid));
+        return portBuilder.build();
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronPortInterface neutronPortInterface = new NeutronPortInterface(providerContext);
+        ServiceRegistration<INeutronPortCRUD> neutronPortInterfaceRegistration = context.registerService(INeutronPortCRUD.class, neutronPortInterface, null);
+        if(neutronPortInterfaceRegistration != null) {
+            registrations.add(neutronPortInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronRouterInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronRouterInterface.java
new file mode 100644 (file)
index 0000000..fbaafe2
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_NetworkReference;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronRouterCRUD;
+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.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.l3.rev150712.routers.attributes.routers.RouterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfoBuilder;
+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.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronRouterInterface extends  AbstractNeutronInterface<Router, NeutronRouter> implements INeutronRouterCRUD {
+    private static final Logger LOGGER = LoggerFactory.getLogger(NeutronRouterInterface.class);
+    // methods needed for creating caches
+
+
+    NeutronRouterInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+
+    // IfNBRouterCRUD Interface methods
+
+    @Override
+    public boolean routerExists(String uuid) {
+        Router router = readMd(createInstanceIdentifier(toMd(uuid)));
+        return router != null;
+    }
+
+    @Override
+    public NeutronRouter getRouter(String uuid) {
+        Router router = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (router == null) {
+            return null;
+        }
+        return fromMd(router);
+    }
+
+    @Override
+    public List<NeutronRouter> getAllRouters() {
+        Set<NeutronRouter> allRouters = new HashSet<>();
+        Routers routers = readMd(createInstanceIdentifier());
+        if (routers != null) {
+            for (Router router: routers.getRouter()) {
+                allRouters.add(fromMd(router));
+            }
+        }
+        LOGGER.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());
+        List<NeutronRouter> ans = new ArrayList<>();
+        ans.addAll(allRouters);
+        return ans;
+    }
+
+    @Override
+    public boolean addRouter(NeutronRouter input) {
+        if (routerExists(input.getID())) {
+            return false;
+        }
+        addMd(input);
+        return true;
+    }
+
+    @Override
+    public boolean removeRouter(String uuid) {
+        if (!routerExists(uuid)) {
+            return false;
+        }
+        return removeMd(toMd(uuid));
+    }
+
+    @Override
+    public boolean updateRouter(String uuid, NeutronRouter delta) {
+        if (!routerExists(uuid)) {
+            return false;
+        }
+        updateMd(delta);
+        return true;
+    }
+
+    @Override
+    public boolean routerInUse(String routerUUID) {
+        if (!routerExists(routerUUID)) {
+            return true;
+        }
+        NeutronRouter target = getRouter(routerUUID);
+        return (target.getInterfaces().size() > 0);
+    }
+
+    @Override
+    protected Router toMd(NeutronRouter router) {
+
+        RouterBuilder routerBuilder = new RouterBuilder();
+
+        if (router.getRouterUUID() != null) {
+            routerBuilder.setUuid(toUuid(router.getRouterUUID()));
+        }
+        if (router.getName() != null) {
+            routerBuilder.setName(router.getName());
+        }
+        if (router.getTenantID() != null && !router.getTenantID().isEmpty()) {
+            routerBuilder.setTenantId(toUuid(router.getTenantID()));
+        }
+        if (router.getStatus() != null) {
+            routerBuilder.setStatus(router.getStatus());
+        }
+        if (router.getGatewayPortId() != null && !router.getGatewayPortId().isEmpty()) {
+            routerBuilder.setGatewayPortId(toUuid(router.getGatewayPortId()));
+        }
+        routerBuilder.setAdminStateUp(router.getAdminStateUp());
+        routerBuilder.setDistributed(router.getDistributed());
+        if (router.getRoutes() != null) {
+            List<String> routes = new ArrayList<>();
+            for (String route : router.getRoutes()) {
+                routes.add(route);
+            }
+            routerBuilder.setRoutes(routes);
+        }
+        if (router.getExternalGatewayInfo() != null) {
+            ExternalGatewayInfo externalGatewayInfo = null;
+            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<>();
+                    for (Neutron_IPs eIP : externalGatewayInfos.getExternalFixedIPs()) {
+                        ExternalFixedIpsBuilder eFixedIpBuilder = new ExternalFixedIpsBuilder();
+                        eFixedIpBuilder.setIpAddress(new IpAddress(eIP.getIpAddress().toCharArray()));
+                        eFixedIpBuilder.setSubnetId(toUuid(eIP.getSubnetUUID()));
+                        externalFixedIps.add(eFixedIpBuilder.build());
+                    }
+                    builder.setExternalFixedIps(externalFixedIps);
+                }
+                externalGatewayInfo = builder.build();
+            }
+            routerBuilder.setExternalGatewayInfo(externalGatewayInfo);
+        }
+        if (router.getInterfaces() != null) {
+            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());
+            }
+            routerBuilder.setInterfaces(interfaces);
+        }
+        if (router.getID() != null) {
+            routerBuilder.setUuid(toUuid(router.getID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron router without UUID");
+        }
+        return routerBuilder.build();
+    }
+
+    @Override
+    protected InstanceIdentifier<Router> createInstanceIdentifier(Router router) {
+        return InstanceIdentifier.create(Neutron.class)
+                 .child(Routers.class)
+                 .child(Router.class, router.getKey());
+    }
+
+    protected InstanceIdentifier<Routers> createInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class).child(Routers.class);
+    }
+
+    @Override
+    protected Router toMd(String uuid) {
+        RouterBuilder routerBuilder = new RouterBuilder();
+        routerBuilder.setUuid(toUuid(uuid));
+        return routerBuilder.build();
+    }
+
+    public NeutronRouter fromMd(Router router) {
+        NeutronRouter result = new NeutronRouter();
+        result.setID(String.valueOf(router.getUuid().getValue()));
+        result.setName(router.getName());
+        result.setTenantID(String.valueOf(router.getTenantId().getValue()));
+        result.setAdminStateUp(router.isAdminStateUp());
+        result.setStatus(router.getStatus());
+        result.setDistributed(router.isDistributed());
+        if (router.getGatewayPortId() != null) {
+            result.setGatewayPortId(String.valueOf(router.getGatewayPortId().getValue()));
+        }
+        if (router.getRoutes() != null) {
+            List<String> routes = new ArrayList<>();
+            for (String route : router.getRoutes()) {
+                routes.add(route);
+            }
+            result.setRoutes(routes);
+        }
+
+        if (router.getExternalGatewayInfo() != null) {
+            NeutronRouter_NetworkReference extGwInfo = new NeutronRouter_NetworkReference();
+            extGwInfo.setNetworkID(String.valueOf(router.getExternalGatewayInfo().getExternalNetworkId().getValue()));
+            extGwInfo.setEnableSNAT(router.getExternalGatewayInfo().isEnableSnat());
+            if (router.getExternalGatewayInfo().getExternalFixedIps() != null) {
+                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()));
+                     fixedIP.setIpAddress(String.valueOf(mdFixedIP.getIpAddress().getValue()));
+                     fixedIPs.add(fixedIP);
+                }
+                extGwInfo.setExternalFixedIPs(fixedIPs);
+            }
+            result.setExternalGatewayInfo(extGwInfo);
+        }
+
+        if (router.getInterfaces() != null) {
+            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());
+                pojoInterface.setID(id);
+                pojoInterface.setTenantID(String.valueOf(mdInterface.getTenantId().getValue()));
+                pojoInterface.setSubnetUUID(String.valueOf(mdInterface.getSubnetId().getValue()));
+                pojoInterface.setPortUUID(String.valueOf(mdInterface.getPortId().getValue()));
+                interfaces.put(id, pojoInterface);
+            }
+            result.setInterfaces(interfaces);
+        }
+        return result;
+    }
+    
+    public static void registerNewInterface(BundleContext context,
+            ProviderContext providerContext,
+            List<ServiceRegistration<?>> registrations) {
+       NeutronRouterInterface neutronRouterInterface = new NeutronRouterInterface(providerContext);
+       ServiceRegistration<INeutronRouterCRUD> neutronRouterInterfaceRegistration = context.registerService(INeutronRouterCRUD.class, neutronRouterInterface, null);
+       if(neutronRouterInterfaceRegistration != null) {
+               registrations.add(neutronRouterInterfaceRegistration);
+       }
+       }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityGroupInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityGroupInterface.java
new file mode 100644 (file)
index 0000000..9c72959
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSecurityGroupCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSecurityRuleCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.NeutronCRUDInterfaces;
+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.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.SecurityGroups;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroupBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class NeutronSecurityGroupInterface extends AbstractNeutronInterface<SecurityGroup,NeutronSecurityGroup> implements INeutronSecurityGroupCRUD {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(NeutronSecurityGroupInterface.class);
+
+    NeutronSecurityGroupInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    @Override
+    public boolean neutronSecurityGroupExists(String uuid) {
+        SecurityGroup group = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (group == null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public NeutronSecurityGroup getNeutronSecurityGroup(String uuid) {
+        SecurityGroup group = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (group == null) {
+            return null;
+        }
+        return fromMd(group);
+    }
+
+    @Override
+    public List<NeutronSecurityGroup> getAllNeutronSecurityGroups() {
+        Set<NeutronSecurityGroup> allSecurityGroups = new HashSet<>();
+        SecurityGroups groups = readMd(createInstanceIdentifier());
+        if (groups != null) {
+            for (SecurityGroup group: groups.getSecurityGroup()) {
+                allSecurityGroups.add(fromMd(group));
+            }
+        }
+        LOGGER.debug("Exiting getSecurityGroups, Found {} OpenStackSecurityGroup", allSecurityGroups.size());
+        List<NeutronSecurityGroup> ans = new ArrayList<>();
+        ans.addAll(allSecurityGroups);
+        return ans;
+    }
+
+    @Override
+    public boolean addNeutronSecurityGroup(NeutronSecurityGroup input) {
+        if (neutronSecurityGroupExists(input.getID())) {
+            return false;
+        }
+        addMd(input);
+        return true;
+    }
+
+    @Override
+    public boolean removeNeutronSecurityGroup(String uuid) {
+        if (!neutronSecurityGroupExists(uuid)) {
+            return false;
+        }
+        removeMd(toMd(uuid));
+        return true;
+    }
+
+    @Override
+    public boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta) {
+        if (!neutronSecurityGroupExists(uuid)) {
+            return false;
+        }
+        updateMd(delta);
+        return true;
+    }
+
+    @Override
+    public boolean neutronSecurityGroupInUse(String securityGroupUUID) {
+        return !neutronSecurityGroupExists(securityGroupUUID);
+    }
+
+    protected NeutronSecurityGroup fromMd(SecurityGroup group) {
+        NeutronSecurityGroup answer = new NeutronSecurityGroup();
+        if (group.getName() != null) {
+            answer.setSecurityGroupName(group.getName());
+        }
+        if (group.getDescription() != null) {
+            answer.setSecurityGroupDescription(group.getDescription());
+        }
+        if (group.getTenantId() != null) {
+            answer.setSecurityGroupTenantID(group.getTenantId().getValue().replace("-",""));
+        }
+        if (group.getSecurityRules() != null) {
+            NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
+                .fetchINeutronSecurityRuleCRUD(this);
+            INeutronSecurityRuleCRUD srCrud = interfaces.getSecurityRuleInterface();
+
+            List<NeutronSecurityRule> rules = new ArrayList<>();
+            for (Uuid uuid: group.getSecurityRules()) {
+                 rules.add(srCrud.getNeutronSecurityRule(uuid.getValue()));
+            }
+            answer.setSecurityRules(rules);
+        }
+        if (group.getUuid() != null) {
+            answer.setID(group.getUuid().getValue());
+        }
+        return answer;
+    }
+
+    @Override
+    protected SecurityGroup toMd(NeutronSecurityGroup securityGroup) {
+        SecurityGroupBuilder securityGroupBuilder = new SecurityGroupBuilder();
+        if (securityGroup.getSecurityGroupName() != null) {
+            securityGroupBuilder.setName(securityGroup.getSecurityGroupName());
+        }
+        if (securityGroup.getSecurityGroupDescription() != null) {
+            securityGroupBuilder.setDescription(securityGroup.getSecurityGroupDescription());
+        }
+        if (securityGroup.getSecurityGroupTenantID() != null) {
+            securityGroupBuilder.setTenantId(toUuid(securityGroup.getSecurityGroupTenantID()));
+        }
+        if (securityGroup.getSecurityRules() != null) {
+            List<Uuid> neutronSecurityRule = new ArrayList<>();
+            for (NeutronSecurityRule securityRule : securityGroup.getSecurityRules()) {
+                if (securityRule.getID() != null) {
+                    neutronSecurityRule.add(toUuid(securityRule.getID()));
+                }
+            }
+            securityGroupBuilder.setSecurityRules(neutronSecurityRule);
+        }
+        if (securityGroup.getID() != null) {
+            securityGroupBuilder.setUuid(toUuid(securityGroup.getID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron securityGroup without UUID");
+        }
+
+        return securityGroupBuilder.build();
+    }
+
+    @Override
+    protected InstanceIdentifier<SecurityGroup> createInstanceIdentifier(SecurityGroup securityGroup) {
+        return InstanceIdentifier.create(Neutron.class)
+            .child(SecurityGroups.class).child(SecurityGroup.class,
+                                               securityGroup.getKey());
+    }
+
+    protected InstanceIdentifier<SecurityGroups> createInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class)
+            .child(SecurityGroups.class);
+    }
+
+    @Override
+    protected SecurityGroup toMd(String uuid) {
+        SecurityGroupBuilder securityGroupBuilder = new SecurityGroupBuilder();
+        securityGroupBuilder.setUuid(toUuid(uuid));
+        return securityGroupBuilder.build();
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronSecurityGroupInterface neutronSecurityGroupInterface = new NeutronSecurityGroupInterface(providerContext);
+        ServiceRegistration<INeutronSecurityGroupCRUD> neutronSecurityGroupInterfaceRegistration = context.registerService(INeutronSecurityGroupCRUD.class, neutronSecurityGroupInterface, null);
+        if(neutronSecurityGroupInterfaceRegistration != null) {
+            registrations.add(neutronSecurityGroupInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityRuleInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSecurityRuleInterface.java
new file mode 100644 (file)
index 0000000..8218c84
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2014, 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSecurityGroupCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSecurityRuleCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.NeutronCRUDInterfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRuleBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+
+public class NeutronSecurityRuleInterface extends AbstractNeutronInterface<SecurityRule, NeutronSecurityRule> implements INeutronSecurityRuleCRUD {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(NeutronSecurityRuleInterface.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(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,"IPv4")
+    .put(EthertypeV6.class,"IPv6")
+    .build();
+
+    NeutronSecurityRuleInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    private void updateSecGroupRuleInSecurityGroup(NeutronSecurityRule input) {
+        NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
+            .fetchINeutronSecurityGroupCRUD(this);
+        INeutronSecurityGroupCRUD sgCrud = interfaces.getSecurityGroupInterface();
+        NeutronSecurityGroup sg = sgCrud.getNeutronSecurityGroup(input.getSecurityRuleGroupID());
+        if(sg != null && sg.getSecurityRules() != null) {
+            for(NeutronSecurityRule sgr :sg.getSecurityRules()) {
+                if(sgr != null && sgr.getID() != null && sgr.getID().equals(input.getID())) {
+                    int index = sg.getSecurityRules().indexOf(sgr);
+                    sg.getSecurityRules().set(index, input);
+                }
+            }
+        }
+        if (sg != null) {
+            sg.getSecurityRules().add(input);
+        }
+    }
+
+    private void removeSecGroupRuleFromSecurityGroup(NeutronSecurityRule input) {
+        NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
+            .fetchINeutronSecurityGroupCRUD(this);
+        INeutronSecurityGroupCRUD sgCrud = interfaces.getSecurityGroupInterface();
+        NeutronSecurityGroup sg = sgCrud.getNeutronSecurityGroup(input.getSecurityRuleGroupID());
+        if(sg != null && sg.getSecurityRules() != null) {
+            List<NeutronSecurityRule> toRemove = new ArrayList<>();
+            for(NeutronSecurityRule sgr :sg.getSecurityRules()) {
+                if(sgr.getID() != null && sgr.getID().equals(input.getID())) {
+                    toRemove.add(sgr);
+                }
+            }
+            sg.getSecurityRules().removeAll(toRemove);
+        }
+    }
+
+    @Override
+    public boolean neutronSecurityRuleExists(String uuid) {
+        SecurityRule rule = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (rule == null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public NeutronSecurityRule getNeutronSecurityRule(String uuid) {
+        SecurityRule rule = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (rule == null) {
+            return null;
+        }
+        return fromMd(rule);
+    }
+
+    @Override
+    public List<NeutronSecurityRule> getAllNeutronSecurityRules() {
+        Set<NeutronSecurityRule> allSecurityRules = new HashSet<>();
+        SecurityRules rules = readMd(createInstanceIdentifier());
+        if (rules != null) {
+            for (SecurityRule rule: rules.getSecurityRule()) {
+                allSecurityRules.add(fromMd(rule));
+            }
+        }
+        LOGGER.debug("Exiting getSecurityRule, Found {} OpenStackSecurityRule", allSecurityRules.size());
+        List<NeutronSecurityRule> ans = new ArrayList<>();
+        ans.addAll(allSecurityRules);
+        return ans;
+    }
+
+    @Override
+    public boolean addNeutronSecurityRule(NeutronSecurityRule input) {
+        if (neutronSecurityRuleExists(input.getID())) {
+            return false;
+        }
+        updateSecGroupRuleInSecurityGroup(input);
+        addMd(input);
+        return true;
+    }
+
+    @Override
+    public boolean removeNeutronSecurityRule(String uuid) {
+        if (!neutronSecurityRuleExists(uuid)) {
+            return false;
+        }
+        removeSecGroupRuleFromSecurityGroup(getNeutronSecurityRule(uuid));
+        removeMd(toMd(uuid));
+        return true;
+    }
+
+    @Override
+    public boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta) {
+        if (!neutronSecurityRuleExists(uuid)) {
+            return false;
+        }
+        updateSecGroupRuleInSecurityGroup(delta);
+        updateMd(delta);
+        return true;
+    }
+
+    @Override
+    public boolean neutronSecurityRuleInUse(String securityRuleUUID) {
+        return !neutronSecurityRuleExists(securityRuleUUID);
+    }
+
+    protected NeutronSecurityRule fromMd(SecurityRule rule) {
+        NeutronSecurityRule answer = new NeutronSecurityRule();
+        if (rule.getTenantId() != null) {
+            answer.setSecurityRuleTenantID(rule.getTenantId().getValue().replace("-",""));
+        }
+        if (rule.getDirection() != null) {
+            answer.setSecurityRuleDirection(DIRECTION_MAP.get(rule.getDirection()));
+        }
+        if (rule.getSecurityGroupId() != null) {
+            answer.setSecurityRuleGroupID(rule.getSecurityGroupId().getValue());
+        }
+        if (rule.getRemoteGroupId() != null) {
+            answer.setSecurityRemoteGroupID(rule.getRemoteGroupId().getValue());
+        }
+        if (rule.getRemoteIpPrefix() != null) {
+            answer.setSecurityRuleRemoteIpPrefix(rule.getRemoteIpPrefix().getIpv4Prefix() != null?
+                    rule.getRemoteIpPrefix().getIpv4Prefix().getValue():rule.getRemoteIpPrefix().getIpv6Prefix().getValue());
+        }
+        if (rule.getProtocol() != null) {
+            answer.setSecurityRuleProtocol(PROTOCOL_MAP.get(rule.getProtocol()));
+        }
+        if (rule.getEthertype() != null) {
+            answer.setSecurityRuleEthertype(ETHERTYPE_MAP.get(rule.getEthertype()));
+        }
+        if (rule.getPortRangeMin() != null) {
+            answer.setSecurityRulePortMin(Integer.valueOf(rule.getPortRangeMin()));
+        }
+        if (rule.getPortRangeMax() != null) {
+            answer.setSecurityRulePortMax(Integer.valueOf(rule.getPortRangeMax()));
+        }
+        if (rule.getId() != null) {
+            answer.setID(rule.getId().getValue());
+        }
+        return answer;
+    }
+
+    @Override
+    protected SecurityRule toMd(NeutronSecurityRule securityRule) {
+        SecurityRuleBuilder securityRuleBuilder = new SecurityRuleBuilder();
+
+        if (securityRule.getSecurityRuleTenantID() != null) {
+            securityRuleBuilder.setTenantId(toUuid(securityRule.getSecurityRuleTenantID()));
+        }
+        if (securityRule.getSecurityRuleDirection() != null) {
+            ImmutableBiMap<String, Class<? extends DirectionBase>> mapper =
+                    DIRECTION_MAP.inverse();
+            securityRuleBuilder.setDirection(mapper.get(securityRule.getSecurityRuleDirection()));
+        }
+        if (securityRule.getSecurityRuleGroupID() != null) {
+            securityRuleBuilder.setSecurityGroupId(toUuid(securityRule.getSecurityRuleGroupID()));
+        }
+        if (securityRule.getSecurityRemoteGroupID() != null) {
+            securityRuleBuilder.setRemoteGroupId(toUuid(securityRule.getSecurityRemoteGroupID()));
+        }
+        if (securityRule.getSecurityRuleRemoteIpPrefix() != null) {
+            securityRuleBuilder.setRemoteIpPrefix(new IpPrefix(securityRule.getSecurityRuleRemoteIpPrefix().toCharArray()));
+        }
+        if (securityRule.getSecurityRuleProtocol() != null) {
+            ImmutableBiMap<String, Class<? extends ProtocolBase>> mapper =
+                    PROTOCOL_MAP.inverse();
+            securityRuleBuilder.setProtocol(mapper.get(securityRule.getSecurityRuleProtocol()));
+        }
+        if (securityRule.getSecurityRuleEthertype() != null) {
+            ImmutableBiMap<String, Class<? extends EthertypeBase>> mapper =
+                    ETHERTYPE_MAP.inverse();
+            securityRuleBuilder.setEthertype(mapper.get(securityRule.getSecurityRuleEthertype()));
+        }
+        if (securityRule.getSecurityRulePortMin() != null) {
+            securityRuleBuilder.setPortRangeMin(Integer.valueOf(securityRule.getSecurityRulePortMin()));
+        }
+        if (securityRule.getSecurityRulePortMax() != null) {
+            securityRuleBuilder.setPortRangeMax(Integer.valueOf(securityRule.getSecurityRulePortMax()));
+        }
+        if (securityRule.getID() != null) {
+            securityRuleBuilder.setId(toUuid(securityRule.getID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron securityRule without UUID");
+        }
+        return securityRuleBuilder.build();
+    }
+
+    @Override
+    protected InstanceIdentifier<SecurityRule> createInstanceIdentifier(SecurityRule securityRule) {
+        return InstanceIdentifier.create(Neutron.class)
+            .child(SecurityRules.class).child(SecurityRule.class,
+                                              securityRule.getKey());
+    }
+
+    protected InstanceIdentifier<SecurityRules> createInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class)
+            .child(SecurityRules.class);
+    }
+
+    @Override
+    protected SecurityRule toMd(String uuid) {
+        SecurityRuleBuilder securityRuleBuilder = new SecurityRuleBuilder();
+        securityRuleBuilder.setId(toUuid(uuid));
+        return securityRuleBuilder.build();
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronSecurityRuleInterface neutronSecurityRuleInterface = new NeutronSecurityRuleInterface(providerContext);
+        ServiceRegistration<INeutronSecurityRuleCRUD> neutronSecurityRuleInterfaceRegistration = context.registerService(INeutronSecurityRuleCRUD.class, neutronSecurityRuleInterface, null);
+        if(neutronSecurityRuleInterfaceRegistration != null) {
+            registrations.add(neutronSecurityRuleInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSubnetInterface.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/crud/impl/NeutronSubnetInterface.java
new file mode 100644 (file)
index 0000000..cf42547
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.crud.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnetIPAllocationPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+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.translator.crud.NeutronCRUDInterfaces;
+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.neutron.constants.rev150712.Dhcpv6Base;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Off;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Slaac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Stateless;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnet.attributes.AllocationPools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnet.attributes.AllocationPoolsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, NeutronSubnet> implements INeutronSubnetCRUD {
+    private static final Logger LOGGER = LoggerFactory.getLogger(NeutronSubnetInterface.class);
+
+    private static final ImmutableBiMap<Class<? extends IpVersionBase>,Integer> IPV_MAP
+            = new ImmutableBiMap.Builder<Class<? extends IpVersionBase>,Integer>()
+            .put(IpVersionV4.class, 4)
+            .put(IpVersionV6.class, 6)
+            .build();
+
+    private static final ImmutableBiMap<Class<? extends Dhcpv6Base>,String> DHCPV6_MAP
+            = new ImmutableBiMap.Builder<Class<? extends Dhcpv6Base>,String>()
+            .put(Dhcpv6Off.class,"off")
+            .put(Dhcpv6Stateful.class,"dhcpv6-stateful")
+            .put(Dhcpv6Slaac.class,"slaac")
+            .put(Dhcpv6Stateless.class,"dhcpv6-stateless")
+            .build();
+
+    NeutronSubnetInterface(ProviderContext providerContext) {
+        super(providerContext);
+    }
+
+    // IfNBSubnetCRUD methods
+
+    @Override
+    public boolean subnetExists(String uuid) {
+        Subnet subnet = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (subnet == null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public NeutronSubnet getSubnet(String uuid) {
+        Subnet subnet = readMd(createInstanceIdentifier(toMd(uuid)));
+        if (subnet == null) {
+            return null;
+        }
+        return fromMd(subnet);
+    }
+
+    @Override
+    public List<NeutronSubnet> getAllSubnets() {
+        Set<NeutronSubnet> allSubnets = new HashSet<>();
+        Subnets subnets = readMd(createInstanceIdentifier());
+        if (subnets != null) {
+            for (Subnet subnet: subnets.getSubnet()) {
+                allSubnets.add(fromMd(subnet));
+            }
+        }
+        LOGGER.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());
+        List<NeutronSubnet> ans = new ArrayList<>();
+        ans.addAll(allSubnets);
+        return ans;
+    }
+
+    @Override
+    public boolean addSubnet(NeutronSubnet input) {
+        String id = input.getID();
+        if (subnetExists(id)) {
+            return false;
+        }
+        addMd(input);
+        return true;
+    }
+
+    @Override
+    public boolean removeSubnet(String uuid) {
+        NeutronSubnet target = getSubnet(uuid);
+        if (target == null) {
+            return false;
+        }
+        removeMd(toMd(uuid));
+        return true;
+    }
+
+    @Override
+    public boolean updateSubnet(String uuid, NeutronSubnet delta) {
+        if (!subnetExists(uuid)) {
+            return false;
+        }
+/* note: because what we get is *not* a delta but (at this point) the updated
+ * object, this is much simpler - just replace the value and update the mdsal
+ * with it */
+        updateMd(delta);
+        return true;
+    }
+
+// note: this is being set to false in preparation for deprecation and removal
+    @Override
+    public boolean subnetInUse(String subnetUUID) {
+        return false;
+    }
+
+    protected NeutronSubnet fromMd(Subnet subnet) {
+        NeutronSubnet result = new NeutronSubnet();
+        result.setName(subnet.getName());
+        result.setTenantID(String.valueOf(subnet.getTenantId().getValue()).replace("-",""));
+        result.setNetworkUUID(subnet.getNetworkId().getValue());
+        result.setIpVersion(IPV_MAP.get(subnet.getIpVersion()));
+        result.setCidr(subnet.getCidr());
+        result.setGatewayIP(String.valueOf(subnet.getGatewayIp().getValue()));
+        result.setIpV6RaMode(DHCPV6_MAP.get(subnet.getIpv6RaMode()));
+        result.setIpV6AddressMode(DHCPV6_MAP.get(subnet.getIpv6AddressMode()));
+        result.setEnableDHCP(subnet.isEnableDhcp());
+        if (subnet.getAllocationPools() != null) {
+            List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<>();
+            for (AllocationPools allocationPool : subnet.getAllocationPools()) {
+                NeutronSubnetIPAllocationPool pool = new NeutronSubnetIPAllocationPool();
+                pool.setPoolStart(allocationPool.getStart());
+                pool.setPoolEnd(allocationPool.getEnd());
+                allocationPools.add(pool);
+            }
+            result.setAllocationPools(allocationPools);
+        }
+        if (subnet.getDnsNameservers() != null) {
+            List<String> dnsNameServers = new ArrayList<>();
+            for (IpAddress dnsNameServer : subnet.getDnsNameservers()) {
+                dnsNameServers.add(String.valueOf(dnsNameServer.getValue()));
+            }
+            result.setDnsNameservers(dnsNameServers);
+        }
+        result.setID(subnet.getUuid().getValue());
+// 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<>();
+        NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
+            .fetchINeutronPortCRUD(this);
+        INeutronPortCRUD portIf = interfaces.getPortInterface();
+        for (NeutronPort port : portIf.getAllPorts()) {
+            if (port.getFixedIPs() != null) {
+                for (Neutron_IPs ip : port.getFixedIPs()) {
+                    if (ip.getSubnetUUID().equals(result.getID())) {
+                        allPorts.add(port);
+                    }
+                }
+            }
+        }
+        List<NeutronPort> ports = new ArrayList<>();
+        ports.addAll(allPorts);
+        result.setPorts(ports);
+        return result;
+    }
+
+    protected Subnet toMd(NeutronSubnet subnet) {
+        SubnetBuilder subnetBuilder = new SubnetBuilder();
+        if (subnet.getName() != null) {
+            subnetBuilder.setName(subnet.getName());
+        }
+        if (subnet.getTenantID() != null) {
+            subnetBuilder.setTenantId(toUuid(subnet.getTenantID()));
+        }
+        if (subnet.getNetworkUUID() != null) {
+            subnetBuilder.setNetworkId(toUuid(subnet.getNetworkUUID()));
+        }
+        if (subnet.getIpVersion() != null) {
+            ImmutableBiMap<Integer, Class<? extends IpVersionBase>> mapper =
+                    IPV_MAP.inverse();
+            subnetBuilder.setIpVersion(mapper.get(subnet
+                    .getIpVersion()));
+        }
+        if (subnet.getCidr() != null) {
+            subnetBuilder.setCidr(subnet.getCidr());
+        }
+        if (subnet.getGatewayIP() != null) {
+            IpAddress ipAddress = new IpAddress(subnet.getGatewayIP()
+                    .toCharArray());
+            subnetBuilder.setGatewayIp(ipAddress);
+        }
+        if (subnet.getIpV6RaMode() != null) {
+            ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
+                    DHCPV6_MAP.inverse();
+            subnetBuilder.setIpv6RaMode(mapper.get(subnet.getIpV6RaMode()));
+        }
+        if (subnet.getIpV6AddressMode() != null) {
+            ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
+                    DHCPV6_MAP.inverse();
+            subnetBuilder.setIpv6AddressMode(mapper.get(subnet.getIpV6AddressMode()));
+        }
+        subnetBuilder.setEnableDhcp(subnet.getEnableDHCP());
+        if (subnet.getAllocationPools() != null) {
+            List<AllocationPools> allocationPools = new ArrayList<>();
+            for (NeutronSubnetIPAllocationPool allocationPool : subnet
+                    .getAllocationPools()) {
+                AllocationPoolsBuilder builder = new AllocationPoolsBuilder();
+                builder.setStart(allocationPool.getPoolStart());
+                builder.setEnd(allocationPool.getPoolEnd());
+                AllocationPools temp = builder.build();
+                allocationPools.add(temp);
+            }
+            subnetBuilder.setAllocationPools(allocationPools);
+        }
+        if (subnet.getDnsNameservers() != null) {
+            List<IpAddress> dnsNameServers = new ArrayList<>();
+            for (String dnsNameServer : subnet.getDnsNameservers()) {
+                IpAddress ipAddress = new IpAddress(dnsNameServer.toCharArray());
+                dnsNameServers.add(ipAddress);
+            }
+            subnetBuilder.setDnsNameservers(dnsNameServers);
+        }
+        if (subnet.getID() != null) {
+            subnetBuilder.setUuid(toUuid(subnet.getID()));
+        } else {
+            LOGGER.warn("Attempting to write neutron subnet without UUID");
+        }
+        return subnetBuilder.build();
+    }
+
+    @Override
+    protected InstanceIdentifier<Subnet> createInstanceIdentifier(Subnet subnet) {
+        return InstanceIdentifier.create(Neutron.class).child(Subnets.class)
+                .child(Subnet.class, subnet.getKey());
+    }
+
+    protected InstanceIdentifier<Subnets> createInstanceIdentifier() {
+        return InstanceIdentifier.create(Neutron.class)
+                .child(Subnets.class);
+    }
+
+    @Override
+    protected Subnet toMd(String uuid) {
+        SubnetBuilder subnetBuilder = new SubnetBuilder();
+        subnetBuilder.setUuid(toUuid(uuid));
+        return subnetBuilder.build();
+    }
+
+    public static void registerNewInterface(BundleContext context,
+                                            ProviderContext providerContext,
+                                            List<ServiceRegistration<?>> registrations) {
+        NeutronSubnetInterface neutronSubnetInterface = new NeutronSubnetInterface(providerContext);
+        ServiceRegistration<INeutronSubnetCRUD> neutronSubnetInterfaceRegistration = context.registerService(INeutronSubnetCRUD.class, neutronSubnetInterface, null);
+        if(neutronSubnetInterfaceRegistration != null) {
+            registrations.add(neutronSubnetInterfaceRegistration);
+        }
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallAware.java
new file mode 100644 (file)
index 0000000..f5348cb
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewall;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Firewall Rules needs to implement
+ *
+ */
+
+public interface INeutronFirewallAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified firewall can be created
+     *
+     * @param firewall
+     *            instance of proposed new Firewall object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronFirewall(NeutronFirewall firewall);
+
+    /**
+     * Services provide this interface method for taking action after a firewall has been created
+     *
+     * @param firewall
+     *            instance of new Firewall object
+     */
+    void neutronFirewallCreated(NeutronFirewall firewall);
+
+    /**
+     * Services provide this interface method to indicate if the specified firewall can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the firewall object using patch semantics
+     * @param original
+     *            instance of the Firewall object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronFirewall(NeutronFirewall delta, NeutronFirewall original);
+
+    /**
+     * Services provide this interface method for taking action after a firewall has been updated
+     *
+     * @param firewall
+     *            instance of modified Firewall object
+     */
+    void neutronFirewallUpdated(NeutronFirewall firewall);
+
+    /**
+     * Services provide this interface method to indicate if the specified firewall can be deleted
+     *
+     * @param firewall
+     *            instance of the Firewall object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronFirewall(NeutronFirewall firewall);
+
+    /**
+     * Services provide this interface method for taking action after a firewall has been deleted
+     *
+     * @param firewall
+     *            instance of deleted Firewall object
+     */
+    void neutronFirewallDeleted(NeutronFirewall firewall);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallPolicyAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallPolicyAware.java
new file mode 100644 (file)
index 0000000..2b8c0c4
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallPolicy;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Firewall Policys needs to implement
+ *
+ */
+
+public interface INeutronFirewallPolicyAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified firewallPolicy can be created
+     *
+     * @param firewallPolicy
+     *            instance of proposed new Firewall Policy object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronFirewallPolicy(NeutronFirewallPolicy firewallPolicy);
+
+    /**
+     * Services provide this interface method for taking action after a firewallPolicy has been created
+     *
+     * @param firewallPolicy
+     *            instance of new Firewall Policy object
+     */
+    void neutronFirewallPolicyCreated(NeutronFirewallPolicy firewallPolicy);
+
+    /**
+     * Services provide this interface method to indicate if the specified firewallPolicy can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the firewallPolicy object using patch semantics
+     * @param original
+     *            instance of the Firewall Policy object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronFirewallPolicy(NeutronFirewallPolicy delta, NeutronFirewallPolicy original);
+
+    /**
+     * Services provide this interface method for taking action after a firewallPolicy has been updated
+     *
+     * @param firewallPolicy
+     *            instance of modified Firewall Policy object
+     */
+    void neutronFirewallPolicyUpdated(NeutronFirewallPolicy firewallPolicy);
+
+    /**
+     * Services provide this interface method to indicate if the specified firewallPolicy can be deleted
+     *
+     * @param firewallPolicy
+     *            instance of the Firewall Policy object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronFirewallPolicy(NeutronFirewallPolicy firewallPolicy);
+
+    /**
+     * Services provide this interface method for taking action after a firewallPolicy has been deleted
+     *
+     * @param firewallPolicy
+     *            instance of deleted Firewall Policy object
+     */
+    void neutronFirewallPolicyDeleted(NeutronFirewallPolicy firewallPolicy);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallRuleAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFirewallRuleAware.java
new file mode 100644 (file)
index 0000000..efc5752
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallRule;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Firewall Rules needs to implement
+ *
+ */
+
+public interface INeutronFirewallRuleAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified firewallRule can be created
+     *
+     * @param firewallRule
+     *            instance of proposed new Firewall Rule object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronFirewallRule(NeutronFirewallRule firewallRule);
+
+    /**
+     * Services provide this interface method for taking action after a firewallRule has been created
+     *
+     * @param firewallRule
+     *            instance of new Firewall Rule object
+     */
+    void neutronFirewallRuleCreated(NeutronFirewallRule firewallRule);
+
+    /**
+     * Services provide this interface method to indicate if the specified firewallRule can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the firewallRule object using patch semantics
+     * @param original
+     *            instance of the Firewall Rule object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronFirewallRule(NeutronFirewallRule delta, NeutronFirewallRule original);
+
+    /**
+     * Services provide this interface method for taking action after a firewallRule has been updated
+     *
+     * @param firewallRule
+     *            instance of modified Firewall Rule object
+     */
+    void neutronFirewallRuleUpdated(NeutronFirewallRule firewallRule);
+
+    /**
+     * Services provide this interface method to indicate if the specified firewallRule can be deleted
+     *
+     * @param firewallRule
+     *            instance of the Firewall Rule object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronFirewallRule(NeutronFirewallRule firewallRule);
+
+    /**
+     * Services provide this interface method for taking action after a firewallRule has been deleted
+     *
+     * @param firewallRule
+     *            instance of deleted Firewall Rule object
+     */
+    void neutronFirewallRuleDeleted(NeutronFirewallRule firewallRule);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFloatingIPAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronFloatingIPAware.java
new file mode 100644 (file)
index 0000000..f9ca5e7
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron FloatingIPs needs to implement
+ *
+ */
+
+public interface INeutronFloatingIPAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified floatingIP can be created
+     *
+     * @param floatingIP
+     *            instance of proposed new Neutron FloatingIP object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateFloatingIP(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method for taking action after a floatingIP has been created
+     *
+     * @param floatingIP
+     *            instance of new Neutron FloatingIP object
+     */
+    void neutronFloatingIPCreated(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method to indicate if the specified floatingIP can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the floatingIP object using patch semantics
+     * @param original
+     *            instance of the Neutron FloatingIP object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateFloatingIP(NeutronFloatingIP delta, NeutronFloatingIP original);
+
+    /**
+     * Services provide this interface method for taking action after a floatingIP has been updated
+     *
+     * @param floatingIP
+     *            instance of modified Neutron FloatingIP object
+     */
+    void neutronFloatingIPUpdated(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method to indicate if the specified floatingIP can be deleted
+     *
+     * @param floatingIP
+     *            instance of the Neutron FloatingIP object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteFloatingIP(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method for taking action after a floatingIP has been deleted
+     *
+     * @param floatingIP
+     *            instance of deleted Neutron FloatingIP object
+     */
+    void neutronFloatingIPDeleted(NeutronFloatingIP floatingIP);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerAware.java
new file mode 100644 (file)
index 0000000..84f68cf
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of LoadBalancer Rules needs to implement
+ *
+ */
+
+public interface INeutronLoadBalancerAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancer can be created
+     *
+     * @param loadBalancer
+     *            instance of proposed new LoadBalancer object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronLoadBalancer(NeutronLoadBalancer loadBalancer);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancer has been created
+     *
+     * @param loadBalancer
+     *            instance of new LoadBalancer object
+     */
+    void neutronLoadBalancerCreated(NeutronLoadBalancer loadBalancer);
+
+    /**
+     * Services provide this interface method to indicate if the
+     * specified loadBalancer can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the loadBalancer object using patch semantics
+     * @param original
+     *            instance of the LoadBalancer object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronLoadBalancer(NeutronLoadBalancer delta, NeutronLoadBalancer original);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancer has been updated
+     *
+     * @param loadBalancer
+     *            instance of modified LoadBalancer object
+     */
+    void neutronLoadBalancerUpdated(NeutronLoadBalancer loadBalancer);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancer can be deleted
+     *
+     * @param loadBalancer
+     *            instance of the LoadBalancer object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronLoadBalancer(NeutronLoadBalancer loadBalancer);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancer has been deleted
+     *
+     * @param loadBalancer
+     *            instance of deleted LoadBalancer object
+     */
+    void neutronLoadBalancerDeleted(NeutronLoadBalancer loadBalancer);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerHealthMonitorAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerHealthMonitorAware.java
new file mode 100644 (file)
index 0000000..bd46389
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerHealthMonitor;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of LoadBalancerHealthMonitor Rules needs to implement
+ *
+ */
+
+public interface INeutronLoadBalancerHealthMonitorAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerHealthMonitor can be created
+     *
+     * @param loadBalancerHealthMonitor
+     *            instance of proposed new LoadBalancerHealthMonitor object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronLoadBalancerHealthMonitor(NeutronLoadBalancerHealthMonitor loadBalancerHealthMonitor);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerHealthMonitor has been created
+     *
+     * @param loadBalancerHealthMonitor
+     *            instance of new LoadBalancerHealthMonitor object
+     */
+    void neutronLoadBalancerHealthMonitorCreated(NeutronLoadBalancerHealthMonitor loadBalancerHealthMonitor);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerHealthMonitor can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the loadBalancerHealthMonitor object using patch semantics
+     * @param original
+     *            instance of the LoadBalancerHealthMonitor object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronLoadBalancerHealthMonitor(NeutronLoadBalancerHealthMonitor delta,
+            NeutronLoadBalancerHealthMonitor original);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerHealthMonitor has been updated
+     *
+     * @param loadBalancerHealthMonitor
+     *            instance of modified LoadBalancerHealthMonitor object
+     */
+    void neutronLoadBalancerHealthMonitorUpdated(NeutronLoadBalancerHealthMonitor loadBalancerHealthMonitor);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerHealthMonitor can be deleted
+     *
+     * @param loadBalancerHealthMonitor
+     *            instance of the LoadBalancerHealthMonitor object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronLoadBalancerHealthMonitor(NeutronLoadBalancerHealthMonitor loadBalancerHealthMonitor);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerHealthMonitor has been deleted
+     *
+     * @param loadBalancerHealthMonitor
+     *            instance of deleted LoadBalancerHealthMonitor object
+     */
+    void neutronLoadBalancerHealthMonitorDeleted(NeutronLoadBalancerHealthMonitor loadBalancerHealthMonitor);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerListenerAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerListenerAware.java
new file mode 100644 (file)
index 0000000..a54689d
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerListener;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of LoadBalancerListener Rules needs to implement
+ *
+ */
+
+public interface INeutronLoadBalancerListenerAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerListener can be created
+     *
+     * @param loadBalancerListener
+     *            instance of proposed new LoadBalancerListener object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronLoadBalancerListener(NeutronLoadBalancerListener loadBalancerListener);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerListener has been created
+     *
+     * @param loadBalancerListener
+     *            instance of new LoadBalancerListener object
+     */
+    void neutronLoadBalancerListenerCreated(NeutronLoadBalancerListener loadBalancerListener);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerListener can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the loadBalancerListener object using patch semantics
+     * @param original
+     *            instance of the LoadBalancerListener object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronLoadBalancerListener(NeutronLoadBalancerListener delta,
+            NeutronLoadBalancerListener original);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerListener has been updated
+     *
+     * @param loadBalancerListener
+     *            instance of modified LoadBalancerListener object
+     */
+    void neutronLoadBalancerListenerUpdated(NeutronLoadBalancerListener loadBalancerListener);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerListener can be deleted
+     *
+     * @param loadBalancerListener
+     *            instance of the LoadBalancerListener object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronLoadBalancerListener(NeutronLoadBalancerListener loadBalancerListener);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerListener has been deleted
+     *
+     * @param loadBalancerListener
+     *            instance of deleted LoadBalancerListener object
+     */
+    void neutronLoadBalancerListenerDeleted(NeutronLoadBalancerListener loadBalancerListener);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerPoolAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerPoolAware.java
new file mode 100644 (file)
index 0000000..76d5410
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of LoadBalancerPool Rules needs to implement
+ *
+ */
+
+public interface INeutronLoadBalancerPoolAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerPool can be created
+     *
+     * @param loadBalancerPool
+     *            instance of proposed new LoadBalancerPool object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronLoadBalancerPool(NeutronLoadBalancerPool loadBalancerPool);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerPool has been created
+     *
+     * @param loadBalancerPool
+     *            instance of new LoadBalancerPool object
+     */
+    void neutronLoadBalancerPoolCreated(NeutronLoadBalancerPool loadBalancerPool);
+
+    /**
+     * Services provide this interface method to indicate if the
+     * specified loadBalancerPool can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the loadBalancerPool object using patch semantics
+     * @param original
+     *            instance of the LoadBalancerPool object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronLoadBalancerPool(NeutronLoadBalancerPool delta, NeutronLoadBalancerPool original);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerPool has been updated
+     *
+     * @param loadBalancerPool
+     *            instance of modified LoadBalancerPool object
+     */
+    void neutronLoadBalancerPoolUpdated(NeutronLoadBalancerPool loadBalancerPool);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerPool can be deleted
+     *
+     * @param loadBalancerPool
+     *            instance of the LoadBalancerPool object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronLoadBalancerPool(NeutronLoadBalancerPool loadBalancerPool);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerPool has been deleted
+     *
+     * @param loadBalancerPool
+     *            instance of deleted LoadBalancerPool object
+     */
+    void neutronLoadBalancerPoolDeleted(NeutronLoadBalancerPool loadBalancerPool);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerPoolMemberAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronLoadBalancerPoolMemberAware.java
new file mode 100644 (file)
index 0000000..d1e333f
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+
+public interface INeutronLoadBalancerPoolMemberAware {
+
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerPoolMember can be created
+     *
+     * @param loadBalancerPoolMember
+     *            instance of proposed new LoadBalancerPool object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember loadBalancerPoolMember);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerPoolMember has been created
+     *
+     * @param loadBalancerPoolMember
+     *            instance of new LoadBalancerPool object
+     */
+    void neutronLoadBalancerPoolMemberCreated(NeutronLoadBalancerPoolMember loadBalancerPoolMember);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerPoolMember can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the loadBalancerPoolMember object using patch semantics
+     * @param original
+     *            instance of the LoadBalancerPool object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember delta,
+            NeutronLoadBalancerPoolMember original);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerPoolMember has been updated
+     *
+     * @param loadBalancerPoolMember
+     *            instance of modified LoadBalancerPool object
+     */
+    void neutronLoadBalancerPoolMemberUpdated(NeutronLoadBalancerPoolMember loadBalancerPoolMember);
+
+    /**
+     * Services provide this interface method to indicate if the specified loadBalancerPoolMember can be deleted
+     *
+     * @param loadBalancerPoolMember
+     *            instance of the LoadBalancerPool object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember loadBalancerPoolMember);
+
+    /**
+     * Services provide this interface method for taking action after a loadBalancerPoolMember has been deleted
+     *
+     * @param loadBalancerPoolMember
+     *            instance of deleted LoadBalancerPool object
+     */
+    void neutronLoadBalancerPoolMemberDeleted(NeutronLoadBalancerPoolMember loadBalancerPoolMember);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronNetworkAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronNetworkAware.java
new file mode 100644 (file)
index 0000000..70f69c4
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Networks needs to implement
+ *
+ */
+
+public interface INeutronNetworkAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified network can be created
+     *
+     * @param network
+     *            instance of proposed new Neutron Network object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateNetwork(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method for taking action after a network has been created
+     *
+     * @param network
+     *            instance of new Neutron Network object
+     */
+    void neutronNetworkCreated(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method to indicate if the specified network can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the network object using patch semantics
+     * @param original
+     *            instance of the Neutron Network object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original);
+
+    /**
+     * Services provide this interface method for taking action after a network has been updated
+     *
+     * @param network
+     *            instance of modified Neutron Network object
+     */
+    void neutronNetworkUpdated(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method to indicate if the specified network can be deleted
+     *
+     * @param network
+     *            instance of the Neutron Network object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteNetwork(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method for taking action after a network has been deleted
+     *
+     * @param network
+     *            instance of deleted Neutron Network object
+     */
+    void neutronNetworkDeleted(NeutronNetwork network);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronPortAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronPortAware.java
new file mode 100644 (file)
index 0000000..e697482
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Ports needs to implement
+ *
+ */
+
+public interface INeutronPortAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified port can be created
+     *
+     * @param port
+     *            instance of proposed new Neutron Port object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreatePort(NeutronPort port);
+
+    /**
+     * Services provide this interface method for taking action after a port has been created
+     *
+     * @param port
+     *            instance of new Neutron Port object
+     */
+    void neutronPortCreated(NeutronPort port);
+
+    /**
+     * Services provide this interface method to indicate if the specified port can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the port object using patch semantics
+     * @param original
+     *            instance of the Neutron Port object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdatePort(NeutronPort delta, NeutronPort original);
+
+    /**
+     * Services provide this interface method for taking action after a port has been updated
+     *
+     * @param port
+     *            instance of modified Neutron Port object
+     */
+    void neutronPortUpdated(NeutronPort port);
+
+    /**
+     * Services provide this interface method to indicate if the specified port can be deleted
+     *
+     * @param port
+     *            instance of the Neutron Port object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeletePort(NeutronPort port);
+
+    /**
+     * Services provide this interface method for taking action after a port has been deleted
+     *
+     * @param port
+     *            instance of deleted Port Network object
+     */
+    void neutronPortDeleted(NeutronPort port);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronRouterAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronRouterAware.java
new file mode 100644 (file)
index 0000000..8577e7d
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Routers needs to implement
+ *
+ */
+
+public interface INeutronRouterAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified router can be created
+     *
+     * @param router
+     *            instance of proposed new Neutron Router object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateRouter(NeutronRouter router);
+
+    /**
+     * Services provide this interface method for taking action after a router has been created
+     *
+     * @param router
+     *            instance of new Neutron Router object
+     */
+    void neutronRouterCreated(NeutronRouter router);
+
+    /**
+     * Services provide this interface method to indicate if the specified router can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the router object using patch semantics
+     * @param original
+     *            instance of the Neutron Router object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateRouter(NeutronRouter delta, NeutronRouter original);
+
+    /**
+     * Services provide this interface method for taking action after a router has been updated
+     *
+     * @param router
+     *            instance of modified Neutron Router object
+     */
+    void neutronRouterUpdated(NeutronRouter router);
+
+    /**
+     * Services provide this interface method to indicate if the specified router can be deleted
+     *
+     * @param router
+     *            instance of the Neutron Router object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteRouter(NeutronRouter router);
+
+    /**
+     * Services provide this interface method for taking action after a router has been deleted
+     *
+     * @param router
+     *            instance of deleted Router Network object
+     */
+    void neutronRouterDeleted(NeutronRouter router);
+
+    /**
+     * Services provide this interface method to indicate if the
+     * specified interface can be attached to the specified router
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface to be attached to the router
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the attach operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canAttachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+    /**
+     * Services provide this interface method for taking action
+     * after an interface has been added to a router
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface being attached to the router
+     */
+    void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+    /**
+     * Services provide this interface method to indicate if the
+     * specified interface can be detached from the specified router
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface to be detached to the router
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the detach operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+    /**
+     * Services provide this interface method for taking action after an interface has been removed from a router
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface being detached from the router
+     */
+    void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSecurityGroupAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSecurityGroupAware.java
new file mode 100644 (file)
index 0000000..d0323eb
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Security Groups needs to implement
+ */
+
+public interface INeutronSecurityGroupAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified security group can be created
+     *
+     * @param securityGroup instance of proposed new Neutron Security Group object
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the create operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    int canCreateNeutronSecurityGroup(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method for taking action after a security group has been created
+     *
+     * @param securityGroup instance of new Neutron Security Group object
+     */
+    void neutronSecurityGroupCreated(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method to indicate if the specified security group can be changed using the specified
+     * delta
+     *
+     * @param delta    updates to the security group object using patch semantics
+     * @param original instance of the Neutron Security Group object to be updated
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the update operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    int canUpdateNeutronSecurityGroup(NeutronSecurityGroup delta, NeutronSecurityGroup original);
+
+    /**
+     * Services provide this interface method for taking action after a security group has been updated
+     *
+     * @param securityGroup instance of modified Neutron Security Group object
+     */
+    void neutronSecurityGroupUpdated(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method to indicate if the specified security group can be deleted
+     *
+     * @param securityGroup instance of the Neutron Security Group object to be deleted
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the delete operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    int canDeleteNeutronSecurityGroup(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method for taking action after a security group has been deleted
+     *
+     * @param securityGroup instance of deleted Neutron Security Group object
+     */
+    void neutronSecurityGroupDeleted(NeutronSecurityGroup securityGroup);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSecurityRuleAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSecurityRuleAware.java
new file mode 100644 (file)
index 0000000..6a8eaef
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+
+/**
+ * This interface defines the methods required to be aware of Neutron Security Rules
+ */
+
+public interface INeutronSecurityRuleAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified security rule can be created
+     *
+     * @param securityRule instance of proposed new Neutron Security Rule object
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the create operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    int canCreateNeutronSecurityRule(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method for taking action after a security rule has been created
+     *
+     * @param securityRule instance of new Neutron Security Rule object
+     */
+    void neutronSecurityRuleCreated(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method to indicate if the specified security rule can be changed using the specified
+     * delta
+     *
+     * @param delta    updates to the security rule object using patch semantics
+     * @param original instance of the Neutron Security Rule object to be updated
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the update operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original);
+
+    /**
+     * Services provide this interface method for taking action after a security rule has been updated
+     *
+     * @param securityRule instance of modified Neutron Security Rule object
+     */
+    void neutronSecurityRuleUpdated(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method to indicate if the specified security rule can be deleted
+     *
+     * @param securityRule instance of the Neutron Security Rule object to be deleted
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the delete operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    int canDeleteNeutronSecurityRule(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method for taking action after a security rule has been deleted
+     *
+     * @param securityRule instance of deleted Neutron Security Rule object
+     */
+    void neutronSecurityRuleDeleted(NeutronSecurityRule securityRule);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSubnetAware.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/INeutronSubnetAware.java
new file mode 100644 (file)
index 0000000..55ae58b
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013, 2015 IBM Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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.translator.iaware;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Subnets needs to implement
+ *
+ */
+
+public interface INeutronSubnetAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified subnet can be created
+     *
+     * @param subnet
+     *            instance of proposed new Neutron Subnet object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canCreateSubnet(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method for taking action after a subnet has been created
+     *
+     * @param subnet
+     *            instance of new Neutron Subnet object
+     */
+    void neutronSubnetCreated(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method to indicate if the specified subnet can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the subnet object using patch semantics
+     * @param original
+     *            instance of the Neutron Subnet object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original);
+
+    /**
+     * Services provide this interface method for taking action after a subnet has been updated
+     *
+     * @param subnet
+     *            instance of modified Neutron Subnet object
+     */
+    void neutronSubnetUpdated(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method to indicate if the specified subnet can be deleted
+     *
+     * @param subnet
+     *            instance of the Subnet Router object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    int canDeleteSubnet(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method for taking action after a subnet has been deleted
+     *
+     * @param subnet
+     *            instance of deleted Router Subnet object
+     */
+    void neutronSubnetDeleted(NeutronSubnet subnet);
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronFloatingIPChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronFloatingIPChangeListener.java
new file mode 100644 (file)
index 0000000..44adae8
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronFloatingIPAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.floatingips.attributes.Floatingips;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.floatingips.attributes.floatingips.Floatingip;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronFloatingIPChangeListener implements DataChangeListener, AutoCloseable{
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronFloatingIPChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronFloatingIPChangeListener(DataBroker db){
+        this.db = db;
+        InstanceIdentifier<Floatingip> path = InstanceIdentifier
+                .create(Neutron.class)
+                .child(Floatingips.class)
+                .child(Floatingip.class);
+        LOG.debug("Register listener for Neutron FloatingIp model data changes");
+        registration =
+                this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, DataChangeScope.ONE);
+
+    }
+
+    @Override
+    public void onDataChanged(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}",changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronFloatingIPAware.class, this);
+        createFloatingIP(changes, subscribers);
+        updateFloatingIP(changes, subscribers);
+        deleteFloatingIP(changes, subscribers);
+    }
+
+    private void createFloatingIP(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newFloatingIP : changes.getCreatedData().entrySet()) {
+               if(newFloatingIP.getValue() instanceof Floatingip){
+                NeutronFloatingIP floatingip= fromMd((Floatingip)newFloatingIP.getValue());
+                for(Object entry: subscribers){
+                    INeutronFloatingIPAware subscriber = (INeutronFloatingIPAware)entry;
+                    subscriber.neutronFloatingIPCreated(floatingip);
+                }
+               }
+        }
+    }
+
+    private void updateFloatingIP(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updateFloatingIP : changes.getUpdatedData().entrySet()) {
+               if(updateFloatingIP.getValue() instanceof Floatingip){
+                NeutronFloatingIP floatingip = fromMd((Floatingip)updateFloatingIP.getValue());
+                for(Object entry: subscribers){
+                    INeutronFloatingIPAware subscriber = (INeutronFloatingIPAware)entry;
+                    subscriber.neutronFloatingIPUpdated(floatingip);
+                }
+               }
+        }
+    }
+
+    private void deleteFloatingIP(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedFloatingIPPath : changes.getRemovedPaths()) {
+               if(deletedFloatingIPPath.getTargetType().equals(Floatingip.class)){
+                NeutronFloatingIP floatingip = fromMd((Floatingip)changes.getOriginalData().get(deletedFloatingIPPath));
+                for(Object entry: subscribers){
+                    INeutronFloatingIPAware subscriber = (INeutronFloatingIPAware)entry;
+                    subscriber.neutronFloatingIPDeleted(floatingip);
+                }
+               }
+        }
+    }
+
+    /*
+     * This method is borrowed from NeutronFloatingIPInterface.java class of Neutron Northbound class.
+     * We will be utilizing similar code from other classes from the same package of neutron project.
+     */
+    private NeutronFloatingIP fromMd(Floatingip fip) {
+        NeutronFloatingIP result = new NeutronFloatingIP();
+        result.setID(String.valueOf(fip.getUuid().getValue()));
+        if (fip.getFloatingNetworkId() != null) {
+            result.setFloatingNetworkUUID(String.valueOf(fip.getFloatingNetworkId().getValue()));
+        }
+        if (fip.getPortId() != null) {
+            result.setPortUUID(String.valueOf(fip.getPortId().getValue()));
+        }
+        if (fip.getFixedIpAddress() != null ) {
+            result.setFixedIPAddress(String.valueOf(fip.getFixedIpAddress().getValue()));
+        }
+        if (fip.getFloatingIpAddress() != null) {
+            result.setFloatingIPAddress(String.valueOf(fip.getFloatingIpAddress().getValue()));
+        }
+        if (fip.getTenantId() != null) {
+            result.setTenantUUID(String.valueOf(fip.getTenantId().getValue()));
+        }
+        if (fip.getRouterId() != null) {
+            result.setRouterUUID(String.valueOf(fip.getRouterId().getValue()));
+        }
+        result.setStatus(fip.getStatus());
+        return result;
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronIAwareUtil.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronIAwareUtil.java
new file mode 100644 (file)
index 0000000..fdb1e81
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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.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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronIAwareUtil {
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(NeutronIAwareUtil.class);
+
+    private NeutronIAwareUtil() {
+    }
+
+    public static Object[] getInstances(Class<?> clazz,Object bundle) {
+        Object instances[] = null;
+        try {
+            BundleContext bCtx = FrameworkUtil.getBundle(bundle.getClass())
+                    .getBundleContext();
+
+            ServiceReference<?>[] services = null;
+                services = bCtx.getServiceReferences(clazz.getName(),
+                        null);
+            if (services != null) {
+                instances = new Object[services.length];
+                for (int i = 0; i < services.length; i++) {
+                    instances[i] = bCtx.getService(services[i]);
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.error("Instance reference is NULL", e);
+        }
+        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;
+    }
+
+
+
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronLoadBalancerPoolChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronLoadBalancerPoolChangeListener.java
new file mode 100644 (file)
index 0000000..faaaa83
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+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.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer_SessionPersistence;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_ID;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerPoolAware;
+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.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.ProtocolTcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.Pools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.Pool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.pool.members.Member;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+public class NeutronLoadBalancerPoolChangeListener implements DataChangeListener, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronLoadBalancerPoolChangeListener.class);
+
+    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")
+            .build();
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronLoadBalancerPoolChangeListener(DataBroker db){
+        this.db = db;
+        InstanceIdentifier<Pool> path = InstanceIdentifier
+                .create(Neutron.class)
+                .child(Pools.class)
+                .child(Pool.class);
+        LOG.debug("Register listener for Neutron Load Balancer Pool model data changes");
+        registration =
+                this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, AsyncDataBroker.DataChangeScope.ONE);
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+
+    @Override
+    public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}", changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronLoadBalancerPoolAware.class, this);
+        createPool(changes, subscribers);
+        updatePool(changes, subscribers);
+        deletePool(changes, subscribers);
+    }
+
+    private void createPool(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newPool : changes.getCreatedData().entrySet()) {
+               if(newPool.getValue() instanceof Pool){
+                NeutronLoadBalancerPool loadBalancerPool = fromMd((Pool) newPool.getValue());
+                for (Object entry : subscribers) {
+                    INeutronLoadBalancerPoolAware subscriber = (INeutronLoadBalancerPoolAware) entry;
+                    subscriber.neutronLoadBalancerPoolCreated(loadBalancerPool);
+                }
+               }
+        }
+    }
+    private void updatePool(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updatePool : changes.getUpdatedData().entrySet()) {
+               if(updatePool.getValue() instanceof Pool){
+                NeutronLoadBalancerPool loadBalancerPool = fromMd((Pool)updatePool.getValue());
+                for(Object entry: subscribers){
+                    INeutronLoadBalancerPoolAware subscriber = (INeutronLoadBalancerPoolAware) entry;
+                    subscriber.neutronLoadBalancerPoolUpdated(loadBalancerPool);
+                }
+               }
+        }
+    }
+    private void deletePool(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedPoolPath : changes.getRemovedPaths()) {
+               if(deletedPoolPath.getTargetType().equals(Pool.class)){
+                NeutronLoadBalancerPool loadBalancerPool = fromMd((Pool)changes.getOriginalData().get(deletedPoolPath));
+                for(Object entry: subscribers){
+                    INeutronLoadBalancerPoolAware subscriber = (INeutronLoadBalancerPoolAware) entry;
+                    subscriber.neutronLoadBalancerPoolDeleted(loadBalancerPool);
+                }
+               }
+        }
+    }
+
+    /*
+     * This method is borrowed from NeutronLoadBalancerPool.java class of Neutron Northbound class.
+     * in the original location, this method is called extractFields.
+     * We will be utilizing similar code from other classes from the same package of neutron project.
+     */
+    private NeutronLoadBalancerPool fromMd(Pool pool) {
+        NeutronLoadBalancerPool result = new NeutronLoadBalancerPool();
+
+        result.setID(pool.getUuid().getValue());
+        if (pool.getTenantId() != null) {
+            result.setLoadBalancerPoolTenantID(pool.getTenantId().getValue());
+        }
+        if (pool.getName() != null) {
+            result.setLoadBalancerPoolName(pool.getName());
+        }
+        if (pool.getDescr() != null) {
+            result.setLoadBalancerPoolDescription(pool.getDescr());
+        }
+        if (pool.getProtocol() != null) {
+            result.setLoadBalancerPoolProtocol(PROTOCOL_MAP.get(pool.getProtocol()));
+        }
+        if (pool.getLbAlgorithm() != null) {
+            result.setLoadBalancerPoolLbAlgorithm(pool.getLbAlgorithm());
+        }
+
+        // TODO: setNeutronLoadBalancerPoolHealthMonitorID is a list? Fill in, when its needed.
+        if (pool.getHealthmonitorId() != null) {
+               result.setNeutronLoadBalancerPoolHealthMonitorID(pool.getHealthmonitorId().getValue());
+        }
+
+        if (pool.isAdminStateUp() != null) {
+            result.setLoadBalancerPoolAdminStateIsUp(pool.isAdminStateUp());
+        }
+
+        List<Neutron_ID> listeners = new ArrayList();
+        if (pool.getListeners() != null) {
+            for (Uuid listenerUuid : pool.getListeners()) {
+                listeners.add(new Neutron_ID(listenerUuid.getValue()));
+            }
+        }
+        result.setLoadBalancerPoolListeners(listeners);
+
+        if (pool.getSessionPersistence() != null) {
+            NeutronLoadBalancer_SessionPersistence sessionPersistence = new NeutronLoadBalancer_SessionPersistence();
+            sessionPersistence.setCookieName(pool.getSessionPersistence().getCookieName());
+            sessionPersistence.setType(pool.getSessionPersistence().getType());
+            result.setLoadBalancerSessionPersistence(sessionPersistence);
+        }
+
+        List<NeutronLoadBalancerPoolMember> loadBalancerPoolMembers = new ArrayList();
+        if (pool.getMembers() != null) {
+            for (Member member : pool.getMembers().getMember()) {
+                NeutronLoadBalancerPoolMember neutronMember = new NeutronLoadBalancerPoolMember();
+
+                neutronMember.setPoolID(pool.getUuid().getValue());
+                neutronMember.setPoolMemberID(member.getUuid().getValue());
+
+                // TODO: locate and populate remainder attributes, when its needed
+                // member.setPoolMemberAddress(xxx);
+                // member.setPoolMemberAdminStateIsUp(xxx);
+                // member.setPoolMemberProtoPort(xxx);
+                // member.setPoolMemberSubnetID(xxx);
+                // member.setPoolMemberTenantID(xxx);
+                // member.setPoolMemberWeight(xxx);
+
+                loadBalancerPoolMembers.add(neutronMember);
+            }
+        }
+        result.setLoadBalancerPoolMembers(loadBalancerPoolMembers);
+
+        return result;
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronLoadBalancerPoolMemberChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronLoadBalancerPoolMemberChangeListener.java
new file mode 100644 (file)
index 0000000..357e263
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.Map.Entry;
+
+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.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronLoadBalancerPoolMemberAware;
+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.neutron.lbaasv2.rev150712.lbaas.attributes.Pools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.Pool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.PoolKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.pool.Members;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev150712.lbaas.attributes.pools.pool.members.Member;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronLoadBalancerPoolMemberChangeListener implements DataChangeListener, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronLoadBalancerPoolMemberChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronLoadBalancerPoolMemberChangeListener(DataBroker db){
+        this.db = db;
+        InstanceIdentifier<Member> path = InstanceIdentifier
+                .create(Neutron.class)
+                .child(Pools.class)
+                .child(Pool.class)
+                .child(Members.class)
+                .child(Member.class);
+        LOG.debug("Register listener for Neutron Load Balancer Pool Member model data changes");
+        registration =
+                this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this,
+                        AsyncDataBroker.DataChangeScope.ONE);
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+
+    @Override
+    public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}", changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronLoadBalancerPoolMemberAware.class, this);
+        createPoolMember(changes, subscribers);
+        updatePoolMember(changes, subscribers);
+        deletePoolMember(changes, subscribers);
+    }
+
+    private void createPoolMember(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newPoolMember : changes.getCreatedData().entrySet()) {
+               if(newPoolMember.getValue() instanceof Member){
+                NeutronLoadBalancerPoolMember neutronLBPoolMember = fromMd(newPoolMember.getKey(), (Member) newPoolMember.getValue());
+                for (Object entry : subscribers) {
+                    INeutronLoadBalancerPoolMemberAware subscriber = (INeutronLoadBalancerPoolMemberAware) entry;
+                    subscriber.neutronLoadBalancerPoolMemberCreated(neutronLBPoolMember);
+                }
+               }
+        }
+    }
+    private void updatePoolMember(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updatePoolMember : changes.getUpdatedData().entrySet()) {
+               if(updatePoolMember.getValue() instanceof Member){
+                NeutronLoadBalancerPoolMember neutronLBPoolMember =
+                        fromMd(updatePoolMember.getKey(), (Member) updatePoolMember.getValue());
+                for(Object entry: subscribers){
+                    INeutronLoadBalancerPoolMemberAware subscriber = (INeutronLoadBalancerPoolMemberAware) entry;
+                    subscriber.neutronLoadBalancerPoolMemberUpdated(neutronLBPoolMember);
+                }
+               }
+        }
+    }
+    private void deletePoolMember(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedPoolMemberPath : changes.getRemovedPaths()) {
+               if(deletedPoolMemberPath.getTargetType().equals(Member.class)){
+                NeutronLoadBalancerPoolMember neutronLBPoolMember =
+                        fromMd(deletedPoolMemberPath, (Member) changes.getOriginalData().get(deletedPoolMemberPath));
+                for(Object entry: subscribers){
+                    INeutronLoadBalancerPoolMemberAware subscriber = (INeutronLoadBalancerPoolMemberAware) entry;
+                    subscriber.neutronLoadBalancerPoolMemberDeleted(neutronLBPoolMember);
+                }
+               }
+        }
+    }
+
+    /*
+     * This method is borrowed from NeutronLoadBalancerPoolMember.java class of Neutron Northbound class.
+     * in the original location, this method is called extractFields.
+     * We will be utilizing similar code from other classes from the same package of neutron project.
+     */
+    private NeutronLoadBalancerPoolMember fromMd(InstanceIdentifier<?> iid, Member member) {
+        NeutronLoadBalancerPoolMember result = new NeutronLoadBalancerPoolMember();
+
+        final PoolKey poolsKey = iid.firstKeyOf(Pool.class, PoolKey.class);
+        if (poolsKey != null) {
+            result.setPoolID(poolsKey.getUuid().getValue());
+        }
+
+        result.setID(member.getUuid().getValue());
+        if (member.isAdminStateUp() != null) {
+            result.setPoolMemberAdminStateIsUp(member.isAdminStateUp());
+        }
+
+        final IpAddress memberIpAddress = member.getAddress();
+        if (memberIpAddress != null) {
+            if (memberIpAddress.getIpv4Address() != null) {
+                result.setPoolMemberAddress(memberIpAddress.getIpv4Address().getValue());
+            } else if (memberIpAddress.getIpv6Address() != null) {
+                result.setPoolMemberAddress(memberIpAddress.getIpv6Address().getValue());
+            }
+        }
+
+        if (member.getProtocolPort() != null) {
+            result.setPoolMemberProtoPort(member.getProtocolPort());
+        }
+        if (member.getSubnetId() != null) {
+            result.setPoolMemberSubnetID(member.getSubnetId().getValue());
+        }
+        if (member.getTenantId() != null) {
+            result.setPoolMemberTenantID(member.getTenantId().getValue());
+        }
+        if (member.getWeight() != null) {
+            result.setPoolMemberWeight(member.getWeight());
+        }
+
+        return result;
+    }
+}
+
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronNetworkChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronNetworkChangeListener.java
new file mode 100644 (file)
index 0000000..7d2344e
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+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.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork_Segment;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronNetworkAware;
+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.ext.rev150712.NetworkL3Extension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeGre;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.neutron.networks.network.Segments;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+public class NeutronNetworkChangeListener implements DataChangeListener, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkChangeListener.class);
+
+    private static final ImmutableBiMap<Class<? extends NetworkTypeBase>,String> NETWORK_MAP
+    = new ImmutableBiMap.Builder<Class<? extends NetworkTypeBase>,String>()
+    .put(NetworkTypeFlat.class,"flat")
+    .put(NetworkTypeGre.class,"gre")
+    .put(NetworkTypeVlan.class,"vlan")
+    .put(NetworkTypeVxlan.class,"vxlan")
+    .build();
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronNetworkChangeListener(DataBroker db){
+        this.db = db;
+        InstanceIdentifier<Network> path = InstanceIdentifier
+                .create(Neutron.class)
+                .child(Networks.class)
+                .child(Network.class);
+        LOG.debug("Register listener for Neutron Network model data changes");
+        registration =
+                this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, DataChangeScope.ONE);
+
+    }
+
+    @Override
+    public void onDataChanged(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}",changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronNetworkAware.class, this);
+        createNetwork(changes, subscribers);
+        updateNetwork(changes, subscribers);
+        deleteNetwork(changes, subscribers);
+    }
+
+    private void createNetwork(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newNetwork : changes.getCreatedData().entrySet()) {
+               if(newNetwork.getValue() instanceof Network){
+                NeutronNetwork network = fromMd((Network)newNetwork.getValue());
+                for(Object entry: subscribers){
+                    INeutronNetworkAware subscriber = (INeutronNetworkAware)entry;
+                    subscriber.neutronNetworkCreated(network);
+                }
+               }
+        }
+    }
+
+    private void updateNetwork(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updateNetwork : changes.getUpdatedData().entrySet()) {
+               if(updateNetwork.getValue() instanceof Network){
+                NeutronNetwork network = fromMd((Network)updateNetwork.getValue());
+                for(Object entry: subscribers){
+                    INeutronNetworkAware subscriber = (INeutronNetworkAware)entry;
+                    subscriber.neutronNetworkUpdated(network);
+                }
+               }
+        }
+    }
+
+    private void deleteNetwork(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedNetworkPath : changes.getRemovedPaths()) {
+               if(deletedNetworkPath.getTargetType().equals(Network.class)){
+                NeutronNetwork network = fromMd((Network)changes.getOriginalData().get(deletedNetworkPath));
+                for(Object entry: subscribers){
+                    INeutronNetworkAware subscriber = (INeutronNetworkAware)entry;
+                    subscriber.neutronNetworkDeleted(network);
+                }
+               }
+        }
+    }
+
+    /*
+     * This method is borrowed from NeutronNetworkInterface.java class of Neutron Northbound class.
+     * We will be utilizing similar code from other classes from the same package of neutron project.
+     */
+    private NeutronNetwork fromMd(Network network) {
+        NeutronNetwork result = new NeutronNetwork();
+        result.setAdminStateUp(network.isAdminStateUp());
+        result.setNetworkName(network.getName());
+        result.setShared(network.isShared());
+        result.setStatus(network.getStatus());
+
+        // todo remove '-' chars as tenant id doesn't use them
+        result.setTenantID(network.getTenantId().getValue());
+        result.setID(network.getUuid().getValue());
+
+        NetworkL3Extension l3Extension = network.getAugmentation(NetworkL3Extension.class);
+        result.setRouterExternal(l3Extension.isExternal());
+
+        NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
+        result.setProviderPhysicalNetwork(providerExtension.getPhysicalNetwork());
+        result.setProviderSegmentationID(providerExtension.getSegmentationId());
+        result.setProviderNetworkType(NETWORK_MAP.get(providerExtension.getNetworkType()));
+        List<NeutronNetwork_Segment> segments = new ArrayList<>();
+        if (providerExtension.getSegments() != null) {
+            for (Segments segment: providerExtension.getSegments()) {
+                NeutronNetwork_Segment neutronSegment = new NeutronNetwork_Segment();
+                neutronSegment.setProviderPhysicalNetwork(segment.getPhysicalNetwork());
+                neutronSegment.setProviderSegmentationID(segment.getSegmentationId());
+                neutronSegment.setProviderNetworkType(NETWORK_MAP.get(segment.getNetworkType()));
+                segments.add(neutronSegment);
+            }
+        }
+        result.setSegments(segments);
+        return result;
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronPortChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronPortChangeListener.java
new file mode 100644 (file)
index 0000000..6f7bab9
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort_AllowedAddressPairs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort_ExtraDHCPOption;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort_VIFDetail;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSecurityGroupCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.NeutronCRUDInterfaces;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronPortAware;
+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.binding.rev150712.PortBindingExtension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.binding.attributes.VifDetails;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.ExtraDhcpOpts;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronPortChangeListener implements DataChangeListener, AutoCloseable{
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronPortChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronPortChangeListener(DataBroker db){
+        this.db = db;
+        InstanceIdentifier<Port> path = InstanceIdentifier
+                .create(Neutron.class)
+                .child(Ports.class)
+                .child(Port.class);
+        LOG.debug("Register listener for Neutron Port model data changes");
+        registration =
+                this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, DataChangeScope.ONE);
+
+    }
+
+    @Override
+    public void onDataChanged(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}",changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronPortAware.class, this);
+        createPort(changes, subscribers);
+        updatePort(changes, subscribers);
+        deletePort(changes, subscribers);
+    }
+
+    private void createPort(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newPort : changes.getCreatedData().entrySet()) {
+               if(newPort.getValue() instanceof Port){
+                NeutronPort port = fromMd((Port)newPort.getValue());
+                for(Object entry: subscribers){
+                    INeutronPortAware subscriber = (INeutronPortAware)entry;
+                    subscriber.neutronPortCreated(port);
+                }
+               }
+        }
+    }
+
+    private void updatePort(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        Map<String, NeutronPort> originalPortMap = getChangedPorts(changes.getOriginalData());
+        for (Entry<InstanceIdentifier<?>, DataObject> updatePort : changes.getUpdatedData().entrySet()) {
+            if (updatePort.getValue() instanceof Port) {
+                NeutronPort port = fromMd((Port)updatePort.getValue());
+                NeutronPort originalPort = originalPortMap.get(port.getID());
+                if (originalPort != null) {
+                    port.setOriginalPort(originalPort);
+                } else {
+                    LOG.warn("Original Port data is missing");
+                }
+                for (Object entry: subscribers) {
+                    INeutronPortAware subscriber = (INeutronPortAware)entry;
+                    subscriber.neutronPortUpdated(port);
+                }
+            }
+        }
+    }
+
+    private void deletePort(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedPortPath : changes.getRemovedPaths()) {
+            if(deletedPortPath.getTargetType().equals(Port.class)){
+                NeutronPort port = fromMd((Port)changes.getOriginalData().get(deletedPortPath));
+                for(Object entry: subscribers){
+                    INeutronPortAware subscriber = (INeutronPortAware)entry;
+                    subscriber.neutronPortDeleted(port);
+                }
+            }
+        }
+    }
+
+    /*
+     * This method is borrowed from NeutronPortInterface.java class of Neutron Northbound class.
+     * We will be utilizing similar code from other classes from the same package of neutron project.
+     */
+    private NeutronPort fromMd(Port port) {
+
+        NeutronPort result = new NeutronPort();
+        result.setAdminStateUp(port.isAdminStateUp());
+        if (port.getAllowedAddressPairs() != null) {
+            List<NeutronPort_AllowedAddressPairs> pairs = new ArrayList<>();
+            for (AllowedAddressPairs mdPair : port.getAllowedAddressPairs()) {
+                NeutronPort_AllowedAddressPairs pair = new NeutronPort_AllowedAddressPairs();
+                pair.setIpAddress(mdPair.getIpAddress());
+                pair.setMacAddress(mdPair.getMacAddress());
+                pair.setPortID(mdPair.getPortId());
+                pairs.add(pair);
+            }
+            result.setAllowedAddressPairs(pairs);
+        }
+        result.setDeviceID(port.getDeviceId());
+        result.setDeviceOwner(port.getDeviceOwner());
+        if (port.getExtraDhcpOpts() != null) {
+            List<NeutronPort_ExtraDHCPOption> options = new ArrayList<>();
+            for (ExtraDhcpOpts opt : port.getExtraDhcpOpts()) {
+                NeutronPort_ExtraDHCPOption arg = new NeutronPort_ExtraDHCPOption();
+                arg.setName(opt.getOptName());
+                arg.setValue(opt.getOptValue());
+                options.add(arg);
+            }
+            result.setExtraDHCPOptions(options);
+        }
+        if (port.getFixedIps() != null) {
+            List<Neutron_IPs> ips = new ArrayList<>();
+            for (FixedIps mdIP : port.getFixedIps()) {
+                Neutron_IPs ip = new Neutron_IPs();
+                ip.setIpAddress(String.valueOf(mdIP.getIpAddress().getValue()));
+                ip.setSubnetUUID(mdIP.getSubnetId().getValue());
+                ips.add(ip);
+            }
+            result.setFixedIPs(ips);
+        }
+        result.setMacAddress(port.getMacAddress());
+        result.setName(port.getName());
+        result.setNetworkUUID(String.valueOf(port.getNetworkId().getValue()));
+        if (port.getSecurityGroups() != null) {
+            Set<NeutronSecurityGroup> allGroups = new HashSet<>();
+            NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces().fetchINeutronSecurityGroupCRUD(this);
+            INeutronSecurityGroupCRUD sgIf = interfaces.getSecurityGroupInterface();
+            for (Uuid sgUuid : port.getSecurityGroups()) {
+                NeutronSecurityGroup secGroup = sgIf.getNeutronSecurityGroup(sgUuid.getValue());
+                if (secGroup != null) {
+                    allGroups.add(sgIf.getNeutronSecurityGroup(sgUuid.getValue()));
+                }
+            }
+            List<NeutronSecurityGroup> groups = new ArrayList<>();
+            groups.addAll(allGroups);
+            result.setSecurityGroups(groups);
+        }
+        result.setStatus(port.getStatus());
+        if (port.getTenantId() != null) {
+            result.setTenantID(String.valueOf(port.getTenantId().getValue()).replace("-", ""));
+        }
+        result.setPortUUID(String.valueOf(port.getUuid().getValue()));
+        addExtensions(port, result);
+        return result;
+    }
+
+    protected void addExtensions(Port port, NeutronPort result) {
+        PortBindingExtension binding = port.getAugmentation(PortBindingExtension.class);
+        result.setBindinghostID(binding.getHostId());
+        if (binding.getVifDetails() != null) {
+            List<NeutronPort_VIFDetail> details = new ArrayList<>();
+            for (VifDetails vifDetail : binding.getVifDetails()) {
+                NeutronPort_VIFDetail detail = new NeutronPort_VIFDetail();
+                detail.setPortFilter(vifDetail.isPortFilter());
+                detail.setOvsHybridPlug(vifDetail.isOvsHybridPlug());
+                details.add(detail);
+            }
+            result.setVIFDetail(details);
+        }
+        result.setBindingvifType(binding.getVifType());
+        result.setBindingvnicType(binding.getVnicType());
+    }
+
+    private  Map<String,NeutronPort> getChangedPorts(Map<InstanceIdentifier<?>, DataObject> changedData) {
+        LOG.trace("getChangedPorts:" + changedData);
+        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());
+                portMap.put(port.getID(), port);
+            }
+        }
+        return portMap;
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronRouterChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronRouterChangeListener.java
new file mode 100644 (file)
index 0000000..a45c0a4
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_NetworkReference;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronRouterAware;
+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.l3.rev150712.routers.attributes.routers.router.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronRouterChangeListener implements DataChangeListener, AutoCloseable{
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronRouterChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronRouterChangeListener(DataBroker db){
+        this.db = db;
+        InstanceIdentifier<Router> path = InstanceIdentifier
+                .create(Neutron.class)
+                .child(Routers.class)
+                .child(Router.class);
+        LOG.debug("Register listener for Neutron Router model data changes");
+        registration =
+                this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, DataChangeScope.ONE);
+
+    }
+
+    @Override
+    public void onDataChanged(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}",changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronRouterAware.class, this);
+        createRouter(changes, subscribers);
+        updateRouter(changes, subscribers);
+        deleteRouter(changes, subscribers);
+    }
+
+    private void createRouter(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newRouter : changes.getCreatedData().entrySet()) {
+               if(newRouter.getValue() instanceof Router){
+                NeutronRouter router = fromMd((Router)newRouter.getValue());
+                for(Object entry: subscribers){
+                    INeutronRouterAware subscriber = (INeutronRouterAware)entry;
+                    subscriber.neutronRouterCreated(router);
+                }
+               }
+        }
+
+    }
+
+    private void updateRouter(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updateRouter : changes.getUpdatedData().entrySet()) {
+               if(updateRouter.getValue() instanceof Router){
+                NeutronRouter router = fromMd((Router)updateRouter.getValue());
+                for(Object entry: subscribers){
+                    INeutronRouterAware subscriber = (INeutronRouterAware)entry;
+                    subscriber.neutronRouterUpdated(router);
+                }
+               }
+        }
+    }
+
+    private void deleteRouter(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedRouterPath : changes.getRemovedPaths()) {
+               if(deletedRouterPath.getTargetType().equals(Router.class)){
+                NeutronRouter router = fromMd((Router)changes.getOriginalData().get(deletedRouterPath));
+                for(Object entry: subscribers){
+                    INeutronRouterAware subscriber = (INeutronRouterAware)entry;
+                    subscriber.neutronRouterDeleted(router);
+                }
+               }
+        }
+    }
+
+    /*
+     * This method is borrowed from NeutronRouterInterface.java class of Neutron Northbound class.
+     * We will be utilizing similar code from other classes from the same package of neutron project.
+     */
+    private NeutronRouter fromMd(Router router) {
+        NeutronRouter result = new NeutronRouter();
+        result.setID(String.valueOf(router.getUuid().getValue()));
+        result.setName(router.getName());
+        result.setTenantID(String.valueOf(router.getTenantId().getValue()));
+        result.setAdminStateUp(router.isAdminStateUp());
+        result.setStatus(router.getStatus());
+        result.setDistributed(router.isDistributed());
+        if (router.getGatewayPortId() != null) {
+            result.setGatewayPortId(String.valueOf(router.getGatewayPortId().getValue()));
+        }
+        if (router.getRoutes() != null) {
+            List<String> routes = new ArrayList<>();
+            for (String route : router.getRoutes()) {
+                routes.add(route);
+            }
+            result.setRoutes(routes);
+        }
+
+        if (router.getExternalGatewayInfo() != null) {
+            NeutronRouter_NetworkReference extGwInfo = new NeutronRouter_NetworkReference();
+            extGwInfo.setNetworkID(String.valueOf(router.getExternalGatewayInfo().getExternalNetworkId().getValue()));
+            extGwInfo.setEnableSNAT(router.getExternalGatewayInfo().isEnableSnat());
+            if (router.getExternalGatewayInfo().getExternalFixedIps() != null) {
+                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()));
+                     fixedIP.setIpAddress(String.valueOf(mdFixedIP.getIpAddress().getValue()));
+                     fixedIPs.add(fixedIP);
+                }
+                extGwInfo.setExternalFixedIPs(fixedIPs);
+            }
+            result.setExternalGatewayInfo(extGwInfo);
+        }
+
+        if (router.getInterfaces() != null) {
+            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());
+                pojoInterface.setID(id);
+                pojoInterface.setTenantID(String.valueOf(mdInterface.getTenantId().getValue()));
+                pojoInterface.setSubnetUUID(String.valueOf(mdInterface.getSubnetId().getValue()));
+                pojoInterface.setPortUUID(String.valueOf(mdInterface.getPortId().getValue()));
+                interfaces.put(id, pojoInterface);
+            }
+            result.setInterfaces(interfaces);
+        }
+        return result;
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityGroupDataChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityGroupDataChangeListener.java
new file mode 100644 (file)
index 0000000..335de4f
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSecurityRuleCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.NeutronCRUDInterfaces;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityGroupAware;
+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.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.SecurityGroups;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronSecurityGroupDataChangeListener implements
+        DataChangeListener, AutoCloseable {
+    private static final Logger LOG = LoggerFactory
+            .getLogger(NeutronSecurityGroupDataChangeListener.class);
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronSecurityGroupDataChangeListener(DataBroker db) {
+        this.db = db;
+        InstanceIdentifier<SecurityGroup> path = InstanceIdentifier
+                .create(Neutron.class).child(SecurityGroups.class)
+                .child(SecurityGroup.class);
+        LOG.debug("Register listener for Neutron Secutiry group model data changes");
+        registration = this.db.registerDataChangeListener(
+                LogicalDatastoreType.CONFIGURATION, path, this,
+                DataChangeScope.ONE);
+
+    }
+
+    @Override
+    public void onDataChanged(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}", changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(
+                INeutronSecurityGroupAware.class, this);
+        createSecurityGroup(changes, subscribers);
+        updateSecurityGroup(changes, subscribers);
+        deleteSecurityGroup(changes, subscribers);
+    }
+
+    private void createSecurityGroup(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newSecutiryGroup : changes
+                .getCreatedData().entrySet()) {
+            if (newSecutiryGroup.getValue() instanceof SecurityGroup) {
+                NeutronSecurityGroup secutiryGroup = fromMd((SecurityGroup) newSecutiryGroup
+                        .getValue());
+                for (Object entry : subscribers) {
+                    INeutronSecurityGroupAware subscriber = (INeutronSecurityGroupAware) entry;
+                    subscriber.neutronSecurityGroupCreated(secutiryGroup);
+                }
+            }
+        }
+
+    }
+
+    private void updateSecurityGroup(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updateSecurityGroup : changes
+                .getUpdatedData().entrySet()) {
+            if (updateSecurityGroup.getValue() instanceof SecurityGroup) {
+                NeutronSecurityGroup securityGroup = fromMd((SecurityGroup) updateSecurityGroup
+                        .getValue());
+                for (Object entry : subscribers) {
+                    INeutronSecurityGroupAware subscriber = (INeutronSecurityGroupAware) entry;
+                    subscriber.neutronSecurityGroupUpdated(securityGroup);
+                }
+            }
+        }
+    }
+
+    private void deleteSecurityGroup(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedSecurityGroup : changes
+                .getRemovedPaths()) {
+            if (deletedSecurityGroup.getTargetType()
+                    .equals(SecurityGroup.class)) {
+                NeutronSecurityGroup securityGroup = fromMd((SecurityGroup) changes
+                        .getOriginalData().get(deletedSecurityGroup));
+                for (Object entry : subscribers) {
+                    INeutronSecurityGroupAware subscriber = (INeutronSecurityGroupAware) entry;
+                    subscriber.neutronSecurityGroupDeleted(securityGroup);
+                }
+            }
+        }
+    }
+
+    private NeutronSecurityGroup fromMd(SecurityGroup group) {
+        NeutronSecurityGroup answer = new NeutronSecurityGroup();
+        if (group.getName() != null) {
+            answer.setSecurityGroupName(group.getName());
+        }
+        if (group.getDescription() != null) {
+            answer.setSecurityGroupDescription(group.getDescription());
+        }
+        if (group.getTenantId() != null) {
+            answer.setSecurityGroupTenantID(group.getTenantId().getValue()
+                    .replace("-", ""));
+        }
+        if (group.getSecurityRules() != null) {
+            NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
+                    .fetchINeutronSecurityRuleCRUD(this);
+            INeutronSecurityRuleCRUD srCrud = interfaces
+                    .getSecurityRuleInterface();
+
+            List<NeutronSecurityRule> rules = new ArrayList<>();
+            for (Uuid uuid : group.getSecurityRules()) {
+                rules.add(srCrud.getNeutronSecurityRule(uuid.getValue()));
+            }
+            answer.setSecurityRules(rules);
+        }
+        if (group.getUuid() != null) {
+            answer.setID(group.getUuid().getValue());
+        }
+        return answer;
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityRuleDataChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSecurityRuleDataChangeListener.java
new file mode 100644 (file)
index 0000000..6f09a7f
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.Map.Entry;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
+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.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;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+public class NeutronSecurityRuleDataChangeListener implements DataChangeListener, AutoCloseable {
+
+    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(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,"IPv4")
+            .put(EthertypeV6.class,"IPv6")
+            .build();
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronSecurityRuleDataChangeListener(DataBroker db) {
+        this.db = db;
+        InstanceIdentifier<SecurityRule> path = InstanceIdentifier
+                .create(Neutron.class).child(SecurityRules.class)
+                .child(SecurityRule.class);
+        LOG.debug("Register listener for Neutron Secutiry rules model data changes");
+        registration = this.db.registerDataChangeListener(
+                LogicalDatastoreType.CONFIGURATION, path, this,
+                DataChangeScope.ONE);
+
+    }
+
+    @Override
+    public void onDataChanged(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}", changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(
+                INeutronSecurityRuleAware.class, this);
+        createSecurityRule(changes, subscribers);
+        updateSecurityRule(changes, subscribers);
+        deleteSecurityRule(changes, subscribers);
+    }
+
+    private void createSecurityRule(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newSecutiryRule : changes
+                .getCreatedData().entrySet()) {
+            if (newSecutiryRule.getValue() instanceof SecurityRule) {
+                NeutronSecurityRule secutiryRule = fromMd((SecurityRule) newSecutiryRule
+                        .getValue());
+                for (Object entry : subscribers) {
+                    INeutronSecurityRuleAware subscriber = (INeutronSecurityRuleAware) entry;
+                    subscriber.neutronSecurityRuleCreated(secutiryRule);
+                }
+            }
+        }
+
+    }
+
+    private void updateSecurityRule(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updateSecurityRule : changes
+                .getUpdatedData().entrySet()) {
+            if (updateSecurityRule.getValue() instanceof SecurityRule) {
+                NeutronSecurityRule securityRule = fromMd((SecurityRule) updateSecurityRule
+                        .getValue());
+                for (Object entry : subscribers) {
+                    INeutronSecurityRuleAware subscriber = (INeutronSecurityRuleAware) entry;
+                    subscriber.neutronSecurityRuleUpdated(securityRule);
+                }
+            }
+        }
+    }
+
+    private void deleteSecurityRule(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedSecurityRule : changes
+                .getRemovedPaths()) {
+            if (deletedSecurityRule.getTargetType().equals(SecurityRule.class)) {
+                NeutronSecurityRule securityRule = fromMd((SecurityRule) changes
+                        .getOriginalData().get(deletedSecurityRule));
+                for (Object entry : subscribers) {
+                    INeutronSecurityRuleAware subscriber = (INeutronSecurityRuleAware) entry;
+                    subscriber.neutronSecurityRuleDeleted(securityRule);
+                }
+            }
+        }
+    }
+
+    private NeutronSecurityRule fromMd(SecurityRule rule) {
+        NeutronSecurityRule answer = new NeutronSecurityRule();
+        if (rule.getTenantId() != null) {
+            answer.setSecurityRuleTenantID(rule.getTenantId().getValue()
+                    .replace("-", ""));
+        }
+        if (rule.getDirection() != null) {
+            answer.setSecurityRuleDirection(DIRECTION_MAP.get(rule
+                    .getDirection()));
+        }
+        if (rule.getSecurityGroupId() != null) {
+            answer.setSecurityRuleGroupID(rule.getSecurityGroupId().getValue());
+        }
+        if (rule.getRemoteGroupId() != null) {
+            answer.setSecurityRemoteGroupID(rule.getRemoteGroupId().getValue());
+        }
+        if (rule.getRemoteIpPrefix() != null) {
+            answer.setSecurityRuleRemoteIpPrefix(rule.getRemoteIpPrefix().getIpv4Prefix()!= null?
+                    rule.getRemoteIpPrefix().getIpv4Prefix().getValue():rule.getRemoteIpPrefix().getIpv6Prefix().getValue());
+        }
+        if (rule.getProtocol() != null) {
+            answer.setSecurityRuleProtocol(PROTOCOL_MAP.get(rule.getProtocol()));
+        }
+        if (rule.getEthertype() != null) {
+            answer.setSecurityRuleEthertype(ETHERTYPE_MAP.get(rule
+                    .getEthertype()));
+        }
+        if (rule.getPortRangeMin() != null) {
+            answer.setSecurityRulePortMin(Integer.valueOf(rule
+                    .getPortRangeMin()));
+        }
+        if (rule.getPortRangeMax() != null) {
+            answer.setSecurityRulePortMax(Integer.valueOf(rule
+                    .getPortRangeMax()));
+        }
+        if (rule.getId() != null) {
+            answer.setID(rule.getId().getValue());
+        }
+        return answer;
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSubnetChangeListener.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/translator/iaware/impl/NeutronSubnetChangeListener.java
new file mode 100644 (file)
index 0000000..916598d
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * 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.openstack.netvirt.translator.iaware.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnetIPAllocationPool;
+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.crud.NeutronCRUDInterfaces;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSubnetAware;
+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.neutron.constants.rev150712.Dhcpv6Base;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Off;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Slaac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Stateless;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnet.attributes.AllocationPools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableBiMap;
+
+public class NeutronSubnetChangeListener implements DataChangeListener, AutoCloseable{
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronSubnetChangeListener.class);
+
+    private static final ImmutableBiMap<Class<? extends IpVersionBase>,Integer> IPV_MAP
+    = new ImmutableBiMap.Builder<Class<? extends IpVersionBase>,Integer>()
+    .put(IpVersionV4.class, 4)
+    .put(IpVersionV6.class, 6)
+    .build();
+
+    private static final ImmutableBiMap<Class<? extends Dhcpv6Base>,String> DHCPV6_MAP
+    = new ImmutableBiMap.Builder<Class<? extends Dhcpv6Base>,String>()
+    .put(Dhcpv6Off.class,"off")
+    .put(Dhcpv6Stateful.class,"dhcpv6-stateful")
+    .put(Dhcpv6Slaac.class,"slaac")
+    .put(Dhcpv6Stateless.class,"dhcpv6-stateless")
+    .build();
+
+    private ListenerRegistration<DataChangeListener> registration;
+    private DataBroker db;
+
+    public NeutronSubnetChangeListener(DataBroker db){
+        this.db = db;
+        InstanceIdentifier<Subnet> path = InstanceIdentifier
+                .create(Neutron.class)
+                .child(Subnets.class)
+                .child(Subnet.class);
+        LOG.debug("Register listener for Neutron Subnet model data changes");
+        registration =
+                this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, DataChangeScope.ONE);
+
+    }
+
+    @Override
+    public void onDataChanged(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
+        LOG.trace("Data changes : {}",changes);
+
+        Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronSubnetAware.class, this);
+        createSubnet(changes, subscribers);
+        updateSubnet(changes, subscribers);
+        deleteSubnet(changes, subscribers);
+    }
+
+    private void createSubnet(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> newSubnet : changes.getCreatedData().entrySet()) {
+               if(newSubnet.getValue() instanceof Subnet){
+                NeutronSubnet subnet = fromMd((Subnet)newSubnet.getValue());
+                for(Object entry: subscribers){
+                    INeutronSubnetAware subscriber = (INeutronSubnetAware)entry;
+                    subscriber.neutronSubnetCreated(subnet);
+                }
+               }
+        }
+    }
+
+    private void updateSubnet(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (Entry<InstanceIdentifier<?>, DataObject> updateSubnet : changes.getUpdatedData().entrySet()) {
+               if(updateSubnet.getValue() instanceof Subnet){
+                NeutronSubnet subnet = fromMd((Subnet)updateSubnet.getValue());
+                for(Object entry: subscribers){
+                    INeutronSubnetAware subscriber = (INeutronSubnetAware)entry;
+                    subscriber.neutronSubnetUpdated(subnet);
+                }
+               }
+        }
+    }
+
+    private void deleteSubnet(
+            AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
+            Object[] subscribers) {
+        for (InstanceIdentifier<?> deletedSubnetPath : changes.getRemovedPaths()) {
+               if(deletedSubnetPath.getTargetType().equals(Subnet.class)){
+                NeutronSubnet subnet = fromMd((Subnet)changes.getOriginalData().get(deletedSubnetPath));
+                for(Object entry: subscribers){
+                    INeutronSubnetAware subscriber = (INeutronSubnetAware)entry;
+                    subscriber.neutronSubnetDeleted(subnet);
+                }
+               }
+        }
+    }
+
+    /*
+     * This method is borrowed from NeutronSubnetInterface.java class of Neutron Northbound class.
+     * We will be utilizing similar code from other classes from the same package of neutron project.
+     */
+    private NeutronSubnet fromMd(Subnet subnet) {
+        NeutronSubnet result = new NeutronSubnet();
+        result.setName(subnet.getName());
+        result.setTenantID(String.valueOf(subnet.getTenantId().getValue()).replace("-",""));
+        result.setNetworkUUID(subnet.getNetworkId().getValue());
+        result.setIpVersion(IPV_MAP.get(subnet.getIpVersion()));
+        result.setCidr(subnet.getCidr());
+        if (subnet.getGatewayIp() != null) {
+            result.setGatewayIP(String.valueOf(subnet.getGatewayIp().getValue()));
+        }
+        if (subnet.getIpv6RaMode() != null) {
+            result.setIpV6RaMode(DHCPV6_MAP.get(subnet.getIpv6RaMode()));
+        }
+        if (subnet.getIpv6AddressMode() != null) {
+            result.setIpV6AddressMode(DHCPV6_MAP.get(subnet.getIpv6AddressMode()));
+        }
+        result.setEnableDHCP(subnet.isEnableDhcp());
+        if (subnet.getAllocationPools() != null) {
+            List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<>();
+            for (AllocationPools allocationPool : subnet.getAllocationPools()) {
+                NeutronSubnetIPAllocationPool pool = new NeutronSubnetIPAllocationPool();
+                pool.setPoolStart(allocationPool.getStart());
+                pool.setPoolEnd(allocationPool.getEnd());
+                allocationPools.add(pool);
+            }
+            result.setAllocationPools(allocationPools);
+        }
+        if (subnet.getDnsNameservers() != null) {
+            List<String> dnsNameServers = new ArrayList<>();
+            for (IpAddress dnsNameServer : subnet.getDnsNameservers()) {
+                dnsNameServers.add(String.valueOf(dnsNameServer.getValue()));
+            }
+            result.setDnsNameservers(dnsNameServers);
+        }
+        result.setID(subnet.getUuid().getValue());
+
+        // read through the ports and put the ones in this subnet into the internal
+        // myPorts object.
+       Set<NeutronPort> allPorts = new HashSet<>();
+        NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
+            .fetchINeutronPortCRUD(this);
+        INeutronPortCRUD portIf = interfaces.getPortInterface();
+        for (NeutronPort port : portIf.getAllPorts()) {
+            if (port.getFixedIPs() != null) {
+                for (Neutron_IPs ip : port.getFixedIPs()) {
+                    if (ip.getSubnetUUID().equals(result.getID())) {
+                        allPorts.add(port);
+                    }
+                }
+            }
+        }
+        List<NeutronPort> ports = new ArrayList<>();
+        ports.addAll(allPorts);
+        result.setPorts(ports);
+        return result;
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+
+}
index afa353bbdeae7ff8d7d0731b55968755950b6391..70196830f93ac51db7f91a64b73da028734f68b1 100644 (file)
@@ -49,13 +49,14 @@ public class AbstractEventTest {
     public void testAbstractEvent(){
         assertEquals("Error, getAction() did not return the correct value", Action.DELETE, abstractEvent1.getAction());
 
-        assertEquals("Error, getHandletType() did not return the correct value", HandlerType.SOUTHBOUND, abstractEvent1.getHandlerType());
+        assertEquals("Error, getHandlerType() did not return the correct value", HandlerType.SOUTHBOUND, abstractEvent1.getHandlerType());
 
         assertTrue("Error, equals() did not succeed", abstractEvent2.equals(abstractEvent3));
 
         assertNotNull("Error, hashCode() did not return any value", abstractEvent1.hashCode());
         assertEquals("Error, hashCode() is not consistent", abstractEvent2.hashCode(), abstractEvent3.hashCode());
 
-        assertEquals("Error, toString() did not return the correct value", "AbstractEvent [handlerType=SOUTHBOUND action=DELETE]", abstractEvent1.toString());
+        assertEquals("Error, toString() did not return the correct value",
+                "AbstractEvent [transactionId=1 handlerType=SOUTHBOUND action=DELETE]", abstractEvent1.toString());
     }
 }
index 4d9435ef4e842884fa372ee45e4ea64cc4eb872c..9640e603d0881896952e83739e4eb8967af05061 100644 (file)
@@ -22,13 +22,11 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.NeutronFirewall;
-import org.opendaylight.neutron.spi.NeutronFirewallPolicy;
-import org.opendaylight.neutron.spi.NeutronFirewallRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewall;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallPolicy;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFirewallRule;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
-import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -152,7 +150,7 @@ public class FWaasHandlerTest {
         PowerMockito.mockStatic(ServiceHelper.class);
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, fwaasHandler)).thenReturn(eventDispatcher);
 
-        fwaasHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        fwaasHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", fwaasHandler.eventDispatcher, eventDispatcher);
     }
index c05ac5e0135a9a3fb35a78d863443afe0c24dd38..cbfeed386e6c5f625baa50ee3f79ea3e4ac73473 100644 (file)
@@ -21,12 +21,11 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.opendaylight.neutron.spi.NeutronFloatingIP;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -64,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
@@ -85,7 +84,7 @@ public class FloatingIPHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, floatingHandler)).thenReturn(eventDispatcher);
         PowerMockito.when(ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, floatingHandler)).thenReturn(neutronL3Adapter);
 
-        floatingHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        floatingHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", floatingHandler.eventDispatcher, eventDispatcher);
         assertEquals("Error, did not return the correct object", getNeutronL3Adapter(), neutronL3Adapter);
index d2cad128a6d7347bcb47e36b53fa3f02ca8d37cf..806231e004bd33b3698199247a03579f43322b90 100644 (file)
@@ -31,14 +31,14 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronLoadBalancer;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
@@ -47,7 +47,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -201,7 +201,7 @@ public class LBaaSHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(LoadBalancerProvider.class, lbaasHandler)).thenReturn(loadBalancerProvider);
         PowerMockito.when(ServiceHelper.getGlobalInstance(NodeCacheManager.class, lbaasHandler)).thenReturn(nodeCacheManager);
 
-        lbaasHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        lbaasHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", lbaasHandler.eventDispatcher, eventDispatcher);
         assertEquals("Error, did not return the correct object", getField("loadBalancerProvider"), loadBalancerProvider);
index 9ed3dbe4aa128b3d96916a3fb79b646cc6d1afd1..35317e0d443317a7318c50b3c7240308f2239794 100644 (file)
@@ -30,14 +30,14 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronLoadBalancer;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
@@ -46,7 +46,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -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);
 
@@ -197,7 +197,7 @@ public class LBaaSPoolHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(LoadBalancerProvider.class, lBaaSPoolHandler)).thenReturn(loadBalancerProvider);
         PowerMockito.when(ServiceHelper.getGlobalInstance(NodeCacheManager.class, lBaaSPoolHandler)).thenReturn(nodeCacheManager);
 
-        lBaaSPoolHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        lBaaSPoolHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", lBaaSPoolHandler.eventDispatcher, eventDispatcher);
         assertEquals("Error, did not return the correct object", getField("loadBalancerProvider"), loadBalancerProvider);
index d9575c3b635f2aa0b4ff6294af46e6406a08d8ad..ee02019085076b70016da10c46722e8f2cbfa397 100644 (file)
@@ -30,14 +30,14 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerCRUD;
-import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronLoadBalancer;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
-import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancer;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPool;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronLoadBalancerPoolMember;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
@@ -46,7 +46,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -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);
 
@@ -220,7 +220,7 @@ public class LBaaSPoolMemberHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(LoadBalancerProvider.class, lBaaSPoolMemberHandler)).thenReturn(loadBalancerProvider);
         PowerMockito.when(ServiceHelper.getGlobalInstance(NodeCacheManager.class, lBaaSPoolMemberHandler)).thenReturn(nodeCacheManager);
 
-        lBaaSPoolMemberHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        lBaaSPoolMemberHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", lBaaSPoolMemberHandler.eventDispatcher, eventDispatcher);
         assertEquals("Error, did not return the correct object", getField("loadBalancerProvider"), loadBalancerProvider);
index 53bffdcd6abdfebea9841b23bd7fec34374ef520..455bee9cd1426a55744066b79491acc3d0d90fcf 100644 (file)
@@ -28,8 +28,8 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
@@ -40,7 +40,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -164,7 +164,7 @@ public class NetworkHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, networkHandler)).thenReturn(southbound);
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, networkHandler)).thenReturn(eventDispatcher);
 
-        networkHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        networkHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("tenantNetworkManager"), tenantNetworkManager);
         assertEquals("Error, did not return the correct object", getField("bridgeConfigurationManager"), bridgeConfigurationManager);
index 87a8c69243bba1a235f2350f1ff5372217581868..fce0462938234e4239008633ecf6560b6a00504f 100644 (file)
@@ -19,13 +19,13 @@ import java.util.Map;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronSubnet;
-import org.opendaylight.neutron.spi.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 /**
@@ -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 db98417f9a2324e7bd8a47119b511f3a2471db30..6d72ee26a441fe3b32943eb137ef0d2fb5a03ef8 100644 (file)
@@ -26,7 +26,7 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
@@ -35,7 +35,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -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);
@@ -120,7 +120,7 @@ public class PortHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, portHandler)).thenReturn(southbound);
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, portHandler)).thenReturn(eventDispatcher);
 
-        portHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        portHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("nodeCacheManager"), nodeCacheManager);
         assertEquals("Error, did not return the correct object", getField("neutronL3Adapter"), neutronL3Adapter);
index 5668c06283cca8f2ce92d21ab248df5f45a8a55e..660aad36146458a2498a363ee203e5e33890c34f 100644 (file)
@@ -21,12 +21,12 @@ 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.neutron.spi.NeutronSecurityGroup;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -41,6 +41,7 @@ public class PortSecurityHandlerTest {
 
     @InjectMocks private PortSecurityHandler portSecurityHandler;
     private PortSecurityHandler posrtSecurityHandlerSpy;
+    @Mock EventDispatcher eventDispatcher;
 
     @Before
     public void setUp() {
@@ -73,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
@@ -86,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
@@ -101,7 +102,7 @@ public class PortSecurityHandlerTest {
         PowerMockito.mockStatic(ServiceHelper.class);
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, portSecurityHandler)).thenReturn(eventDispatcher);
 
-        portSecurityHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        portSecurityHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", portSecurityHandler.eventDispatcher, eventDispatcher);
     }
index bccb4dccea5040780812a97b2913b6eadb8fce1e..c993984100a1e603c9fa2fc2851e812b6d2a4afa 100644 (file)
@@ -21,13 +21,12 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.opendaylight.neutron.spi.NeutronRouter;
-import org.opendaylight.neutron.spi.NeutronRouter_Interface;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronRouter_Interface;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -97,7 +96,7 @@ public class RouterHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, routerHandler)).thenReturn(neutronL3Adapter);
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, routerHandler)).thenReturn(eventDispatcher);
 
-        routerHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        routerHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("neutronL3Adapter"), neutronL3Adapter);
         assertEquals("Error, did not return the correct object", routerHandler.eventDispatcher, eventDispatcher);
index 818f285489d244f4eb709c664c8310f19bd71d78..bc754725ca67b605dd23c25e020dea75a805a6e0 100644 (file)
@@ -25,7 +25,7 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.SouthboundEvent.Type;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
@@ -46,7 +46,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.re
 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.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -82,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
@@ -219,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);
 
@@ -254,7 +254,7 @@ public class SouthboundHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, southboundHandler)).thenReturn(eventDispatcher);
         PowerMockito.when(ServiceHelper.getGlobalInstance(OvsdbInventoryService.class, southboundHandler)).thenReturn(ovsdbInventoryService);
 
-        southboundHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        southboundHandler.setDependencies(mock(ServiceReference.class));
         assertEquals("Error, did not return the correct object", getField("configurationService"), configurationService);
         assertEquals("Error, did not return the correct object", getField("networkingProviderManager"), networkingProviderManager);
         assertEquals("Error, did not return the correct object", getField("tenantNetworkManager"), tenantNetworkManager);
index d473217aa4afc781464216f6ce1d67fd563cbdd3..10d3c281013d5b129ff43a59beea1cc569f64afe 100644 (file)
@@ -21,12 +21,11 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.opendaylight.neutron.spi.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSubnet;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -65,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
@@ -85,7 +84,7 @@ public class SubnetHandlerTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, subnetHandler)).thenReturn(neutronL3Adapter);
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, subnetHandler)).thenReturn(eventDispatcher);
 
-        subnetHandler.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        subnetHandler.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("neutronL3Adapter"), neutronL3Adapter);
         assertEquals("Error, did not return the correct object", subnetHandler.eventDispatcher, eventDispatcher);
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 {
diff --git a/openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/api/UuidUtilsTest.java b/openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/api/UuidUtilsTest.java
deleted file mode 100644 (file)
index c4d8ef3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2014 Red Hat, Inc.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Authors : Dave Tucker
- */
-
-package org.opendaylight.ovsdb.openstack.netvirt.api;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class UuidUtilsTest {
-
-    static final String NEUTRON_ID = "f1bf546b-79e8-4c42-93c1-147009c85c1d";
-    static final String NEUTRON_KEY = "f1bf546b79e8c4293c1147009c85c1d";
-    static final String INVALID_NEUTRON_ID = "f1bf546b-79e8-4c42-93c1-147009c85c1d-invalid";
-    static final String KEYSTONE_ID = "879704f8cd7d4e60a41177fc99254b5e";
-    static final String KEYSTONE_KEY = "879704f8cd7de60a41177fc99254b5e";
-    static final String GARBAGE = "foobar12345";
-
-    @Test
-    public void testConvertNeutronIDToKey() throws Exception {
-        Assert.assertNull(UuidUtils.convertNeutronIDToKey(null));
-        Assert.assertNull(UuidUtils.convertNeutronIDToKey(INVALID_NEUTRON_ID));
-        Assert.assertEquals(KEYSTONE_KEY,UuidUtils.convertNeutronIDToKey(KEYSTONE_ID));
-        Assert.assertEquals(NEUTRON_KEY, UuidUtils.convertNeutronIDToKey(NEUTRON_ID));
-        /* ToDo: Validation check in this method should be stricter
-        This assertion should ideally fail, but it passes today
-        */
-        Assert.assertEquals(UuidUtils.convertNeutronIDToKey(GARBAGE), GARBAGE);
-    }
-
-    @Test
-    public void testIsValidNeutronID() throws Exception {
-        Assert.assertTrue(UuidUtils.isValidNeutronID(NEUTRON_ID));
-        Assert.assertTrue(UuidUtils.isValidNeutronID(KEYSTONE_ID));
-        Assert.assertFalse(UuidUtils.isValidNeutronID(INVALID_NEUTRON_ID));
-        /* ToDo: Validation check in this method should be stricter
-        This assertion should ideally fail, but it passes today
-        */
-        Assert.assertTrue(UuidUtils.isValidNeutronID(GARBAGE));
-    }
-}
\ No newline at end of file
index d549a3489833fcbd3b4267c3ec89df94973609ea..c5073c336340f130074a7dbe6f8e2e558b83a1c2 100644 (file)
@@ -12,6 +12,7 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyList;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.RETURNS_MOCKS;
@@ -33,17 +34,18 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbTables;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeSystem;
 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.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -222,7 +224,7 @@ public class BridgeConfigurationManagerImplTest {
         PowerMockito.mockStatic(ConfigProperties.class);
         when(ConfigProperties.getProperty(any(Class.class), anyString())).thenReturn(ADDRESS);
 
-        when(southbound.addBridge(any(Node.class), anyString(), anyString())).thenReturn(true);
+        when(southbound.addBridge(any(Node.class), anyString(), anyList(), eq(DatapathTypeSystem.class))).thenReturn(true);
         when(configurationService.isL3ForwardingEnabled()).thenReturn(true);
 
         bridgeConfigurationManagerImpl.prepareNode(node);
@@ -262,12 +264,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);
@@ -338,7 +344,7 @@ public class BridgeConfigurationManagerImplTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(NetworkingProviderManager.class, bridgeConfigurationManagerImpl)).thenReturn(networkingProviderManager);
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, bridgeConfigurationManagerImpl)).thenReturn(southbound);
 
-        bridgeConfigurationManagerImpl.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        bridgeConfigurationManagerImpl.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("configurationService"), configurationService);
         assertEquals("Error, did not return the correct object", getField("networkingProviderManager"), networkingProviderManager);
index 9c774bcfb2869d3277fa641ab3e442677a79140d..bce39e44c1c3619bfe2f374ae44d1dc7f271d4c4 100644 (file)
@@ -28,7 +28,7 @@ import org.opendaylight.ovsdb.utils.config.ConfigProperties;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -96,7 +96,7 @@ public class ConfigurationServiceImplTest {
         PowerMockito.mockStatic(ServiceHelper.class);
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, configurationServiceImpl)).thenReturn(southbound);
 
-        configurationServiceImpl.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        configurationServiceImpl.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("southbound"), southbound);
     }
diff --git a/openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtilsTest.java b/openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/MdsalUtilsTest.java
deleted file mode 100644 (file)
index f07d227..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2015 Inocybe and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-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 org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-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;
-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.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-/**
- * Unit test for class {@link MdsalUtils}
- *
- */
-@RunWith(MockitoJUnitRunner.class)
-@SuppressWarnings({ "unchecked", "rawtypes" })
-public class MdsalUtilsTest {
-
-    @InjectMocks private MdsalUtils mdsalUtils;
-
-    @Mock private DataBroker databroker;
-
-    @Test
-    public void testDelete() {
-        WriteTransaction writeTransaction = mock(WriteTransaction.class);
-        when(databroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
-        CheckedFuture<Void, TransactionCommitFailedException> future = mock(CheckedFuture.class);
-        when(writeTransaction.submit()).thenReturn(future );
-
-        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, mock(InstanceIdentifier.class));
-
-        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(1)).submit();
-
-        assertTrue("Error, the delete transaction failed", result);
-    }
-
-    @Test
-    public void testMerge() {
-        WriteTransaction writeTransaction = mock(WriteTransaction.class);
-        when(databroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
-        CheckedFuture<Void, TransactionCommitFailedException> future = mock(CheckedFuture.class);
-        when(writeTransaction.submit()).thenReturn(future );
-
-        boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, mock(InstanceIdentifier.class), mock(DataObject.class));
-
-        verify(writeTransaction, times(1)).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class), anyBoolean());
-        verify(writeTransaction, times(1)).submit();
-
-        assertTrue("Error, the merge transaction failed", result);
-    }
-
-    @Test
-    public void testPut() {
-        WriteTransaction writeTransaction = mock(WriteTransaction.class);
-        when(databroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
-        CheckedFuture<Void, TransactionCommitFailedException> future = mock(CheckedFuture.class);
-        when(writeTransaction.submit()).thenReturn(future );
-
-        boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, mock(InstanceIdentifier.class), mock(DataObject.class));
-
-        verify(writeTransaction, times(1)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class), anyBoolean());
-        verify(writeTransaction, times(1)).submit();
-
-        assertTrue("Error, the put transaction failed", result);
-    }
-
-    @Test
-    public void testRead() throws ReadFailedException {
-        ReadOnlyTransaction readOnlyTransaction = mock(ReadOnlyTransaction.class);
-        when(databroker.newReadOnlyTransaction()).thenReturn(readOnlyTransaction);
-        CheckedFuture<Optional, ReadFailedException> future = mock(CheckedFuture.class);
-        Optional opt = mock(Optional.class);
-        when(opt.isPresent()).thenReturn(true);
-        DataObject obj = mock(DataObject.class);
-        when(opt.get()).thenReturn(obj );
-        when(future.checkedGet()).thenReturn(opt);
-        when(readOnlyTransaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(future);
-
-        DataObject result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, mock(InstanceIdentifier.class));
-
-        verify(readOnlyTransaction, times(1)).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(readOnlyTransaction, times(1)).close();
-
-        assertEquals("Error, the read transaction failed", obj, result);
-    }
-}
index 82ccf2571ec00b5d607eb51aa3d1ab0dd583156d..fc9a266f80cb7917c6c721b0c37d10f32cb3bdfc 100644 (file)
@@ -35,16 +35,16 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronFloatingIP;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronRouter;
-import org.opendaylight.neutron.spi.NeutronRouter_Interface;
-import org.opendaylight.neutron.spi.NeutronSubnet;
-import org.opendaylight.neutron.spi.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronFloatingIP;
+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.NeutronSubnet;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+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.api.Action;
 import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
@@ -63,7 +63,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.OvsdbTerminationPointAugmentation;
 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.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.api.support.membermodification.MemberMatcher;
@@ -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,12 @@ 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));
+        TenantNetworkManager tenantNetworkManager = mock(TenantNetworkManager.class);
+        MemberModifier.field(NeutronL3Adapter.class, "tenantNetworkManager").set(neutronL3Adapter , tenantNetworkManager);
+        when(tenantNetworkManager.isTenantNetworkPresentInNode(any(Node.class), eq(ID))).thenReturn(true);
+        PowerMockito.doReturn(15L).when(neutronL3Adapter, "getDpidForIntegrationBridge", any(Node.class));
 
         // init instance variables
         networkIdToRouterMacCache .put(UUID, MAC_ADDRESS);
@@ -519,10 +523,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 +535,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,20 +565,21 @@ 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);
         when(neutronPort.getFixedIPs()).thenReturn(ips);
+        when(neutronPort.getNetworkUUID()).thenReturn(UUID);
         NeutronSubnet neutronSubnet = mock(NeutronSubnet.class);
         when(neutronSubnet.getNetworkUUID()).thenReturn(UUID);
         when(neutronSubnet.getGatewayIP()).thenReturn(IP);
@@ -591,9 +588,10 @@ public class NeutronL3AdapterTest {
         when(neutronNetwork.getProviderSegmentationID()).thenReturn(ID);
         when(neutronNetwork.getRouterExternal()).thenReturn(false); //might change that to true
         when(neutronNetwork.getNetworkUUID()).thenReturn(UUID);
+        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));
@@ -605,6 +603,7 @@ public class NeutronL3AdapterTest {
         // init instance variables
         INeutronPortCRUD neutronPortCache = mock(INeutronPortCRUD.class);
         PowerMockito.when(neutronPortCache.getPort(anyString())).thenReturn(neutronPort);
+        PowerMockito.when(neutronPortCache.getAllPorts()).thenReturn(new ArrayList<NeutronPort>());
         INeutronSubnetCRUD neutronSubnetCache = mock(INeutronSubnetCRUD.class);
         PowerMockito.when(neutronSubnetCache.getSubnet(anyString())).thenReturn(neutronSubnet);
         INeutronNetworkCRUD neutronNetworkCache = mock(INeutronNetworkCRUD.class);
@@ -618,7 +617,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();
@@ -638,14 +637,16 @@ public class NeutronL3AdapterTest {
 
         networkIdToRouterMacCache.put(UUID, MAC_ADDRESS);
         networkIdToRouterIpListCache.put(UUID, ips);
+        subnetIdToRouterInterfaceCache.put(UUID, intf);
         networkIdToRouterMacCacheSize = networkIdToRouterMacCache.size();
         networkIdToRouterIpListCacheSize = networkIdToRouterIpListCache.size();
         subnetIdToRouterInterfaceCacheSize = subnetIdToRouterInterfaceCache.size();
 
-        Whitebox.invokeMethod(neutronL3Adapter, "programFlowsForNeutronRouterInterface", intf, true);
+        Whitebox.invokeMethod(neutronL3Adapter, "handleNeutronRouterInterfaceEvent", neutronRouter, intf, Action.DELETE);
 
+        PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowsForNeutronRouterInterface", intf, true);
         PowerMockito.verifyPrivate(neutronL3Adapter, times(2)).invoke("getDpidForIntegrationBridge", any(Node.class));
-        PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowsForNeutronRouterInterfacePair", any(Node.class), anyLong(), any(NeutronRouter_Interface.class), any(NeutronRouter_Interface.class), any(NeutronNetwork.class), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE), anyBoolean());
+        PowerMockito.verifyPrivate(neutronL3Adapter, times(2)).invoke("programFlowsForNeutronRouterInterfacePair", any(Node.class), anyLong(), any(NeutronRouter_Interface.class), any(NeutronRouter_Interface.class), any(NeutronNetwork.class), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE), anyBoolean());
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowForNetworkFromExternal", any(Node.class), anyLong(), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE));
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programStaticArpStage1", anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programIpRewriteExclusionStage1", any(Node.class), anyLong(), anyString(), anyString(), eq(Action.DELETE));
@@ -675,7 +676,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);
@@ -710,7 +711,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);
@@ -719,24 +719,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);
@@ -754,28 +748,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
@@ -789,28 +776,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
@@ -824,10 +804,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);
@@ -836,21 +814,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
@@ -863,32 +836,25 @@ 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
+    /*@Test
     public void testPrepareProgramOutboundIpRewriteStage2() throws Exception {
         assertEquals("Error, did not return the correct status code", new Status(StatusCode.BADREQUEST), Whitebox.invokeMethod(neutronL3Adapter, "programOutboundIpRewriteStage2", floatingIpObject, Action.ADD));
 
@@ -897,7 +863,7 @@ public class NeutronL3AdapterTest {
         PowerMockito.when(InetAddress.getByName(anyString())).thenReturn(inetAddress);
 
         assertEquals("Error, did not return the correct status code", new Status(StatusCode.SUCCESS), Whitebox.invokeMethod(neutronL3Adapter, "programOutboundIpRewriteStage2", floatingIpObject, Action.ADD));
-    }
+    }*/
 
     @Test
     public void testGetMaskLenFromCidr() throws Exception {
@@ -914,14 +880,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
@@ -947,7 +913,7 @@ public class NeutronL3AdapterTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(NodeCacheManager.class, neutronL3Adapter)).thenReturn(nodeCacheManager);
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, neutronL3Adapter)).thenReturn(southbound);
 
-        neutronL3Adapter.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        neutronL3Adapter.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("tenantNetworkManager"), tenantNetworkManager);
         assertEquals("Error, did not return the correct object", getField("configurationService"), configurationService);
@@ -962,6 +928,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);
@@ -993,6 +961,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 {
@@ -1006,6 +976,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 59bf8ec4867321b874d07369cba028bb0268150d..45d48bb849a3854addb794002448dadb98d72824 100644 (file)
@@ -30,7 +30,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.OvsdbNodeAugmentation;
 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.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -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));
@@ -123,7 +123,7 @@ public class NodeCacheManagerImplTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, nodeCacheManagerImpl)).thenReturn(southbound);
         PowerMockito.when(ServiceHelper.getGlobalInstance(EventDispatcher.class, nodeCacheManagerImpl)).thenReturn(eventDispatcher);
 
-        nodeCacheManagerImpl.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        nodeCacheManagerImpl.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("southbound"), southbound);
         assertEquals("Error, did not return the correct object", getSuperField("eventDispatcher"), eventDispatcher);
index 606e27f0fdfbd7ed176e5a7d6ffe71ea383369c4..54e44a45911a93bddc6488a5bb5d65e9fb88ea3c 100644 (file)
@@ -24,7 +24,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbInventoryService;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.osgi.framework.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -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));
 
@@ -85,7 +85,7 @@ public class ProviderNetworkManagerImplTest {
         PowerMockito.mockStatic(ServiceHelper.class);
         PowerMockito.when(ServiceHelper.getGlobalInstance(OvsdbInventoryService.class, providerNetworkManagerImpl)).thenReturn(ovsdbInventoryService);
 
-        providerNetworkManagerImpl.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        providerNetworkManagerImpl.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("ovsdbInventoryService"), ovsdbInventoryService);
     }
diff --git a/openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityGroupCacheManagerImplTest.java b/openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityGroupCacheManagerImplTest.java
new file mode 100644 (file)
index 0000000..eaa2579
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2015 Hewlett-Packard Enterprise and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the 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 static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+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.openstack.netvirt.translator.crud.INeutronSecurityGroupCRUD;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * Unit test fort {@link SecurityGroupCacheManagerImpl}
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(ServiceHelper.class)
+public class SecurityGroupCacheManagerImplTest {
+
+    @InjectMocks private SecurityGroupCacheManagerImpl securityGroupCacheManagerImpl;
+    @Mock private INeutronPortCRUD neutronPortCache;
+    @Mock private INeutronSecurityGroupCRUD securityGroupCache;
+    @Mock NeutronPort neutronPort_Vm1;
+    @Mock NeutronPort neutronPort_Vm2;
+    @Mock NeutronPort neutronPort_Vm3;
+    @Mock NeutronPort neutronPort_Vm4;
+    @Mock NeutronPort neutronPort_Vm5;
+    @Mock SecurityServicesManager securityServicesManager;
+    @Mock NeutronSecurityGroup neutronSecurityGroup_1;
+    @Mock NeutronSecurityGroup neutronSecurityGroup_2;
+    @Mock NeutronSecurityGroup neutronSecurityGroup_3;
+    @Mock NeutronSecurityRule neutronSecurityRule_1;
+    @Mock NeutronSecurityRule neutronSecurityRule_2;
+    @Mock NeutronSecurityRule neutronSecurityRule_3;
+    @Mock Neutron_IPs neutron_ip_1;
+    @Mock Neutron_IPs neutron_ip_2;
+    @Mock Neutron_IPs neutron_ip_3;
+    @Mock Neutron_IPs neutron_ip_4;
+    @Mock Neutron_IPs neutron_ip_5;
+
+    private static final String NEUTRON_PORT_ID_VM_1 = "neutronID_VM_1";
+    private static final String NEUTRON_PORT_ID_VM_2 = "neutronID_VM_2";
+    private static final String NEUTRON_PORT_ID_VM_3 = "neutronID_VM_3";
+    private static final String NEUTRON_PORT_ID_VM_4 = "neutronID_VM_4";
+    private static final String NEUTRON_PORT_ID_VM_5 = "neutronID_VM_5";
+    private static final String SECURITY_GROUP_ID_1 = "securityGroupId_1";
+    private static final String SECURITY_GROUP_ID_2 = "securityGroupId_2";
+    private static final String SECURITY_GROUP_ID_3 = "securityGroupId_3";
+    private static final List<Neutron_IPs> neutron_IPs_1 = new ArrayList<>();
+    private static final List<Neutron_IPs> neutron_IPs_2 = new ArrayList<>();
+    private static final List<Neutron_IPs> neutron_IPs_3 = new ArrayList<>();
+    private static final List<Neutron_IPs> neutron_IPs_4 = new ArrayList<>();
+    private static final List<Neutron_IPs> neutron_IPs_5 = new ArrayList<>();
+
+    @Before
+    public void setUp() throws Exception {
+
+        List<NeutronSecurityGroup> securityGroups_Vm_1 = new ArrayList<>();
+        securityGroups_Vm_1.add(neutronSecurityGroup_1);
+        List<NeutronSecurityGroup> securityGroups_Vm_2 = new ArrayList<>();
+        securityGroups_Vm_2.add(neutronSecurityGroup_2);
+        List<NeutronSecurityGroup> securityGroups_Vm_3 = new ArrayList<>();
+        securityGroups_Vm_3.add(neutronSecurityGroup_3);
+        List<NeutronSecurityRule> securityRule_1 = new ArrayList<>();
+        securityRule_1.add(neutronSecurityRule_1);
+        List<NeutronSecurityRule> securityRule_2 = new ArrayList<>();
+        securityRule_2.add(neutronSecurityRule_2);
+        List<NeutronSecurityRule> securityRule_3 = new ArrayList<>();
+        securityRule_3.add(neutronSecurityRule_3);
+
+        neutron_IPs_1.add(neutron_ip_1);
+        neutron_IPs_2.add(neutron_ip_2);
+        neutron_IPs_3.add(neutron_ip_3);
+        neutron_IPs_4.add(neutron_ip_4);
+        neutron_IPs_5.add(neutron_ip_5);
+
+        when(neutronPort_Vm1.getID()).thenReturn(NEUTRON_PORT_ID_VM_1);
+        when(neutronPort_Vm2.getID()).thenReturn(NEUTRON_PORT_ID_VM_2);
+        when(neutronPort_Vm3.getID()).thenReturn(NEUTRON_PORT_ID_VM_3);
+        when(neutronPort_Vm4.getID()).thenReturn(NEUTRON_PORT_ID_VM_4);
+        when(neutronPort_Vm5.getID()).thenReturn(NEUTRON_PORT_ID_VM_5);
+        when(neutronPort_Vm1.getSecurityGroups()).thenReturn(securityGroups_Vm_1);
+        when(neutronPort_Vm2.getSecurityGroups()).thenReturn(securityGroups_Vm_1);
+        when(neutronPort_Vm3.getSecurityGroups()).thenReturn(securityGroups_Vm_3);
+        when(neutronPort_Vm4.getSecurityGroups()).thenReturn(securityGroups_Vm_1);
+        when(neutronPort_Vm5.getSecurityGroups()).thenReturn(securityGroups_Vm_3);
+        when(neutronSecurityGroup_1.getSecurityRules()).thenReturn(securityRule_1);
+        when(neutronSecurityGroup_2.getSecurityRules()).thenReturn(securityRule_2);
+        when(neutronSecurityGroup_3.getSecurityRules()).thenReturn(securityRule_3);
+        when(neutronSecurityGroup_1.getSecurityGroupUUID()).thenReturn(SECURITY_GROUP_ID_1);
+        when(neutronSecurityGroup_2.getSecurityGroupUUID()).thenReturn(SECURITY_GROUP_ID_2);
+        when(neutronSecurityGroup_3.getSecurityGroupUUID()).thenReturn(SECURITY_GROUP_ID_3);
+        when(neutronSecurityRule_1.getSecurityRemoteGroupID()).thenReturn(SECURITY_GROUP_ID_1);
+        when(neutronSecurityRule_3.getSecurityRemoteGroupID()).thenReturn(SECURITY_GROUP_ID_2);
+        when(neutronPort_Vm1.getFixedIPs()).thenReturn(neutron_IPs_1);
+        when(neutronPort_Vm2.getFixedIPs()).thenReturn(neutron_IPs_2);
+        when(neutronPort_Vm3.getFixedIPs()).thenReturn(neutron_IPs_3);
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(neutronPort_Vm1);
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_2))).thenReturn(neutronPort_Vm2);
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_3))).thenReturn(neutronPort_Vm3);
+    }
+
+    /**
+     * Remote Cache is empty a new port is added.
+     */
+    @Test
+    public void testPortAddedWithNoRemoteSGInCache() {
+        securityGroupCacheManagerImpl.portAdded(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_1);
+        verify(securityServicesManager, times(0)).syncSecurityRule(any(NeutronPort.class), any(NeutronSecurityRule.class), any(Neutron_IPs.class),anyBoolean());
+    }
+
+    /**
+     * Remote Cache is empty a new port is removed.
+     */
+    @Test
+    public void testPortRemovedWithNoRemoteSGInCache() {
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_1);
+        securityGroupCacheManagerImpl.portRemoved(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_1);
+        verify(securityServicesManager, times(0)).syncSecurityRule(any(NeutronPort.class), any(NeutronSecurityRule.class), any(Neutron_IPs.class),anyBoolean());
+    }
+
+    /**
+     * neutronSecurityGroup_1 has a rule which has neutronSecurityGroup_1 as remote SG.
+     * A port with neutronSecurityGroup_1 is present in cache and new one is added.
+     */
+    @Test
+    public void testPortAddedWithSelfInCache() {
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_1);
+        securityGroupCacheManagerImpl.portAdded(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_1);
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_2);
+        securityGroupCacheManagerImpl.portAdded(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_2);
+        verify(securityServicesManager, times(1)).syncSecurityRule(eq(neutronPort_Vm1), eq(neutronSecurityRule_1), eq(neutron_ip_2),eq(true));
+    }
+
+    /**
+     * neutronSecurityGroup_1 has a rule which has neutronSecurityGroup_1 as remote SG.
+     * Two port with neutronSecurityGroup_1 is present in cache and  one of them is removed.
+     */
+    @Test
+    public void testPortRemovedWithSelfInCache() {
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_1);
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_2);
+        securityGroupCacheManagerImpl.portRemoved(SECURITY_GROUP_ID_1, NEUTRON_PORT_ID_VM_2);
+        verify(securityServicesManager, times(1)).syncSecurityRule(eq(neutronPort_Vm1), eq(neutronSecurityRule_1), eq(neutron_ip_2),eq(false));
+    }
+
+    /**
+     * neutronSecurityGroup_3 has a rule which has neutronSecurityGroup_2 as remote SG.
+     * A port with neutronSecurityGroup_3 is present in cache. A new port is added with
+     * neutronSecurityGroup_2 as security group.
+     */
+    @Test
+    public void testPortAddedWithCidrInCache() {
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_2, NEUTRON_PORT_ID_VM_3);
+        securityGroupCacheManagerImpl.portAdded(SECURITY_GROUP_ID_2, NEUTRON_PORT_ID_VM_2);
+        verify(securityServicesManager, times(1)).syncSecurityRule(eq(neutronPort_Vm3), eq(neutronSecurityRule_3), eq(neutron_ip_2),eq(true));
+    }
+
+    /**
+     * neutronSecurityGroup_3 has a rule which has neutronSecurityGroup_2 as remote SG.
+     * A port with neutronSecurityGroup_3 is present in cache. A  port with
+     * neutronSecurityGroup_2 as security group is removed..
+     */
+    @Test
+    public void testPortRemovedWithCidrInCache() {
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_2, NEUTRON_PORT_ID_VM_3);
+        securityGroupCacheManagerImpl.portRemoved(SECURITY_GROUP_ID_2, NEUTRON_PORT_ID_VM_2);
+        verify(securityServicesManager, times(1)).syncSecurityRule(eq(neutronPort_Vm3), eq(neutronSecurityRule_3), eq(neutron_ip_2),eq(false));
+    }
+
+    /**
+     *  A port is removed from the cache.
+     */
+    @Test
+    public void testPortRemovedFromCache() {
+        securityGroupCacheManagerImpl.addToCache(SECURITY_GROUP_ID_2, NEUTRON_PORT_ID_VM_3);
+        securityGroupCacheManagerImpl.removeFromCache(SECURITY_GROUP_ID_2, NEUTRON_PORT_ID_VM_3);
+        securityGroupCacheManagerImpl.portRemoved(SECURITY_GROUP_ID_2, NEUTRON_PORT_ID_VM_2);
+        verify(securityServicesManager, times(0)).syncSecurityRule(any(NeutronPort.class), any(NeutronSecurityRule.class), any(Neutron_IPs.class),anyBoolean());
+    }
+}
index d7a2e3117705875d24b6209cc49f956f8591f52f..bd048aa291817188291ab90cb21caaa9ad42db5c 100644 (file)
@@ -9,9 +9,13 @@ package org.opendaylight.ovsdb.openstack.netvirt.impl;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.lang.reflect.Field;
@@ -23,13 +27,24 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronSecurityGroup;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+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;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronSubnetCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
+import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
-import org.osgi.framework.BundleContext;
+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.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -43,27 +58,108 @@ import org.powermock.modules.junit4.PowerMockRunner;
 public class SecurityServicesImplTest {
 
     @InjectMocks private SecurityServicesImpl securityServicesImpl;
-
+    @Mock INeutronNetworkCRUD neutronNetworkCache;
     @Mock private INeutronPortCRUD neutronPortCache;
+    @Mock private INeutronSubnetCRUD subNetCache;
     @Mock private Southbound southbound;
+    @Mock private ConfigurationService configurationService;
+    @Mock NeutronNetwork neutronNetwork;
+    @Mock NeutronPort neutronPort_Vm1;
+    @Mock NeutronPort neutronPort_Vm2;
+    @Mock NeutronPort neutronPort_Vm3;
+    @Mock NeutronSecurityGroup neutronSecurityGroup_1;
+    @Mock NeutronSecurityGroup neutronSecurityGroup_2;
+    @Mock NeutronSecurityGroup neutronSecurityGroup_3;
+    @Mock NeutronSecurityRule neutronSecurityRule_1;
+    @Mock NeutronSecurityRule neutronSecurityRule_2;
+    @Mock NeutronSecurityRule neutronSecurityRule_3;
+    @Mock  NeutronPort neutronPort_Dhcp;
+    @Mock Neutron_IPs neutron_ip_1;
+    @Mock Neutron_IPs neutron_ip_2;
+    @Mock Neutron_IPs neutron_ip_3;
+    @Mock NeutronSubnet subnet;
+    @Mock Node node;
+    @Mock OvsdbTerminationPointAugmentation tp;
+    @Mock IngressAclProvider ingressAclService;
+    @Mock EgressAclProvider egressAclService;
 
-    @Mock private NeutronSecurityGroup neutronSecurityGroup;
-
-    private static final String NEUTRON_PORT_ID = "neutronID";
-    private static final String DEVICE_OWNER = "compute";
+    private static final String NEUTRON_PORT_ID_VM_1 = "neutronID_VM_1";
+    private static final String NEUTRON_PORT_ID_VM_2 = "neutronID_VM_2";
+    private static final String NEUTRON_PORT_ID_VM_3 = "neutronID_VM_3";
+    private static final String NEUTRON_PORT_ID_DHCP = "neutronID_VM_DHCP";
+    private static final String SECURITY_GROUP_ID_1 = "securityGroupId_1";
+    private static final String SECURITY_GROUP_ID_2 = "securityGroupId_2";
+    private static final String SECURITY_GROUP_ID_3 = "securityGroupId_3";
+    private static final String DEVICE_OWNER_VM = "compute";
+    private static final String DEVICE_OWNER_DHCP = "dhcp";
+    private static final String SUBNET_UUID = "subnet_uuid";
+    private static final List<Neutron_IPs> neutron_IPs_1 = new ArrayList<>();
+    private static final List<Neutron_IPs> neutron_IPs_2 = new ArrayList<>();
+    private static final List<Neutron_IPs> neutron_IPs_3 = new ArrayList<>();
 
     @Before
     public void setUp(){
-        NeutronPort neutronPort = mock(NeutronPort.class);
+        List<NeutronSecurityGroup> securityGroups_1 = new ArrayList<>();
+        securityGroups_1.add(neutronSecurityGroup_1);
+        List<NeutronSecurityGroup> securityGroups_2 = new ArrayList<>();
+        securityGroups_2.add(neutronSecurityGroup_2);
+        List<NeutronSecurityGroup> securityGroups_3 = new ArrayList<>();
+        securityGroups_3.add(neutronSecurityGroup_3);
+        List<NeutronSecurityRule> securityRule_1 = new ArrayList<>();
+        securityRule_1.add(neutronSecurityRule_1);
+        List<NeutronSecurityRule> securityRule_2 = new ArrayList<>();
+        securityRule_1.add(neutronSecurityRule_2);
+        List<NeutronSecurityRule> securityRule_3 = new ArrayList<>();
+        securityRule_1.add(neutronSecurityRule_3);
 
-        List<NeutronSecurityGroup> securityGroups = new ArrayList<NeutronSecurityGroup>();
-        securityGroups.add(neutronSecurityGroup);
+        neutron_IPs_1.add(neutron_ip_1);
+        neutron_IPs_2.add(neutron_ip_2);
+        neutron_IPs_3.add(neutron_ip_3);
 
-        when(neutronPort.getSecurityGroups()).thenReturn(securityGroups);
-        when(neutronPort.getDeviceOwner()).thenReturn(DEVICE_OWNER);
+        when(neutronPort_Vm1.getID()).thenReturn(NEUTRON_PORT_ID_VM_1);
+        when(neutronPort_Vm2.getID()).thenReturn(NEUTRON_PORT_ID_VM_2);
+        when(neutronPort_Vm3.getID()).thenReturn(NEUTRON_PORT_ID_VM_3);
+        when(neutronPort_Vm1.getSecurityGroups()).thenReturn(securityGroups_1);
+        when(neutronPort_Vm2.getSecurityGroups()).thenReturn(securityGroups_2);
+        when(neutronPort_Vm3.getSecurityGroups()).thenReturn(securityGroups_3);
+        when(neutronSecurityGroup_1.getSecurityRules()).thenReturn(securityRule_1);
+        when(neutronSecurityGroup_2.getSecurityRules()).thenReturn(securityRule_2);
+        when(neutronSecurityGroup_3.getSecurityRules()).thenReturn(securityRule_3);
+        when(neutronSecurityGroup_1.getSecurityGroupUUID()).thenReturn(SECURITY_GROUP_ID_1);
+        when(neutronSecurityGroup_2.getSecurityGroupUUID()).thenReturn(SECURITY_GROUP_ID_2);
+        when(neutronSecurityGroup_3.getSecurityGroupUUID()).thenReturn(SECURITY_GROUP_ID_3);
+        when(neutronPort_Vm1.getDeviceOwner()).thenReturn(DEVICE_OWNER_VM);
+        when(neutronPort_Vm2.getDeviceOwner()).thenReturn(DEVICE_OWNER_VM);
+        when(neutronPort_Vm3.getDeviceOwner()).thenReturn(DEVICE_OWNER_VM);
+        when(neutronPort_Dhcp.getDeviceOwner()).thenReturn(DEVICE_OWNER_DHCP);
+        when(neutronPort_Vm1.getFixedIPs()).thenReturn(neutron_IPs_1);
+        when(neutronPort_Vm2.getFixedIPs()).thenReturn(neutron_IPs_2);
+        when(neutronPort_Vm3.getFixedIPs()).thenReturn(neutron_IPs_3);
+        when(neutron_ip_1.getSubnetUUID()).thenReturn(SUBNET_UUID);
+        List<NeutronPort> portList = new ArrayList<>();
+        portList.add(neutronPort_Vm1);
+        portList.add(neutronPort_Dhcp);
+        when(subnet.getPortsInSubnet()).thenReturn(portList);
 
-        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class), anyString())).thenReturn(NEUTRON_PORT_ID);
-        when(neutronPortCache.getPort(anyString())).thenReturn(neutronPort);
+        List<Node> nodeList = new ArrayList<>();
+        nodeList.add(node);
+        List<OvsdbTerminationPointAugmentation> tpList = new ArrayList<>();
+        tpList.add(tp);
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class), eq("iface-id"))).thenReturn(NEUTRON_PORT_ID_VM_1);
+        when(southbound.readOvsdbTopologyNodes()).thenReturn(nodeList);
+        when(southbound.getBridgeNode(any(Node.class), anyString())).thenReturn(node);
+        when(southbound.getTerminationPointsOfBridge(node)).thenReturn(tpList);
+        when(southbound.getDataPathId(node)).thenReturn(1L);
+        when(southbound.getBridgeName(node)).thenReturn("br-int");
+        when(southbound.getOFPort(any(OvsdbTerminationPointAugmentation.class))).thenReturn(2L);
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class),eq("attached-mac"))).thenReturn("attached-mac");
+        when(configurationService.getIntegrationBridgeName()).thenReturn("br-int");
+        when(neutronNetworkCache.getNetwork(anyString())).thenReturn(neutronNetwork);
+        when(neutronNetwork.getProviderSegmentationID()).thenReturn("1000");
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(neutronPort_Vm1);
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_DHCP))).thenReturn(neutronPort_Dhcp);
+        when(neutronPortCache.getAllPorts()).thenReturn(portList);
+        when(subNetCache.getSubnet(eq(SUBNET_UUID))).thenReturn(subnet);
     }
 
     /**
@@ -80,7 +176,401 @@ public class SecurityServicesImplTest {
     @Test
     public void testSecurityGroupInPort(){
         assertEquals("Error, did not return the good neutronSecurityGroup of securityGroups",
-                     neutronSecurityGroup, securityServicesImpl.getSecurityGroupInPortList(mock(OvsdbTerminationPointAugmentation.class)).get(0));
+                     neutronSecurityGroup_1, securityServicesImpl.getSecurityGroupInPortList(mock(OvsdbTerminationPointAugmentation.class)).get(0));
+    }
+
+    /**
+     * Test getDhcpServerPort returning a valid port.
+     */
+    @Test
+    public void testGetDhcpServerPort() {
+        NeutronPort dhcpPort = securityServicesImpl.getDhcpServerPort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,neutronPort_Dhcp);
+    }
+
+    /**
+     * Test getDhcpServerPort with null port id returned by the southbound.
+     */
+    @Test
+    public void testGetDhcpServerPortWithNullPortId() {
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class), anyString())).thenReturn(null);
+        NeutronPort dhcpPort = securityServicesImpl.getDhcpServerPort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test getDhcpServerPort with port not present in cache.
+     */
+    @Test
+    public void testGetDhcpServerPortWithNullPort() {
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(null);
+        NeutronPort dhcpPort = securityServicesImpl.getDhcpServerPort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test getDhcpServerPort with a dhcp port as the input port.
+     */
+    @Test
+    public void testGetDhcpServerPortWithDhcpPort() {
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(neutronPort_Dhcp);
+        NeutronPort dhcpPort = securityServicesImpl.getDhcpServerPort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,neutronPort_Dhcp);
+    }
+
+    /**
+     * Test getDhcpServerPort with a dhcp port with fixed ip null
+     * for the input port..
+     */
+    @Test
+    public void testGetDhcpServerPortWithFixedIpNull() {
+        when(neutronPort_Vm1.getFixedIPs()).thenReturn(null);
+        NeutronPort dhcpPort = securityServicesImpl.getDhcpServerPort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test getDhcpServerPort with a dhcp port with fixed ip empty
+     * for the input port.
+     */
+    @Test
+    public void testGetDhcpServerPortWithFixedIpEmpty() {
+        when(neutronPort_Vm1.getFixedIPs()).thenReturn(new ArrayList<Neutron_IPs>());
+        NeutronPort dhcpPort = securityServicesImpl.getDhcpServerPort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test getDhcpServerPort with a dhcp port with no port in subnet.
+     */
+    @Test
+    public void testGetDhcpServerPortWithNoPortinSubnet() {
+        when(subnet.getPortsInSubnet()).thenReturn(new ArrayList<NeutronPort>());
+        NeutronPort dhcpPort = securityServicesImpl.getDhcpServerPort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test getNeutronPortFromDhcpIntf with port not present in cache.
+     */
+    @Test
+    public void testGetNeutronPortFromDhcpIntfWithNullPort() {
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(null);
+        NeutronPort dhcpPort = securityServicesImpl.getNeutronPortFromDhcpIntf(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test getNeutronPortFromDhcpIntf with port id returned null
+     * from the southbound.
+     */
+    @Test
+    public void testGetNeutronPortFromDhcpIntfWithNullPortId() {
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class), anyString())).thenReturn(null);
+        NeutronPort dhcpPort = securityServicesImpl.getNeutronPortFromDhcpIntf(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test getNeutronPortFromDhcpIntf valid
+     */
+    @Test
+    public void testGetNeutronPortFromDhcpIntfWithDhcpPort() {
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(neutronPort_Dhcp);
+        NeutronPort dhcpPort = securityServicesImpl.getNeutronPortFromDhcpIntf(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,neutronPort_Dhcp);
+    }
+
+    /**
+     * Test getNeutronPortFromDhcpIntf with the port passed
+     * a vm port.
+     */
+    @Test
+    public void testGetNeutronPortFromDhcpIntfWithVmPort() {
+        NeutronPort dhcpPort = securityServicesImpl.getNeutronPortFromDhcpIntf(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(dhcpPort,null);
+    }
+
+    /**
+     * Test isComputePort with the port passed a vm port.
+     */
+    @Test
+    public void testIsComputePortWithComputePort() {
+        boolean isComputePort = securityServicesImpl.isComputePort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(isComputePort,true);
+    }
+
+    /**
+     * Test isComputePort with the port passed a dhcp port.
+     */
+    @Test
+    public void testIsComputePortWithDhcpPort() {
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(neutronPort_Dhcp);
+        boolean isComputePort = securityServicesImpl.isComputePort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(isComputePort,false);
+    }
+
+    /**
+     * Test isComputePort with port id null from southbound.
+     */
+    @Test
+    public void testIsComputePortWithNullPortId() {
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class), anyString())).thenReturn(null);
+        boolean isComputePort = securityServicesImpl.isComputePort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(isComputePort,false);
+    }
+
+    /**
+     * Test isComputePort with port not present in cache.
+     */
+    @Test
+    public void testIsComputePortWithNullPort() {
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(null);
+        boolean isComputePort = securityServicesImpl.isComputePort(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(isComputePort,false);
+    }
+
+    /**
+     * Test getIpAddressList valid.
+     */
+    @Test
+    public void testGetIpAddressList() {
+        List<Neutron_IPs> ipList = securityServicesImpl.getIpAddressList(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(ipList,neutron_IPs_1);
+    }
+
+    /**
+     * Test getIpAddressList with port not present in cache..
+     */
+    @Test
+    public void testGetIpAddressListWithNullPort() {
+        when(neutronPortCache.getPort(eq(NEUTRON_PORT_ID_VM_1))).thenReturn(null);
+        List<Neutron_IPs> ipList = securityServicesImpl.getIpAddressList(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(ipList,null);
+    }
+
+
+    /**
+     * Test getIpAddressList  with port id null from southbound.
+     */
+    @Test
+    public void testGetIpAddressListWithNullPortId() {
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class), anyString())).thenReturn(null);
+        List<Neutron_IPs> ipList = securityServicesImpl.getIpAddressList(mock(OvsdbTerminationPointAugmentation.class));
+        assertEquals(ipList,null);
+    }
+
+    /**
+     * Test getVmListForSecurityGroup valid.
+     */
+    @Test
+    public void testGetVmListForSecurityGroup() {
+        List<NeutronPort> portList = new ArrayList<>();
+        portList.add(neutronPort_Vm1);
+        portList.add(neutronPort_Vm2);
+        portList.add(neutronPort_Vm3);
+        portList.add(neutronPort_Dhcp);
+        when(neutronPortCache.getAllPorts()).thenReturn(portList);
+        List<Neutron_IPs> ipList = securityServicesImpl.getVmListForSecurityGroup(NEUTRON_PORT_ID_VM_1, SECURITY_GROUP_ID_2);
+        assertEquals(ipList,neutron_IPs_2);
+    }
+
+    /**
+     * Test getVmListForSecurityGroup with no vm with the
+     * SG associated..
+     */
+    @Test
+    public void testGetVmListForSecurityGroupWithNoVm() {
+        List<NeutronPort> portList = new ArrayList<>();
+        portList.add(neutronPort_Vm1);
+        portList.add(neutronPort_Vm2);
+        portList.add(neutronPort_Vm3);
+        portList.add(neutronPort_Dhcp);
+        when(neutronPortCache.getAllPorts()).thenReturn(portList);
+        List<Neutron_IPs> ipList = securityServicesImpl.getVmListForSecurityGroup(NEUTRON_PORT_ID_VM_1, SECURITY_GROUP_ID_1);
+        assert(ipList.isEmpty());
+    }
+
+    /**
+     * Test syncSecurityGroup addition
+     */
+    @Test
+    public void testSyncSecurityGroupAddition() {
+        List<NeutronSecurityGroup> securityGroupsList = new ArrayList<>();
+        securityGroupsList.add(neutronSecurityGroup_1);
+        securityServicesImpl.syncSecurityGroup(neutronPort_Vm1, securityGroupsList, true);
+        verify(ingressAclService, times(1)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(true));
+        verify(egressAclService, times(1)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(true));
+    }
+
+    /**
+     * Test syncSecurityGroup deletion
+     */
+    @Test
+    public void testSyncSecurityGroupDeletion() {
+        List<NeutronSecurityGroup> securityGroupsList = new ArrayList<>();
+        securityGroupsList.add(neutronSecurityGroup_1);
+        securityServicesImpl.syncSecurityGroup(neutronPort_Vm1, securityGroupsList, false);
+        verify(ingressAclService, times(1)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+        verify(egressAclService, times(1)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityGroup deletion with port null
+     */
+    @Test
+    public void testSyncSecurityGroupPortNull() {
+        List<NeutronSecurityGroup> securityGroupsList = new ArrayList<>();
+        securityGroupsList.add(neutronSecurityGroup_1);
+        securityServicesImpl.syncSecurityGroup(null, securityGroupsList, false);
+        verify(ingressAclService, times(0)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+        verify(egressAclService, times(0)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityGroup deletion with Sg null
+     */
+    @Test
+    public void testSyncSecurityGroupSgNull() {
+        List<NeutronSecurityGroup> securityGroupsList = new ArrayList<>();
+        securityGroupsList.add(neutronSecurityGroup_1);
+        when(neutronPort_Vm1.getSecurityGroups()).thenReturn(null);
+        securityServicesImpl.syncSecurityGroup(neutronPort_Vm1, null, false);
+        verify(ingressAclService, times(0)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+        verify(egressAclService, times(0)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityGroup deletion with Mac null
+     */
+    @Test
+    public void testSyncSecurityGroupAttachedMacNull() {
+        List<NeutronSecurityGroup> securityGroupsList = new ArrayList<>();
+        securityGroupsList.add(neutronSecurityGroup_1);
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class),eq("attached-mac"))).thenReturn(null);
+        securityServicesImpl.syncSecurityGroup(neutronPort_Vm1, securityGroupsList, false);
+        verify(ingressAclService, times(0)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+        verify(egressAclService, times(0)).programPortSecurityGroup(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityGroup_1), eq(NEUTRON_PORT_ID_VM_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityRule addition of egress rule.
+     */
+    @Test
+    public void testSyncSecurityRuleAdditionEgress() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("egress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, true);
+        verify(egressAclService, times(1)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(true));
+    }
+
+    /**
+     * Test syncSecurityRule addition of ingress rule.
+     */
+    @Test
+    public void testSyncSecurityRuleAdditionIngress() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("ingress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, true);
+        verify(ingressAclService, times(1)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(true));
+    }
+
+    /**
+     * Test syncSecurityRule deletion of egress rule.
+     */
+    @Test
+    public void testSyncSecurityRuleDeletionEgress() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("egress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, false);
+        verify(egressAclService, times(1)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityRule deletion of ingress rule.
+     */
+    @Test
+    public void testSyncSecurityRuleDeletionIngress() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("ingress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, false);
+        verify(ingressAclService, times(1)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityRule deletion of ingress rule with port null.
+     */
+    @Test
+    public void testSyncSecurityRuleDeletionIngressPortNull() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("ingress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        securityServicesImpl.syncSecurityRule(null, neutronSecurityRule_1, neutron_ip_1, false);
+        verify(ingressAclService, times(0)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityRule deletion of ingress rule with sg null.
+     */
+    @Test
+    public void testSyncSecurityRuleDeletionIngressSgNull() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronPort_Vm1.getSecurityGroups()).thenReturn(null);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("ingress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, false);
+        verify(ingressAclService, times(0)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityRule deletion of ingress rule with mac null.
+     */
+    @Test
+    public void testSyncSecurityRuleDeletionIngressAttachedMacNull() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("ingress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        when(southbound.getInterfaceExternalIdsValue(any(OvsdbTerminationPointAugmentation.class),eq("attached-mac"))).thenReturn(null);
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, false);
+        verify(ingressAclService, times(0)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(false));
+    }
+
+
+    /**
+     * Test syncSecurityRule deletion of ingress rule no ipv4 ether.
+     */
+    @Test
+    public void testSyncSecurityRuleDeletionIngressNonIpV4() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("ingress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv6");
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, false);
+        verify(ingressAclService, times(0)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(false));
+    }
+
+    /**
+     * Test syncSecurityRule deletion of ingress rule with invalid direction.
+     */
+    @Test
+    public void testSyncSecurityRuleDeletionInvalidDirection() {
+        List<NeutronSecurityRule> securityRuleList = new ArrayList<>();
+        securityRuleList.add(neutronSecurityRule_1);
+        when(neutronSecurityRule_1.getSecurityRuleDirection()).thenReturn("outgress");
+        when(neutronSecurityRule_1.getSecurityRuleEthertype()).thenReturn("IPv4");
+        securityServicesImpl.syncSecurityRule(neutronPort_Vm1, neutronSecurityRule_1, neutron_ip_1, false);
+        verify(ingressAclService, times(0)).programPortSecurityRule(eq(new Long(1)), eq("1000"), eq("attached-mac"), eq(2L), eq(neutronSecurityRule_1), eq(neutron_ip_1), eq(false));
     }
 
     @Test
@@ -90,7 +580,7 @@ public class SecurityServicesImplTest {
         PowerMockito.mockStatic(ServiceHelper.class);
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, securityServicesImpl)).thenReturn(southbound);
 
-        securityServicesImpl.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        securityServicesImpl.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("southbound"), southbound);
     }
index 23fe830cc47f83048449d6587724c9a2a661700b..92e92ea7d45c99c66625c02819e6acf0aede2cd2 100644 (file)
@@ -26,17 +26,17 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.neutron.spi.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -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");
@@ -178,7 +178,7 @@ public class TenantNetworkManagerImplTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(VlanConfigurationCache.class, tenantNetworkManagerImpl)).thenReturn(vlanConfigurationCache);
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, tenantNetworkManagerImpl)).thenReturn(southbound);
 
-        tenantNetworkManagerImpl.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        tenantNetworkManagerImpl.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("vlanConfigurationCache"), vlanConfigurationCache);
         assertEquals("Error, did not return the correct object", getField("southbound"), southbound);
index 7d23ebe9d3a7cca593614bc2deda36cdd48129c0..6f4695fb80fbbc78106d78380919dd2f061d9fcb 100644 (file)
@@ -21,14 +21,14 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.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.BundleContext;
+
 import org.osgi.framework.ServiceReference;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
@@ -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);
@@ -89,7 +89,7 @@ public class VlanConfigurationCacheImplTest {
         PowerMockito.when(ServiceHelper.getGlobalInstance(TenantNetworkManager.class, vlanConfigurationCacheImpl)).thenReturn(tenantNetworkManager);
         PowerMockito.when(ServiceHelper.getGlobalInstance(Southbound.class, vlanConfigurationCacheImpl)).thenReturn(southbound);
 
-        vlanConfigurationCacheImpl.setDependencies(mock(BundleContext.class), mock(ServiceReference.class));
+        vlanConfigurationCacheImpl.setDependencies(mock(ServiceReference.class));
 
         assertEquals("Error, did not return the correct object", getField("tenantNetworkManager"), tenantNetworkManager);
         assertEquals("Error, did not return the correct object", getField("southbound"), southbound);
index 8227469facc3e605fcaccd1d1f67adf057c8f60b..c98cc7e3e66b9b94a52dd7c7f8e581701ad8b66f 100644 (file)
@@ -12,12 +12,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>openstack</artifactId>
   <version>1.2.1-SNAPSHOT</version>
   <name>${project.artifactId}</name>
@@ -53,4 +54,25 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <module>net-virt-it</module>
     <module>net-virt-sfc</module>
   </modules>
+
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
 </project>
diff --git a/ovs-sfc/pom.xml b/ovs-sfc/pom.xml
deleted file mode 100644 (file)
index 2ef948c..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-  <modelVersion>4.0.0</modelVersion>
-
-  <parent>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>commons</artifactId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/parent</relativePath>
-  </parent>
-
-  <artifactId>ovssfc</artifactId>
-  <version>0.2.0-SNAPSHOT</version>
-  <packaging>bundle</packaging>
-  <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
-  <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
-  <licenses>
-    <license>
-      <name>Eclipse Public License v1.0</name>
-      <url>http://www.eclipse.org/legal/epl-v10.html</url>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>Sam Hague</name>
-      <email>shague@gmail.com</email>
-      <url>https://github.com/shague</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>
-    <jmxGeneratorPath>target/generated-sources/config</jmxGeneratorPath>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>config-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-config</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-common-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.openflowplugin.model</groupId>
-      <artifactId>model-flow-base</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.openflowplugin.model</groupId>
-      <artifactId>model-flow-service</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.model</groupId>
-      <artifactId>model-inventory</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>library</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>plugin</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>schema.openvswitch</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.ovsdb</groupId>
-      <artifactId>utils.mdsal-openflow</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.sfc</groupId>
-      <artifactId>sfc-model</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>concepts</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.mdsal</groupId>
-      <artifactId>yang-binding</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.yangtools</groupId>
-      <artifactId>yang-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.mdsal.model</groupId>
-      <artifactId>ietf-inet-types</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.mdsal.model</groupId>
-      <artifactId>opendaylight-l2-types</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Embed-Dependency>utils.mdsal-openflow;type=!pom;inline=false</Embed-Dependency>
-            <Embed-Transitive>true</Embed-Transitive>
-            <Include-Resource>
-              /OSGI-OPT/ovs-sfc/53-ovssfc-provider.xml=${project.basedir}/src/main/resources/initial/53-ovssfc-provider.xml,{maven-resources}
-            </Include-Resource>
-          </instructions>
-          <manifestLocation>${project.basedir}/META-INF</manifestLocation>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.opendaylight.yangtools</groupId>
-        <artifactId>yang-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>config</id>
-            <goals>
-              <goal>generate-sources</goal>
-            </goals>
-            <configuration>
-              <codeGenerators>
-                <generator>
-                  <codeGeneratorClass>
-                    org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-                  </codeGeneratorClass>
-                  <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                  <additionalConfiguration>
-                    <namespaceToPackage1>
-                      urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
-                    </namespaceToPackage1>
-                  </additionalConfiguration>
-                </generator>
-              </codeGenerators>
-              <inspectDependencies>true</inspectDependencies>
-            </configuration>
-          </execution>
-        </executions>
-        <dependencies>
-          <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>yang-jmx-generator-plugin</artifactId>
-            <version>${controller.config.version}</version>
-          </dependency>
-          <dependency>
-            <groupId>org.opendaylight.mdsal</groupId>
-            <artifactId>maven-sal-api-gen-plugin</artifactId>
-            <version>${yangtools.version}</version>
-          </dependency>
-        </dependencies>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/ovs-sfc/src/main/java/org/opendaylight/controller/config/yang/config/ovssfc_provider/impl/OvsSfcProviderModule.java b/ovs-sfc/src/main/java/org/opendaylight/controller/config/yang/config/ovssfc_provider/impl/OvsSfcProviderModule.java
deleted file mode 100644 (file)
index 14bfb76..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-* Copyright (C) 2014 Red Hat, Inc.
-*
-* This program and the accompanying materials are made available under the
-* terms of the Eclipse Public License v1.0 which accompanies this distribution,
-* and is available at http://www.eclipse.org/legal/epl-v10.html
-*
-* Authors : Sam Hague
-*/
-package org.opendaylight.controller.config.yang.config.ovssfc_provider.impl;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.ovsdb.ovssfc.OvsSfcProvider;
-
-public class OvsSfcProviderModule extends org.opendaylight.controller.config.yang.config.ovssfc_provider.impl.AbstractOvsSfcProviderModule {
-    public OvsSfcProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
-        super(identifier, dependencyResolver);
-    }
-
-    public OvsSfcProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.ovssfc_provider.impl.OvsSfcProviderModule oldModule, java.lang.AutoCloseable oldInstance) {
-        super(identifier, dependencyResolver, oldModule, oldInstance);
-    }
-
-    @Override
-    public void customValidation() {
-        // add custom validation form module attributes here.
-    }
-
-    @Override
-    public java.lang.AutoCloseable createInstance() {
-        DataBroker dataBroker = getDataBrokerDependency();
-        final OvsSfcProvider ovsSfcProvider = new OvsSfcProvider(dataBroker);
-
-        final class AutoCloseableSfc implements AutoCloseable {
-
-            @Override
-            public void close() throws Exception {
-                ovsSfcProvider.close();
-            }
-        }
-
-        AutoCloseable ret = new AutoCloseableSfc();
-        return ret;
-    }
-
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/controller/config/yang/config/ovssfc_provider/impl/OvsSfcProviderModuleFactory.java b/ovs-sfc/src/main/java/org/opendaylight/controller/config/yang/config/ovssfc_provider/impl/OvsSfcProviderModuleFactory.java
deleted file mode 100644 (file)
index 15a9fff..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
-* Generated file
-*
-* Generated from: yang module name: ovssfc-provider-impl yang module local name: ovssfc-provider-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Mon Aug 11 13:45:11 EDT 2014
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.config.ovssfc_provider.impl;
-public class OvsSfcProviderModuleFactory extends org.opendaylight.controller.config.yang.config.ovssfc_provider.impl.AbstractOvsSfcProviderModuleFactory {
-
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AbstractDataListener.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AbstractDataListener.java
deleted file mode 100644 (file)
index 300186f..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-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.LogicalDatastoreType;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public abstract class AbstractDataListener implements DataChangeListener {
-    private DataBroker dataBroker;
-    private InstanceIdentifier<?> iID;
-    private ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
-
-    public void setDataBroker (DataBroker dataBroker) {
-        this.dataBroker = dataBroker;
-    }
-
-    public void setIID (InstanceIdentifier<?> IID) {
-        this.iID = IID;
-    }
-
-    public void registerAsDataChangeListener () {
-        dataChangeListenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
-                iID, this, DataBroker.DataChangeScope.SUBTREE);
-    }
-
-    public void registerAsDataChangeListener (AsyncDataBroker.DataChangeScope dataChangeScope) {
-        dataChangeListenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
-                iID, this, dataChangeScope);
-    }
-
-    public void closeDataChangeListener () {
-        dataChangeListenerRegistration.close();
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AclUtils.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/AclUtils.java
deleted file mode 100644 (file)
index bc8f9c8..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-//import com.google.common.base.Optional;
-//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.cisco.params.xml.ns.yang.sfc.acl.rev140701.Actions1;
-//import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.acl.rev140701.Actions1Builder;
-//import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.acl.rev140701.access.lists.access.list.access.list.entries.actions.SfcAction;
-//import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.acl.rev140701.access.lists.access.list.access.list.entries.actions.sfc.action.AclServiceFunctionPath;
-//import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.acl.rev140701.access.lists.access.list.access.list.entries.actions.sfc.action.AclServiceFunctionPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.AccessLists;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.AccessListsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.AccessList;
-//import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.AccessListBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.access.list.AccessListEntries;
-//import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.access.list.AccessListEntriesBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.access.list.access.list.entries.ActionsBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.access.list.access.list.entries.MatchesBuilder;
-//import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.access.list.access.list.entries.matches.ace.type.AceIpBuilder;
-//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.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-//import java.util.ArrayList;
-//import java.util.List;
-//import java.util.concurrent.ExecutionException;
-
-public class AclUtils {
-    private static final Logger logger = LoggerFactory.getLogger(AclUtils.class);
-    private AccessList accessList;
-    private AccessLists accessLists;
-
-    public AclUtils () {
-        // TODO: remove these when then acl restconf is fixed
-        //setAccessList();
-        //setAccessLists();
-    }
-/*
-    public AccessLists readAccessLists () {
-        InstanceIdentifier<AccessLists> iID =
-                InstanceIdentifierUtils.createAccessListsPath();
-
-        ReadOnlyTransaction readTx = OvsSfcProvider.getOvsSfcProvider().getDataBroker().newReadOnlyTransaction();
-        Optional<AccessLists> dataObject = null;
-        try {
-            dataObject = readTx.read(LogicalDatastoreType.CONFIGURATION, iID).get();
-        } catch (InterruptedException | ExecutionException e) {
-            e.printStackTrace();
-        }
-        if ((dataObject != null) && (dataObject.get() != null)) {
-            logger.trace("\nOVSSFC {}\n   acl: {}",
-                    Thread.currentThread().getStackTrace()[1], dataObject.get().toString());
-            return dataObject.get();
-        } else {
-            logger.trace("\nOVSSFC {}, acl: null", Thread.currentThread().getStackTrace()[1]);
-            return null;
-        }
-    }
-
-    public AccessListEntries getAccessList (String servicePathName) {
-        AccessListEntries accessListEntry = null;
-        // TODO: revert when reston fix is in
-        //AccessLists accessLists = readAccessLists();
-        AccessLists accessLists = this.accessLists;
-
-        List<AccessList> accessListList = accessLists.getAccessList();
-        for (AccessList accessList : accessListList) {
-            List<AccessListEntries> accessListEntriesList = accessList.getAccessListEntries();
-            for (AccessListEntries accessListEntries : accessListEntriesList) {
-                SfcAction sfcAction = accessListEntries.getActions().getAugmentation(Actions1.class).getSfcAction();
-                //String aclServicePathName = ((AclServiceFunctionPath)sfcAction).getServiceFunctionPath();
-                //if (servicePathName.equals(aclServicePathName)) {
-                //    accessListEntry = accessListEntries;
-                //    break;
-                //}
-            }
-        }
-
-        return accessListEntry;
-    }
-
-    public AccessListEntries getAccessList () {
-        AccessListEntries accessListEntry = null;
-
-        setAccessList();
-
-        List<AccessListEntries> accessListEntriesList = accessList.getAccessListEntries();
-        for (AccessListEntries accessListEntries : accessListEntriesList) {
-            accessListEntry = accessListEntries;
-        }
-
-        return accessListEntry;
-    }
-
-    private AccessList setAccessList () {
-        PortNumber portNumber = new PortNumber(80);
-        DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder();
-        destinationPortRangeBuilder.setLowerPort(portNumber);
-        destinationPortRangeBuilder.setUpperPort(portNumber);
-
-        AceIpBuilder aceIpBuilder = new AceIpBuilder();
-        aceIpBuilder.setDestinationPortRange(destinationPortRangeBuilder.build());
-
-        MatchesBuilder matchesBuilder = new MatchesBuilder();
-        matchesBuilder.setAceType(aceIpBuilder.build());
-
-        //AclServiceFunctionPathBuilder aclServiceFunctionPathBuilder = new AclServiceFunctionPathBuilder();
-        //aclServiceFunctionPathBuilder.setServiceFunctionPath("sfp1");
-
-        Actions1Builder actions1Builder = new Actions1Builder();
-        //actions1Builder.setSfcAction(aclServiceFunctionPathBuilder.build());
-
-        ActionsBuilder actionsBuilder = new ActionsBuilder();
-        actionsBuilder.addAugmentation(Actions1.class, actions1Builder.build());
-
-        AccessListEntriesBuilder accessListEntriesBuilder = new AccessListEntriesBuilder();
-        accessListEntriesBuilder.setRuleName("http");
-        accessListEntriesBuilder.setMatches(matchesBuilder.build());
-        accessListEntriesBuilder.setActions(actionsBuilder.build());
-        List<AccessListEntries> accessListEntriesList = new ArrayList<>();
-        accessListEntriesList.add(accessListEntriesBuilder.build());
-
-        AccessListBuilder accessListBuilder = new AccessListBuilder();
-        accessListBuilder.setAclName("http");
-        accessListBuilder.setAccessListEntries(accessListEntriesList);
-
-        logger.trace("acl: {}", accessListBuilder.build());
-        accessList = accessListBuilder.build();
-        return accessListBuilder.build();
-    }
-
-    private AccessLists setAccessLists () {
-        PortNumber portNumber = new PortNumber(80);
-        DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder();
-        destinationPortRangeBuilder.setLowerPort(portNumber);
-        destinationPortRangeBuilder.setUpperPort(portNumber);
-
-        AceIpBuilder aceIpBuilder = new AceIpBuilder();
-        aceIpBuilder.setDestinationPortRange(destinationPortRangeBuilder.build());
-
-        MatchesBuilder matchesBuilder = new MatchesBuilder();
-        matchesBuilder.setAceType(aceIpBuilder.build());
-
-        //AclServiceFunctionPathBuilder aclServiceFunctionPathBuilder = new AclServiceFunctionPathBuilder();
-        //aclServiceFunctionPathBuilder.setServiceFunctionPath("sfp1");
-
-        Actions1Builder actions1Builder = new Actions1Builder();
-        //actions1Builder.setSfcAction(aclServiceFunctionPathBuilder.build());
-
-        ActionsBuilder actionsBuilder = new ActionsBuilder();
-        actionsBuilder.addAugmentation(Actions1.class, actions1Builder.build());
-
-        AccessListEntriesBuilder accessListEntriesBuilder = new AccessListEntriesBuilder();
-        accessListEntriesBuilder.setRuleName("http");
-        accessListEntriesBuilder.setMatches(matchesBuilder.build());
-        accessListEntriesBuilder.setActions(actionsBuilder.build());
-        List<AccessListEntries> accessListEntriesList = new ArrayList<>();
-        accessListEntriesList.add(accessListEntriesBuilder.build());
-
-        AccessListBuilder accessListBuilder = new AccessListBuilder();
-        accessListBuilder.setAclName("http");
-        accessListBuilder.setAccessListEntries(accessListEntriesList);
-        List<AccessList> accessListList = new ArrayList<>();
-        accessListList.add(accessListBuilder.build());
-
-        AccessListsBuilder accessListsBuilder = new AccessListsBuilder();
-        accessListsBuilder.setAccessList(accessListList);
-
-        logger.trace("acls: {}", accessListsBuilder.build());
-        accessLists = accessListsBuilder.build();
-        return accessListsBuilder.build();
-    }
-*/
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/EventHandler.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/EventHandler.java
deleted file mode 100644 (file)
index 5117a33..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EventHandler {
-    private static final Logger logger = LoggerFactory.getLogger(EventHandler.class);
-    private ExecutorService eventHandler;
-    private BlockingQueue<SfcEvent> events;
-
-    void init () {
-        eventHandler = Executors.newSingleThreadExecutor();
-        this.events = new LinkedBlockingQueue<>();
-    }
-
-    void start () {
-        eventHandler.submit(new Runnable() {
-            @Override
-            public void run() {
-            while (true) {
-                SfcEvent ev;
-                try {
-                    ev = events.take();
-                } catch (InterruptedException e) {
-                    logger.info("The event handler thread was interrupted, shutting down", e);
-                    return;
-                }
-                logger.trace("\nOVSSFC: {}, event: {}", Thread.currentThread().getStackTrace()[1], ev);
-                switch (ev.getType()) {
-                case SFP:
-                    try {
-                        OvsSfcProvider.getOvsSfcProvider().sfp.processSfp(ev.getAction(), ev.serviceFunctionPath);
-                    } catch (Exception e) {
-                        logger.error("Exception caught in processSfp {}", ev, e);
-                    }
-                    break;
-                case SFPS:
-                    try {
-                        OvsSfcProvider.getOvsSfcProvider().sfp.processSfps(ev.getAction(), ev.serviceFunctionPaths);
-                    } catch (Exception e) {
-                        logger.error("Exception caught in processSfps {}", ev, e);
-                    }
-                    break;
-                default:
-                    logger.warn("Unable to process {}", ev);
-                }
-            }
-            }
-        });
-    }
-
-    void stop () throws InterruptedException{
-        // stop accepting new tasks
-        eventHandler.shutdown();
-
-        if (!eventHandler.awaitTermination(100, TimeUnit.MICROSECONDS)) {
-            System.out.println("Still waiting...");
-            //System.exit(0);
-        }
-        System.out.println("Exiting normally...");
-
-/*
-        try {
-            // Wait a while for existing tasks to terminate
-            if (!eventHandler.awaitTermination(10, TimeUnit.SECONDS)) {
-                eventHandler.shutdownNow();
-                // Wait a while for tasks to respond to being cancelled
-                if (!eventHandler.awaitTermination(10, TimeUnit.SECONDS)) {
-                    logger.error("EventHandler did not terminate");
-                }
-            }
-        } catch (InterruptedException e) {
-            // (Re-)Cancel if current thread also interrupted
-            eventHandler.shutdownNow();
-            // Preserve interrupt status
-            Thread.currentThread().interrupt();
-        }
-*/
-    }
-
-    public void enqueueSfpEvent (SfcEvent.Action action, ServiceFunctionPath serviceFunctionPath) {
-        SfcEvent event = new SfcEvent(SfcEvent.Type.SFP, action, serviceFunctionPath);
-        enqueueEvent(event);
-    }
-
-    public void enqueueSfpsEvent (SfcEvent.Action action, ServiceFunctionPaths serviceFunctionPaths) {
-        SfcEvent event = new SfcEvent(SfcEvent.Type.SFPS, action, serviceFunctionPaths);
-        enqueueEvent(event);
-    }
-
-    public void enqueueEvent (SfcEvent event) {
-        try {
-            events.put(event);
-        } catch (InterruptedException e) {
-            logger.error("Thread was interrupted while trying to enqueue event ", e);
-        }
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/Flows.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/Flows.java
deleted file mode 100644 (file)
index 5a0125c..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.CheckedFuture;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-//import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
-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.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.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.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.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.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-
-public class Flows {
-    private static final Logger logger = LoggerFactory.getLogger(Flows.class);
-    private OvsSfcProvider ovsSfcProvider = OvsSfcProvider.getOvsSfcProvider();
-    private static final short TABLE_0_DEFAULT_INGRESS = 0;
-    private static final short TABLE_1_CLASSIFIER = 5;
-    private static final short TABLE_2_NEXTHOP = 6;
-    private static final short SFC_PRIORITY = 100;
-    private static final String OPENFLOW = "openflow:";
-
-    private NodeBuilder createNodeBuilder (String nodeId) {
-        NodeBuilder builder = new NodeBuilder();
-        builder.setId(new NodeId(nodeId));
-        builder.setKey(new NodeKey(builder.getId()));
-        return builder;
-    }
-
-    private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        DataBroker dataBroker = OvsSfcProvider.getOvsSfcProvider().getDataBroker();
-        if (dataBroker == null) {
-            logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
-            return;
-        }
-
-        WriteTransaction modification = dataBroker.newWriteOnlyTransaction();
-        InstanceIdentifier<Flow> path1 = 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();
-        //modification.delete(LogicalDatastoreType.OPERATIONAL, nodeBuilderToInstanceId(nodeBuilder));
-        //modification.delete(LogicalDatastoreType.OPERATIONAL, path1);
-        //modification.delete(LogicalDatastoreType.CONFIGURATION, nodeBuilderToInstanceId(nodeBuilder));
-        modification.delete(LogicalDatastoreType.CONFIGURATION, path1);
-
-        CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
-        try {
-            commitFuture.get();  // TODO: Make it async (See bug 1362)
-            logger.debug("Transaction success for deletion of Flow "+flowBuilder.getFlowName());
-        } catch (InterruptedException|ExecutionException e) {
-            logger.error(e.getMessage(), e);
-        }
-    }
-
-    private void writeFlow (FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
-        DataBroker dataBroker = OvsSfcProvider.getOvsSfcProvider().getDataBroker();
-        if (dataBroker == null) {
-            logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller.");
-            return;
-        }
-
-        ReadWriteTransaction modification = dataBroker.newReadWriteTransaction();
-        InstanceIdentifier<Flow> path1 = 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();
-
-        //modification.put(LogicalDatastoreType.OPERATIONAL, path1, flowBuilder.build());
-        modification.put(LogicalDatastoreType.CONFIGURATION, path1, flowBuilder.build(), true /*createMissingParents*/);
-
-        CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modification.submit();
-        try {
-            commitFuture.get();  // TODO: Make it async (See bug 1362)
-            logger.debug("Transaction success for write of Flow "+flowBuilder.getFlowName());
-        } catch (InterruptedException|ExecutionException e) {
-            logger.error(e.getMessage(), e);
-        }
-    }
-
-    private void writeLLDPRule(Long dpidLong) {
-
-        String nodeName = OPENFLOW + dpidLong;
-        EtherType etherType = new EtherType(0x88CCL);
-
-        MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-        FlowBuilder flowBuilder = new FlowBuilder();
-
-        // Create Match(es) and Set them in the FlowBuilder Object
-        flowBuilder.setMatch(MatchUtils.createEtherTypeMatch(matchBuilder, etherType).build());
-
-        // Create the OF Actions and Instructions
-        InstructionBuilder ib = new InstructionBuilder();
-        InstructionsBuilder isb = new InstructionsBuilder();
-
-        // Instructions List Stores Individual Instructions
-        List<Instruction> instructions = Lists.newArrayList();
-
-        // Call the InstructionBuilder Methods Containing Actions
-        InstructionUtils.createSendToControllerInstructions(nodeName, ib);
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
-        instructions.add(ib.build());
-
-        // Add InstructionBuilder to the Instruction(s)Builder List
-        isb.setInstruction(instructions);
-
-        // Add InstructionsBuilder to FlowBuilder
-        flowBuilder.setInstructions(isb.build());
-
-        String flowId = "LLDP";
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setPriority(10);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId((short) 0);
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
-        writeFlow(flowBuilder, nodeBuilder);
-    }
-
-    /*
-     * Create a NORMAL Table Miss Flow Rule
-     * Match: any
-     * Action: forward to NORMAL pipeline
-     */
-    private void writeNormalRule (Long dpidLong) {
-        String nodeName = OPENFLOW + dpidLong;
-
-        MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-        FlowBuilder flowBuilder = new FlowBuilder();
-
-        //flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, 1L).build());
-
-        // Create the OF Actions and Instructions
-        InstructionBuilder ib = new InstructionBuilder();
-        InstructionsBuilder isb = new InstructionsBuilder();
-
-        // Instructions List Stores Individual Instructions
-        List<Instruction> instructions = Lists.newArrayList();
-
-        // Call the InstructionBuilder Methods Containing Actions
-        InstructionUtils.createNormalInstructions(nodeName, ib);
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
-        instructions.add(ib.build());
-
-        // Add InstructionBuilder to the Instruction(s)Builder List
-        isb.setInstruction(instructions);
-
-        // Add InstructionsBuilder to FlowBuilder
-        flowBuilder.setInstructions(isb.build());
-
-        String flowId = "NORMAL";
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setMatch(matchBuilder.build());
-        flowBuilder.setPriority(10);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(TABLE_0_DEFAULT_INGRESS);
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
-        writeFlow(flowBuilder, nodeBuilder);
-    }
-
-    public void initializeFlowRules (Long dpid) {
-        /*
-         * Table(0) Rule #1
-         * ----------------
-         * Match: LLDP (0x88CCL)
-         * Action: Packet_In to Controller Reserved Port
-         */
-
-        //Uri value = new Uri(OutputPortValues.CONTROLLER.toString());
-        //Uri value2 = new Uri(InputPortValues);
-
-        writeLLDPRule(dpid);
-        writeNormalRule(dpid);
-    }
-
-    public static MatchBuilder createInPortLocalMatch(MatchBuilder matchBuilder, Long dpidLong, String portId) {
-
-        NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + portId);
-        logger.debug("createInPortMatch() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, "LOCAL");
-        matchBuilder.setInPort(NodeConnectorId.getDefaultInstance(ncid.getValue()));
-        matchBuilder.setInPort(ncid);
-
-        return matchBuilder;
-    }
-
-    /*
-     * Match: in_port, tcp, tcp_dst
-     * Actions: mod_vlan_vid, resubmit(,30)
-     */
-    public void writeIngressAcl (Long dpid, long inPort, int vlan, boolean write) {
-        String nodeName = OPENFLOW + dpid;
-
-        MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-        FlowBuilder flowBuilder = new FlowBuilder();
-
-        //flowBuilder.setMatch(createInPortLocalMatch(matchBuilder, dpid, OutputPortValues.LOCAL.toString()).build());
-        PortNumber portNumber = new PortNumber(80);
-        //flowBuilder.setMatch(MatchUtils.createSetDstTcpMatch(matchBuilder, portNumber).build());
-
-        String flowId = "ingressAcl_"+portNumber.getValue();
-        flowBuilder.setId(new FlowId(flowId));
-        FlowKey key = new FlowKey(new FlowId(flowId));
-        flowBuilder.setMatch(matchBuilder.build());
-        flowBuilder.setPriority(100);
-        //flowBuilder.setStrict(true);
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(TABLE_0_DEFAULT_INGRESS);
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName(flowId);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
-
-        if (write) {
-            // Create the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
-            InstructionsBuilder isb = new InstructionsBuilder();
-
-            // Instructions List Stores Individual Instructions
-            List<Instruction> instructions = Lists.newArrayList();
-
-            // Call the InstructionBuilder Methods Containing Actions
-/*
-            // GOTO Instructions Need to be added first to the List
-            InstructionUtils.createGotoTableInstructions(ib, (short)5);
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-*/
-            // Set VLAN ID Instruction
-            InstructionUtils.createSetVlanInstructions(ib, new VlanId(vlan));
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructions.add(ib.build());
-            // Add InstructionBuilder to the Instruction(s)Builder List
-            isb.setInstruction(instructions);
-
-            // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
-
-            //ActionUtils.nxResubmitAction(0, (short)6);
-            writeFlow(flowBuilder, nodeBuilder);
-        } else {
-            removeFlow(flowBuilder, nodeBuilder);
-        }
-
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/InstanceIdentifierUtils.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/InstanceIdentifierUtils.java
deleted file mode 100644 (file)
index 62028c2..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-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.sfc.rev140701.ServiceFunctionChains;
-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.service.function.forwarders.ServiceFunctionForwarder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderKey;
-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.acl.rev140520.AccessLists;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public final class InstanceIdentifierUtils {
-
-    private InstanceIdentifierUtils() {
-        throw new UnsupportedOperationException("Utility class should never be instantiated");
-    }
-
-    public static final InstanceIdentifier<AccessLists> createAccessListsPath () {
-        return InstanceIdentifier.builder(AccessLists.class).build();
-    }
-
-    public static final InstanceIdentifier<ServiceFunctionChains> createServiceFunctionChainsPath () {
-        return InstanceIdentifier.builder(ServiceFunctionChains.class).build();
-    }
-
-    public static final InstanceIdentifier<ServiceFunctionForwarder> createServiceFunctionForwarderPath () {
-        return InstanceIdentifier.builder(ServiceFunctionForwarders.class)
-                .child(ServiceFunctionForwarder.class).build();
-    }
-
-    public static final InstanceIdentifier<ServiceFunctionForwarder> createServiceFunctionForwarderPath (String name) {
-        ServiceFunctionForwarderKey serviceFunctionForwarderKey = new ServiceFunctionForwarderKey(name);
-        return InstanceIdentifier.builder(ServiceFunctionForwarders.class)
-                .child(ServiceFunctionForwarder.class, serviceFunctionForwarderKey)
-                .build();
-    }
-
-    public static final InstanceIdentifier<ServiceFunctionForwarders> createServiceFunctionForwardersPath () {
-        return InstanceIdentifier.builder(ServiceFunctionForwarders.class).build();
-    }
-
-    public static final InstanceIdentifier<ServiceFunction> createServiceFunctionPath (String name) {
-        ServiceFunctionKey serviceFunctionKey = new ServiceFunctionKey(name);
-        return InstanceIdentifier.builder(ServiceFunctions.class)
-                .child(ServiceFunction.class, serviceFunctionKey)
-                .build();
-    }
-
-    public static final InstanceIdentifier<ServiceFunctionPaths> createServiceFunctionPathsPath () {
-        return InstanceIdentifier.builder(ServiceFunctionPaths.class).build();
-    }
-
-    public static final InstanceIdentifier<ServiceFunctionPath> createServiceFunctionPathPath () {
-        return InstanceIdentifier.builder(ServiceFunctionPaths.class)
-                .child(ServiceFunctionPath.class).build();
-    }
-}
\ No newline at end of file
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsSfcProvider.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsSfcProvider.java
deleted file mode 100644 (file)
index 533ad2a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class OvsSfcProvider implements AutoCloseable {
-    private static final Logger logger = LoggerFactory.getLogger(OvsSfcProvider.class);
-    private static OvsSfcProvider ovsSfcProvider;
-    private DataBroker dataBroker;
-    private SfcDataListener sfcDataListener;
-    private SffDataListener sffDataListener;
-    private SfpDataListener sfpDataListener;
-    protected SfpHandler sfp;
-    protected EventHandler eventHandler;
-    protected AclUtils aclUtils;
-    protected OvsUtils ovsUtils;
-    protected SfUtils sfUtils;
-    protected SffUtils sffUtils;
-    protected Flows flows;
-
-    public OvsSfcProvider (DataBroker dataBroker) {
-        ovsSfcProvider = this;
-        setDataBroker(dataBroker);
-
-        sfcDataListener = new SfcDataListener(dataBroker);
-        sffDataListener = new SffDataListener(dataBroker);
-        sfpDataListener = new SfpDataListener(dataBroker);
-        aclUtils = new AclUtils();
-        ovsUtils = new OvsUtils();
-        sfUtils = new SfUtils();
-        sffUtils = new SffUtils();
-        flows = new Flows();
-        sfp = new SfpHandler();
-        eventHandler = new EventHandler();
-        eventHandler.init();
-        eventHandler.start();
-
-        logger.info("Initialized");
-    }
-
-    public void setDataBroker (DataBroker dataBroker) {
-        this.dataBroker = dataBroker;
-    }
-
-    public DataBroker getDataBroker () {
-        return this.dataBroker;
-    }
-
-    public static OvsSfcProvider getOvsSfcProvider () {
-        return OvsSfcProvider.ovsSfcProvider;
-    }
-
-    @Override
-    public void close () throws Exception {
-        sfcDataListener.closeDataChangeListener();
-        sffDataListener.closeDataChangeListener();
-        sfpDataListener.closeDataChangeListener();
-        logger.info("Closed");
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsUtils.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/OvsUtils.java
deleted file mode 100644 (file)
index 3fa5845..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.ServiceHelper;
-import org.opendaylight.ovsdb.lib.notation.Row;
-import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
-import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
-import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
-import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class OvsUtils {
-    private static final Logger logger = LoggerFactory.getLogger(OvsUtils.class);
-    private OvsSfcProvider ovsSfcProvider = OvsSfcProvider.getOvsSfcProvider();
-
-    private OvsdbConnectionService getOvsdbConnectionService () {
-        return (OvsdbConnectionService) ServiceHelper.getGlobalInstance(OvsdbConnectionService.class, this);
-    }
-
-    private OvsdbConfigurationService getOvsdbConfigurationService () {
-        return (OvsdbConfigurationService) ServiceHelper.getGlobalInstance(OvsdbConfigurationService.class, this);
-    }
-
-    public Node getNodeFromSystemId (String systemId) {
-        Node node = null;
-
-        OvsdbConnectionService connectionService = getOvsdbConnectionService();
-        Preconditions.checkNotNull(connectionService);
-        List<Node> ovsNodes = connectionService.getNodes();
-        if (ovsNodes != null) {
-            for (Node ovsNode : ovsNodes) {
-                if (systemId.equals(getSystemId(ovsNode))) {
-                    node = ovsNode;
-                }
-            }
-        }
-
-        logger.trace("\nOVSSFC {}\n ovsNode: {}",
-                Thread.currentThread().getStackTrace()[1],
-                node != null ? node.toString() : "");
-
-        return node;
-    }
-
-
-    public String getSystemId (Node ovsNode) {
-        String systemId = "";
-
-        if (ovsNode == null) {
-            return systemId;
-        }
-        OvsdbConfigurationService ovsdbConfigurationService = getOvsdbConfigurationService();
-        if (ovsdbConfigurationService == null) {
-            return systemId;
-        }
-
-        Map<String, Row> table =
-                ovsdbConfigurationService.getRows(ovsNode, ovsdbConfigurationService.getTableName(ovsNode, OpenVSwitch.class));
-
-        if (table == null) {
-            logger.error("OpenVSwitch table is null for Node {} ", ovsNode);
-            return systemId;
-        }
-
-        // Loop through all the Open_vSwitch rows looking for the first occurrence of external_ids.
-        // The specification does not restrict the number of rows so we choose the first we find.
-        for (Row row : table.values()) {
-            OpenVSwitch ovsRow = ovsdbConfigurationService.getTypedRow(ovsNode, OpenVSwitch.class, row);
-            Map<String, String> externalIds = ovsRow.getExternalIdsColumn().getData();
-            if (externalIds == null) {
-                continue;
-            }
-
-            systemId = externalIds.get("system-id");
-        }
-
-        logger.trace("\nOVSSFC {}\n system-id: {}",
-                Thread.currentThread().getStackTrace()[1],
-                systemId);
-
-        return systemId;
-    }
-
-    public String getBridgeUUID (Node ovsNode, String bridgeName) {
-        String uuid = "";
-
-        if (ovsNode == null) {
-            return uuid;
-        }
-
-        OvsdbConfigurationService ovsdbConfigurationService = getOvsdbConfigurationService();
-        if (ovsdbConfigurationService == null) {
-            return uuid;
-        }
-
-        try {
-            Map<String, Row> table = ovsdbConfigurationService.
-                    getRows(ovsNode, ovsdbConfigurationService.getTableName(ovsNode, Bridge.class));
-
-            if (table != null) {
-                for (String key : table.keySet()) {
-                    Bridge bridge = ovsdbConfigurationService.getTypedRow(ovsNode, Bridge.class, table.get(key));
-                    if (bridge.getName().equals(bridgeName)) {
-                        uuid = key;
-                    }
-                }
-            }
-        } catch (Exception e) {
-            logger.error("Error getting Bridge Identifier for {} / {}", ovsNode, bridgeName, e);
-        }
-
-        logger.trace("\nOVSSFC {}\n uuid: {}",
-                Thread.currentThread().getStackTrace()[1],
-                uuid);
-
-        return uuid;
-    }
-
-    public Long getDpid (Node ovsNode, String bridgeName) {
-        Long dpid = 0L;
-
-        if (ovsNode == null) {
-            return dpid;
-        }
-
-        logger.trace("\nOVSSFC Enter {}\n ovsNode: {}, bridgeName: {}",
-                Thread.currentThread().getStackTrace()[1],
-                ovsNode, bridgeName);
-
-        String bridgeUuid = ovsSfcProvider.ovsUtils.getBridgeUUID(ovsNode, bridgeName);
-        if (bridgeUuid == null) {
-            return dpid;
-        }
-
-        logger.trace("\nOVSSFC {}\n ovsNode: {}, bridgeName: {}, uuid: {}",
-                Thread.currentThread().getStackTrace()[1],
-                ovsNode, bridgeName, bridgeUuid);
-
-        OvsdbConfigurationService ovsdbConfigurationService = getOvsdbConfigurationService();
-        try {
-            Row bridgeRow = ovsdbConfigurationService
-                    .getRow(ovsNode, ovsdbConfigurationService.getTableName(ovsNode, Bridge.class), bridgeUuid);
-            Bridge bridge = ovsdbConfigurationService.getTypedRow(ovsNode, Bridge.class, bridgeRow);
-            Set<String> dpids = bridge.getDatapathIdColumn().getData();
-            if (dpids != null && !dpids.isEmpty()) {
-                dpid = HexEncode.stringToLong((String) dpids.toArray()[0]);
-            }
-        } catch (Exception e) {
-            logger.error("Error finding Bridge's OF DPID", e);
-        }
-        return dpid;
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfUtils.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfUtils.java
deleted file mode 100644 (file)
index 8efb65d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import com.google.common.base.Optional;
-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.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.ExecutionException;
-
-public class SfUtils {
-    private static final Logger logger = LoggerFactory.getLogger(SfUtils.class);
-
-    public ServiceFunction readServiceFunction (String name) {
-        InstanceIdentifier<ServiceFunction> iID =
-                InstanceIdentifierUtils.createServiceFunctionPath(name);
-
-        ReadOnlyTransaction readTx = OvsSfcProvider.getOvsSfcProvider().getDataBroker().newReadOnlyTransaction();
-        Optional<ServiceFunction> dataObject = null;
-        try {
-            dataObject = readTx.read(LogicalDatastoreType.CONFIGURATION, iID).get();
-        } catch (InterruptedException | ExecutionException e) {
-            e.printStackTrace();
-        }
-        if ((dataObject != null) && (dataObject.get() != null)) {
-            logger.trace("\nOVSSFC Exit: {}\n   sf: {}",
-                    Thread.currentThread().getStackTrace()[1], dataObject.get().toString());
-            return dataObject.get();
-        } else {
-            logger.trace("\nOVSSFC Exit: {}, sf: null", Thread.currentThread().getStackTrace()[1]);
-            return null;
-        }
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcDataListener.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcDataListener.java
deleted file mode 100644 (file)
index b07283c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.ServiceFunctionChains;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.util.Map;
-
-public class SfcDataListener extends AbstractDataListener {
-    private static final Logger logger = LoggerFactory.getLogger(SfcDataListener.class);
-
-    public SfcDataListener (DataBroker dataBroker) {
-        setDataBroker(dataBroker);
-        setIID(InstanceIdentifierUtils.createServiceFunctionChainsPath());
-        registerAsDataChangeListener();
-    }
-
-    @Override
-    public void onDataChanged (final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change ) {
-        logger.trace("\nOVSSFC Enter: {}", Thread.currentThread().getStackTrace()[1]);
-
-        Map<InstanceIdentifier<?>, DataObject> dataCreatedObject = change.getCreatedData();
-
-        Map<InstanceIdentifier<?>, DataObject> dataUpdatedConfigurationObject = change.getUpdatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataUpdatedConfigurationObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionChains) {
-                ServiceFunctionChains updatedServiceFunctionChains = (ServiceFunctionChains) entry.getValue();
-                logger.trace("\nOVSSFC sfc:\n   {}", updatedServiceFunctionChains.toString());
-            }
-        }
-
-        logger.trace("\nOVSSFC Exit: {}", Thread.currentThread().getStackTrace()[1]);
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcEvent.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfcEvent.java
deleted file mode 100644 (file)
index 9a4c517..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-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;
-
-public class SfcEvent {
-    protected ServiceFunctionPath serviceFunctionPath;
-    protected ServiceFunctionPaths serviceFunctionPaths;
-    private Type type;
-    private Action action;
-    public enum Type { SFP, SFPS };
-    public enum Action { CREATE, UPDATE, DELETE };
-
-    public SfcEvent (Type type) {
-        this.type = type;
-    }
-
-    public SfcEvent (Type type, Action action, ServiceFunctionPath serviceFunctionPath) {
-        this.type = type;
-        this.action = action;
-        this.serviceFunctionPath = serviceFunctionPath;
-    }
-
-    public SfcEvent (Type type, Action action, ServiceFunctionPaths serviceFunctionPaths) {
-        this.type = type;
-        this.action = action;
-        this.serviceFunctionPaths = serviceFunctionPaths;
-    }
-
-    public Type getType () {
-        return type;
-    }
-
-    public void setType (Type type) {
-        this.type = type;
-    }
-
-    public Action getAction () {
-        return action;
-    }
-
-    public void setAction (Action action) {
-        this.action = action;
-    }
-
-    @Override
-    public String toString () {
-        switch (type) {
-        case SFP:
-            return "SfcEvent{" +
-                    "type=" + type + ", action=" + action + ", " +
-                    "ServiceFunctionPath=" + serviceFunctionPath +
-                    '}';
-        case SFPS:
-            return "SfcEvent{" +
-                    "type=" + type + ", action=" + action + ", " +
-                    "ServiceFunctionPaths=" + serviceFunctionPaths +
-                    '}';
-        default:
-            return "undefined";
-        }
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffDataListener.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffDataListener.java
deleted file mode 100644 (file)
index 1b20443..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.util.Map;
-
-public class SffDataListener extends AbstractDataListener {
-    private static final Logger logger = LoggerFactory.getLogger(SffDataListener.class);
-
-    public SffDataListener (DataBroker dataBroker) {
-        setDataBroker(dataBroker);
-        setIID(InstanceIdentifierUtils.createServiceFunctionForwarderPath());
-        registerAsDataChangeListener();
-    }
-
-    @Override
-    public void onDataChanged (final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change ) {
-        Map<InstanceIdentifier<?>, DataObject> dataObject;
-        logger.trace("\nOVSSFC Enter: {}", Thread.currentThread().getStackTrace()[1]);
-
-        dataObject = change.getCreatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionForwarder) {
-                ServiceFunctionForwarder serviceFunctionForwarder = (ServiceFunctionForwarder) entry.getValue();
-                logger.trace("\nOVSSFC CREATE: sff:\n   {}", serviceFunctionForwarder.toString());
-            }
-        }
-
-        dataObject = change.getUpdatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionForwarder) {
-                ServiceFunctionForwarder serviceFunctionForwarder = (ServiceFunctionForwarder) entry.getValue();
-                logger.trace("\nOVSSFC UPDATE: sff:\n   {}", serviceFunctionForwarder.toString());
-            }
-        }
-
-        logger.trace("\nOVSSFC Exit: {}", Thread.currentThread().getStackTrace()[1]);
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffUtils.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SffUtils.java
deleted file mode 100644 (file)
index 0242348..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import com.google.common.base.Optional;
-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.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.ovs.rev140701.ServiceFunctionForwarder1;
-//import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.service.function.forwarders.service.function.forwarder.ovs.ExternalIds;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-//import java.util.List;
-import java.util.concurrent.ExecutionException;
-
-public class SffUtils {
-    private static final Logger logger = LoggerFactory.getLogger(SffUtils.class);
-
-    public ServiceFunctionForwarder readServiceFunctionForwarder (String name) {
-        InstanceIdentifier<ServiceFunctionForwarder> iID =
-                InstanceIdentifierUtils.createServiceFunctionForwarderPath(name);
-
-        ReadOnlyTransaction readTx = OvsSfcProvider.getOvsSfcProvider().getDataBroker().newReadOnlyTransaction();
-        Optional<ServiceFunctionForwarder> dataObject = null;
-        try {
-            dataObject = readTx.read(LogicalDatastoreType.CONFIGURATION, iID).get();
-        } catch (InterruptedException | ExecutionException e) {
-            e.printStackTrace();
-        }
-        if ((dataObject != null) && (dataObject.get() != null)) {
-            logger.trace("\nOVSSFC Exit: {}\n   sff: {}",
-                    Thread.currentThread().getStackTrace()[1], dataObject.get().toString());
-            return dataObject.get();
-        } else {
-            logger.trace("\nOVSSFC Exit: {}, sff: null", Thread.currentThread().getStackTrace()[1]);
-            return null;
-        }
-    }
-
-    public String getSystemId (ServiceFunctionForwarder serviceFunctionForwarder) {
-        String systemId = "";
-
-        //List<ExternalIds> externalIds = serviceFunctionForwarder.getAugmentation(ServiceFunctionForwarder1.class).getOvs().getExternalIds();
-        //for (ExternalIds externalId : externalIds) {
-        //    if (externalId.getName().equals("system-id")) {
-        //        systemId = externalId.getValue();
-        //    }
-        //}
-
-        logger.trace("\nOVSSFC {}\n system-id: {}",
-                Thread.currentThread().getStackTrace()[1],
-                systemId);
-
-        return systemId;
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpDataListener.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpDataListener.java
deleted file mode 100644 (file)
index 5322164..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-//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.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.util.Map;
-//import java.util.Set;
-
-public class SfpDataListener extends AbstractDataListener {
-    private static final Logger logger = LoggerFactory.getLogger(SfpDataListener.class);
-
-    public SfpDataListener (DataBroker dataBroker) {
-        setDataBroker(dataBroker);
-        //setIID(InstanceIdentifierUtils.createServiceFunctionPathsPath());
-        setIID(InstanceIdentifierUtils.createServiceFunctionPathPath());
-        registerAsDataChangeListener(DataBroker.DataChangeScope.BASE);
-    }
-
-    @Override
-    public void onDataChanged (final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change ) {
-        Map<InstanceIdentifier<?>, DataObject> dataObject;
-
-        logger.trace("\nOVSSFC Enter: {}", Thread.currentThread().getStackTrace()[1]);
-/* Keeping for reference in case I need to use it
-        DataObject dom = change.getOriginalSubtree();
-        if (dom instanceof ServiceFunctionPaths) {
-            ServiceFunctionPaths serviceFunctionPaths = (ServiceFunctionPaths) dom;
-            logger.trace("\nOVSSFC ORIGINAL SUBTREE: sfps:\n   {}", serviceFunctionPaths.toString());
-
-            //OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpEvent(SfcEvent.Action.CREATE, serviceFunctionPaths);
-        }
-        dom = change.getUpdatedSubtree();
-        if (dom instanceof ServiceFunctionPaths) {
-            ServiceFunctionPaths serviceFunctionPaths = (ServiceFunctionPaths) dom;
-            logger.trace("\nOVSSFC UPDATED SUBTREE: sfps:\n   {}", serviceFunctionPaths.toString());
-
-            OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpEvent(SfcEvent.Action.UPDATE, serviceFunctionPaths);
-        }
-
-        dataObject = change.getOriginalData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionPaths) {
-                ServiceFunctionPaths serviceFunctionPaths = (ServiceFunctionPaths) entry.getValue();
-                logger.trace("\nOVSSFC ORIGINAL: sfps:\n   {}", serviceFunctionPaths.toString());
-
-                //OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpEvent(SfcEvent.Action.CREATE, serviceFunctionPaths);
-            }
-        }
-
-        Map<InstanceIdentifier<?>, DataObject> originalDataObject = change.getOriginalData();
-        Set<InstanceIdentifier<?>> iID = change.getRemovedPaths();
-        for (InstanceIdentifier instanceIdentifier : iID) {
-            DataObject dObject = originalDataObject.get(instanceIdentifier);
-            if (dObject instanceof ServiceFunctionPath) {
-                ServiceFunctionPath serviceFunctionPath = (ServiceFunctionPath) dataObject;
-                logger.trace("\nOVSSFC DELETE: sfp:\n   {}", serviceFunctionPath.toString());
-
-                OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpEvent(SfcEvent.Action.DELETE, serviceFunctionPath);
-            }
-        }
-
-        dataObject = change.getUpdatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionPaths) {
-                ServiceFunctionPaths updatedServiceFunctionPaths = (ServiceFunctionPaths) entry.getValue();
-                logger.trace("\nOVSSFC UPDATE: sfps:\n   {}", updatedServiceFunctionPaths.toString());
-
-                OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpsEvent(SfcEvent.Action.UPDATE, updatedServiceFunctionPaths);
-            }
-        }
-*/
-/*
-        dataObject = change.getCreatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionPaths) {
-                ServiceFunctionPaths serviceFunctionPaths = (ServiceFunctionPaths) entry.getValue();
-                logger.trace("\nOVSSFC CREATE: sfps:\n   {}", serviceFunctionPaths.toString());
-
-                OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpsEvent(SfcEvent.Action.CREATE, serviceFunctionPaths);
-            }
-        }
-*/
-        dataObject = change.getCreatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionPath) {
-                ServiceFunctionPath serviceFunctionPath = (ServiceFunctionPath) entry.getValue();
-                logger.trace("\nOVSSFC CREATE: sfp:\n   {}", serviceFunctionPath.toString());
-
-                OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpEvent(SfcEvent.Action.CREATE, serviceFunctionPath);
-            }
-        }
-
-        dataObject = change.getUpdatedData();
-        for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dataObject.entrySet()) {
-            if (entry.getValue() instanceof ServiceFunctionPath) {
-                ServiceFunctionPath updatedServiceFunctionPath = (ServiceFunctionPath) entry.getValue();
-                logger.trace("\nOVSSFC UPDATE: sfp:\n   {}", updatedServiceFunctionPath.toString());
-
-                OvsSfcProvider.getOvsSfcProvider().eventHandler.enqueueSfpEvent(SfcEvent.Action.UPDATE, updatedServiceFunctionPath);
-            }
-        }
-
-       logger.trace("\nOVSSFC Exit: {}", Thread.currentThread().getStackTrace()[1]);
-    }
-}
diff --git a/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpHandler.java b/ovs-sfc/src/main/java/org/opendaylight/ovsdb/ovssfc/SfpHandler.java
deleted file mode 100644 (file)
index 4c71f35..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2014, 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.ovssfc;
-
-import org.opendaylight.controller.sal.core.Node;
-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.sfp.rev140701.service.function.paths.service.function.path.ServicePathHop;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.lists.access.list.AccessListEntries;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-
-public class SfpHandler {
-    private static final Logger LOGGER = LoggerFactory.getLogger(SfpHandler.class);
-    private OvsSfcProvider ovsSfcProvider = OvsSfcProvider.getOvsSfcProvider();
-    private int vlan;
-
-    public int getVlan () {
-        return vlan;
-    }
-
-    public void setVlan (int vlan) {
-        this.vlan = vlan;
-    }
-
-    void processSfp (SfcEvent.Action action, ServiceFunctionPath serviceFunctionPath) {
-        LOGGER.trace("\nOVSSFC Enter: {}, action: {}\n   sfp: {}",
-                Thread.currentThread().getStackTrace()[1],
-                action.toString(),
-                serviceFunctionPath.toString());
-
-        switch (action) {
-            case CREATE:
-            case UPDATE:
-                sfpUpdate(serviceFunctionPath);
-                break;
-            case DELETE:
-                break;
-            default:
-                break;
-        }
-
-        LOGGER.trace("\nOVSSFC Exit: {}", Thread.currentThread().getStackTrace()[1]);
-    }
-
-    void processSfps (SfcEvent.Action action, ServiceFunctionPaths serviceFunctionPaths) {
-        LOGGER.trace("\nOVSSFC Enter: {}, action: {}\n   sfps: {}",
-                Thread.currentThread().getStackTrace()[1],
-                action.toString(),
-                serviceFunctionPaths.toString());
-
-        switch (action) {
-        case CREATE:
-        case UPDATE:
-            break;
-        case DELETE:
-            break;
-        default:
-            break;
-        }
-
-        LOGGER.trace("\nOVSSFC Exit: {}", Thread.currentThread().getStackTrace()[1]);
-    }
-
-    /*
-     * Get the ingress ssf. This sff will take the ingress acl flows.
-     * Get the acl.
-     * Get the system-id from the sff to find the ovs node.
-     * Program flows.
-     *
-     */
-    private void sfpUpdate (ServiceFunctionPath serviceFunctionPath) {
-        LOGGER.trace("\nOVSSFC {}\n Building SFP {}",
-                Thread.currentThread().getStackTrace()[1],
-                serviceFunctionPath.getName());
-
-        // TODO: replace with correct getAccessList when the restonf issue is fixed.
-        //ovsSfcProvider.aclUtils.getAccessList(serviceFunctionPath.getName());
-        AccessListEntries accessListEntries = null;
-        LOGGER.trace("\n   acl: {}", accessListEntries);
-        // TODO: code to convert acl into flows
-
-        String serviceFunctionForwarderName;
-        ServiceFunctionForwarder serviceFunctionForwarder = null;
-        Short startingIndex = serviceFunctionPath.getStartingIndex();
-        List<ServicePathHop> servicePathHopList = serviceFunctionPath.getServicePathHop();
-        for (ServicePathHop servicePathHop : servicePathHopList) {
-            LOGGER.trace("\n   sph: {}", servicePathHop);
-
-            serviceFunctionForwarderName = servicePathHop.getServiceFunctionForwarder();
-            serviceFunctionForwarder = ovsSfcProvider.sffUtils.readServiceFunctionForwarder(serviceFunctionForwarderName);
-            if (serviceFunctionForwarder != null) {
-                String systemId = ovsSfcProvider.sffUtils.getSystemId(serviceFunctionForwarder);
-                Node ovsNode = ovsSfcProvider.ovsUtils.getNodeFromSystemId(systemId);
-                if (ovsNode != null) {
-                    Long dpid = ovsSfcProvider.ovsUtils.getDpid(ovsNode, serviceFunctionForwarderName);
-                    if (dpid.equals(0)) {
-                        LOGGER.warn("cannot find dpid for {}", serviceFunctionForwarderName);
-                        continue;
-                    }
-                    if (servicePathHop.getServiceIndex().equals(startingIndex)) {
-                        ovsSfcProvider.flows.initializeFlowRules(dpid);
-                        // Add ingress classifier rule
-                        ovsSfcProvider.flows.writeIngressAcl(dpid, 0L, 0, true);
-                        // Add vlan t0 rule
-                    }
-                    // Add t30 classifier reg rule
-                    // Add t31 nextHop rule
-                }
-            }
-        }
-    }
-
-}
diff --git a/ovs-sfc/src/main/resources/initial/53-ovssfc-provider.xml b/ovs-sfc/src/main/resources/initial/53-ovssfc-provider.xml
deleted file mode 100644 (file)
index f196113..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<snapshot>
-    <configuration>
-        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
-                <module>
-                    <type xmlns:ovssfc="urn:opendaylight:params:xml:ns:yang:controller:config:ovssfc-provider:impl">
-                        ovssfc:ovssfc-provider-impl
-                    </type>
-                    <name>ovssfc-provider-impl</name>
-
-                    <data-broker>
-                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
-                        <name>binding-data-broker</name>
-                    </data-broker>
-                </module>
-            </modules>
-        </data>
-
-    </configuration>
-
-    <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:config:ovssfc-provider:impl?module=ovssfc-provider-impl&amp;revision=2014-06-30</capability>
-    </required-capabilities>
-
-</snapshot>
diff --git a/ovs-sfc/src/main/yang/ovssfc-provider-impl.yang b/ovs-sfc/src/main/yang/ovssfc-provider-impl.yang
deleted file mode 100644 (file)
index 7d10c3b..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// vi: set smarttab et sw=4 tabstop=4:
-module ovssfc-provider-impl {
-
-  yang-version 1;
-  namespace "urn:opendaylight:params:xml:ns:yang:controller:config:ovssfc-provider:impl";
-  prefix "ovssfc-provider-impl";
-
-  import config { prefix config; revision-date 2013-04-05; }
-  import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
-
-
-  description
-      "This module contains the base YANG definitions for
-      ovssfc-provider impl implementation.";
-
-  revision "2014-06-30" {
-      description
-          "Initial revision.";
-  }
-
-  identity ovssfc-provider-impl {
-      base config:module-type;
-
-      config:java-name-prefix OvsSfcProvider;
-  }
-
-  augment "/config:modules/config:module/config:configuration" {
-    case ovssfc-provider-impl {
-      when "/config:modules/config:module/config:type = 'ovssfc-provider-impl'";
-
-      //wires in the data-broker service
-      container data-broker {
-        uses config:service-ref {
-          refine type {
-              mandatory false;
-              config:required-identity mdsal:binding-async-data-broker;
-          }
-        }
-      }
-    }
-  }
-}
diff --git a/ovs-sfc/src/test/java/org/opendaylight/ovsdb/ovssfc/EventHandlerTest.java b/ovs-sfc/src/test/java/org/opendaylight/ovsdb/ovssfc/EventHandlerTest.java
deleted file mode 100644 (file)
index 2900984..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-package org.opendaylight.ovsdb.ovssfc;
-
-import static org.junit.Assert.assertTrue;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-//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.sf.rev140701.PutServiceFunctionInputBuilder;
-import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-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.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.sfp.rev140701.service.function.paths.service.function.path.SfpServiceFunction;
-//import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.service.function.path.SfpServiceFunctionBuilder;
-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.yang.common.RpcResult;
-//import org.opendaylight.yangtools.yang.binding.DataObject;
-//import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-//import ch.qos.logback.classic.Level;
-
-import java.util.ArrayList;
-//import java.util.HashMap;
-import java.util.List;
-//import java.util.Map;
-//import java.util.concurrent.Future;
-
-import static org.mockito.Mockito.mock;
-//import static org.mockito.Mockito.when;
-//import static org.mockito.Mockito.when;
-
-public class EventHandlerTest {
-    static final Logger logger = LoggerFactory.getLogger(EventHandler.class);
-    DataBroker dataBroker;
-    DataChangeEvent dataChangeEvent;
-    OvsSfcProvider sfcProvider;
-
-    @Before
-    public void setUp() {
-        dataBroker = mock(DataBroker.class);
-        dataChangeEvent = mock(DataChangeEvent.class);
-        sfcProvider = new OvsSfcProvider(dataBroker);
-
-        //ch.qos.logback.classic.Logger rootLogger =
-        //        (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
-        //rootLogger.setLevel(Level.toLevel("trace"));
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        //System.out.println(">>>>>Running test stop 1");
-        //sfcProvider.eventHandler.shutdownNow();
-        sfcProvider.eventHandler.stop();
-        //System.out.println(">>>>>Running test stop 2");
-    }
-
-    @Test
-    public void testNA () {
-        assertTrue(true);
-    }
-
-    @Ignore
-    @Test(timeout=1000)
-    public void testSfpUpdate() throws Exception {
-        //ch.qos.logback.classic.Logger rootLogger =
-        //        (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
-        //rootLogger.setLevel(Level.toLevel("trace"));
-
-        List<SfDataPlaneLocator> sfDpLList = new ArrayList<>();
-        sfDpLList.add(putSf("dpi-1", "dpi", "10.1.1.1", "10.1.1.1", 10000).build());
-        sfDpLList.add(putSf("napt44-1", "napt44", "10.1.1.2", "10.1.1.2", 10000).build());
-/* model changed and broke tests
-        SfpServiceFunctionBuilder sfBuilder = new SfpServiceFunctionBuilder();
-        List<SfpServiceFunction> sfList = new ArrayList<>();
-        sfBuilder.setName("sf1");
-        sfBuilder.setServiceIndex((short)3);
-        sfBuilder.setServiceFunctionForwarder("sff1");
-        sfList.add(sfBuilder.build());
-        sfBuilder.setName("sf2");
-        sfBuilder.setServiceIndex((short)2);
-        sfBuilder.setServiceFunctionForwarder("sff1");
-        sfList.add(sfBuilder.build());
-*/
-        ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
-        sfpBuilder.setName("sfp1");
-        sfpBuilder.setServiceChainName("sfp1");
-        sfpBuilder.setPathId(1L);
-        //sfpBuilder.setStartingIndex((short) (sfList.size() + 1));
-        //sfpBuilder.setSfpServiceFunction(sfList);
-
-        ServiceFunctionPathsBuilder builder = new ServiceFunctionPathsBuilder();
-        List<ServiceFunctionPath> sfpList = new ArrayList<>();
-        sfpList.add(sfpBuilder.build());
-        builder.setServiceFunctionPath(sfpList);
-
-        //sfcProvider.eventHandler.enqueueSfpEvent(builder.build());
-        Thread.sleep(100);
-        System.out.println(">>>>>Running test end");
-    }
-
-    private SfDataPlaneLocatorBuilder putSf(String name, String type,
-                                            String ipMgmt, String ipLocator, int portLocator) {
-        logger.info("\n####### Start: {}", Thread.currentThread().getStackTrace()[1]);
-
-        // Build Locator Type (ip and port)
-        IpAddress ipAddress = new IpAddress(ipLocator.toCharArray());
-        PortNumber portNumber = new PortNumber(portLocator);
-        IpBuilder ipBuilder = new IpBuilder();
-        ipBuilder = ipBuilder.setIp(ipAddress).setPort(portNumber);
-
-        // Build Data Plane Locator and populate with Locator Type
-
-        SfDataPlaneLocatorBuilder sfDataPlaneLocatorBuilder = new SfDataPlaneLocatorBuilder();
-        sfDataPlaneLocatorBuilder = sfDataPlaneLocatorBuilder.setLocatorType(ipBuilder.build());
-        return sfDataPlaneLocatorBuilder;
-
-/*
-        // Build ServiceFunctionBuilder and set all data constructed above
-        PutServiceFunctionInputBuilder putServiceFunctionInputBuilder = new PutServiceFunctionInputBuilder();
-        putServiceFunctionInputBuilder = putServiceFunctionInputBuilder.setName(name).setType(type).
-                setIpMgmtAddress(new IpAddress(ipMgmt.toCharArray())).
-                setSfDataPlaneLocator(sfDataPlaneLocatorBuilder.build());
-
-        try {
-            Future<RpcResult<Void>> fr = sfService.putServiceFunction(putServiceFunctionInputBuilder.build());
-            RpcResult<Void> result = fr.get();
-            if (result != null) {
-                logger.info("\n####### {} result: {}", Thread.currentThread().getStackTrace()[1], result);
-                if (result.isSuccessful()) {
-                    logger.info("\n####### {}: successfully finished", Thread.currentThread().getStackTrace()[1]);
-                } else {
-                    logger.warn("\n####### {}: not successfully finished", Thread.currentThread().getStackTrace()[1]);
-                }
-                return result.isSuccessful();
-            } else {
-                logger.warn("\n####### {} result is NULL", Thread.currentThread().getStackTrace()[1]);
-                return Boolean.FALSE;
-            }
-
-        } catch (Exception e) {
-            logger.warn("\n####### {} Error occurred: {}", Thread.currentThread().getStackTrace()[1], e);
-            e.printStackTrace();
-            return Boolean.FALSE;
-        }
-    }
-*/
-    }
-}
diff --git a/ovs-sfc/src/test/resources/ServiceFunctionAcl.json b/ovs-sfc/src/test/resources/ServiceFunctionAcl.json
deleted file mode 100644 (file)
index ed1944d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "access-lists": {
-        "access-list": [
-            {
-                "acl-name": "http",
-                "access-list-entries": [
-                    {
-                        "rule-name": "http",
-                        "matches": {
-                            "destination-port-range": {
-                                "lower-port": "80",
-                                "upper-port": "80"
-                            }
-                        },
-                        "actions": {
-                            "service-function-path": "sfp1"
-                        }
-                    }
-                ]
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/ovs-sfc/src/test/resources/ServiceFunctionChains.json b/ovs-sfc/src/test/resources/ServiceFunctionChains.json
deleted file mode 100644 (file)
index 6ccf483..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "service-function-chains": {
-        "service-function-chain": [
-            {
-                "name": "sfc1",
-                "symmetric": false,
-                "sfc-service-function": [
-                    {
-                        "name": "napt44-abstract1",
-                        "type": "napt44"
-                    },
-                    {
-                        "name": "napt44-abstract2",
-                        "type": "napt44"
-                    }
-                ]
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/ovs-sfc/src/test/resources/ServiceFunctionForwarders.json b/ovs-sfc/src/test/resources/ServiceFunctionForwarders.json
deleted file mode 100644 (file)
index efd6330..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-{
-    "service-function-forwarders": {
-        "service-function-forwarder": [
-            {
-                "name": "sff1",
-                "service-node": "sff1",
-                "classifier": "acl-sfp-1-http",
-                "sff-data-plane-locator": [
-                    {
-                        "name": "sff1",
-                        "data-plane-locator": {
-                            "port": 5000,
-                            "ip": "192.168.120.45",
-                            "transport": "service-locator:vxlan-gpe"
-                        }
-                    }
-                ],
-                "service-function-dictionary": [
-                    {
-                        "name": "sf11",
-                        "type": "napt44",
-                        "failmode": "close",
-                        "sff-sf-data-plane-locator": {
-                            "transport": "service-locator:vxlan-gpe",
-                            "port": 10000,
-                            "ip": "10.1.11.1"
-                        },
-                        "sff-interfaces": [
-                            {
-                                "sff-interface": "vsff1-sf11"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "sf12",
-                        "type": "napt44",
-                        "failmode": "close",
-                        "sff-sf-data-plane-locator": {
-                            "transport": "service-locator:vxlan-gpe",
-                            "port": 10000,
-                            "ip": "10.1.12.1"
-                        },
-                        "sff-interfaces": [
-                            {
-                                "sff-interface": "vsff1-sf12"
-                            }
-                        ]
-                    }
-                ],
-                "ovs": {
-                    "uuid": "5b791cee-9b85-454d-a915-3c5b33538696",
-                    "bridge-name": "sff1",
-                    "rest-uri": "http://www.example.com/sffs/sff-bootstrap",
-                    "external-ids": [
-                        {
-                            "name": "system-id",
-                            "value": "66485d3b-01d5-4792-a85e-705417f9458b"
-                        }
-                    ]
-                }
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/ovs-sfc/src/test/resources/ServiceFunctionPaths.json b/ovs-sfc/src/test/resources/ServiceFunctionPaths.json
deleted file mode 100644 (file)
index b45eca7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-    "service-function-paths": {
-        "service-function-path": [
-            {
-                "name": "sfp1",
-                "service-chain-name": "sfc1",
-                "starting-index": "3",
-                "path-id": "1",
-                "service-path-hop": [
-                    {
-                        "hop-number": "1",
-                        "service-function-name": "sf11",
-                        "service-function-forwarder": "sff1",
-                        "service_index": "3"
-                    },
-                    {
-                        "hop-number": "2",
-                        "service-function-name": "sf12",
-                        "service-function-forwarder": "sff1",
-                        "service_index": "2"
-                    }
-                ]
-            }
-        ]
-    }
-}
\ No newline at end of file
diff --git a/ovs-sfc/src/test/resources/ServiceFunctions.json b/ovs-sfc/src/test/resources/ServiceFunctions.json
deleted file mode 100644 (file)
index bf6a0b8..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-    "service-functions": {
-        "service-function": [
-            {
-                "name": "sf11",
-                "type": "napt44",
-                "nsh-aware": false,
-                "ip-mgmt-address": "10.1.11.1",
-                "sf-data-plane-locator": {
-                    "name": "sf11",
-                    "transport": "service-locator:vxlan-gpe",
-                    "port": 10000,
-                    "ip": "10.1.11.1",
-                    "service-function-forwarder": "sff1"
-                }
-            },
-            {
-                "name": "sf12",
-                "type": "napt44",
-                "nsh-aware": false,
-                "ip-mgmt-address": "10.1.12.1",
-                "sf-data-plane-locator": {
-                    "name": "sf12",
-                    "transport": "service-locator:vxlan-gpe",
-                    "port": 10000,
-                    "ip": "10.1.12.1",
-                    "service-function-forwarder": "sff1"
-                }
-            }
-        ]
-    }
-}
\ No newline at end of file
index 62b622c9777986544a6a7620f4d850a9068bc0ed..20e5f92e8da2c7d4a6468011c96b2b963d85c9fd 100644 (file)
@@ -11,6 +11,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
+  <parent>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>ovsdb-artifacts</artifactId>
   <version>1.2.1-SNAPSHOT</version>
index 381a4b08c11c82199974f4a1368e74f5cd2de8c0..36c68b0193fdbe5c7f39d271412431edfcc16926 100644 (file)
@@ -9,14 +9,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>commons</artifactId>
-        <version>1.4.0-SNAPSHOT</version>
-        <relativePath>../../commons/parent</relativePath>
+      <groupId>org.opendaylight.odlparent</groupId>
+      <artifactId>odlparent-lite</artifactId>
+      <version>1.6.0-SNAPSHOT</version>
+      <relativePath/>
     </parent>
 
+    <groupId>org.opendaylight.ovsdb</groupId>
     <artifactId>ovsdb-ui-bundle</artifactId>
-    <version>${ovsdb.ui.version}</version>
+    <version>1.2.1-SNAPSHOT</version>
     <packaging>bundle</packaging>
     <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
     <licenses>
@@ -31,16 +32,21 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
         <tag>HEAD</tag>
         <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
     </scm>
+
+    <properties>
+      <dlux.version>0.3.0-SNAPSHOT</dlux.version>
+    </properties>
+
     <dependencies>
-        <dependency>
-            <groupId>org.opendaylight.dlux</groupId>
-            <artifactId>loader</artifactId>
-            <version>${dlux.loader.version}</version>
+      <dependency>
+        <groupId>org.opendaylight.dlux</groupId>
+          <artifactId>loader</artifactId>
+          <version>${dlux.version}</version>
         </dependency>
         <dependency>
           <groupId>org.opendaylight.ovsdb</groupId>
           <artifactId>ovsdb-ui-module</artifactId>
-          <version>${ovsdb.ui.version}</version>
+          <version>${project.version}</version>
         </dependency>
     </dependencies>
     <build>
@@ -82,7 +88,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <version>2.5.3</version>
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
index fdaafdab73e691e6983ec1776f906ac5aa6c0b86..99eede7bf183608b10ecdb517f1ea68cac3fe2c1 100644 (file)
@@ -12,7 +12,9 @@
         <property name="angularJs" value="app.ovsdb"/>
         <property name="cssDependencies">
             <list>
-                <value>src/app/ovsdb/ovsdb.css</value>
+                <value>src/app/ovsdb/css/select2.min.css</value>
+                <value>src/app/ovsdb/css/toggle-switch.css</value>
+                <value>src/app/ovsdb/css/ovsdb.css</value>
             </list>
         </property>
     </bean>
index a56816a92978a805c5e3362c34ba29080b084bbb..9ccaf3990b026de8c1fa33b0002b90c5b9a11477 100644 (file)
@@ -9,14 +9,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
-        <groupId>org.opendaylight.ovsdb</groupId>
-        <artifactId>commons</artifactId>
-        <version>1.4.0-SNAPSHOT</version>
-        <relativePath>../../commons/parent</relativePath>
+      <groupId>org.opendaylight.odlparent</groupId>
+      <artifactId>odlparent-lite</artifactId>
+      <version>1.6.0-SNAPSHOT</version>
+      <relativePath/>
     </parent>
 
+    <groupId>org.opendaylight.ovsdb</groupId>
     <artifactId>ovsdb-ui-module</artifactId>
-    <version>${ovsdb.ui.version}</version>
+    <version>1.2.1-SNAPSHOT</version>
     <packaging>jar</packaging>
     <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
     <licenses>
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/Graph.js b/ovsdb-ui/module/src/main/resources/ovsdb/Graph.js
new file mode 100644 (file)
index 0000000..977e75b
--- /dev/null
@@ -0,0 +1,371 @@
+define(['app/ovsdb/lib/d3.min', 'app/ovsdb/OvsCore', 'app/ovsdb/matrix', 'underscore'], function(d3, OvsCore, Geom, _) {
+  'use strict';
+
+  var root = null,
+    forceLayout = null,
+    baseBB = null,
+    nodes = null,
+    links = null,
+    nodeData = [],
+    linkData = [],
+    drag = null,
+    nodePosCache = null;
+
+  function Graph(id, width, height) {
+    var x = d3.scale.linear()
+      .domain([0, width])
+      .range([0, width]);
+
+    var y = d3.scale.linear()
+      .domain([0, height])
+      .range([height, 0]);
+
+    var tmp = d3.select(id).append("svg")
+    .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');
+
+    root = tmp.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 6]).on("zoom", zoom))
+      .append("g");
+
+    this.matrix = new Geom.Matrix();
+
+  //  this._bg = tmp.insert('svg:polygon', ':first-child');
+  //  this._bg.attr('id', 'ttt').attr('fill', 'rgb(250, 220, 220)').attr('stroke', 'rgb(250,0,0)');
+
+    drag = d3.behavior.drag()
+      .origin(function(d) {
+        return d;
+      })
+      .on("dragstart", dragstarted.bind(this))
+      .on("drag", dragmove.bind(this))
+      .on("dragend", dragend.bind(this));
+
+    // a layout for the bridge and his link
+    forceLayout = new d3.layout.force()
+      .gravity(0.05)
+      .charge(-400)
+      .linkDistance(80)
+      .size([width, height])
+      .on('tick', this.update.bind(this));
+
+    addDefs();
+  }
+
+  function zoom() {
+    root.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
+  }
+
+  function dragstarted(d) {
+    d3.event.sourceEvent.stopPropagation();
+    forceLayout.stop();
+  }
+
+  function dragmove(d) {
+    d.x += d3.event.dx;
+    d.y += d3.event.dy;
+    d.px += d3.event.dx;
+    d.py += d3.event.dy;
+    this.update();
+  }
+
+  function dragend(d) {
+    d.fixed = true;
+    this.update();
+    forceLayout.resume();
+    baseBB = null;
+  }
+
+  // Define reusable svg item like box-shadow
+  function addDefs() {
+    // box-shadow
+    var defs = d3.select('svg').insert('svg:defs', ':first-child');
+    var filter = defs.append('svg:filter').attr('id', 'selectNode').attr('x', '-20%').attr('y', '-20%').attr('width', '140%').attr('height', '140%');
+    filter.append('feGaussianBlur').attr('stdDeviation', '2').attr('result', 'coloredBlur');
+    var femerge = filter.append('feMerge');
+    femerge.append('feMergeNode').attr('in', 'coloredBlur');
+    femerge.append('feMergeNode').attr('in', 'SourceGraphic');
+  }
+
+  function sortLink(links) {
+    links.sort(function(a,b) {
+      if (a.source > b.source) {
+        return 1;
+      } else if (a.source < b.source) {
+        return -1;
+      }
+      else {
+        if (a.target > b.target) {
+          return 1;
+        }
+        if (a.target < b.target) {
+          return -1;
+        } else {
+          return 0;
+        }
+      }
+    });
+  }
+
+  function setLinkIndexAndNum(links) {
+    _.each(links, function(link, i) {
+      if (i != 0 && links[i].source == links[i-1].source &&
+        links[i].target == links[i-1].target) {
+          links[i].linkindex = links[i-1].linkindex + 1;
+        } else {
+          links[i].linkindex = 1;
+        }
+    });
+  }
+
+  // Properties to quick access and set nodes and links
+  Object.defineProperties(Graph.prototype, {
+    links: {
+      get: function() {
+        return links;
+      },
+      set: function(value) {
+        sortLink(value);
+        setLinkIndexAndNum(value);
+
+        forceLayout.links(value);
+        links = root.selectAll('links')
+          .data(value)
+          .enter().append('svg:path')
+          .attr('class', function(d) {
+            return d.linkType;
+          })
+          .attr('fill', 'none')
+          .attr('stroke-dasharray', function(d) {
+            return d.dashArray;
+          })
+          .attr('stroke-width', function(d) {
+            return d.width;
+          })
+          .attr('stroke', function(d) {
+            return d.color;
+          });
+      }
+    },
+    nodes: {
+      get: function() {
+        return nodes;
+      },
+      set: function(value) {
+        var _this = this; // context change in callback function and we need both
+
+        forceLayout.nodes(value);
+        nodes = root.selectAll('.nodes')
+          .data(value)
+          .enter().append('svg:g')
+          .call(drag)
+          .attr('class', function(d) {
+            return (d.node instanceof OvsCore.BridgeNode) ? 'bridge' : 'switch';
+          })
+          .on('click', function(d) {
+            if (d3.event.defaultPrevented) return;
+            _this.onNodeClick(d, nodes, links, this);
+          })
+          .on("mouseover", function(d) {
+            _this.onNodeOver(d, nodes, links, this);
+          })
+          .on("mouseout", function(d) {
+            _this.onNodeOut(d, nodes, links, this);
+          });
+
+        nodes.append('text')
+          .attr('x', 0)
+          .attr('y', 30)
+          .attr('fill', 'black')
+          .attr('text-anchor', 'middle')
+          .text(function(d) {
+            if (d.node instanceof OvsCore.BridgeNode)
+              return d.node.flowInfo.ip;
+            else
+              return d.node.otherLocalIp;
+          });
+
+        //svg node
+        var layer = d3.selectAll('g.switch').append('svg:g').attr('class', 'switch').attr('transform', 'translate(-16 -16)');
+        layer.append('svg:rect').style('fill-rule', 'evenodd').attr('ry', '3.6808').attr('height', '28.901')
+          .attr('width', '28.784').style('stroke', '#002b69').attr('y', '0').attr('x', '0').style('stroke-width', "3px").style('fill', '#2a7fff');
+        layer.append('svg:path').attr('d', 'm27.043 6.2-5.0754 3.3764-.01018-2.1082-5.9209-.022.01773-2.6018 5.9031-.037.08118-2.1164z').style('fill', "#002b69");
+        layer.append('svg:path').attr('d', "m26.866 19.4-5.0754 3.3764-.01018-2.1082-5.9209-.022.01773-2.6018 5.9031-.037.08118-2.1164z").style('fill', "#002b69");
+        layer.append('svg:path').attr('d', "m3.0872 11.6 5.0754 3.3764.01018-2.1082 5.9209-.022-.01773-2.6018-5.9031-.037-.08118-2.1164z").style('fill', "#002b69");
+        layer.append('svg:path').attr('d', "m3.2639 24.8 5.0754 3.3764.01018-2.1082 5.9209-.022-.01773-2.6018-5.9031-.037-.08118-2.1164z").style('fill', "#002b69");
+
+        //svg bridge
+        var layer = d3.selectAll('g.bridge').append('svg:g').attr('transform', 'translate(-16 -16)');
+        layer.append('svg:path').style('fill', '#d40000').style('stroke', '#ff0000').style('stroke-width', '0.10413094')
+          .style('stroke-linecap', 'round') //stroke-linejoin:round
+          .attr('d', 'm 2.9656662,3.4868 c 4.8978761,7.5117 16.2156478,6.1742 21.9929178,2.0807 l 2.154019,-1.5814 -0.08265,18.1941 -2.055088,2.0313 -24.17161713,0.055 -0.0255688,-18.6893 z');
+        layer.append('svg:path').style('fill', '#ff5555').style('stroke', '#ff0000').style('stroke-width', '0.10413094')
+          .style('stroke-linecap', 'round') //stroke-linejoin:round
+          .attr('d', 'm 0.83642587,5.5637 c 4.89787603,7.5117 18.41115613,4.1109 24.18842613,0.018 l -0.06627,18.6546 -24.12215693,0 z');
+      }
+    }
+  });
+
+  // Update the node and link position on the canvas
+  Graph.prototype.update = function(e) {
+    var k = 1 , //.1 * e.alpha
+      isDragging = (e !== null)
+/*
+    if (!isDragging) {
+      k = .1 * e.alpha;
+    }
+
+    if (!isDragging) {
+      forceLayout.nodes().forEach(function(o) {
+        var i = (o.node instanceof OvsCore.OvsNode) ? 1 : 0;
+        o.y += (layerAnchor[i].y - o.y) * k;
+        o.x += (layerAnchor[i].x - o.x) * k;
+      });
+    }*/
+
+    if (links) {
+      links.attr('d', (function(d) {
+        var srcT = this.matrix.transformPoint(d.source.x, d.source.y),
+          targetT = this.matrix.transformPoint(d.target.x, d.target.y),
+          src = {x:srcT.elements[0],y:srcT.elements[1]},
+          tgt = {x:targetT.elements[0],y:targetT.elements[1]},
+          anchor1 = {}, anchor2 = {};
+
+        if (d.linkType === 'tunnel') {
+          // curve the line and arc it on a direction of a 90 degree vector
+          var perp = { x : -tgt.y, y: tgt.x};
+          var srcNorm = Math.sqrt(src.x * src.x + src.y * src.y);
+          var perpNorm = Math.sqrt(perp.x * perp.x + perp.y * perp.y);
+          var dy = (perp.y/perpNorm - src.y/srcNorm);
+          var dx = (perp.x/perpNorm - src.x/srcNorm);
+
+          anchor1 = {x: src.x - dx * 30, y: src.y - dy * 30 };
+          anchor2 = {x: tgt.x - dx * 30, y: tgt.y - dy * 30 };
+        } else {
+          // default strait line
+          anchor1 = src;
+          anchor2 = tgt;
+        }
+
+        return OvsCore.Util.String.Format('M{0},{1} C{2},{3} {4},{5} {6},{7}',
+          srcT.elements[0], srcT.elements[1],
+          anchor1.x, anchor1.y,
+          anchor2.x, anchor2.y,
+          targetT.elements[0], targetT.elements[1]
+        );
+      }).bind(this));
+    }
+
+    nodes.attr("transform", (function(d) {
+      var a = new Geom.Matrix.fromString(root.attr('transform'));
+      var tmp = Geom.Matrix.combine(a, this.matrix);
+
+      var transV = this.matrix.transformPoint(d.x, d.y);
+      var v = tmp.transformPoint(d.x, d.y);
+      d.pos = {
+        x: v.elements[0],
+        y: v.elements[1]
+      };
+      nodePosCache[d.node.nodeId] =  { pos: d.pos, fixed: d.fixed};
+      return "translate(" + transV.elements[0] + ',' + transV.elements[1] + ')';
+    }).bind(this));
+  };
+
+  Graph.prototype.setPosCache = function(cache) {
+    nodePosCache = cache;
+  };
+
+  // Apply few matrix transform to fake a perspective effet
+  Graph.prototype.applyPerspective = function(value) {
+    if (!baseBB)
+      baseBB = root.node().getBBox();
+
+    var padding = 50;
+    var persMatrix = new Geom.Matrix()
+      .translate(-(baseBB.x + baseBB.width / 2), -(baseBB.y + baseBB.height / 2))
+      .skew(-25, 0)
+      .scale(1, 0.6)
+      .translate(baseBB.x + baseBB.width / 2, baseBB.y + baseBB.height / 2);
+
+    this.matrix.transform = value ? this.matrix.transform.x(persMatrix.transform) : this.matrix.transform.x(persMatrix.transform.inverse());
+
+    var p1 = this.matrix.transformPoint(baseBB.x - padding, baseBB.y - padding);
+    var p2 = this.matrix.transformPoint(baseBB.x - padding, baseBB.y + baseBB.height + padding);
+    var p3 = this.matrix.transformPoint(baseBB.x + baseBB.width + padding, baseBB.y + baseBB.height + padding);
+    var p4 = this.matrix.transformPoint(baseBB.x + baseBB.width + padding, baseBB.y - padding);
+
+    this._bg.attr('points', OvsCore.Util.String.Format("{0},{1} {2},{3} {4},{5} {6},{7}",
+      p1.elements[0],
+      p1.elements[1],
+      //--
+      p2.elements[0],
+      p2.elements[1],
+      //--
+      p3.elements[0],
+      p3.elements[1],
+      //--
+      p4.elements[0],
+      p4.elements[1])).style('display', (value) ? 'block' : 'none');
+
+    this.update();
+  };
+
+  function positionateBaseOnCache() {
+    forceLayout.stop();
+    forceLayout.nodes().forEach(function(d) {
+      var nodeCached = nodePosCache[d.node.nodeId];
+      d.px = d.x = nodeCached.pos.x;
+      d.py = d.y = nodeCached.pos.y;
+      d.fixed = nodeCached.fixed;
+    });
+    forceLayout.resume();
+  }
+
+  // start the force layout
+  Graph.prototype.start = function() {
+    forceLayout.linkStrength(function(link) {
+      if (link.linkType === 'bridgeOvsLink') {
+        return 0;
+      }
+      return 1;
+    });
+    forceLayout.start();
+    if (_.size(nodePosCache) > 0) {
+      positionateBaseOnCache();
+    }
+  };
+
+  Graph.prototype.freeDOM = function() {
+    nodes.remove();
+    links.remove();
+    forceLayout.nodes([]);
+    forceLayout.links([]);
+  };
+
+  // Enable to manipulate attributes of the graph group node
+  Graph.prototype.attr = function(name, value) {
+    return root.attr(name, value);
+  };
+
+  // Enable the monipulate the css of the graph group node
+  Graph.prototype.style = function(name, value) {
+    return root.style(name, value);
+  };
+
+  Graph.prototype.selectAll = function(a) {
+    return root.selectAll(a);
+  };
+
+  // callback function
+  Graph.prototype.onNodeOver = _.noop;
+  Graph.prototype.onNodeOut = _.noop;
+  Graph.prototype.onNodeClick = _.noop;
+
+  return Graph;
+});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/LogicalGraph.js b/ovsdb-ui/module/src/main/resources/ovsdb/LogicalGraph.js
new file mode 100644 (file)
index 0000000..735fc6e
--- /dev/null
@@ -0,0 +1,520 @@
+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
+    },
+    // config
+    nodeWidth = 15,
+    nodeHeight = -1,
+    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,
+    networkOffset = 15,
+    linkHeight = 5,
+    // datas
+    networkData = [],
+    routerData = [],
+    vmData = [],
+    linkData = [],
+    tmpNetHolder = {},
+    // d3 layer over datas
+    d3Node = null,
+    d3Link = null,
+    d3Vm = null,
+    d3Router = null,
+    randomize = OvsCore.Util.Math.Random(42);
+
+  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');
+
+    tmp.append('svg:rect')
+      .attr('width', width)
+      .attr('height', height)
+      .attr('fill', 'white');
+
+    root = tmp.call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
+      .append("g");
+    tmp.on("dblclick.zoom", null);
+    addDefs();
+  }
+
+  // Define reusable svg item like box-shadow
+  function addDefs() {
+    // box-shadow
+    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('feOffset').attr('in', 'SourceGraphic').attr('in2', 'blurOut').attr('mode', 'normal');
+  }
+
+  function zoom() {
+    root.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
+  }
+
+  Object.defineProperties(LogicalGraph.prototype, {
+    networks: {
+      set: function (value) {
+        networkData = value;
+        value.forEach(function (net) {
+          routerData = routerData.concat(net.routers);
+        });
+        value.forEach(function (net) {
+          vmData = vmData.concat(net.instances);
+        });
+      }
+    }
+  });
+
+  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 () {
+    d3Node.remove();
+    d3Link.remove();
+    d3Vm.remove();
+    d3Router.remove();
+
+    networkData = [];
+    routerData = [];
+    vmData = [];
+    linkData = [];
+    bbox = {
+      x: 0,
+      y: 15,
+      width: 0,
+      height: 0
+    };
+  };
+
+  function addLinksToDom(linksData) {
+    d3Link = root.selectAll('.llink')
+      .data(linksData).enter().append('svg:g');
+
+    d3Link.append('rect')
+      .attr('width', function (d) {
+        return d.target.x - d.source.x;
+      })
+      .attr('height', linkHeight)
+      .style('fill', function (d) {
+        return d.color;
+      });
+
+    d3Link.append('text')
+      .attr('x', 40)
+      .attr('y', -3)
+      .text(function (d) {
+        return d.text;
+      });
+  }
+
+  function addNetWorkRouterVmsToDom(networks, routers, vms) {
+    var ctx = this,
+      timer = null;
+
+    d3Node = root.selectAll('.network')
+      .data(networks).enter()
+      .append('svg:g');
+    d3Router = root.selectAll('.routers')
+      .data(routers).enter()
+      .append('svg:g');
+    d3Vm = root.selectAll('.vm')
+      .data(vms).enter()
+      .append('svg:g');
+
+    // append coresponding form
+    d3Node.append('svg:rect')
+      .attr('width', nodeWidth)
+      .attr('height', nodeHeight)
+      .attr('rx', 10)
+      .attr('ry', 10)
+      .style('fill', function (d) {
+        return d.color;
+      }).on('click', function (d) {
+        if (d3.event.defaultPrevented) return;
+        timer = setTimeout(function () {
+          ctx.onClick(d);
+        }.bind(this), 150);
+      }).on('dblclick', function (d) {
+        clearTimeout(timer);
+        ctx.dblClick(d);
+      });
+
+    // append the network name text
+    d3Node.append('text')
+      .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 info for the network ip
+    d3Node.append('text')
+      .attr('x', nodeWidth + 10)
+      .attr('y', nodeHeight - 15)
+      .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;
+      });
+
+    // vm
+    d3Vm.append('svg:image')
+      .attr('width', defaultVmsWidth)
+      .attr('height', defaultVmsHeight)
+      .attr('filter', 'url(#boxShadow)')
+      .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) {
+        if (d3.event.defaultPrevented) return;
+        timer = setTimeout(function () {
+          ctx.onClick(d);
+        }.bind(this), 150);
+      }).on('dblclick', function (d) {
+        clearTimeout(timer);
+        ctx.dblClick(d);
+      });
+
+    // router
+    d3Router.append('svg:image')
+      .attr('width', defaultRouterWidth)
+      .attr('height', defaultRouterHeight)
+      .attr('xlink:href', 'src/app/ovsdb/assets/router.png')
+      .on('click', function (d) {
+        if (d3.event.defaultPrevented) return;
+        timer = setTimeout(function () {
+          ctx.onClick(d);
+        }.bind(this), 150);
+      }).on('dblclick', function (d) {
+        clearTimeout(timer);
+        ctx.dblClick(d);
+      });
+
+    // router name label
+    d3Router.append('text')
+      .attr('x', defaultRouterWidth * 0.5)
+      .attr('y', defaultRouterHeight + 15)
+      .attr('text-anchor', 'middle')
+      .attr('class', 'linfolabel')
+      .text(function (d) {
+        return d.name;
+      });
+
+    // vm name label
+    d3Vm.append('text')
+      .attr('x', defaultVmsWidth * 0.5)
+      .attr('y', defaultVmsHeight + 15)
+      .attr('text-anchor', 'middle')
+      .attr('class', 'linfolabel')
+      .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) {
+        return (d.floatingIp) ? d.floatingIp.ip : '';
+      });
+
+  }
+
+  function findNetworkWithRouter(router) {
+    var result = [];
+    _.each(router.interfaces, function (inter) {
+      if (inter.type === 'router_interface') {
+        var net = tmpNetHolder[inter.networkId] || null;
+
+        if (net) {
+          result.push({
+            network: net,
+            interface: inter
+          });
+        }
+      }
+    });
+
+    return result;
+  }
+
+  function positionateNetwork(network, x, y, margin) {
+    network.x = x;
+    network.y = y;
+    margin = margin || 0;
+    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.width = network.x > bbox.width ? network.x : bbox.width;
+
+    // get the number of "childs" (router, vm)
+    var nbRouter = network.routers.length;
+    var nbVm = network.instances.length;
+
+    if (!network.external) {
+      _.each(network.subnets, function (subnet, i) {
+        network.ip += subnet.cidr;
+        if (i < network.subnets.length - 1) {
+          network.ip += ', ';
+        }
+      });
+    }
+
+    // if needed, ajust the height of the network
+    // to be able to display all children
+    ajustHeighBaseOnChilds(nbRouter, nbVm);
+
+    var py = positionateRouter(network, x + routerMargin.width, y + margin);
+
+    positionateVm(network, x + vmMargin.width, py + 35 + margin);
+    delete tmpNetHolder[network.id];
+  }
+
+  function positionateRouter(network, x, y) {
+    var px = x,
+      py = y;
+
+    // loop over all routers
+    _.each(network.routers, function (router, i) {
+      router.x = getRouterCentroid(x, py).x;
+      router.y = py;
+      py += getRouterMarginHeight();
+
+      if (network.external) {
+        // find network ip with the gateway ip
+        var gateway = router.externalGateway.external_fixed_ips[0].ip_address;
+        var netIp = gateway.slice(0, gateway.lastIndexOf('.')) + '.0';
+        network.ip = netIp;
+      }
+
+      // look is the router is the highest
+      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,
+        text: router.externalGateway.external_fixed_ips[0].ip_address
+      });
+
+      // go to the next layer
+      var nets = findNetworkWithRouter(router),
+        step = defaultRouterHeight / (nets.length + 1);
+
+      _.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)
+          },
+          color: net.network.color,
+          text: net.interface.ip.ip_address
+        });
+      });
+    });
+    return py;
+  }
+
+  function positionateVm(network, x, y) {
+
+    // I do vm before router because router
+    // will step to another BUS
+    _.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.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,
+        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
+   */
+  function setTopologyPosition(networks) {
+    _.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 = networkMargin.width,
+        net = tmpNetHolder[key];
+      positionateNetwork(net, bbox.x + bbox.width + margin, bbox.y);
+    }
+  }
+
+  /*
+   * Check and ajust the height for a network.
+   */
+  function ajustHeighBaseOnChilds(nbRouter, nbVm) {
+    // calculate the height for the number of childs
+    var childHeight = nbRouter * (getRouterMarginHeight()) +
+      nbVm * (getVmMarginHeight()) + ipNetworkTextMaxLength;
+
+    // if heigh bigger than the default network height resize it
+    if (childHeight > nodeHeight) {
+      nodeHeight = childHeight + networkOffset;
+    }
+  }
+
+  /*
+   * Set the view to the modal position
+   */
+  function update() {
+
+    d3Node.attr('transform', function (d) {
+      return OvsCore.Util.String.Format("translate({0}, {1})",
+        d.x, d.y
+      );
+    });
+
+    d3Router.attr('transform', function (d, i) {
+      return OvsCore.Util.String.Format("translate({0}, {1})",
+        d.x, d.y
+      );
+    });
+
+    d3Vm.attr('transform', function (d) {
+      return OvsCore.Util.String.Format("translate({0}, {1})",
+        d.x, d.y
+      );
+    });
+
+    d3Link.attr('transform', function (d) {
+      return OvsCore.Util.String.Format("translate({0}, {1})",
+        d.source.x, d.source.y
+      );
+    });
+
+    // resize the graph if bigger than the canvas
+    var bbox = root.node().getBBox();
+    if (bbox.width > canvasWidth || bbox.height > canvasHeight) {
+      var sx = (canvasWidth - 30) / bbox.width,
+        sy = (canvasHeight - 30) / bbox.height,
+        s = sx < sy ? sx : sy;
+      d3.select('.layer_0').attr('transform', 'scale(' + s + ')');
+      console.log(root.node().getBBox());
+    }
+  }
+
+  function getRouterCentroid(x, y) {
+    return {
+      x: x + defaultRouterWidth * 0.5,
+      y: y + defaultRouterHeight * 0.5
+    };
+  }
+
+  function getRouterMarginHeight() {
+    return (defaultRouterHeight + routerMargin.height);
+  }
+
+  function getVmMarginHeight() {
+    return (defaultVmsHeight + vmMargin.height);
+  }
+
+  function getNetworkLayerPosition(x) {
+    return {
+      x: x + networkMargin.width,
+      y: networkMargin.height
+    };
+  }
+
+  function getVmLayerPosition(nbRouter, x) {
+    var t = {
+      x: x + vmMargin.width * 2,
+      y: getRoutersDim(nbRouter).height + getVmMarginHeight()
+    };
+    return t;
+  }
+
+  LogicalGraph.prototype.onClick = _.noop;
+  LogicalGraph.prototype.dblClick = _.noop;
+
+  return LogicalGraph;
+});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/OvsCore.js b/ovsdb-ui/module/src/main/resources/ovsdb/OvsCore.js
new file mode 100644 (file)
index 0000000..70733ef
--- /dev/null
@@ -0,0 +1,710 @@
+/*
+ * 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
+ */
+
+define(['underscore'], function (_) {
+
+  var Topology = (function () {
+
+    function Topology(topoId) {
+      this.topoId = topoId || '';
+      this._bridgeNodes = {};
+      this._ovsdbNodes = {};
+      this._links = {};
+    }
+
+    Object.defineProperties(Topology.prototype, {
+      bridgeNodes: {
+        get: function () {
+          return this._bridgeNodes;
+        }
+      },
+      nodes: {
+        get: function () {
+          return _.extend({}, this._bridgeNodes, this._ovsdbNodes);
+        }
+      },
+      ovsdbNodes: {
+        get: function () {
+          return this._ovsdbNodes;
+        }
+      },
+      links: {
+        get: function () {
+          return this._links;
+        }
+      }
+    });
+
+    Topology.prototype.registerBridgeNode = function (bridgeNode) {
+      this._bridgeNodes[bridgeNode.nodeId] = bridgeNode;
+    };
+
+    Topology.prototype.registerOvsdbNode = function (ovsdbNode) {
+      this._ovsdbNodes[ovsdbNode.nodeId] = ovsdbNode;
+    };
+
+    Topology.prototype.registerLink = function (link) {
+      if (this._links[link.linkId]) {
+        console.warn('Two links have the same id (' + link.linkId + '), the first one will be overrided');
+      }
+      this._links[link.linkId] = link;
+    };
+
+    Topology.prototype.updateLink = function () {
+      _.each(this._links, (function (link, key) {
+        if (link instanceof Link) {
+          srcNode = _.filter(this._bridgeNodes, function (node) {
+            return node.getFLowName() === link.srcNodeId;
+          });
+          destNode = _.filter(this._bridgeNodes, function (node) {
+            return node.getFLowName() === link.destNodeId;
+          });
+          link.srcNodeId = srcNode[0].nodeId;
+          link.destNodeId = destNode[0].nodeId;
+        }
+        link.source = Object.keys(this.nodes).indexOf(link.srcNodeId);
+        link.target = Object.keys(this.nodes).indexOf(link.destNodeId);
+
+      }).bind(this));
+    };
+
+    return Topology;
+  })();
+
+  var OvsNode = (function () {
+    function OvsNode(nodeId, inetMgr, inetNode, otherLocalIp, ovsVersion) {
+      this.nodeId = nodeId;
+      this.inetMgr = inetMgr;
+      this.inetNode = inetNode;
+      this.otherLocalIp = otherLocalIp;
+      this.ovsVersion = ovsVersion;
+    }
+
+    OvsNode.prototype.showIpAdress = function () {
+      return this.otherLocalIp;
+    };
+
+    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
+            }
+          ]
+        }]
+      };
+    };
+
+    return OvsNode;
+  })();
+
+  var BridgeNode = (function () {
+
+    function BridgeNode(nodeId, dpIp, name, controllerTarget, controllerConnected) {
+      this.nodeId = nodeId;
+      this.dpIp = dpIp;
+      this.name = name;
+      this.controllerTarget = controllerTarget;
+      this.controllerConnected = controllerConnected;
+      this._tpList = [];
+      this.flowInfo = {};
+      this.flowTable = [];
+    }
+
+    Object.defineProperties(BridgeNode.prototype, {
+      tPs: {
+        get: function () {
+          return this._tpList;
+        }
+      },
+    });
+
+    var dpToFlow = function (dpId) {
+      return 'openflow:' + parseInt(dpId.replace(/:/g, ''), 16);
+    };
+
+    BridgeNode.prototype.getFLowName = function () {
+      return (!this.dpIp) ? this.nodeId : dpToFlow(this.dpIp);
+    };
+
+    BridgeNode.prototype.addTerminationPoint = function (tp) {
+      this._tpList.push(tp);
+      this._tpList.sort(function (tp1, tp2) {
+        return tp1.ofPort - tp2.ofPort;
+      });
+    };
+
+    BridgeNode.prototype.addFlowTableInfo = function (flowTable) {
+      this.flowTable.push(flowTable);
+      this.flowTable.sort(function (ft1, ft2) {
+        return ft1.key - ft2.key;
+      });
+    };
+
+    BridgeNode.prototype.pretty = function () {
+      return {
+        'tabs': [
+          'Basic Info',
+          'Ports',
+          'Flow Info',
+          'Flow Tables'
+        ],
+        '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': 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': true,
+            'headers': ['Table Id', 'Value'],
+            'datas': this.flowTable.map(function (t) {
+              return [t.key, t.value];
+            })
+          }
+        ]
+      };
+    };
+
+    return BridgeNode;
+  })();
+
+  var TerminationPoint = (function () {
+    function TerminationPoint(name, ofPort, tpType, mac, ifaceId) {
+      this.name = name;
+      this.ofPort = ofPort;
+      this.tpType = tpType;
+      this.mac = mac || '';
+      this.ifaceId = ifaceId || '';
+    }
+    return TerminationPoint;
+  })();
+
+  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;
+
+      // styling
+      styles = _.extend({}, styles);
+      this.color = styles.color;
+      this.width = styles.width || 1;
+      this.dashArray = styles.dashArray || 'None';
+
+      // d3js needed values
+      this.source = -1;
+      this.target = -1;
+    }
+    return BaseLink;
+  })();
+
+  var Link = (function () {
+    function Link(linkId, srcNodeId, destNodeId) {
+      var opt = {
+        color: 'black'
+      };
+
+      BaseLink.call(this, linkId, srcNodeId, destNodeId, 'link', opt);
+    }
+
+    Link.prototype = Object.create(BaseLink.prototype);
+    Link.prototype.constructor = Link;
+
+    return Link;
+  })();
+
+  var TunnelLink = (function () {
+    function TunnelLink(linkId, srcNodeId, destNodeId, linkType, color) {
+      var opt = {
+        color: 'green',
+        width: 2,
+        dashArray: '5,5'
+      };
+      BaseLink.call(this, linkId, srcNodeId, destNodeId, 'tunnel', opt);
+    }
+
+    TunnelLink.prototype = Object.create(BaseLink.prototype);
+    TunnelLink.prototype.constructor = TunnelLink;
+
+    return TunnelLink;
+  })();
+
+  var BridgeOvsLink = (function () {
+    function BridgeOvsLink(linkId, srcNodeId, destNodeId, linkType, color) {
+      var opt = {
+        color: 'gray',
+        dashArray: '10,10'
+      };
+      BaseLink.call(this, linkId, srcNodeId, destNodeId, 'bridgeOvsLink', opt);
+    }
+
+    BridgeOvsLink.prototype = Object.create(BaseLink.prototype);
+    BridgeOvsLink.prototype.constructor = BridgeOvsLink;
+
+    return BridgeOvsLink;
+  })();
+
+  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,
+          prime = 1987,
+          maximum = 1000;
+
+        if (nseed) {
+          seed = nseed;
+        }
+
+        return {
+          next: function (min, max) {
+            seed *= constant;
+            seed += prime;
+
+            return min && max ? min + seed % maximum / maximum * (max - min) : seed % maximum / maximum;
+          }
+        };
+      };
+      return Maths;
+    })();
+
+    var String = (function () {
+
+      function String() {
+
+      }
+      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]);
+        }
+        return s;
+      };
+
+      return String;
+
+    })();
+    return {
+      Math: Maths,
+      String: String
+    };
+  })();
+
+  var Neutron = (function () {
+
+    var SubNet = (function () {
+      function SubNet(id, networkId, name, ipVersion, cidr, gatewayIp, tenantId) {
+        this.id = id;
+        this.networkId = networkId;
+        this.name = name;
+        this.ipVersion = ipVersion;
+        this.cidr = cidr;
+        this.gatewayIp = gatewayIp;
+        this.tenantId = tenantId;
+      }
+      return SubNet;
+    })();
+
+    var Network = (function () {
+      function Network(id, name, shared, status, external, tenantId) {
+        this.id = id;
+        this.ip = '';
+        this.name = name;
+        this.shared = shared;
+        this.status = status;
+        this.external = external;
+        this.tenantId = tenantId;
+        this.subnets = [];
+        this.instances = [];
+        this.routers = [];
+      }
+
+      Network.prototype.addSubNets = function (subnets) {
+        if (subnets) {
+          if (_.isArray(subnets)) {
+            var i = 0;
+            for (; i < subnets.length; ++i) {
+              this.subnets.push(subnets[i]);
+            }
+          } else {
+            this.subnets.push(subnet);
+          }
+        }
+      };
+
+      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 () {
+        return {
+          'tabs': [
+            'Info',
+            'Subnets'
+          ],
+          'containts': [
+            {
+              '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
+                }
+              ]
+            },
+            {
+              '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];
+              })
+            }
+          ]
+        };
+      };
+
+      return Network;
+    })();
+
+    var Port = (function () {
+      function Port(id, networkId, name, tenantId, deviceId, deviceOwner, fixed_ips, mac) {
+        this.id = id;
+        this.networkId = networkId;
+        this.name = name;
+        this.tenantId = '' + tenantId || '';
+        this.deviceId = deviceId;
+        this.deviceOwner = deviceOwner;
+        this.fixed_ips = fixed_ips;
+        this.mac = mac;
+      }
+
+      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
+          }
+        ];
+      };
+
+      return Port;
+    })();
+
+    var Router = (function () {
+      function Router(id, name, status, tenantId, externalGateway) {
+        this.id = id;
+        this.name = name;
+        this.status = status;
+        this.tenantId = tenantId;
+        this.interfaces = [];
+        this.externalGateway = externalGateway;
+      }
+
+      Router.prototype.pretty = function () {
+        return {
+          'tabs': [
+            'Info',
+            'Interfaces'
+          ],
+          'containts': [
+            {
+              '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
+                }
+              ]
+            },
+            {
+              '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];
+              })
+            }
+          ]
+        };
+      };
+
+      return Router;
+    })();
+
+    var Instance = (function () {
+      function Instance(id, networkId, name, ip, mac, deviceOwner, tenantId, topoInfo) {
+        this.id = id;
+        this.networkId = networkId;
+        this.name = name;
+        this.ip = ip;
+        this.mac = '' + mac;
+        this.type = deviceOwner;
+        this.tenantId = tenantId;
+        this.topoInfo = topoInfo || [];
+        this.floatingIp = {};
+      }
+
+      Instance.prototype.extractFloatingIps = function (floatingIps) {
+        var ctx = this;
+        this.floatingIp = _.find(floatingIps, function (fIp) {
+          return fIp.tenantId === ctx.tenantId &&
+            fIp.fixedIp === ctx.ip;
+        });
+      };
+
+      Instance.prototype.pretty = function () {
+        return {
+          'tabs': [
+            'Info',
+            'Ports'
+          ],
+          'containts': [
+            {
+              '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
+                }
+              ]
+            },
+            {
+              '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()];
+              })
+            }
+          ]
+        };
+      };
+
+      return Instance;
+    })();
+
+    var FloatingIp = (function () {
+      function FloatingIp(id, networkId, portId, fixedIp, floatingIp, tentantId, status) {
+        this.id = id;
+        this.networkId = networkId;
+        this.portId = portId;
+        this.fixedIp = fixedIp;
+        this.ip = floatingIp;
+        this.tenantId = tentantId;
+        this.status = status;
+      }
+
+      return FloatingIp;
+    })();
+
+    return {
+      Network: Network,
+      Port: Port,
+      Instance: Instance,
+      FloatingIp: FloatingIp,
+      Router: Router,
+      SubNet: SubNet
+    };
+  })();
+
+  return {
+    OvsNode: OvsNode,
+    BridgeNode: BridgeNode,
+    TerminationPoint: TerminationPoint,
+    Topology: Topology,
+    Tunnel: Tunnel,
+    BaseLink: BaseLink,
+    Link: Link,
+    TunnelLink: TunnelLink,
+    BridgeOvsLink: BridgeOvsLink,
+    Util: Util,
+    Neutron: Neutron
+  };
+});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/assets/dhcp.png b/ovsdb-ui/module/src/main/resources/ovsdb/assets/dhcp.png
new file mode 100644 (file)
index 0000000..d52cbd4
Binary files /dev/null and b/ovsdb-ui/module/src/main/resources/ovsdb/assets/dhcp.png differ
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/assets/router.png b/ovsdb-ui/module/src/main/resources/ovsdb/assets/router.png
new file mode 100644 (file)
index 0000000..fde4ce5
Binary files /dev/null and b/ovsdb-ui/module/src/main/resources/ovsdb/assets/router.png differ
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/assets/vm.png b/ovsdb-ui/module/src/main/resources/ovsdb/assets/vm.png
new file mode 100644 (file)
index 0000000..50cbcf6
Binary files /dev/null and b/ovsdb-ui/module/src/main/resources/ovsdb/assets/vm.png differ
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/css/ovsdb.css b/ovsdb-ui/module/src/main/resources/ovsdb/css/ovsdb.css
new file mode 100644 (file)
index 0000000..a27e9b1
--- /dev/null
@@ -0,0 +1,220 @@
+/*\r
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+*/\r
+\r
+#errorMessage {\r
+  display: none;\r
+}\r
+.switch-light {\r
+  width: 140px;\r
+}\r
+.switch-light span > span {\r
+  color: black;\r
+}\r
+.link {\r
+  stroke: #999;\r
+  stroke-opacity: 0.8;\r
+}\r
+.form-inline > span,\r
+label {\r
+  padding-right: 15px;\r
+}\r
+#list_container {\r
+  border: 1px solid white;\r
+  background-color: #414042;\r
+  height: 600px;\r
+}\r
+#list_container label {\r
+  color: white;\r
+}\r
+svg,\r
+#list_container {\r
+  width: 100%;\r
+}\r
+svg {\r
+  border: none;\r
+  border-radius: 0;\r
+  background-image: none;\r
+  background-color: white;\r
+  height: 580px;\r
+}\r
+#list_container > .row {\r
+  margin-left: 15px;\r
+  margin-right: 15px;\r
+}\r
+.container {\r
+  padding-top: 15px;\r
+  width: 1200px;\r
+}\r
+.row {\r
+  padding-bottom: 15px;\r
+}\r
+.select2-selection__choice {\r
+  background-color: orange !important;\r
+  border-color: black !important;\r
+  color: black !important;\r
+}\r
+.select2-selection__choice > span {\r
+  color: black !important;\r
+}\r
+.select2-results {\r
+  color: black !important;\r
+}\r
+.table.table-bordered {\r
+  background-color: white;\r
+  color: black;\r
+}\r
+#graph_header {\r
+  width: 100%;\r
+  height: 20px;\r
+  background-color: white;\r
+  border-bottom: 1px solid #ccc;\r
+}\r
+.icon-fullscreen,\r
+.icon-resize-small {\r
+  margin-right: 5px;\r
+  margin-top: 2px;\r
+}\r
+.bg_rect {\r
+  fill: #FFA6A6;\r
+  opacity: .4;\r
+  stroke: #ff0000;\r
+}\r
+kbd {\r
+  color: #333;\r
+  border-radius: 3px;\r
+  padding: 2px 4px;\r
+  font-size: 90%;\r
+  background-color: #DDD;\r
+  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.25);\r
+}\r
+.network_info {\r
+  text-align: center;\r
+  width: 170px;\r
+  height: 80px;\r
+  padding: 5px;\r
+  border-radius: 5px;\r
+  border: 1px solid black;\r
+}\r
+#network_summary {\r
+  width: auto;\r
+  height: auto;\r
+  left: 15px;\r
+  padding: 5px;\r
+}\r
+.graph_window {\r
+  position: absolute !important;\r
+  background-color: rgba(255, 255, 255, 0.7);\r
+  -webkit-box-shadow: 0px 0px 25px 0px rgba(0, 0, 0, 0.75);\r
+  -moz-box-shadow: 0px 0px 25px 0px rgba(0, 0, 0, 0.75);\r
+  box-shadow: 0px 0px 25px 0px rgba(0, 0, 0, 0.75);\r
+  padding: 5px;\r
+  z-index: 2;\r
+  border-radius: 5px;\r
+  top: 25px;\r
+  min-height: 35px;\r
+  min-width: 100px;\r
+  overflow: hidden;\r
+}\r
+#graph_summary {\r
+  width: 160px;\r
+  height: 100px;\r
+  right: 10px;\r
+}\r
+\r
+div.window_body {\r
+  height: 80%;\r
+  font-size:12px;\r
+  color:#ccc;\r
+}\r
+div.window_content {\r
+  position:relative;\r
+  max-height:350px;\r
+  height:100%;\r
+  overflow-y: auto;\r
+}\r
+div.window_header > hr {\r
+  margin-top: 0;\r
+  margin-bottom: 10px;\r
+}\r
+div.window_header > span {\r
+  width: 100%;\r
+  display: inline;\r
+}\r
+#network_table_window,\r
+#node_table_window {\r
+  width: 355px;\r
+  height: 215px;\r
+}\r
+#node_table_window {\r
+  top: 300px;\r
+  left: 25px;\r
+}\r
+#network_table_window {\r
+  top: 300px;\r
+  right: 25px;\r
+}\r
+.window-icon {\r
+  color: black;\r
+  float: right;\r
+  margin-right: 5px;\r
+}\r
+.window-icon:hover {\r
+  background-color: #ddd;\r
+  cursor: pointer;\r
+}\r
+\r
+.linfolabel {\r
+  font-size : 12px;\r
+  letter-spacing: 1px;\r
+}\r
+#tabs > ul > li > a {\r
+  color:white !important;\r
+}\r
+#tabs > ul > li.ui-state-active {\r
+  border: 1px solid white;\r
+}\r
+\r
+#tabs > ul > li.ui-state-hover > a{\r
+  color:black !important;\r
+}\r
+\r
+#tabs > ul > li > a:focus {\r
+  background-color:inherit !important;\r
+}\r
+\r
+#lDialog, #pDialog {\r
+  position:absolute;\r
+  font-size: 11px;\r
+  width: auto;\r
+  min-width: 450px;\r
+  display:none;\r
+  background-color: rgb(255, 255, 255);\r
+  border: 1px solid black;\r
+  border-radius: 10px;\r
+  height: auto;\r
+  padding: 10px;\r
+}\r
+\r
+.window_content > ul > li.ui-state-active {\r
+  border-top: 1px solid #dddddd;\r
+  border-left: 1px solid #dddddd;\r
+  border-right: 1px solid #dddddd;\r
+}\r
+\r
+.arrow-left {\r
+       width: 0;\r
+       height: 0;\r
+       border-top: 10px solid transparent;\r
+       border-bottom: 10px solid transparent;\r
+\r
+       border-right:10px solid blue;\r
+}\r
+\r
+span.selection {\r
+  font-size: 10px;\r
+}\r
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/css/select2.min.css b/ovsdb-ui/module/src/main/resources/ovsdb/css/select2.min.css
new file mode 100755 (executable)
index 0000000..1c72344
--- /dev/null
@@ -0,0 +1 @@
+.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle;}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none;}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px;}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none;}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap;}.select2-container .select2-search--inline{float:left;}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none;}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051;}.select2-results{display:block;}.select2-results__options{list-style:none;margin:0;padding:0;}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none;}.select2-results__option[aria-selected]{cursor:pointer;}.select2-container--open .select2-dropdown{left:0;}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0;}.select2-search--dropdown{display:block;padding:4px;}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box;}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none;}.select2-search--dropdown.select2-search--hide{display:none;}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0);}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px;}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px;}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999;}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px;}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0;}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left;}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto;}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default;}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none;}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px;}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%;}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left;}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px;}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px;}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder{float:right;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto;}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto;}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0;}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default;}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none;}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0;}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa;}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto;}.select2-container--default .select2-results__option[role=group]{padding:0;}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999;}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd;}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em;}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em;}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white;}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px;}.select2-container--classic .select2-selection--single{background-color:#f6f6f6;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #ffffff 50%, #eeeeee 100%);background-image:-o-linear-gradient(top, #ffffff 50%, #eeeeee 100%);background-image:linear-gradient(to bottom, #ffffff 50%, #eeeeee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb;}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px;}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px;}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999;}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);background-image:-o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);background-image:linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#cccccc', GradientType=0);}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0;}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left;}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto;}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb;}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none;}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px;}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #ffffff 0%, #eeeeee 50%);background-image:-o-linear-gradient(top, #ffffff 0%, #eeeeee 50%);background-image:linear-gradient(to bottom, #ffffff 0%, #eeeeee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eeeeee 50%, #ffffff 100%);background-image:-o-linear-gradient(top, #eeeeee 50%, #ffffff 100%);background-image:linear-gradient(to bottom, #eeeeee 50%, #ffffff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0;}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb;}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px;}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none;}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px;}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px;}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto;}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto;}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb;}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0;}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0;}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;}.select2-container--classic .select2-dropdown{background-color:white;border:1px solid transparent;}.select2-container--classic .select2-dropdown--above{border-bottom:none;}.select2-container--classic .select2-dropdown--below{border-top:none;}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto;}.select2-container--classic .select2-results__option[role=group]{padding:0;}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey;}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:white;}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px;}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb;}
\ No newline at end of file
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/css/toggle-switch.css b/ovsdb-ui/module/src/main/resources/ovsdb/css/toggle-switch.css
new file mode 100644 (file)
index 0000000..78cb2b3
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+* CSS TOGGLE SWITCHES
+* Unlicense
+*
+* Ionuț Colceriu - ghinda.net
+* https://github.com/ghinda/css-toggle-switch
+*
+*/
+/* Supported values are px, rem-calc, em-calc */
+/* Functions */
+/* Toggle Switches */
+/* Shared */
+/* Checkbox
+*/
+/* Radio Switch
+*/
+/* Hide by default
+*/
+.switch-toggle a, .switch-light span span {
+  display: none; }
+
+/* We can't test for a specific feature,
+* so we only target browsers with support for media queries.
+*/
+@media only screen {
+  /* Checkbox switch
+  */
+  .switch-light {
+    display: block;
+    min-height: 1.875em;
+    /* Outline the toggles when the inputs are focused
+  */
+    position: relative;
+    overflow: visible;
+    padding: 0;
+    margin-left: 6.25em;
+    /* Position the label over all the elements, except the slide-button (<a>)
+  * Clicking anywhere on the label will change the switch-state
+  */
+    /* Don't hide the input from screen-readers and keyboard access
+  */ }
+    .switch-light * {
+      -webkit-box-sizing: border-box;
+      -moz-box-sizing: border-box;
+      box-sizing: border-box; }
+    .switch-light a {
+      display: block;
+      -webkit-transition: all 0.2s ease-out;
+      -moz-transition: all 0.2s ease-out;
+      transition: all 0.2s ease-out; }
+    .switch-light label, .switch-light > span {
+      line-height: 1.875em;
+      vertical-align: middle; }
+    .switch-light input:focus ~ a, .switch-light input:focus + label {
+      outline: 1px dotted #888; }
+    .switch-light label {
+      position: relative;
+      z-index: 3;
+      display: block;
+      width: 100%; }
+    .switch-light input {
+      position: absolute;
+      opacity: 0;
+      z-index: 5; }
+      .switch-light input:checked ~ a {
+        right: 0%; }
+    .switch-light > span {
+      position: absolute;
+      left: -6.25em;
+      width: 100%;
+      margin: 0;
+      padding-right: 6.25em;
+      text-align: left; }
+      .switch-light > span span {
+        position: absolute;
+        top: 0;
+        left: 0;
+        z-index: 5;
+        display: block;
+        width: 50%;
+        margin-left: 6.25em;
+        text-align: center; }
+        .switch-light > span span:last-child {
+          left: 50%; }
+    .switch-light a {
+      position: absolute;
+      right: 50%;
+      top: 0;
+      z-index: 4;
+      display: block;
+      width: 50%;
+      height: 100%;
+      padding: 0; }
+
+  /* Radio switch
+  */
+  .switch-toggle {
+    display: block;
+    min-height: 1.875em;
+    /* Outline the toggles when the inputs are focused
+  */
+    position: relative;
+    display: table;
+    table-layout: fixed;
+    /* For callout panels in foundation
+  */
+    padding: 0 !important;
+    /* Generate styles for the multiple states */ }
+    .switch-toggle * {
+      -webkit-box-sizing: border-box;
+      -moz-box-sizing: border-box;
+      box-sizing: border-box; }
+    .switch-toggle a {
+      display: block;
+      -webkit-transition: all 0.2s ease-out;
+      -moz-transition: all 0.2s ease-out;
+      transition: all 0.2s ease-out; }
+    .switch-toggle label, .switch-toggle > span {
+      line-height: 1.875em;
+      vertical-align: middle; }
+    .switch-toggle input:focus ~ a, .switch-toggle input:focus + label {
+      outline: 1px dotted #888; }
+    .switch-toggle * {
+      font-size: 1em; }
+    .switch-toggle input {
+      position: absolute;
+      opacity: 0; }
+    .switch-toggle input + label {
+      position: relative;
+      z-index: 2;
+      display: table-cell;
+      width: 50%;
+      padding: 0 0.5em;
+      margin: 0;
+      text-align: center; }
+    .switch-toggle a {
+      position: absolute;
+      top: 0;
+      left: 0;
+      padding: 0;
+      z-index: 1;
+      width: 50%;
+      height: 100%; }
+    .switch-toggle input:last-of-type:checked ~ a {
+      left: 50%; }
+    .switch-toggle.switch-3 label, .switch-toggle.switch-3 a {
+      width: 33.3333333333%; }
+    .switch-toggle.switch-3 input:checked:nth-of-type(2) ~ a {
+      left: 33.3333333333%; }
+    .switch-toggle.switch-3 input:checked:last-of-type ~ a {
+      left: 66.6666666667%; }
+    .switch-toggle.switch-4 label, .switch-toggle.switch-4 a {
+      width: 25%; }
+    .switch-toggle.switch-4 input:checked:nth-of-type(2) ~ a {
+      left: 25%; }
+    .switch-toggle.switch-4 input:checked:nth-of-type(3) ~ a {
+      left: 50%; }
+    .switch-toggle.switch-4 input:checked:last-of-type ~ a {
+      left: 75%; }
+    .switch-toggle.switch-5 label, .switch-toggle.switch-5 a {
+      width: 20%; }
+    .switch-toggle.switch-5 input:checked:nth-of-type(2) ~ a {
+      left: 20%; }
+    .switch-toggle.switch-5 input:checked:nth-of-type(3) ~ a {
+      left: 40%; }
+    .switch-toggle.switch-5 input:checked:nth-of-type(4) ~ a {
+      left: 60%; }
+    .switch-toggle.switch-5 input:checked:last-of-type ~ a {
+      left: 80%; }
+
+  /* Standalone Themes */
+  /* Candy Theme
+  * Based on the "Sort Switches / Toggles (PSD)" by Ormal Clarck
+  * http://www.premiumpixels.com/freebies/sort-switches-toggles-psd/
+  */
+  .switch-candy {
+    background-color: #2d3035;
+    border-radius: 3px;
+    color: #fff;
+    font-weight: bold;
+    text-align: center;
+    text-shadow: 1px 1px 1px #191b1e;
+    box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0 rgba(255, 255, 255, 0.2); }
+    .switch-candy label {
+      color: #fff;
+      -webkit-transition: color 0.2s ease-out;
+      -moz-transition: color 0.2s ease-out;
+      transition: color 0.2s ease-out; }
+    .switch-candy input:checked + label {
+      color: #333;
+      text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); }
+    .switch-candy a {
+      border: 1px solid #333;
+      background-color: #70c66b;
+      border-radius: 3px;
+      background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0));
+      background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0));
+      box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.45); }
+    .switch-candy > span {
+      color: #333;
+      text-shadow: none; }
+    .switch-candy span {
+      color: #fff; }
+    .switch-candy.switch-candy-blue a {
+      background-color: #38a3d4; }
+    .switch-candy.switch-candy-yellow a {
+      background-color: #f5e560; }
+
+  /* Android Theme
+  */
+  .switch-android {
+    background-color: #464747;
+    border-radius: 1px;
+    box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0;
+    color: #fff;
+    /* Selected ON switch-light
+    */ }
+    .switch-android label {
+      color: #fff; }
+    .switch-android > span span {
+      opacity: 0;
+      margin-left: 7.1875em;
+      -webkit-transition: all 0.1s;
+      -moz-transition: all 0.1s;
+      transition: all 0.1s; }
+      .switch-android > span span:first-of-type {
+        opacity: 1; }
+    .switch-android > span span, .switch-android input + label {
+      font-size: 85%;
+      line-height: 2.15625em; }
+    .switch-android a {
+      background-color: #666;
+      border-radius: 1px;
+      box-shadow: inset rgba(255, 255, 255, 0.2) 0 1px 0, inset rgba(0, 0, 0, 0.3) 0 -1px 0; }
+    .switch-android.switch-light input:checked ~ a {
+      background-color: #0E88B1; }
+    .switch-android.switch-light input:checked ~ span span:first-of-type {
+      opacity: 0; }
+    .switch-android.switch-light input:checked ~ span span:last-of-type {
+      opacity: 1; }
+    .switch-android.switch-toggle, .switch-android > span span {
+      text-transform: uppercase; }
+
+  /* iOS Theme
+  */
+  .switch-ios.switch-light {
+    color: #868686; }
+    .switch-ios.switch-light a {
+      left: 0;
+      width: 1.875em;
+      background-color: #fff;
+      border: 1px solid #d3d3d3;
+      border-radius: 100%;
+      -webkit-transition: all 0.3s ease-out;
+      -moz-transition: all 0.3s ease-out;
+      transition: all 0.3s ease-out;
+      box-shadow: inset 0 -3px 3px rgba(0, 0, 0, 0.025), 0 1px 4px rgba(0, 0, 0, 0.15), 0 4px 4px rgba(0, 0, 0, 0.1); }
+    .switch-ios.switch-light > span span {
+      width: 100%;
+      left: 0;
+      opacity: 0; }
+      .switch-ios.switch-light > span span:first-of-type {
+        opacity: 1;
+        padding-left: 1.875em; }
+      .switch-ios.switch-light > span span:last-of-type {
+        padding-right: 1.875em; }
+    .switch-ios.switch-light > span:before {
+      content: '';
+      display: block;
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      left: 6.25em;
+      top: 0;
+      background-color: #fafafa;
+      border: 1px solid #d3d3d3;
+      border-radius: 30px;
+      -webkit-transition: all 0.5s ease-out;
+      -moz-transition: all 0.5s ease-out;
+      transition: all 0.5s ease-out;
+      box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; }
+    .switch-ios.switch-light input:checked ~ a {
+      left: 100%;
+      margin-left: -1.875em; }
+    .switch-ios.switch-light input:checked ~ span:before {
+      border-color: #53d76a;
+      box-shadow: inset 0 0 0 30px #53d76a; }
+    .switch-ios.switch-light input:checked ~ span span:first-of-type {
+      opacity: 0; }
+    .switch-ios.switch-light input:checked ~ span span:last-of-type {
+      opacity: 1;
+      color: #fff; }
+  .switch-ios.switch-toggle {
+    background-color: #fafafa;
+    border: 1px solid #d3d3d3;
+    border-radius: 30px;
+    box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; }
+    .switch-ios.switch-toggle a {
+      background-color: #53d76a;
+      border-radius: 25px;
+      -webkit-transition: all 0.3s ease-out;
+      -moz-transition: all 0.3s ease-out;
+      transition: all 0.3s ease-out; }
+    .switch-ios.switch-toggle label {
+      color: #868686; }
+  .switch-ios input:checked + label {
+    color: #3a3a3a; }
+ }
+
+/* Bugfix for older Webkit, including mobile Webkit. Adapted from
+* http://css-tricks.com/webkit-sibling-bug/
+*/
+@media only screen and (-webkit-max-device-pixel-ratio: 2) and (max-device-width: 80em) {
+  .switch-light, .switch-toggle {
+    -webkit-animation: webkitSiblingBugfix infinite 1s; } }
+
+@-webkit-keyframes webkitSiblingBugfix {
+  from {
+    -webkit-transform: translate3d(0, 0, 0); }
+
+  to {
+    -webkit-transform: translate3d(0, 0, 0); } }
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/index.tpl.html b/ovsdb-ui/module/src/main/resources/ovsdb/index.tpl.html
deleted file mode 100644 (file)
index 3aec420..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<!--\r
- * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
--->\r
-\r
-<div class="form-group">\r
-  <span>In progress</span>\r
-  <div id="errorMessage" class="alert alert-danger" role="alert">\r
-      {{err.message}}\r
-  </div>\r
-</div>\r
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/lib/d3.min.js b/ovsdb-ui/module/src/main/resources/ovsdb/lib/d3.min.js
new file mode 100644 (file)
index 0000000..34d5513
--- /dev/null
@@ -0,0 +1,5 @@
+!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n.toLowerCase()))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c
+},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r
+},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.5"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||n({type:"zoomend"}),d=null}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(v=e(d=m||ta.mouse(this)),Dl.call(this),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv("      ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t
+},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t)||/^(#|rgb\(|hsl\()/.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));
+return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}();
\ No newline at end of file
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/lib/select2.full.min.js b/ovsdb-ui/module/src/main/resources/ovsdb/lib/select2.full.min.js
new file mode 100755 (executable)
index 0000000..59d8c1a
--- /dev/null
@@ -0,0 +1,3 @@
+/*! Select2 4.0.0 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(n=n.slice(0,n.length-1),a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.concat(a),k=0;k<a.length;k+=1)if(m=a[k],"."===m)a.splice(k,1),k-=1;else if(".."===m){if(1===k&&(".."===a[2]||".."===a[0]))break;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){return n.apply(b,v.call(arguments,0).concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n<c.length;n+=1)if(m=o(c[n],f),k=m.f,"require"===k)u[n]=p.require(a);else if("exports"===k)u[n]=p.exports(a),s=!0;else if("module"===k)h=u[n]=p.module(a);else if(e(q,k)||e(r,k)||e(t,k))u[n]=j(k);else{if(!m.p)throw new Error(a+" missing "+k);m.p.load(m.n,g(f,!0),i(k),{}),u[n]=q[k]}l=d?d.apply(q[a],u):void 0,a&&(h&&h.exports!==b&&h.exports!==q[a]?q[a]=h.exports:l===b&&s||(q[a]=l))}else a&&(q[a]=d)},a=c=n=function(a,c,d,e,f){if("string"==typeof a)return p[a]?p[a](c):j(o(a,c).f);if(!a.splice){if(s=a,s.deps&&n(s.deps,s.callback),!c)return;c.splice?(a=c,c=d,d=null):a=b}return c=c||function(){},"function"==typeof d&&(d=e,e=f),e?m(b,a,c,d):setTimeout(function(){m(b,a,c,d)},4),n},n.config=function(a){return n(a)},a._defined=q,d=function(a,b,c){b.splice||(c=b,b=[]),e(q,a)||e(r,a)||(r[a]=[a,b,c])},d.amd={jQuery:!0}}(),b.requirejs=a,b.require=c,b.define=d}}(),b.define("almond",function(){}),b.define("jquery",[],function(){var b=a||$;return null==b&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),b}),b.define("select2/utils",["jquery"],function(a){function b(a){var b=a.prototype,c=[];for(var d in b){var e=b[d];"function"==typeof e&&"constructor"!==d&&c.push(d)}return c}var c={};c.Extend=function(a,b){function c(){this.constructor=a}var d={}.hasOwnProperty;for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},c.Decorate=function(a,c){function d(){var b=Array.prototype.unshift,d=c.prototype.constructor.length,e=a.prototype.constructor;d>0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h<g.length;h++){var i=g[h];d.prototype[i]=a.prototype[i]}for(var j=(function(a){var b=function(){};a in d.prototype&&(b=d.prototype[a]);var e=c.prototype[a];return function(){var a=Array.prototype.unshift;return a.call(arguments,b),e.apply(this,arguments)}}),k=0;k<f.length;k++){var l=f[k];d.prototype[l]=j(l)}return d};var d=function(){this.listeners={}};return d.prototype.on=function(a,b){this.listeners=this.listeners||{},a in this.listeners?this.listeners[a].push(b):this.listeners[a]=[b]},d.prototype.trigger=function(a){var b=Array.prototype.slice;this.listeners=this.listeners||{},a in this.listeners&&this.invoke(this.listeners[a],b.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},d.prototype.invoke=function(a,b){for(var c=0,d=a.length;d>c;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e<c.length;e++){var f=c[e];f=f.substring(0,1).toLowerCase()+f.substring(1),f in d||(d[f]={}),e==c.length-1&&(d[f]=a[b]),d=d[f]}delete a[b]}}return a},c.hasScroll=function(b,c){var d=a(c),e=c.style.overflowX,f=c.style.overflowY;return e!==f||"hidden"!==f&&"visible"!==f?"scroll"===e||"scroll"===f?!0:d.innerHeight()<c.scrollHeight||d.innerWidth()<c.scrollWidth:!1},c.escapeMarkup=function(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<ul class="select2-results__options" role="tree"></ul>');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('<li role="treeitem" class="select2-results__option"></li>'),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),this.$results.append(d)},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c<a.results.length;c++){var d=a.results[c],e=this.option(d);b.push(e)}this.$results.append(b)},c.prototype.position=function(a,b){var c=b.find(".select2-results");c.append(a)},c.prototype.sort=function(a){var b=this.options.get("sorter");return b(a)},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")});var f=e.filter("[aria-selected=true]");f.length>0?f.first().trigger("mouseenter"):e.first().trigger("mouseenter")})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";{a(h)}this.template(b,h);for(var i=[],j=0;j<b.children.length;j++){var k=b.children[j],l=this.option(k);i.push(l)}var m=a("<ul></ul>",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b){var c=this,d=b.id+"-results";this.$results.attr("id",d),b.on("results:all",function(a){c.clear(),c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("results:append",function(a){c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("query",function(a){c.showLoading(a)}),b.on("select",function(){b.isOpen()&&c.setClasses()}),b.on("unselect",function(){b.isOpen()&&c.setClasses()}),b.on("open",function(){c.$results.attr("aria-expanded","true"),c.$results.attr("aria-hidden","false"),c.setClasses(),c.ensureHighlightVisible()}),b.on("close",function(){c.$results.attr("aria-expanded","false"),c.$results.attr("aria-hidden","true"),c.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=c.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=c.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?c.trigger("close"):c.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a);if(0!==d){var e=d-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top,h=f.offset().top,i=c.$results.scrollTop()+(h-g);0===e?c.$results.scrollTop(0):0>h-g&&c.$results.scrollTop(i)}}),b.on("results:next",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a),e=d+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top+c.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=c.$results.scrollTop()+h-g;0===e?c.$results.scrollTop(0):h>g&&c.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){c.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=c.$results.scrollTop(),d=c.$results.get(0).scrollHeight-c.$results.scrollTop()+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&d<=c.$results.height();e?(c.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(c.$results.scrollTop(c.$results.get(0).scrollHeight-c.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var d=a(this),e=d.data("data");return"true"===d.attr("aria-selected")?void(c.options.get("multiple")?c.trigger("unselect",{originalEvent:b,data:e}):c.trigger("close")):void c.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(){var b=a(this).data("data");c.getHighlightedResults().removeClass("select2-results__option--highlighted"),c.trigger("results:focus",{data:b,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('<span class="select2-selection" role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a){var b=this,d=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){b.trigger("focus",a)}),this.$selection.on("blur",function(a){b.trigger("blur",a)}),this.$selection.on("keydown",function(a){b.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){b.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){b.update(a.data)}),a.on("open",function(){b.$selection.attr("aria-expanded","true"),b.$selection.attr("aria-owns",d),b._attachCloseHandler(a)}),a.on("close",function(){b.$selection.attr("aria-expanded","false"),b.$selection.removeAttr("aria-activedescendant"),b.$selection.removeAttr("aria-owns"),b.$selection.focus(),b._detachCloseHandler(a)}),a.on("enable",function(){b.$selection.attr("tabindex",b._tabindex)}),a.on("disable",function(){b.$selection.attr("tabindex","-1")})},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),a},d.prototype.bind=function(a){var b=this;d.__super__.bind.apply(this,arguments);var c=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",c),this.$selection.attr("aria-labelledby",c),this.$selection.on("mousedown",function(a){1===a.which&&b.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(){}),this.$selection.on("blur",function(){}),a.on("selection:update",function(a){b.update(a.data)})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){return a("<span></span>")},d.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.display(b),d=this.$selection.find(".select2-selection__rendered");d.empty().append(c),d.prop("title",b.title||b.text)},d}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('<ul class="select2-selection__rendered"></ul>'),a},d.prototype.bind=function(){var b=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){b.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(c){var d=a(this),e=d.parent(),f=e.data("data");b.trigger("unselect",{originalEvent:c,data:f})})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){var b=a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d<a.length;d++){var e=a[d],f=this.display(e),g=this.selectionContainer();g.append(f),g.prop("title",e.title||e.text),g.data("data",e),b.push(g)}var h=this.$selection.find(".select2-selection__rendered");c.appendMany(h,b)}},d}),b.define("select2/selection/placeholder",["../utils"],function(){function a(a,b,c){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c)}return a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.createPlaceholder=function(a,b){var c=this.selectionContainer();return c.html(this.display(b)),c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),c},a.prototype.update=function(a,b){var c=1==b.length&&b[0].id!=this.placeholder.id,d=b.length>1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},a}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e<d.length;e++){var f={data:d[e]};if(this.trigger("unselect",f),f.prevented)return}this.$element.val(this.placeholder.id).trigger("change"),this.trigger("toggle")}}},c.prototype._handleKeyboardClear=function(a,c,d){d.isOpen()||(c.which==b.DELETE||c.which==b.BACKSPACE)&&this._handleClear(c)},c.prototype.update=function(b,c){if(b.call(this,c),!(this.$selection.find(".select2-selection__placeholder").length>0||0===c.length)){var d=a('<span class="select2-selection__clear">&times;</span>');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></li>');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus()}),b.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.focus()}),b.on("enable",function(){e.$search.prop("disabled",!1)}),b.on("disable",function(){e.$search.prop("disabled",!0)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e.trigger("blur",a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}}),this.$selection.on("input",".select2-search--inline",function(){e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input",".select2-search--inline",function(a){e.handleSearch(a)})},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.trigger("open"),this.$search.val(b.text+" ")},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f<a.length;f++){var g=a[f].id;-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")});else{var d=a.id;this.$element.val(d),this.$element.trigger("change")}},d.prototype.unselect=function(a){var b=this;if(this.$element.prop("multiple"))return a.selected=!1,c(a.element).is("option")?(a.element.selected=!1,void this.$element.trigger("change")):void this.current(function(d){for(var e=[],f=0;f<d.length;f++){var g=d[f].id;g!==a.id&&-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")})},d.prototype.bind=function(a){var b=this;this.container=a,a.on("select",function(a){b.select(a.data)}),a.on("unselect",function(a){b.unselect(a.data)})},d.prototype.destroy=function(){this.$element.find("*").each(function(){c.removeData(this,"data")})},d.prototype.query=function(a,b){var d=[],e=this,f=this.$element.children();f.each(function(){var b=c(this);if(b.is("option")||b.is("optgroup")){var f=e.item(b),g=e.matches(a,f);null!==g&&d.push(g)}}),b({results:d})},d.prototype.addOptions=function(a){b.appendMany(this.$element,a)},d.prototype.option=function(a){var b;a.children?(b=document.createElement("optgroup"),b.label=a.text):(b=document.createElement("option"),void 0!==b.textContent?b.textContent=a.text:b.innerText=a.text),a.id&&(b.value=a.id),a.disabled&&(b.disabled=!0),a.selected&&(b.selected=!0),a.title&&(b.title=a.title);var d=c(b),e=this._normalizeItem(a);return e.element=b,c.data(b,"data",e),d},d.prototype.item=function(a){var b={};
+if(b=c.data(a[0],"data"),null!=b)return b;if(a.is("option"))b={id:a.val(),text:a.text(),disabled:a.prop("disabled"),selected:a.prop("selected"),title:a.prop("title")};else if(a.is("optgroup")){b={text:a.prop("label"),children:[],title:a.prop("title")};for(var d=a.children("option"),e=[],f=0;f<d.length;f++){var g=c(d[f]),h=this.item(g);e.push(h)}b.children=e}return b=this._normalizeItem(b),b.element=a[0],c.data(a[0],"data",b),b},d.prototype._normalizeItem=function(a){c.isPlainObject(a)||(a={id:a,text:a}),a=c.extend({},{text:""},a);var b={selected:!1,disabled:!1};return null!=a.id&&(a.id=a.id.toString()),null!=a.text&&(a.text=a.text.toString()),null==a._resultId&&a.id&&null!=this.container&&(a._resultId=this.generateResultId(this.container,a)),c.extend({},b,a)},d.prototype.matches=function(a,b){var c=this.options.get("matcher");return c(a,b)},d}),b.define("select2/data/array",["./select","../utils","jquery"],function(a,b,c){function d(a,b){var c=b.get("data")||[];d.__super__.constructor.call(this,a,b),this.addOptions(this.convertToOptions(c))}return b.Extend(d,a),d.prototype.select=function(a){var b=this.$element.find("option").filter(function(b,c){return c.value==a.id.toString()});0===b.length&&(b=this.option(a),this.addOptions(b)),d.__super__.select.call(this,a)},d.prototype.convertToOptions=function(a){function d(a){return function(){return c(this).val()==a.id}}for(var e=this,f=this.$element.find("option"),g=f.map(function(){return e.item(c(this)).id}).get(),h=[],i=0;i<a.length;i++){var j=this._normalizeItem(a[i]);if(c.inArray(j.id,g)>=0){var k=f.filter(d(j)),l=this.item(k),m=(c.extend(!0,{},l,j),this.option(l));k.replaceWith(m)}else{var n=this.option(j);if(j.children){var o=this.convertToOptions(j.children);b.appendMany(n,o)}h.push(n)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(b,c){this.ajaxOptions=this._applyDefaults(c.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),a.__super__.constructor.call(this,b,c)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return{q:a.term}},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url(a)),"function"==typeof f.data&&(f.data=f.data(a)),this.ajaxOptions.delay&&""!==a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");if(void 0!==f&&(this.createTag=f),b.call(this,c,d),a.isArray(e))for(var g=0;g<e.length;g++){var h=e[g],i=this._normalizeItem(h),j=this.option(i);this.$element.append(j)}}return b.prototype.query=function(a,b,c){function d(a,f){for(var g=a.results,h=0;h<g.length;h++){var i=g[h],j=null!=i.children&&!d({results:i.children},!0),k=i.text===b.term;if(k||j)return f?!1:(a.data=g,void c(a))}if(f)return!0;var l=e.createTag(b);if(null!=l){var m=e.option(l);m.attr("data-select2-tag",!0),e.addOptions([m]),e.insertTag(g,l)}a.results=g,c(a)}var e=this;return this._removeOldTags(),null==b.term||null!=b.page?void a.call(this,b,c):void a.call(this,b,d)},b.prototype.createTag=function(b,c){var d=a.trim(c.term);return""===d?null:{id:d,text:d}},b.prototype.insertTag=function(a,b,c){b.unshift(c)},b.prototype._removeOldTags=function(){var b=(this._lastTag,this.$element.find("option[data-select2-tag]"));b.each(function(){this.selected||a(this).remove()})},b}),b.define("select2/data/tokenizer",["jquery"],function(a){function b(a,b,c){var d=c.get("tokenizer");void 0!==d&&(this.tokenizer=d),a.call(this,b,c)}return b.prototype.bind=function(a,b,c){a.call(this,b,c),this.$search=b.dropdown.$search||b.selection.$search||c.find(".select2-search__field")},b.prototype.query=function(a,b,c){function d(a){e.select(a)}var e=this;b.term=b.term||"";var f=this.tokenizer(b,this.options,d);f.term!==b.term&&(this.$search.length&&(this.$search.val(f.term),this.$search.focus()),b.term=f.term),a.call(this,b,c)},b.prototype.tokenizer=function(b,c,d,e){for(var f=d.get("tokenSeparators")||[],g=c.term,h=0,i=this.createTag||function(a){return{id:a.term,text:a.term}};h<g.length;){var j=g[h];if(-1!==a.inArray(j,f)){var k=g.substr(0,h),l=a.extend({},c,{term:k}),m=i(l);e(m),g=g.substr(h+1)||"",h=0}else h++}return{term:g}},b}),b.define("select2/data/minimumInputLength",[],function(){function a(a,b,c){this.minimumInputLength=c.get("minimumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",b.term.length<this.minimumInputLength?void this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumInputLength",[],function(){function a(a,b,c){this.maximumInputLength=c.get("maximumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",this.maximumInputLength>0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<span class="select2-dropdown"><span class="select2-results"></span></span>');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.position=function(){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a){function b(){}return b.prototype.render=function(b){var c=b.call(this),d=a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></span>');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},b.prototype.handleSearch=function(){if(!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},b.prototype.showSearch=function(){return!0},b}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('<li class="option load-more" role="treeitem"></li>'),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(a,b,c){this.$dropdownParent=c.get("dropdownParent")||document.body,a.call(this,b,c)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a("<span></span>"),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c){var d=this,e="scroll.select2."+c.id,f="resize.select2."+c.id,g="orientationchange.select2."+c.id,h=this.$container.parents().filter(b.hasScroll);h.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),h.on(e,function(){var b=a(this).data("select2-scroll-position");a(this).scrollTop(b.y)}),a(window).on(e+" "+f+" "+g,function(){d._positionDropdown(),d._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c){var d="scroll.select2."+c.id,e="resize.select2."+c.id,f="orientationchange.select2."+c.id,g=this.$container.parents().filter(b.hasScroll);g.off(d),a(window).off(d+" "+e+" "+f)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=(this.$container.position(),this.$container.offset());f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.top<f.top-h.height,k=i.bottom>f.bottom+h.height,l={left:f.left,top:g.bottom};c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){this.$dropdownContainer.width();var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d<b.length;d++){var e=b[d];e.children?c+=a(e.children):c++}return c}function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return a(c.data.results)<this.minimumResultsForSearch?!1:b.call(this,c)},b}),b.define("select2/dropdown/selectOnClose",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("close",function(){d._handleSelectOnClose()})},a.prototype._handleSelectOnClose=function(){var a=this.getHighlightedResults();a.length<1||this.trigger("select",{data:a.data("data")})},a}),b.define("select2/dropdown/closeOnSelect",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("select",function(a){d._selectTriggered(a)}),b.on("unselect",function(a){d._selectTriggered(a)})},a.prototype._selectTriggered=function(a,b){var c=b.originalEvent;c&&c.ctrlKey||this.trigger("close")},a}),b.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(a){var b=a.input.length-a.maximum,c="Please delete "+b+" character";return 1!=b&&(c+="s"),c},inputTooShort:function(a){var b=a.minimum-a.input.length,c="Please enter "+b+" or more characters";return c},loadingMore:function(){return"Loading more results…"},maximumSelected:function(a){var b="You can only select "+a.maximum+" item";return 1!=a.maximum&&(b+="s"),b},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),b.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C){function D(){this.reset()}D.prototype.apply=function(l){if(l=a.extend({},this.defaults,l),null==l.dataAdapter){if(l.dataAdapter=null!=l.ajax?o:null!=l.data?n:m,l.minimumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.selectionAdapter=l.multiple?e:d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L<K.length;L++){var M=K[L],N={};try{N=k.loadPath(M)}catch(O){try{M=this.defaults.amdLanguageBase+M,N=k.loadPath(M)}catch(P){l.debug&&window.console&&console.warn&&console.warn('Select2: The language file for "'+M+'" could not be automatically loaded. A fallback will be used instead.');continue}}J.extend(N)}l.translations=J}else{var Q=k.loadPath(this.defaults.amdLanguageBase+"en"),R=new k(l.language);R.extend(Q),l.translations=R}return l},D.prototype.reset=function(){function b(a){function b(a){return l[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function c(d,e){if(""===a.trim(d.term))return e;if(e.children&&e.children.length>0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(this.options.dir=a.prop("dir")?a.prop("dir"):a.closest("[dir]").prop("dir")?a.closest("[dir]").prop("dir"):"ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this._sync=c.bind(this._syncAttributes,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._sync);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._sync)}),this._observer.observe(this.$element[0],{attributes:!0,subtree:!1})):this.$element[0].addEventListener&&this.$element[0].addEventListener("DOMAttrModified",b._sync,!1)},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("focus",function(){a.$container.addClass("select2-container--focus")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open"),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ENTER?(a.trigger("results:select"),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle"),b.preventDefault()):c===d.UP?(a.trigger("results:previous"),b.preventDefault()):c===d.DOWN?(a.trigger("results:next"),b.preventDefault()):(c===d.ESC||c===d.TAB)&&(a.close(),b.preventDefault()):(c===d.ENTER||c===d.SPACE||(c===d.DOWN||c===d.UP)&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable")):this.trigger("enable")},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||(this.trigger("query",{}),this.trigger("open"))},e.prototype.close=function(){this.isOpen()&&this.trigger("close")},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._sync),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&this.$element[0].removeEventListener("DOMAttrModified",this._sync,!1),this._sync=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&(f=d(this),null!=f&&g.push(f))})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;return this._isInitialized?void b.call(this,c):void this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `<select>` element instead."),a.call(this,b,c)}return b.prototype.current=function(b,c){function d(b,c){var e=[];return b.selected||-1!==a.inArray(b.id,c)?(b.selected=!0,e.push(b)):b.selected=!1,b.children&&e.push.apply(e,d(b.children,c)),e}for(var e=[],f=0;f<this._currentData.length;f++){var g=this._currentData[f];e.push.apply(e,d(g,this.$element.val().split(this._valueSeparator)))}c(e)},b.prototype.select=function(b,c){if(this.options.get("multiple")){var d=this.$element.val();d+=this._valueSeparator+c.id,this.$element.val(d),this.$element.trigger("change")}else this.current(function(b){a.map(b,function(a){a.selected=!1})}),this.$element.val(c.id),this.$element.trigger("change")},b.prototype.unselect=function(a,b){var c=this;b.selected=!1,this.current(function(a){for(var d=[],e=0;e<a.length;e++){var f=a[e];
+b.id!=f.id&&d.push(f.id)}c.$element.val(d.join(c._valueSeparator)),c.$element.trigger("change")})},b.prototype.query=function(a,b,c){for(var d=[],e=0;e<this._currentData.length;e++){var f=this._currentData[e],g=this.matches(b,f);null!==g&&d.push(g)}c({results:d})},b.prototype.addOptions=function(b,c){var d=a.map(c,function(b){return a.data(b[0],"data")});this._currentData.push.apply(this._currentData,d)},b}),b.define("select2/compat/matcher",["jquery"],function(a){function b(b){function c(c,d){var e=a.extend(!0,{},d);if(null==c.term||""===a.trim(c.term))return e;if(d.children){for(var f=d.children.length-1;f>=0;f--){var g=d.children[f],h=b(c.term,g.text,g);h||e.children.splice(f,1)}if(e.children.length>0)return e}return b(c.term,d.text,d)?e:null}return c}return b}),b.define("select2/compat/query",[],function(){function a(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."),a.call(this,b,c)}return a.prototype.query=function(a,b,c){b.callback=c;var d=this.options.get("query");d.call(null,b)},a}),b.define("select2/dropdown/attachContainer",[],function(){function a(a,b,c){a.call(this,b,c)}return a.prototype.position=function(a,b,c){var d=c.find(".dropdown-wrapper");d.append(b),b.addClass("select2-dropdown--below"),c.addClass("select2-container--below")},a}),b.define("select2/dropdown/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$dropdown.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("select2/selection/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$selection.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("jquery.select2",["jquery","require","./select2/core","./select2/defaults"],function(a,b,c,d){if(b("jquery.mousewheel"),null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){{var d=a.extend({},b,!0);new c(a(this),d)}}),this;if("string"==typeof b){var d=this.data("select2");null==d&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2.");var f=Array.prototype.slice.call(arguments,1),g=d[b](f);return a.inArray(b,e)>-1?this:g}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),function(c){"function"==typeof b.define&&b.define.amd?b.define("jquery.mousewheel",["jquery"],c):"object"==typeof exports?module.exports=c:c(a)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
\ No newline at end of file
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/lib/sylvester.js b/ovsdb-ui/module/src/main/resources/ovsdb/lib/sylvester.js
new file mode 100755 (executable)
index 0000000..3e83bee
--- /dev/null
@@ -0,0 +1 @@
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('9 17={3i:\'0.1.3\',16:1e-6};l v(){}v.23={e:l(i){8(i<1||i>7.4.q)?w:7.4[i-1]},2R:l(){8 7.4.q},1u:l(){8 F.1x(7.2u(7))},24:l(a){9 n=7.4.q;9 V=a.4||a;o(n!=V.q){8 1L}J{o(F.13(7.4[n-1]-V[n-1])>17.16){8 1L}}H(--n);8 2x},1q:l(){8 v.u(7.4)},1b:l(a){9 b=[];7.28(l(x,i){b.19(a(x,i))});8 v.u(b)},28:l(a){9 n=7.4.q,k=n,i;J{i=k-n;a(7.4[i],i+1)}H(--n)},2q:l(){9 r=7.1u();o(r===0){8 7.1q()}8 7.1b(l(x){8 x/r})},1C:l(a){9 V=a.4||a;9 n=7.4.q,k=n,i;o(n!=V.q){8 w}9 b=0,1D=0,1F=0;7.28(l(x,i){b+=x*V[i-1];1D+=x*x;1F+=V[i-1]*V[i-1]});1D=F.1x(1D);1F=F.1x(1F);o(1D*1F===0){8 w}9 c=b/(1D*1F);o(c<-1){c=-1}o(c>1){c=1}8 F.37(c)},1m:l(a){9 b=7.1C(a);8(b===w)?w:(b<=17.16)},34:l(a){9 b=7.1C(a);8(b===w)?w:(F.13(b-F.1A)<=17.16)},2k:l(a){9 b=7.2u(a);8(b===w)?w:(F.13(b)<=17.16)},2j:l(a){9 V=a.4||a;o(7.4.q!=V.q){8 w}8 7.1b(l(x,i){8 x+V[i-1]})},2C:l(a){9 V=a.4||a;o(7.4.q!=V.q){8 w}8 7.1b(l(x,i){8 x-V[i-1]})},22:l(k){8 7.1b(l(x){8 x*k})},x:l(k){8 7.22(k)},2u:l(a){9 V=a.4||a;9 i,2g=0,n=7.4.q;o(n!=V.q){8 w}J{2g+=7.4[n-1]*V[n-1]}H(--n);8 2g},2f:l(a){9 B=a.4||a;o(7.4.q!=3||B.q!=3){8 w}9 A=7.4;8 v.u([(A[1]*B[2])-(A[2]*B[1]),(A[2]*B[0])-(A[0]*B[2]),(A[0]*B[1])-(A[1]*B[0])])},2A:l(){9 m=0,n=7.4.q,k=n,i;J{i=k-n;o(F.13(7.4[i])>F.13(m)){m=7.4[i]}}H(--n);8 m},2Z:l(x){9 a=w,n=7.4.q,k=n,i;J{i=k-n;o(a===w&&7.4[i]==x){a=i+1}}H(--n);8 a},3g:l(){8 S.2X(7.4)},2d:l(){8 7.1b(l(x){8 F.2d(x)})},2V:l(x){8 7.1b(l(y){8(F.13(y-x)<=17.16)?x:y})},1o:l(a){o(a.K){8 a.1o(7)}9 V=a.4||a;o(V.q!=7.4.q){8 w}9 b=0,2b;7.28(l(x,i){2b=x-V[i-1];b+=2b*2b});8 F.1x(b)},3a:l(a){8 a.1h(7)},2T:l(a){8 a.1h(7)},1V:l(t,a){9 V,R,x,y,z;2S(7.4.q){27 2:V=a.4||a;o(V.q!=2){8 w}R=S.1R(t).4;x=7.4[0]-V[0];y=7.4[1]-V[1];8 v.u([V[0]+R[0][0]*x+R[0][1]*y,V[1]+R[1][0]*x+R[1][1]*y]);1I;27 3:o(!a.U){8 w}9 C=a.1r(7).4;R=S.1R(t,a.U).4;x=7.4[0]-C[0];y=7.4[1]-C[1];z=7.4[2]-C[2];8 v.u([C[0]+R[0][0]*x+R[0][1]*y+R[0][2]*z,C[1]+R[1][0]*x+R[1][1]*y+R[1][2]*z,C[2]+R[2][0]*x+R[2][1]*y+R[2][2]*z]);1I;2P:8 w}},1t:l(a){o(a.K){9 P=7.4.2O();9 C=a.1r(P).4;8 v.u([C[0]+(C[0]-P[0]),C[1]+(C[1]-P[1]),C[2]+(C[2]-(P[2]||0))])}1d{9 Q=a.4||a;o(7.4.q!=Q.q){8 w}8 7.1b(l(x,i){8 Q[i-1]+(Q[i-1]-x)})}},1N:l(){9 V=7.1q();2S(V.4.q){27 3:1I;27 2:V.4.19(0);1I;2P:8 w}8 V},2n:l(){8\'[\'+7.4.2K(\', \')+\']\'},26:l(a){7.4=(a.4||a).2O();8 7}};v.u=l(a){9 V=25 v();8 V.26(a)};v.i=v.u([1,0,0]);v.j=v.u([0,1,0]);v.k=v.u([0,0,1]);v.2J=l(n){9 a=[];J{a.19(F.2F())}H(--n);8 v.u(a)};v.1j=l(n){9 a=[];J{a.19(0)}H(--n);8 v.u(a)};l S(){}S.23={e:l(i,j){o(i<1||i>7.4.q||j<1||j>7.4[0].q){8 w}8 7.4[i-1][j-1]},33:l(i){o(i>7.4.q){8 w}8 v.u(7.4[i-1])},2E:l(j){o(j>7.4[0].q){8 w}9 a=[],n=7.4.q,k=n,i;J{i=k-n;a.19(7.4[i][j-1])}H(--n);8 v.u(a)},2R:l(){8{2D:7.4.q,1p:7.4[0].q}},2D:l(){8 7.4.q},1p:l(){8 7.4[0].q},24:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(7.4.q!=M.q||7.4[0].q!=M[0].q){8 1L}9 b=7.4.q,15=b,i,G,10=7.4[0].q,j;J{i=15-b;G=10;J{j=10-G;o(F.13(7.4[i][j]-M[i][j])>17.16){8 1L}}H(--G)}H(--b);8 2x},1q:l(){8 S.u(7.4)},1b:l(a){9 b=[],12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;b[i]=[];J{j=10-G;b[i][j]=a(7.4[i][j],i+1,j+1)}H(--G)}H(--12);8 S.u(b)},2i:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}8(7.4.q==M.q&&7.4[0].q==M[0].q)},2j:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2i(M)){8 w}8 7.1b(l(x,i,j){8 x+M[i-1][j-1]})},2C:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2i(M)){8 w}8 7.1b(l(x,i,j){8 x-M[i-1][j-1]})},2B:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}8(7.4[0].q==M.q)},22:l(a){o(!a.4){8 7.1b(l(x){8 x*a})}9 b=a.1u?2x:1L;9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}o(!7.2B(M)){8 w}9 d=7.4.q,15=d,i,G,10=M[0].q,j;9 e=7.4[0].q,4=[],21,20,c;J{i=15-d;4[i]=[];G=10;J{j=10-G;21=0;20=e;J{c=e-20;21+=7.4[i][c]*M[c][j]}H(--20);4[i][j]=21}H(--G)}H(--d);9 M=S.u(4);8 b?M.2E(1):M},x:l(a){8 7.22(a)},32:l(a,b,c,d){9 e=[],12=c,i,G,j;9 f=7.4.q,1p=7.4[0].q;J{i=c-12;e[i]=[];G=d;J{j=d-G;e[i][j]=7.4[(a+i-1)%f][(b+j-1)%1p]}H(--G)}H(--12);8 S.u(e)},31:l(){9 a=7.4.q,1p=7.4[0].q;9 b=[],12=1p,i,G,j;J{i=1p-12;b[i]=[];G=a;J{j=a-G;b[i][j]=7.4[j][i]}H(--G)}H(--12);8 S.u(b)},1y:l(){8(7.4.q==7.4[0].q)},2A:l(){9 m=0,12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;J{j=10-G;o(F.13(7.4[i][j])>F.13(m)){m=7.4[i][j]}}H(--G)}H(--12);8 m},2Z:l(x){9 a=w,12=7.4.q,15=12,i,G,10=7.4[0].q,j;J{i=15-12;G=10;J{j=10-G;o(7.4[i][j]==x){8{i:i+1,j:j+1}}}H(--G)}H(--12);8 w},30:l(){o(!7.1y){8 w}9 a=[],n=7.4.q,k=n,i;J{i=k-n;a.19(7.4[i][i])}H(--n);8 v.u(a)},1K:l(){9 M=7.1q(),1c;9 n=7.4.q,k=n,i,1s,1n=7.4[0].q,p;J{i=k-n;o(M.4[i][i]==0){2e(j=i+1;j<k;j++){o(M.4[j][i]!=0){1c=[];1s=1n;J{p=1n-1s;1c.19(M.4[i][p]+M.4[j][p])}H(--1s);M.4[i]=1c;1I}}}o(M.4[i][i]!=0){2e(j=i+1;j<k;j++){9 a=M.4[j][i]/M.4[i][i];1c=[];1s=1n;J{p=1n-1s;1c.19(p<=i?0:M.4[j][p]-M.4[i][p]*a)}H(--1s);M.4[j]=1c}}}H(--n);8 M},3h:l(){8 7.1K()},2z:l(){o(!7.1y()){8 w}9 M=7.1K();9 a=M.4[0][0],n=M.4.q-1,k=n,i;J{i=k-n+1;a=a*M.4[i][i]}H(--n);8 a},3f:l(){8 7.2z()},2y:l(){8(7.1y()&&7.2z()===0)},2Y:l(){o(!7.1y()){8 w}9 a=7.4[0][0],n=7.4.q-1,k=n,i;J{i=k-n+1;a+=7.4[i][i]}H(--n);8 a},3e:l(){8 7.2Y()},1Y:l(){9 M=7.1K(),1Y=0;9 a=7.4.q,15=a,i,G,10=7.4[0].q,j;J{i=15-a;G=10;J{j=10-G;o(F.13(M.4[i][j])>17.16){1Y++;1I}}H(--G)}H(--a);8 1Y},3d:l(){8 7.1Y()},2W:l(a){9 M=a.4||a;o(1g(M[0][0])==\'1f\'){M=S.u(M).4}9 T=7.1q(),1p=T.4[0].q;9 b=T.4.q,15=b,i,G,10=M[0].q,j;o(b!=M.q){8 w}J{i=15-b;G=10;J{j=10-G;T.4[i][1p+j]=M[i][j]}H(--G)}H(--b);8 T},2w:l(){o(!7.1y()||7.2y()){8 w}9 a=7.4.q,15=a,i,j;9 M=7.2W(S.I(a)).1K();9 b,1n=M.4[0].q,p,1c,2v;9 c=[],2c;J{i=a-1;1c=[];b=1n;c[i]=[];2v=M.4[i][i];J{p=1n-b;2c=M.4[i][p]/2v;1c.19(2c);o(p>=15){c[i].19(2c)}}H(--b);M.4[i]=1c;2e(j=0;j<i;j++){1c=[];b=1n;J{p=1n-b;1c.19(M.4[j][p]-M.4[i][p]*M.4[j][i])}H(--b);M.4[j]=1c}}H(--a);8 S.u(c)},3c:l(){8 7.2w()},2d:l(){8 7.1b(l(x){8 F.2d(x)})},2V:l(x){8 7.1b(l(p){8(F.13(p-x)<=17.16)?x:p})},2n:l(){9 a=[];9 n=7.4.q,k=n,i;J{i=k-n;a.19(v.u(7.4[i]).2n())}H(--n);8 a.2K(\'\\n\')},26:l(a){9 i,4=a.4||a;o(1g(4[0][0])!=\'1f\'){9 b=4.q,15=b,G,10,j;7.4=[];J{i=15-b;G=4[i].q;10=G;7.4[i]=[];J{j=10-G;7.4[i][j]=4[i][j]}H(--G)}H(--b);8 7}9 n=4.q,k=n;7.4=[];J{i=k-n;7.4.19([4[i]])}H(--n);8 7}};S.u=l(a){9 M=25 S();8 M.26(a)};S.I=l(n){9 a=[],k=n,i,G,j;J{i=k-n;a[i]=[];G=k;J{j=k-G;a[i][j]=(i==j)?1:0}H(--G)}H(--n);8 S.u(a)};S.2X=l(a){9 n=a.q,k=n,i;9 M=S.I(n);J{i=k-n;M.4[i][i]=a[i]}H(--n);8 M};S.1R=l(b,a){o(!a){8 S.u([[F.1H(b),-F.1G(b)],[F.1G(b),F.1H(b)]])}9 d=a.1q();o(d.4.q!=3){8 w}9 e=d.1u();9 x=d.4[0]/e,y=d.4[1]/e,z=d.4[2]/e;9 s=F.1G(b),c=F.1H(b),t=1-c;8 S.u([[t*x*x+c,t*x*y-s*z,t*x*z+s*y],[t*x*y+s*z,t*y*y+c,t*y*z-s*x],[t*x*z-s*y,t*y*z+s*x,t*z*z+c]])};S.3b=l(t){9 c=F.1H(t),s=F.1G(t);8 S.u([[1,0,0],[0,c,-s],[0,s,c]])};S.39=l(t){9 c=F.1H(t),s=F.1G(t);8 S.u([[c,0,s],[0,1,0],[-s,0,c]])};S.38=l(t){9 c=F.1H(t),s=F.1G(t);8 S.u([[c,-s,0],[s,c,0],[0,0,1]])};S.2J=l(n,m){8 S.1j(n,m).1b(l(){8 F.2F()})};S.1j=l(n,m){9 a=[],12=n,i,G,j;J{i=n-12;a[i]=[];G=m;J{j=m-G;a[i][j]=0}H(--G)}H(--12);8 S.u(a)};l 14(){}14.23={24:l(a){8(7.1m(a)&&7.1h(a.K))},1q:l(){8 14.u(7.K,7.U)},2U:l(a){9 V=a.4||a;8 14.u([7.K.4[0]+V[0],7.K.4[1]+V[1],7.K.4[2]+(V[2]||0)],7.U)},1m:l(a){o(a.W){8 a.1m(7)}9 b=7.U.1C(a.U);8(F.13(b)<=17.16||F.13(b-F.1A)<=17.16)},1o:l(a){o(a.W){8 a.1o(7)}o(a.U){o(7.1m(a)){8 7.1o(a.K)}9 N=7.U.2f(a.U).2q().4;9 A=7.K.4,B=a.K.4;8 F.13((A[0]-B[0])*N[0]+(A[1]-B[1])*N[1]+(A[2]-B[2])*N[2])}1d{9 P=a.4||a;9 A=7.K.4,D=7.U.4;9 b=P[0]-A[0],2a=P[1]-A[1],29=(P[2]||0)-A[2];9 c=F.1x(b*b+2a*2a+29*29);o(c===0)8 0;9 d=(b*D[0]+2a*D[1]+29*D[2])/c;9 e=1-d*d;8 F.13(c*F.1x(e<0?0:e))}},1h:l(a){9 b=7.1o(a);8(b!==w&&b<=17.16)},2T:l(a){8 a.1h(7)},1v:l(a){o(a.W){8 a.1v(7)}8(!7.1m(a)&&7.1o(a)<=17.16)},1U:l(a){o(a.W){8 a.1U(7)}o(!7.1v(a)){8 w}9 P=7.K.4,X=7.U.4,Q=a.K.4,Y=a.U.4;9 b=X[0],1z=X[1],1B=X[2],1T=Y[0],1S=Y[1],1M=Y[2];9 c=P[0]-Q[0],2s=P[1]-Q[1],2r=P[2]-Q[2];9 d=-b*c-1z*2s-1B*2r;9 e=1T*c+1S*2s+1M*2r;9 f=b*b+1z*1z+1B*1B;9 g=1T*1T+1S*1S+1M*1M;9 h=b*1T+1z*1S+1B*1M;9 k=(d*g/f+h*e)/(g-h*h);8 v.u([P[0]+k*b,P[1]+k*1z,P[2]+k*1B])},1r:l(a){o(a.U){o(7.1v(a)){8 7.1U(a)}o(7.1m(a)){8 w}9 D=7.U.4,E=a.U.4;9 b=D[0],1l=D[1],1k=D[2],1P=E[0],1O=E[1],1Q=E[2];9 x=(1k*1P-b*1Q),y=(b*1O-1l*1P),z=(1l*1Q-1k*1O);9 N=v.u([x*1Q-y*1O,y*1P-z*1Q,z*1O-x*1P]);9 P=11.u(a.K,N);8 P.1U(7)}1d{9 P=a.4||a;o(7.1h(P)){8 v.u(P)}9 A=7.K.4,D=7.U.4;9 b=D[0],1l=D[1],1k=D[2],1w=A[0],18=A[1],1a=A[2];9 x=b*(P[1]-18)-1l*(P[0]-1w),y=1l*((P[2]||0)-1a)-1k*(P[1]-18),z=1k*(P[0]-1w)-b*((P[2]||0)-1a);9 V=v.u([1l*x-1k*z,1k*y-b*x,b*z-1l*y]);9 k=7.1o(P)/V.1u();8 v.u([P[0]+V.4[0]*k,P[1]+V.4[1]*k,(P[2]||0)+V.4[2]*k])}},1V:l(t,a){o(1g(a.U)==\'1f\'){a=14.u(a.1N(),v.k)}9 R=S.1R(t,a.U).4;9 C=a.1r(7.K).4;9 A=7.K.4,D=7.U.4;9 b=C[0],1E=C[1],1J=C[2],1w=A[0],18=A[1],1a=A[2];9 x=1w-b,y=18-1E,z=1a-1J;8 14.u([b+R[0][0]*x+R[0][1]*y+R[0][2]*z,1E+R[1][0]*x+R[1][1]*y+R[1][2]*z,1J+R[2][0]*x+R[2][1]*y+R[2][2]*z],[R[0][0]*D[0]+R[0][1]*D[1]+R[0][2]*D[2],R[1][0]*D[0]+R[1][1]*D[1]+R[1][2]*D[2],R[2][0]*D[0]+R[2][1]*D[1]+R[2][2]*D[2]])},1t:l(a){o(a.W){9 A=7.K.4,D=7.U.4;9 b=A[0],18=A[1],1a=A[2],2N=D[0],1l=D[1],1k=D[2];9 c=7.K.1t(a).4;9 d=b+2N,2h=18+1l,2o=1a+1k;9 Q=a.1r([d,2h,2o]).4;9 e=[Q[0]+(Q[0]-d)-c[0],Q[1]+(Q[1]-2h)-c[1],Q[2]+(Q[2]-2o)-c[2]];8 14.u(c,e)}1d o(a.U){8 7.1V(F.1A,a)}1d{9 P=a.4||a;8 14.u(7.K.1t([P[0],P[1],(P[2]||0)]),7.U)}},1Z:l(a,b){a=v.u(a);b=v.u(b);o(a.4.q==2){a.4.19(0)}o(b.4.q==2){b.4.19(0)}o(a.4.q>3||b.4.q>3){8 w}9 c=b.1u();o(c===0){8 w}7.K=a;7.U=v.u([b.4[0]/c,b.4[1]/c,b.4[2]/c]);8 7}};14.u=l(a,b){9 L=25 14();8 L.1Z(a,b)};14.X=14.u(v.1j(3),v.i);14.Y=14.u(v.1j(3),v.j);14.Z=14.u(v.1j(3),v.k);l 11(){}11.23={24:l(a){8(7.1h(a.K)&&7.1m(a))},1q:l(){8 11.u(7.K,7.W)},2U:l(a){9 V=a.4||a;8 11.u([7.K.4[0]+V[0],7.K.4[1]+V[1],7.K.4[2]+(V[2]||0)],7.W)},1m:l(a){9 b;o(a.W){b=7.W.1C(a.W);8(F.13(b)<=17.16||F.13(F.1A-b)<=17.16)}1d o(a.U){8 7.W.2k(a.U)}8 w},2k:l(a){9 b=7.W.1C(a.W);8(F.13(F.1A/2-b)<=17.16)},1o:l(a){o(7.1v(a)||7.1h(a)){8 0}o(a.K){9 A=7.K.4,B=a.K.4,N=7.W.4;8 F.13((A[0]-B[0])*N[0]+(A[1]-B[1])*N[1]+(A[2]-B[2])*N[2])}1d{9 P=a.4||a;9 A=7.K.4,N=7.W.4;8 F.13((A[0]-P[0])*N[0]+(A[1]-P[1])*N[1]+(A[2]-(P[2]||0))*N[2])}},1h:l(a){o(a.W){8 w}o(a.U){8(7.1h(a.K)&&7.1h(a.K.2j(a.U)))}1d{9 P=a.4||a;9 A=7.K.4,N=7.W.4;9 b=F.13(N[0]*(A[0]-P[0])+N[1]*(A[1]-P[1])+N[2]*(A[2]-(P[2]||0)));8(b<=17.16)}},1v:l(a){o(1g(a.U)==\'1f\'&&1g(a.W)==\'1f\'){8 w}8!7.1m(a)},1U:l(a){o(!7.1v(a)){8 w}o(a.U){9 A=a.K.4,D=a.U.4,P=7.K.4,N=7.W.4;9 b=(N[0]*(P[0]-A[0])+N[1]*(P[1]-A[1])+N[2]*(P[2]-A[2]))/(N[0]*D[0]+N[1]*D[1]+N[2]*D[2]);8 v.u([A[0]+D[0]*b,A[1]+D[1]*b,A[2]+D[2]*b])}1d o(a.W){9 c=7.W.2f(a.W).2q();9 N=7.W.4,A=7.K.4,O=a.W.4,B=a.K.4;9 d=S.1j(2,2),i=0;H(d.2y()){i++;d=S.u([[N[i%3],N[(i+1)%3]],[O[i%3],O[(i+1)%3]]])}9 e=d.2w().4;9 x=N[0]*A[0]+N[1]*A[1]+N[2]*A[2];9 y=O[0]*B[0]+O[1]*B[1]+O[2]*B[2];9 f=[e[0][0]*x+e[0][1]*y,e[1][0]*x+e[1][1]*y];9 g=[];2e(9 j=1;j<=3;j++){g.19((i==j)?0:f[(j+(5-i)%3)%3])}8 14.u(g,c)}},1r:l(a){9 P=a.4||a;9 A=7.K.4,N=7.W.4;9 b=(A[0]-P[0])*N[0]+(A[1]-P[1])*N[1]+(A[2]-(P[2]||0))*N[2];8 v.u([P[0]+N[0]*b,P[1]+N[1]*b,(P[2]||0)+N[2]*b])},1V:l(t,a){9 R=S.1R(t,a.U).4;9 C=a.1r(7.K).4;9 A=7.K.4,N=7.W.4;9 b=C[0],1E=C[1],1J=C[2],1w=A[0],18=A[1],1a=A[2];9 x=1w-b,y=18-1E,z=1a-1J;8 11.u([b+R[0][0]*x+R[0][1]*y+R[0][2]*z,1E+R[1][0]*x+R[1][1]*y+R[1][2]*z,1J+R[2][0]*x+R[2][1]*y+R[2][2]*z],[R[0][0]*N[0]+R[0][1]*N[1]+R[0][2]*N[2],R[1][0]*N[0]+R[1][1]*N[1]+R[1][2]*N[2],R[2][0]*N[0]+R[2][1]*N[1]+R[2][2]*N[2]])},1t:l(a){o(a.W){9 A=7.K.4,N=7.W.4;9 b=A[0],18=A[1],1a=A[2],2M=N[0],2L=N[1],2Q=N[2];9 c=7.K.1t(a).4;9 d=b+2M,2p=18+2L,2m=1a+2Q;9 Q=a.1r([d,2p,2m]).4;9 e=[Q[0]+(Q[0]-d)-c[0],Q[1]+(Q[1]-2p)-c[1],Q[2]+(Q[2]-2m)-c[2]];8 11.u(c,e)}1d o(a.U){8 7.1V(F.1A,a)}1d{9 P=a.4||a;8 11.u(7.K.1t([P[0],P[1],(P[2]||0)]),7.W)}},1Z:l(a,b,c){a=v.u(a);a=a.1N();o(a===w){8 w}b=v.u(b);b=b.1N();o(b===w){8 w}o(1g(c)==\'1f\'){c=w}1d{c=v.u(c);c=c.1N();o(c===w){8 w}}9 d=a.4[0],18=a.4[1],1a=a.4[2];9 e=b.4[0],1W=b.4[1],1X=b.4[2];9 f,1i;o(c!==w){9 g=c.4[0],2l=c.4[1],2t=c.4[2];f=v.u([(1W-18)*(2t-1a)-(1X-1a)*(2l-18),(1X-1a)*(g-d)-(e-d)*(2t-1a),(e-d)*(2l-18)-(1W-18)*(g-d)]);1i=f.1u();o(1i===0){8 w}f=v.u([f.4[0]/1i,f.4[1]/1i,f.4[2]/1i])}1d{1i=F.1x(e*e+1W*1W+1X*1X);o(1i===0){8 w}f=v.u([b.4[0]/1i,b.4[1]/1i,b.4[2]/1i])}7.K=a;7.W=f;8 7}};11.u=l(a,b,c){9 P=25 11();8 P.1Z(a,b,c)};11.2I=11.u(v.1j(3),v.k);11.2H=11.u(v.1j(3),v.i);11.2G=11.u(v.1j(3),v.j);11.36=11.2I;11.35=11.2H;11.3j=11.2G;9 $V=v.u;9 $M=S.u;9 $L=14.u;9 $P=11.u;',62,206,'||||elements|||this|return|var||||||||||||function|||if||length||||create|Vector|null|||||||||Math|nj|while||do|anchor||||||||Matrix||direction||normal||||kj|Plane|ni|abs|Line|ki|precision|Sylvester|A2|push|A3|map|els|else||undefined|typeof|contains|mod|Zero|D3|D2|isParallelTo|kp|distanceFrom|cols|dup|pointClosestTo|np|reflectionIn|modulus|intersects|A1|sqrt|isSquare|X2|PI|X3|angleFrom|mod1|C2|mod2|sin|cos|break|C3|toRightTriangular|false|Y3|to3D|E2|E1|E3|Rotation|Y2|Y1|intersectionWith|rotate|v12|v13|rank|setVectors|nc|sum|multiply|prototype|eql|new|setElements|case|each|PA3|PA2|part|new_element|round|for|cross|product|AD2|isSameSizeAs|add|isPerpendicularTo|v22|AN3|inspect|AD3|AN2|toUnitVector|PsubQ3|PsubQ2|v23|dot|divisor|inverse|true|isSingular|determinant|max|canMultiplyFromLeft|subtract|rows|col|random|ZX|YZ|XY|Random|join|N2|N1|D1|slice|default|N3|dimensions|switch|liesIn|translate|snapTo|augment|Diagonal|trace|indexOf|diagonal|transpose|minor|row|isAntiparallelTo|ZY|YX|acos|RotationZ|RotationY|liesOn|RotationX|inv|rk|tr|det|toDiagonalMatrix|toUpperTriangular|version|XZ'.split('|'),0,{}))
\ No newline at end of file
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/matrix.js b/ovsdb-ui/module/src/main/resources/ovsdb/matrix.js
new file mode 100644 (file)
index 0000000..97e82f6
--- /dev/null
@@ -0,0 +1,72 @@
+define(['app/ovsdb/lib/sylvester'], function() {
+  function Transform(a, b, c, d , e, f) {
+    if (a)
+    this.transform = $M([
+      [a, b, c],
+      [d, e, f],
+      [0, 0, 1]
+    ]);
+    else
+      this.transform = Matrix.I(3);
+  }
+
+  Transform.fromString = function(string) {
+    if(!string) {
+      return new Transform();
+    }
+    var g = document.createElementNS("http://www.w3.org/2000/svg", 'g');
+    g.setAttribute('transform', string);
+    var t = g.transform.baseVal.consolidate();
+    var m = t.matrix;
+    return new Transform(m.a, m.b, m.c, m.d, m.e, m.f);
+  }
+
+  Transform.combine = function(ma, mb) {
+    var t = new Transform();
+    t.transform = ma.transform.x(mb.transform);
+    return t;
+  }
+
+  Transform.prototype.translate = function(tx, ty) {
+    this.transform = $M([[1, 0, tx], [0, 1, ty], [0, 0, 1]]).x(this.transform);
+    return this;
+  };
+
+  Transform.prototype.rotate = function(deg) {
+    var rad = parseFloat(deg) * (Math.PI/180),
+    cos = Math.cos(rad),
+    sin = Math.sin(rad);
+
+    this.transform = $M([[cos, -sin, 0], [sin, cos, 0], [0, 0, 1]]).x(this.transform);
+    return this;
+  };
+
+  Transform.prototype.scale = function(x, y) {
+    var x = x,
+    y = y || x;
+
+    this.transform = $M([[x, 0, 0], [0, y, 0], [0, 0, 1]]).x(this.transform);
+    return this;
+  };
+
+  Transform.prototype.skew = function(x, y) {
+    var alpha = Math.tan(parseFloat(x) * (Math.PI/180)),
+     betha = Math.tan(parseFloat(y) * (Math.PI/180));
+
+    this.transform = $M([[1, alpha, 0], [betha, 1, 0], [0, 0, 1]]).x(this.transform);
+    return this;
+  };
+
+  Transform.prototype.transformPoint = function(x, y) {
+    var v = $V([x, y, 1]);
+    return this.transform.x(v);
+  };
+
+  Transform.prototype.toString = function() {
+    return this.transform.inspect();
+  }
+
+  return {
+    Matrix: Transform // Matrix function name already used by Sylvester
+  };
+});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.controller.js b/ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.controller.js
deleted file mode 100644 (file)
index 1cca4f3..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-define([], function() {
-  
-});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.module.js b/ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.module.js
deleted file mode 100644 (file)
index f68d28b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-define([], function() {
-  var ovsdb = angular.module('app.ovsdb', []);
-
-  ovsdb.register = {
-    controller: ovsdb.controller,
-    service: ovsdb.service,
-    factory: ovsdb.factory
-  };
-
-  return ovsdb;
-
-})
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.services.js b/ovsdb-ui/module/src/main/resources/ovsdb/mocks/ovsdb.services.js
deleted file mode 100644 (file)
index 1cca4f3..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-define([], function() {
-  
-});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.constant.js b/ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.constant.js
new file mode 100644 (file)
index 0000000..cc07e73
--- /dev/null
@@ -0,0 +1,72 @@
+define(['app/ovsdb/ovsdb.module'], function (ovsdb) {
+
+  ovsdb.register.constant('nodeIdentifier', {
+    IP: 'ip',
+    ID: 'node-id',
+    REMOTE_PORT: 'remote-port',
+    SRC_NODE: 'source-node',
+    DEST_NODE: 'dest-node',
+    SRC_TP: 'source-tp',
+    DEST_TP: 'dest-tp',
+    ADDRESSES: 'addresses'
+  });
+
+  ovsdb.register.constant('ovsNodeKeys', {
+    NODE_ID: 'node-id',
+    CONNECTION_INFO: 'ovsdb:connection-info',
+    OVS_VERSION: 'ovsdb:ovs-version',
+    LOCAL_IP: 'local-ip',
+    LOCAL_PORT: 'local-port',
+    REMOTE_IP: 'remote-ip',
+    REMOTE_PORT: 'remote-port',
+    OTHER_CONFIG: 'ovsdb:openvswitch-other-configs',
+    OTHER_CONFIG_KEY: 'other-config-key',
+    OTHER_CONFIG_VALUE: 'other-config-value'
+  });
+
+  ovsdb.register.constant('bridgeNodeKeys', {
+    NODE_ID: 'node-id',
+    CONTROLLER_ENTRY: 'ovsdb:controller-entry',
+    TARGET: 'target',
+    IS_CONNECTED: 'is-connected',
+    DATA_PATH: 'ovsdb:datapath-id',
+    BRIDGE_NAME: 'ovsdb:bridge-name',
+    TP: 'termination-point'
+  });
+
+  ovsdb.register.constant('tpKeys', {
+    NAME: 'ovsdb:name',
+    OF_PORT: 'ovsdb:ofport',
+    INTERFACE_TYPE: 'ovsdb:interface-type',
+    ATTACHED_MAC: 'attached-mac',
+    IFACE_ID: 'iface-id',
+    EXTERNAL_KEY_ID: 'external-id-key',
+    EXTERNAL_KEY_VALUE: 'external-id-value'
+  });
+
+  ovsdb.register.constant('flowInfoKeys', {
+    FEATURE: 'flow-node-inventory:switch-features',
+    SOFTWARE: 'flow-node-inventory:software',
+    HARDWARE: 'flow-node-inventory:hardware',
+    MANUFACTURER: 'flow-node-inventory:manufacturer',
+    IP: 'flow-node-inventory:ip-address',
+    TABLE: 'flow-node-inventory:table'
+  });
+
+  ovsdb.register.constant('linkIdentifier', {
+    SRC: 'source',
+    l3_unicast: 'l3-unicast-igp-topology:igp-link-attributes',
+    overlay_tunnel_type: 'overlay:tunnel-type',
+    supported_link: 'supporting-link',
+    ID: 'link-id',
+    DEST: 'destination'
+  });
+
+  ovsdb.register.constant('OVSConstant', {
+    TP_TYPE: {
+      INTERNAL: 'ovsdb:interface-type-internal',
+      VXLAN: 'ovsdb:interface-type-vxlan'
+    }
+  })
+
+});
index 5982a06eaa14cb9b4309f9d7a2d726ac70b6e182..4aac68f04d264adbed8bd4a126fb13c5347eb6ac 100644 (file)
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
  */\r
-\r
-define(['jquery', 'app/ovsdb/ovsdb.module','app/ovsdb/ovsdb.services'], function($, ovsdb) {\r
+define(['jquery', 'underscore', 'app/ovsdb/ovsdb.module', 'app/ovsdb/OvsCore', 'app/ovsdb/ovsdb.directives', 'app/ovsdb/ovsdb.services', 'app/ovsdb/lib/select2.full.min'], function ($, _, ovsdb, OvsCore) {\r
   'use strict';\r
 \r
-  var RootOvsdbCtrl = function($rootScope) {\r
-      $rootScope['section_logo'] = 'logo_ovsdb';\r
-  };\r
-  RootOvsdbCtrl.$inject = ['$rootScope'];\r
+  var RootOvsdbCtrl = function ($rootScope, cssInjector) {\r
+    $rootScope['section_logo'] = 'logo_ovsdb';\r
+    cssInjector.add('src/app/ovsdb/css/select2.min.css');\r
+    cssInjector.add('src/app/ovsdb/css/toggle-switch.css');\r
 \r
-  var BaseOvsdbCtrl = function($scope) {\r
-      $scope['err'] = {\r
-        "message": "",\r
-        "tag": "",\r
-        "type": ""\r
-      };\r
+    cssInjector.add('src/app/ovsdb/css/ovsdb.css');\r
+  };\r
+  RootOvsdbCtrl.$inject = ['$rootScope', 'cssInjector'];\r
 \r
-      $scope.showError = function() {\r
-        $('#errorMessage').fadeIn().delay(3000).fadeOut();\r
-      };\r
+  var BaseOvsdbCtrl = function ($scope) {\r
+    $scope.err = {\r
+      "message": "",\r
+      "tag": "",\r
+      "type": ""\r
+    };\r
+    $scope.showError = function () {\r
+      $('#errorMessage').fadeIn().delay(3000).fadeOut();\r
+    };\r
   };\r
   BaseOvsdbCtrl.$inject = ['$scope'];\r
 \r
-  var OvsdbCtrl = function($scope, TopologyNetworkSvc) {\r
-      BaseOvsdbCtrl.call(this, $scope);\r
+  var OvsdbCtrl = function ($q, $scope, TopologySvc, NeutronSvc, OvsUtil) {\r
+    BaseOvsdbCtrl.call(this, $scope);\r
+    var lgraphDataDefer = $q.defer(),\r
+      physDataDefer = $q.defer(),\r
+      filterTenant = {\r
+        bridgeIds : [''],\r
+        ovsdbIds : ['']\r
+      },\r
+      filterSubnet = {\r
+        bridgeIds : [''],\r
+        ovsdbIds : ['']\r
+      };\r
+\r
+    $scope.dataPromise = physDataDefer.promise;\r
+    $scope.lgraphIsReadyPromise = lgraphDataDefer.promise;\r
+    $scope.canvasWidth = $('#tabs').width();\r
+    $scope.canvasHeight = 580;\r
+\r
+    $scope.dialogData = ['d'];\r
+\r
+    $scope.tenants = [];\r
+    $scope.subnets = [];\r
+    $scope.selectedTenant = '';\r
+    $scope.selectedSubnet = '';\r
+\r
+    $scope.toggleLayer = function () {\r
+      $scope.rotateGraph($scope.opt.layer);\r
+    };\r
+\r
+    $scope.resizeGraph = function () {\r
+      var $row = $('#ovsdb_contain > div.row:first');\r
+      var h = $row.height();\r
+      $row.data('ph', h);\r
+      $row.fadeOut();\r
+      $('#nv_graph > svg').animate({\r
+        height: '+=' + h\r
+      });\r
+    };\r
+\r
+    $scope.minimizeGraph = function () {\r
+      var $row = $('#ovsdb_contain > div.row:first');\r
+      var h = $row.data('ph');\r
+      $row.fadeIn();\r
+      $('#nv_graph > svg').animate({\r
+        height: '-=' + h\r
+      });\r
+    };\r
+\r
+    function applyFilter(inverse) {\r
+      var bridgeIds = _.uniq(filterTenant.bridgeIds.concat(filterSubnet.bridgeIds));\r
+      var ovsdbIds = _.uniq(filterTenant.ovsdbIds.concat(filterSubnet.ovsdbIds));\r
+      $scope.filterNode(bridgeIds, '.bridge');\r
+      $scope.filterNode(ovsdbIds, '.switch');\r
+      $scope.filterLink();\r
+    }\r
+\r
+    function removeFilter() {\r
+      $scope.filterNode([''], '.bridge', false);\r
+      $scope.filterNode([''], '.switch', false);\r
+      $scope.filterLink();\r
+    }\r
+\r
+    $scope.fiterByTenant = function() {\r
+      if ($scope.selectedTenant) {\r
+        var tenant = $scope.selectedTenant;\r
+        OvsUtil.extractLogicalByTenant(tenant.id).then(function(result) {\r
+          var bridgeId = result[0],\r
+            ovsdbId = result[1];\r
+\r
+          filterTenant.bridgeIds = _.uniq(filterTenant.bridgeIds.concat(bridgeId));\r
+          filterTenant.ovsdbIds = _.uniq(filterTenant.ovsdbIds.concat(ovsdbId));\r
+          applyFilter();\r
+        });\r
+      } else {\r
+        filterTenant.bridgeIds = [''];\r
+        filterTenant.ovsdbIds = [''];\r
+        applyFilter();\r
+      }\r
+    };\r
+\r
+    $scope.filterBySubnet = function() {\r
+      if (!_.isEmpty($scope.selectedSubnet)) {\r
+        var subnets = _.map($scope.selectedSubnet, function(d) {\r
+          return d.id;\r
+        });\r
+        OvsUtil.extractLogicalBySubnet(subnets).then(function(result) {\r
+          var bridgeId = result[0],\r
+            ovsdbId = result[1];\r
+            filterSubnet.bridgeIds = _.uniq(filterSubnet.bridgeIds.concat(bridgeId));\r
+            filterSubnet.ovsdbIds = _.uniq(filterSubnet.ovsdbIds.concat(ovsdbId));\r
+            applyFilter();\r
+        });\r
+      } else {\r
+        filterSubnet.bridgeIds = [''];\r
+        filterSubnet.ovsdbIds = [''];\r
+        applyFilter();\r
+      }\r
+    };\r
+\r
+    $scope.onNodeClick = function (d, nodes, links) {\r
+      $scope.pDialogData = d.node.pretty();\r
+      $scope.$apply();\r
+    };\r
+\r
+    $('#tenantSelect').select2({\r
+      width: "200",\r
+      minimumResultsForSearch: Infinity\r
+    }).next().children('span').children('span').css('width', '200'); //hack to have the arrow with the same background\r
+\r
+    $("#tagPicker").select2({\r
+      width: "230",\r
+    });\r
+\r
+    var $tabs = $('#tabs').tabs({selected: 0});\r
+\r
+    $scope.goToPhysicalView = function(d) {\r
+      $tabs.tabs("option", "active", 1);\r
+      $('#tenantSelect').val(d.tenantId).change();\r
+\r
+      if ( d instanceof OvsCore.Neutron.Network) {\r
+        $('#tagPicker').val(d.subnets.map(function(d){return d.id;})).change();\r
+      }\r
+    };\r
+\r
+    OvsUtil.getLogicalTopology().then(function(networks) {\r
+      var tenantList = NeutronSvc.getAllTenants();\r
+      _.each(tenantList, function(t) {\r
+        $scope.tenants.push({id : t, name: t});\r
+      });\r
+      NeutronSvc.getSubNets().then(function(subHash) {\r
+        $scope.subnets = _.values(subHash).map(function(n) { return n[0]; });\r
+      });\r
+\r
+      lgraphDataDefer.resolve(networks);\r
+    });\r
+\r
+    TopologySvc.getTopologies().then(function(d) {\r
+      physDataDefer.resolve(d);\r
+    });\r
 \r
   };\r
-  OvsdbCtrl.$inject = ['$scope', 'TopologyNetworkSvc'];\r
+\r
+  OvsdbCtrl.$inject = ['$q', '$scope', 'TopologySvc', 'NeutronSvc', 'OvsUtil'];\r
   OvsdbCtrl.prototype = Object.create(BaseOvsdbCtrl.prototype);\r
 \r
   ovsdb.register.controller('RootOvsdbCtrl', RootOvsdbCtrl);\r
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.css b/ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.css
deleted file mode 100644 (file)
index 4f7c162..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * 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
-*/
-
-#errorMessage {
-    display:none;
-}
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.directives.js b/ovsdb-ui/module/src/main/resources/ovsdb/ovsdb.directives.js
new file mode 100644 (file)
index 0000000..b929eb9
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * 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
+ */
+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 () {
+    return {
+      restrict: 'EA',
+      scope: false,
+      link: function (scope, elem, attr) {
+        var lgraph = null,
+          tabCreated = false,
+          width = scope.canvasWidth, //ele[0].clientWidth,
+          height = scope.canvasHeight;
+
+        scope.lDialogData = {};
+
+        scope.lgraphIsReadyPromise.then(function (ltopo) {
+          if (!lgraph) {
+            lgraph = new LogicalGraph(elem[0], width, height);
+          }
+
+          lgraph.networks = ltopo;
+
+          lgraph.start();
+
+          lgraph.onClick = function (d) {
+            var dialogId = '#lDialog';
+            scope.lDialogData = d.pretty();
+            scope.$apply();
+
+            if (!tabCreated) {
+              $(dialogId).tabs();
+              $(dialogId).draggable({
+                containment: 'parent',
+                cancel: '.window_content'
+              });
+              tabCreated = true;
+            } else {
+              $(dialogId).tabs('refresh');
+            }
+
+            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) {
+            scope.goToPhysicalView(d);
+          };
+        });
+        scope.hideLogicalDialog = function () {
+          $('#lDialog').tabs("option", "active", 0)
+            .hide();
+        };
+        elem.on('$destroy', function () {
+          if (lgraph) {
+            lgraph.freeDOM();
+          }
+        });
+      }
+    };
+  });
+
+  ovsdb.register.directive('physicalGraph', function (CacheFactory) {
+    return {
+      restrict: 'EA',
+      scope: false,
+      //templateUrl: 'src/app/ovsdb/views/graph_header.tpl.html',
+      link: function (scope, ele, attr) {
+
+        var graph = null,
+          tabCreated = false,
+          width = scope.canvasWidth,
+          height = scope.canvasHeight;
+
+        scope.reset = function () {
+          var transform = d3.transform(vis.attr('transform')),
+            ix = d3.interpolate(x.domain(), [-width / 2, width / 2]),
+            iy = d3.interpolate(y.domain(), [-height / 2, height / 2]),
+            px = x.domain(ix(1)),
+            py = y.domain(iy(1));
+
+          vis.transition().duration(750).call(zoom.x(px).y(py).scale(1).event);
+        };
+
+        scope.dataPromise.then(function (topo) {
+          if (!graph) {
+            console.log('physical graph created');
+            graph = new Graph(ele[0], width, height);
+          }
+          var nodes = _.clone(topo.nodes);
+          var links = _.clone(topo.links);
+
+          graph.setPosCache(CacheFactory.getCacheObj('nodePos'));
+
+          graph.links = _.values(links);
+          graph.nodes = _.map(nodes, function (value) {
+            return {
+              node: value
+            };
+          });
+          graph.start();
+
+          scope.nbOpenFlowSwitch = _.size(topo.bridgeNodes);
+          scope.nbOvsNode = _.size(topo.ovsdbNodes);
+
+          var linkedByIndex = {};
+          _.each(topo.flowLinks, function (d) {
+            linkedByIndex[d.source + ',' + d.target] = true;
+          });
+
+          function isConnected(a, b) {
+            return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index] || a.index == b.index;
+          }
+
+          function hasConnections(a) {
+            for (var property in linkedByIndex) {
+              var s = property.split(",");
+              if ((s[0] == a.index || s[1] == a.index) && linkedByIndex[property])
+                return true;
+            }
+            return false;
+          }
+
+          graph.onNodeOver = function (d, nodes, links) {
+            nodes.selectAll('.switch > rect').style("stroke", function (o) {
+              return isConnected(d, o) ? "blue" : "black";
+            });
+
+            links.style("stroke", function (o) {
+              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;
+            });
+          };
+
+          graph.onNodeClick = function (d, nodes, links, ctx) {
+            /*var node = d3.select(ctx);
+            d3.select('.node_selected').classed('node_selected', false).attr('filter', 'none');
+            node.classed('node_selected', true).attr('filter', 'url(#selectNode)');*/
+            scope.onNodeClick(d);
+            var dialogId = '#pDialog',
+              $dia = $(dialogId);
+
+            if (!tabCreated) {
+              $(dialogId).tabs();
+              $(dialogId).draggable({
+                containment: 'parent',
+                cancel: '.window_content'
+              });
+              tabCreated = true;
+            } else {
+              $(dialogId).tabs('refresh');
+            }
+
+            $dia.css('left', /*e.left + */ 30);
+            $dia.css('top', /*e.top + */ 35);
+            $dia.show();
+          };
+
+        });
+
+        ele.on('$destroy', function () {
+          graph.freeDOM();
+        });
+
+        scope.hidePhysicalDialog = function () {
+          $('#pDialog').tabs("option", "active", 0)
+            .hide();
+        };
+
+        scope.rotateGraph = function (value) {
+          var b = value ? 1 : -1;
+          graphs.applyPerspective(value);
+          graphs.update();
+          $('path.tunnel').toggle();
+        };
+
+        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';
+          });
+
+        };
+
+        scope.filterLink = function () {
+          var links = d3.selectAll(".tunnel, .link, .bridgeOvsLink");
+
+          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';
+          });
+        };
+      }
+    };
+  });
+
+});
index d9cbb5fffbde85e05e03efc478027beeeaccd0d3..4bad2bb534fafc8cabff7278eb119b8f564f05ac 100644 (file)
@@ -12,12 +12,34 @@ define(['angularAMD', 'app/routingConfig', 'Restangular', 'angular-translate', '
   var ovsdb = angular.module('app.ovsdb', ['app.core', 'pascalprecht.translate', 'ui.router.state', 'restangular', 'config']);\r
   ovsdb.register = ovsdb; // for unit test\r
 \r
-  ovsdb.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, NavHelperProvider) {\r
+  // Filter to access neutron opendaylight.\r
+  // This factory need to be to avoid circular dependencies.\r
+  ovsdb.factory('NeutronInterceptor', ['$q', '$window', 'Base64', function($q, $window, Base64) {\r
+    return {\r
+      request : function(config) {\r
+          // Use AAA basic authentication\r
+        if (config.url.indexOf('controller/nb/v2') != -1) {\r
+          config.headers = config.headers || {};\r
+          if ($window.sessionStorage.odlUser && $window.sessionStorage.odlPass) {\r
+            var encoded = Base64.encode('admin' + ':' + 'admin');\r
+            config.headers.Authorization = 'Basic ' + encoded;\r
+          }\r
+        }\r
+        return config;\r
+      },\r
+      response : function(response) {\r
+        return response || $q.when(response);\r
+      }\r
+    };\r
+  }]);\r
+\r
+  ovsdb.config(function($stateProvider, $compileProvider, $controllerProvider, $provide, $httpProvider, NavHelperProvider) {\r
     ovsdb.register = {\r
       controller : $controllerProvider.register,\r
       directive : $compileProvider.directive,\r
       factory : $provide.factory,\r
-      service : $provide.service\r
+      service : $provide.service,\r
+      constant: $provide.constant\r
 \r
     };\r
 \r
@@ -25,10 +47,10 @@ define(['angularAMD', 'app/routingConfig', 'Restangular', 'angular-translate', '
     NavHelperProvider.addToMenu('Ovsdb', {\r
      "link" : "#/ovsdb/index",\r
      "active" : "main.ovsdb.*",\r
-     "title" : "OVSDB",\r
+     "title" : "Network Virtualization",\r
      "icon" : "icon-sitemap",\r
      "page" : {\r
-        "title" : "OVSDB",\r
+        "title" : "NetWork Virtualization",\r
         "description" : "OVSDB"\r
      }\r
     });\r
@@ -39,7 +61,7 @@ define(['angularAMD', 'app/routingConfig', 'Restangular', 'angular-translate', '
       abstract: true,\r
       views : {\r
         'content' : {\r
-          templateUrl: 'src/app/ovsdb/root.tpl.html',\r
+          templateUrl: 'src/app/ovsdb/views/root.tpl.html',\r
           controller: 'RootOvsdbCtrl'\r
         }\r
       }\r
@@ -50,11 +72,13 @@ define(['angularAMD', 'app/routingConfig', 'Restangular', 'angular-translate', '
       access: access.admin,\r
       views: {\r
         '': {\r
-          templateUrl: 'src/app/ovsdb/index.tpl.html',\r
+          templateUrl: 'src/app/ovsdb/views/index.tpl.html',\r
           controller: 'OvsdbCtrl'\r
         }\r
       }\r
     });\r
+\r
+    $httpProvider.interceptors.push('NeutronInterceptor');\r
   });\r
 \r
   return ovsdb;\r
index c144f78e7aeaecd48941886d78d2ea1c7d519a61..4ef135c3f7a083e4807247d6fa7671c8756ef917 100644 (file)
-/*\r
- * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-define(['app/ovsdb/ovsdb.module'],function(ovsdb) {\r
-  'use strict';\r
-\r
-  ovsdb.register.factory('TopologyNetworkRestangular', function(Restangular, ENV) {\r
-    return Restangular.withConfig(function(RestangularConfig) {\r
-      RestangularConfig.setBaseUrl(ENV.getBaseURL("AD_SAL"));\r
-    });\r
-  });\r
-\r
-  ovsdb.register.factory('TopologyNetworkSvc', function(TopologyNetworkRestangular) {\r
-    var svc = {\r
-      base: function(name) {\r
-        return TopologyNetworkRestangular.one('restconf', name).one('network-topology:network-topology');\r
-      },\r
-      data : null\r
-    };\r
-\r
-    svc.getCurrentData = function() {\r
-      return svc.data;\r
-    };\r
-\r
-    svc.getTopologiesIds = function() {\r
-      svc.data = svc.base('operational').getList();\r
-      return svc.data;\r
-    };\r
-\r
-    svc.getConfigNode = function(topologyId, nodeId) {\r
-      return svc.base('config').one('topology', topologyId).one('node', nodeId).get();\r
-    };\r
-\r
-    svc.addConfigNode = function(topologyId, nodeId, data) {\r
-      return svc.base('config').one('topology', topologyId).one('node').put(nodeId, data);\r
-    };\r
-\r
-    svc.addConfigBridge = function(topologyId, nodeId, data) {\r
-        return svc.base('config').one('topology', topologyId).put(nodeId, data);\r
-    };\r
-\r
-    svc.removeConfigNode = function(topologyId, nodeId) {\r
-      return svc.base('config').one('topology', topologyId).one('node', nodeId).remove();\r
-    };\r
-\r
-    svc.addTerminationPointConfig = function(topologyId, nodeId, terminationId, data) {\r
-      return svc.base('config').one('topology', topologyId).one('node', nodeId).one('termination-point').put(terminationId, data);\r
-    };\r
-\r
-    svc.getTerminationPointConfig = function(topologyId, nodeId, terminationId) {\r
-      return svc.base('config').one('topology', topologyId).one('node', nodeId).one('termination-point', terminationId).get();\r
-    };\r
-\r
-    svc.removeTerminationPointConfig = function(topologyId, nodeId, terminationId) {\r
-      return svc.base('config').one('topology', topologyId).one('node', nodeId).one('termination-point', terminationId).remove();\r
-    };\r
-    return svc;\r
-  });\r
-\r
-\r
-  ovsdb.register.factory('TopologyNetworkFactory', function() {\r
-\r
-    var factory = {\r
-        createOvsdbNodeObject: function(nodeId, nodePort, nodeRemoteIp) {\r
-            return {\r
-                "network-topology:node": [\r
-                    {\r
-                        "node-id": nodeId,\r
-                        "connection-info": {\r
-                            "ovsdb:remote-port": nodePort,\r
-                            "ovsdb:remote-ip": nodeRemoteIp\r
-                        }\r
-                    }\r
-                ]\r
-            };\r
-        },\r
-        createConfigNode: function(nodeId, bridgeName,datapathId, protocolEntries, controllerEntries, managedBy) {\r
-            var configNode = {\r
-                "network-topology:node": [\r
-                    {\r
-                        "node-id": nodeId,\r
-                        "ovsdb:bridge-name": bridgeName,\r
-                        "ovsdb:datapath-id": datapathId,\r
-                        "ovsdb:protocol-entry": [ ],\r
-                        "ovsdb:controller-entry": [ ],\r
-                        "ovsdb:managed-by": managedBy\r
-                    }\r
-                ]\r
-            };\r
-\r
-            for (var protocolEntry in protocolEntries) {\r
-                configNode[0]['ovsdb:protocal-entry'].push({\r
-                    "protocol": protocolEntry\r
-                });\r
-            }\r
-\r
-            for (var controllerEntry in controllerEntries) {\r
-                configNode[0]['ovsdb:controller-entry'].push({\r
-                    "protocol" : controllerEntry\r
-                });\r
-            }\r
-\r
-            return configNode;\r
-\r
-        },\r
-        createEndPoint: function(ovsdb_options, name, interface_type, tp_id, vlan_tag, trunks, vlan_mode) {\r
-            var termination_point = {\r
-                "network-topology:termination-point": [\r
-                    {\r
-                        "ovsdb:options": [ ],\r
-                        "ovsdb:name": name,\r
-                        "ovsdb:interface-type": interface_type,\r
-                        "tp-id": tp_id,\r
-                        "vlan-tag": vlan_tag,\r
-                        "trunks": [ ],\r
-                        "vlan-mode":vlan_mode\r
-                    }\r
-                ]\r
-            };\r
-\r
-            for (var ovsdb_option in ovsdb_options) {\r
-                   termination_point[0]['ovsdb:options'].push({\r
-                        "ovsdb:option": ovsdb_option.option,\r
-                        "ovsdb:value" : ovsdb_option.value\r
-                   });\r
-            }\r
-\r
-            for (var trunk in trunks) {\r
-                termination_point[0]['trunks'].push({\r
-                    "trunk":trunk\r
-                });\r
-            }\r
-\r
-            return termination_point;\r
-        }\r
-    };\r
-\r
-    return factory;\r
-\r
-  });\r
-\r
-});\r
+/*
+ * 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
+ */
+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) {
+      RestangularConfig.setBaseUrl(ENV.getBaseURL("MD_SAL"));
+    });
+  }]);
+
+  // nbv2 support depricated in dlux
+  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) {
+    var svc = {},
+      ovsCache = {};
+    /*BUG : Using the persistant cache make the physical
+     * graph links to stop reacting with the force layout
+     * algorithm. The current behavior is to use the cache
+     * only the pile up the datas.
+     */
+    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);
+        });
+      } 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);
+          });
+        } else {
+          cacheDefer.resolve(cacheObj.obj);
+        }
+      }
+
+      return cacheDefer.promise;
+    };
+
+    svc.getCacheObj = function (key) {
+      if (angular.isUndefined(ovsCache[key])) {
+        ovsCache[key] = {};
+      }
+      return ovsCache[key];
+    };
+
+    return svc;
+  });
+
+  var TopologySvc = function (OvsdbRestangular, nodeIdentifier, ovsNodeKeys, bridgeNodeKeys, tpKeys, flowInfoKeys, linkIdentifier, OVSConstant, $q, $http, CacheFactory) {
+    var svc = {
+      base: function (type) {
+        return OvsdbRestangular.one('restconf').one(type);
+      }
+    };
+
+    function parseOvsdbNode(node) {
+      var inetMgr = '',
+        inetNode = '',
+        otherLocalIp = '',
+        otherInfo = null,
+        connectionInfo = null;
+
+      connectionInfo = node[ovsNodeKeys.CONNECTION_INFO];
+      otherInfo = node[ovsNodeKeys.OTHER_CONFIG];
+
+      if (_.isObject(connectionInfo)) {
+        inetMgr = connectionInfo[ovsNodeKeys.LOCAL_IP] + ':' + connectionInfo[ovsNodeKeys.LOCAL_PORT];
+        inetNode = connectionInfo[ovsNodeKeys.REMOTE_IP] + ':' + connectionInfo[ovsNodeKeys.REMOTE_PORT];
+      }
+
+      if (_.isArray(otherInfo)) {
+        _.each(otherInfo, function (value) {
+          if (value[ovsNodeKeys.OTHER_CONFIG_KEY] === 'local_ip') {
+            otherLocalIp = value[ovsNodeKeys.OTHER_CONFIG_VALUE];
+          }
+        });
+      }
+
+      return new OvsCore.OvsNode(node[ovsNodeKeys.NODE_ID], inetMgr, inetNode, otherLocalIp, node[ovsNodeKeys.OVS_VERSION]);
+    }
+
+    function parseBridgeNode(node) {
+      var bridgeNode = null,
+        controllerTarget = '',
+        controllerConnected = false,
+        tp = node[bridgeNodeKeys.TP],
+        controllerEntries = node[bridgeNodeKeys.CONTROLLER_ENTRY];
+
+      _.each(controllerEntries, function (value) {
+        controllerTarget = value[bridgeNodeKeys.TARGET];
+        controllerEntries = value[bridgeNodeKeys.IS_CONNECTED];
+        return false; // break the anonymus function
+      });
+
+      bridgeNode = new OvsCore.BridgeNode(node[bridgeNodeKeys.NODE_ID], node[bridgeNodeKeys.DATA_PATH], node[bridgeNodeKeys.BRIDGE_NAME], controllerTarget, controllerConnected);
+
+      _.each(tp, function (value) {
+        var tp = parseBridgeTP(value);
+
+        if (tp.ofPort == '65534' && (tp.name === 'br-ex' || tp.name === 'br-int')) {
+          return;
+        } else {
+          bridgeNode.addTerminationPoint(tp);
+        }
+
+      });
+
+      return bridgeNode;
+    }
+
+    function parseBridgeTP(tp) {
+      var mac = '',
+        ifaceId = '',
+        extInfo = tp['ovsdb:port-external-ids'] || tp['ovsdb:interface-external-ids'],
+        type = tp[tpKeys.INTERFACE_TYPE];
+
+      _.each(extInfo, function (ext) {
+        if (ext[tpKeys.EXTERNAL_KEY_ID] === tpKeys.ATTACHED_MAC) {
+          mac = ext[tpKeys.EXTERNAL_KEY_VALUE];
+        }
+        if (ext[tpKeys.EXTERNAL_KEY_ID] === tpKeys.IFACE_ID) {
+          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);
+
+    }
+
+    function fetchTopology(cb) {
+      var invNodeDefer = this.base('operational').one('opendaylight-inventory:nodes').getList();
+      var netTopoDefer = this.base('operational').one('network-topology:network-topology').getList();
+
+      // be sure all data are loaded
+      $q.all([invNodeDefer, netTopoDefer]).then(function (values) {
+          var invNode = values[0],
+            netTopo = values[1],
+            index_hash = [],
+            i = 0;
+
+          // check if the data look fine in network topology
+          if (!netTopo || !netTopo['network-topology'] || !netTopo['network-topology'].topology) {
+            throw new Error('Invalid json format while parsing network-topology');
+          }
+
+          // check if the data look fine in inventory node
+          if (!invNode || !invNode.nodes || !invNode.nodes.node) {
+            throw new Error('Invalid JSON format while parsing inventory-node');
+          }
+
+          // get all topologies and start looping
+          var topologies = netTopo['network-topology'].topology,
+            nodes = invNode.nodes.node,
+            topo = new OvsCore.Topology();
+
+          _.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) {
+              if (!node[nodeIdentifier.ID]) {
+                throw new Error('Unexpected node : undefined ' + nodeIdentifier.ID + ' key');
+              }
+              index_hash[node[nodeIdentifier.ID]] = i++;
+
+              if (node['ovsdb:bridge-name']) {
+                //bridge Node
+                topo.registerBridgeNode(parseBridgeNode(node));
+              } else if (node['ovsdb:connection-info']) {
+                // obsvdb Node
+                topo.registerOvsdbNode(parseOvsdbNode(node));
+              }
+            });
+
+            // if there no link it will be an empty array so noop
+            (topology.link || []).forEach(function (link) {
+
+              var source = link[linkIdentifier.SRC]['source-node'],
+                dest = link[linkIdentifier.DEST]['dest-node'];
+
+              topo.registerLink(new OvsCore.Link(link[linkIdentifier.ID], source, dest));
+            });
+
+          });
+
+          _.each(nodes, function (node, index) {
+            if (!node.id) {
+              return;
+            }
+
+            var bridgeId = node.id;
+
+            var bridgeNode = _.filter(topo.bridgeNodes, function (bridgeNode) {
+              return bridgeNode.getFLowName() === bridgeId;
+            })[0];
+
+            // match info for bridge node
+            if (bridgeNode) {
+              bridgeNode.flowInfo.features = node[flowInfoKeys.FEATURE];
+              bridgeNode.flowInfo.software = node[flowInfoKeys.SOFTWARE];
+              bridgeNode.flowInfo.hardware = node[flowInfoKeys.HARDWARE];
+              bridgeNode.flowInfo.manufacturer = node[flowInfoKeys.MANUFACTURER];
+              bridgeNode.flowInfo.ip = node[flowInfoKeys.IP];
+
+              _.each(node[flowInfoKeys.TABLE], function (entry) {
+                if (!_.isUndefined(entry.id)) {
+                  _.each(entry.flow, function (flow) {
+                    bridgeNode.addFlowTableInfo({
+                      key: flow.table_id,
+                      value: flow.id
+                    });
+                  });
+                }
+              });
+            }
+          });
+
+          // show relation between ovsNode and switch with a link
+          _.each(topo.ovsdbNodes, function (node, index) {
+            var bridges = _.filter(topo.bridgeNodes, function (bnode) {
+              return bnode.nodeId.indexOf(node.nodeId) > -1;
+            });
+            _.each(bridges, function (bridge) {
+              var size = _.size(topo.links),
+                link = new OvsCore.BridgeOvsLink(++size, node.nodeId, bridge.nodeId);
+              topo.registerLink(link);
+            });
+          });
+
+          function findVxlan(bridgeNode) {
+            var tunnels = [];
+
+            _.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 instanceof OvsCore.Tunnel) {
+                  tunnels.push({
+                    port: tp,
+                    bridge: node
+                  });
+                }
+              });
+            });
+
+            return tunnels;
+          }
+
+          // extract all tunnel paired with their bridge
+          var tunnels = findVxlan(topo.bridgeNodes);
+          // loop over all pairs
+          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) {
+              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) {
+          throw err;
+        }
+      );
+    }
+
+    svc.getTopologies = function () {
+      return CacheFactory.obtainDataFromCache('topologies', fetchTopology, this);
+    };
+
+    return svc;
+  };
+  TopologySvc.$inject = ['OvsdbRestangular', 'nodeIdentifier', 'ovsNodeKeys', 'bridgeNodeKeys', 'tpKeys', 'flowInfoKeys', 'linkIdentifier', 'OVSConstant', '$q', '$http', 'CacheFactory'];
+
+  var NeutronSvc = function (NeutronRestangular, CacheFactory, $q, $http) {
+    var svc = {
+        base: function (type) {
+          return NeutronRestangular.one(type);
+        }
+      },
+      tenant_hash = {};
+
+    function fetchSubNetworks(cb) {
+      var subnetskDefer = svc.base('subnets').getList();
+      subnetskDefer.then(function (data) {
+        var subnets = data,
+          subnetHash = {};
+
+        if (!subnets || !subnets.subnets) {
+          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
+          ));
+        });
+        cb(subnetHash);
+      });
+    }
+
+    function fetchNetworks(cb) {
+      var networkDefer = svc.base('networks').getList();
+      var subnetskDefer = svc.getSubNets();
+
+      $q.all([subnetskDefer, networkDefer]).then(function (datas) {
+        var subnetsHash = datas[0],
+          networks = datas[1],
+          networkArray = [];
+
+        if (!networks || !networks.networks) {
+          throw new Error('Invalid format from neutron networks');
+        }
+
+        _.each(networks.networks, function (network) {
+          var net = new OvsCore.Neutron.Network(
+            network.id,
+            network.name,
+            network.shared,
+            network.status,
+            network['router:external'],
+            network.tenant_id
+          );
+          tenant_hash[net.tenantId] = {};
+          net.addSubNets(subnetsHash[net.id]);
+          networkArray.push(net);
+        });
+        cb(networkArray);
+      });
+    }
+
+    function fetchRouters(cb) {
+      var routerDefer = svc.base('routers').getList();
+      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,
+            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
+          ));
+        });
+        cb(routerArray);
+      });
+    }
+
+    function fetchPorts(cb) {
+      var portDefer = svc.base('ports').getList();
+      portDefer.then(function (data) {
+        var ports = data.ports,
+          portArray = [];
+
+        if (!ports) {
+          throw new Error('Invalid format from neutron ports');
+        }
+        _.each(ports, function (port) {
+          tenant_hash[port.tenant_id] = {};
+          portArray.push(new OvsCore.Neutron.Port(
+            port.id,
+            port.network_id,
+            port.name,
+            port.tenant_id,
+            port.device_id,
+            port.device_owner,
+            port.fixed_ips,
+            port.mac_address
+          ));
+        });
+        cb(portArray);
+      });
+    }
+
+    function fetchFloatingIps(cb) {
+      var floatingIpDefer = svc.base('floatingips').getList();
+      floatingIpDefer.then(function (data) {
+        var floatingIps = data.floatingips,
+          floatingIpArray = [];
+
+        if (!floatingIps) {
+          throw new Error('Invalid format from neutron floatingIps');
+        }
+
+        _.each(floatingIps, function (fIp) {
+          tenant_hash[fIp.tenant_id] = {};
+          floatingIpArray.push(new OvsCore.Neutron.FloatingIp(
+            fIp.id,
+            fIp.floating_network_id,
+            fIp.port_id,
+            fIp.fixed_ip_address,
+            fIp.floating_ip_address,
+            fIp.tenant_id,
+            fIp.status
+          ));
+        });
+
+        cb(floatingIpArray);
+      });
+    }
+
+    svc.getNetworks = function () {
+      return CacheFactory.obtainDataFromCache('networks', fetchNetworks, this);
+    };
+
+    svc.getSubNets = function () {
+      return CacheFactory.obtainDataFromCache('subnet', fetchSubNetworks, this);
+    };
+
+    svc.getPorts = function () {
+      return CacheFactory.obtainDataFromCache('ports', fetchPorts, this);
+    };
+
+    svc.getRouters = function () {
+      return CacheFactory.obtainDataFromCache('routers', fetchRouters, this);
+    };
+
+    svc.getFloatingIps = function () {
+      return CacheFactory.obtainDataFromCache('floatingips', fetchFloatingIps, this);
+    };
+
+    svc.getAllTenants = function () {
+      return Object.keys(tenant_hash);
+    };
+
+    return svc;
+  };
+  NeutronSvc.$inject = ['NeutronRestangular', 'CacheFactory', '$q', '$http'];
+
+  var OvsUtil = function (NeutronSvc, TopologySvc, CacheFactory, $q) {
+    var svc = {};
+
+    function findOvsdbNodeForBridge(ovsdbNodes, bridge) {
+      return _.find(ovsdbNodes, function (node) {
+        return bridge.nodeId.indexOf(node.nodeId) > -1;
+      });
+    }
+
+    function pileUpTopologyData(cb) {
+      var networksDefer = NeutronSvc.getNetworks(),
+        routersDefer = NeutronSvc.getRouters(),
+        portsDefer = NeutronSvc.getPorts(),
+        floatingDefer = NeutronSvc.getFloatingIps(),
+        netTopoDefer = TopologySvc.getTopologies();
+
+      $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];
+
+        // 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;
+              });
+              if (router) {
+                router.interfaces.push({
+                  id: port.id,
+                  networkId: port.networkId,
+                  ip: port.fixed_ips[0],
+                  mac: port.mac,
+                  type: port.deviceOwner.replace('network:', ''),
+                  tenantId: port.tenantId,
+                  topoInfo: port.topoInfo
+                });
+              }
+              break;
+            case 'compute:None':
+            case 'compute:nova':
+            case 'network:dhcp':
+              var network = _.find(networks, function (n) {
+                  return n.id === port.networkId;
+                }),
+                inst = null;
+
+              if (network) {
+                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);
+
+                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;
+          });
+
+          // 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);
+      });
+    }
+
+    svc.getLogicalTopology = function () {
+      return CacheFactory.obtainDataFromCache('logicalTopology', pileUpTopologyData, this);
+    };
+
+    svc.extractLogicalByTenant = function (tenantId, subSet) {
+      var lTopoDefer = svc.getLogicalTopology(),
+        resultDefer = $q.defer();
+      lTopoDefer.then(function () {
+        var ports = CacheFactory.getCacheObj('ports').obj,
+          filteredPorts = _.filter(ports, function (p) {
+            return p.tenantId === tenantId;
+          });
+
+        if (!_.isEmpty(filteredPorts)) {
+          var bridgeHash = {};
+          _.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) {
+            if (!_.isEmpty(p.topoInfo) && !ovsdbHash[p.topoInfo[0].ovsNode.nodeId]) {
+              ovsdbHash[p.topoInfo[0].ovsNode.nodeId] = {};
+            }
+          });
+
+          resultDefer.resolve([Object.keys(bridgeHash), Object.keys(ovsdbHash)]);
+        } else {
+          resultDefer.resolve([], []);
+        }
+      });
+      return resultDefer.promise;
+    };
+
+    svc.extractLogicalBySubnet = function (subnets, subSet) {
+      var lTopoDefer = svc.getLogicalTopology(),
+        resultDefer = $q.defer();
+      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) {
+            return d.id === p.networkId;
+          });
+
+          return net.asSubnet(subnets);
+        });
+        if (!_.isEmpty(filteredPorts)) {
+          var bridgeHash = {};
+          _.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) {
+            if (!_.isEmpty(p.topoInfo) && !ovsdbHash[p.topoInfo[0].ovsNode.nodeId]) {
+              ovsdbHash[p.topoInfo[0].ovsNode.nodeId] = {};
+            }
+          });
+          resultDefer.resolve([Object.keys(bridgeHash), Object.keys(ovsdbHash)]);
+        } else {
+          resultDefer.resolve([], []);
+        }
+      });
+      return resultDefer.promise;
+    };
+
+    return svc;
+  };
+
+  OvsUtil.$inject = ['NeutronSvc', 'TopologySvc', 'CacheFactory', '$q'];
+
+  ovsdb.register.factory('TopologySvc', TopologySvc);
+  ovsdb.register.factory('NeutronSvc', NeutronSvc);
+  ovsdb.register.factory('OvsUtil', OvsUtil);
+});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/spec/ovsdb.spec.js b/ovsdb-ui/module/src/main/resources/ovsdb/spec/ovsdb.spec.js
deleted file mode 100644 (file)
index 713b9a6..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-define(['ovsdb/ovsdb.controller'], function() {
-  describe('A fake test', function() {
-    it('Should be retuning true', function() {
-      expect(true).toBe(true);
-    });
-  });
-});
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/views/graph_header.tpl.html b/ovsdb-ui/module/src/main/resources/ovsdb/views/graph_header.tpl.html
new file mode 100644 (file)
index 0000000..93a7b6e
--- /dev/null
@@ -0,0 +1,11 @@
+<!-- <div id="graph_header">
+  <span style="color:black; margin-left:15px;">Network Visualizer</span>
+  <i class="icon-fullscreen" style="float:right;" ng-click="resizeGraph()"></i>
+  <i class="icon-resize-small icon-2" style="float:right" ng-click="minimizeGraph()"></i>
+</div>
+-->
+
+<div id="graph_summary" data-option="false" data-title="Network Summary" nv-window style="text-align:center;">
+  <p style="font-style:italic;">{{nbOpenFlowSwitch}} brides
+    <br/> {{nbOvsNode}} switch</p>
+</div>
diff --git a/ovsdb-ui/module/src/main/resources/ovsdb/views/index.tpl.html b/ovsdb-ui/module/src/main/resources/ovsdb/views/index.tpl.html
new file mode 100644 (file)
index 0000000..8cb2a5f
--- /dev/null
@@ -0,0 +1,123 @@
+<!--\r
+ * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+-->\r
+<div id="ovsdb_contain">\r
+  <!--\r
+<div class="row">\r
+  <div class="col-md-2 form-inline">\r
+    <label class="switch-light well">\r
+      <input type="checkbox" ng-model="opt.layer" ng-change="toggleLayer();">\r
+      <span>\r
+        Layer 3\r
+        <span>Off</span>\r
+        <span>On</span>\r
+      </span>\r
+\r
+      <a  class="btn btn-orange"></a>\r
+    </label>\r
+  </div>\r
+  <div class="col-md-2 form-inline">\r
+    <label class="switch-light well">\r
+      <input type="checkbox" ng-model="opt.underlay" ng-change="toggleUnderlay();">\r
+      <span>\r
+        Underlay\r
+        <span>Off</span>\r
+        <span>On</span>\r
+      </span>\r
+\r
+      <a class="btn btn-orange"></a>\r
+    </label>\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
+        </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>\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
+\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 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>\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
+      </div>\r
+      <!-- tab -->\r
+    </div>\r
similarity index 97%
rename from ovsdb-ui/module/src/main/resources/ovsdb/root.tpl.html
rename to ovsdb-ui/module/src/main/resources/ovsdb/views/root.tpl.html
index 1340df593b99f45109bb1a2baeb0ce0d4ca45980..9e3cf154b7ae9245357b9a9b5652290a717d5f62 100644 (file)
@@ -1,8 +1,8 @@
-<!--
-* 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
--->
-<div class="main" ui-view></div>
+<!--\r
+* Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.\r
+*\r
+* This program and the accompanying materials are made available under the\r
+* terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+* and is available at http://www.eclipse.org/legal/epl-v10.html\r
+-->\r
+<div class="main" ui-view></div>\r
index a0d36019bdea9065e9bfa8055c9cd83fad8e37bd..29aae0d95dd2277faa1c5f5aa8c121e658881d2a 100644 (file)
@@ -10,13 +10,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>commons</artifactId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/parent</relativePath>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
-
+  
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>ovsdb-ui</artifactId>
+  <version>1.2.1-SNAPSHOT</version>
   <name>ovsdb-ui</name>
   <packaging>pom</packaging>
   <prerequisites>
@@ -26,4 +28,24 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <module>module</module>
     <module>bundle</module>
   </modules>
+
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/pom.xml b/pom.xml
index 13429af6d10f22f45b811fa45d851a9a223598d5..f77fc9ed40d2abfe99ffe351d2f42f407403d87e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -12,12 +12,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>commons</artifactId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>commons/parent</relativePath>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>ovsdb</artifactId>
   <version>1.2.1-SNAPSHOT</version>
   <name>${project.artifactId}</name> <!-- Used by Sonar to set project name -->
@@ -58,7 +59,6 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <module>karaf</module>
     <!-- OVSDB Components -->
     <module>southbound</module>
-    <module>northbound</module>
     <module>openstack</module>
     <module>ovsdb-artifacts</module>
     <module>schemas</module>
@@ -66,19 +66,25 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <module>ovsdb-ui</module>
     <module>routemgr</module>
     <module>hwvtepsouthbound</module>
-    <!-- Integration Tests -->
-    <module>integrationtest</module>
   </modules>
 
+  <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
   <build>
     <plugins>
       <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-deploy-plugin</artifactId>
         <configuration>
           <skip>true</skip>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
-
 </project>
diff --git a/resources/commons/3-Node-Cluster-Setup-Environment-Variables.postman_environment b/resources/commons/3-Node-Cluster-Setup-Environment-Variables.postman_environment
new file mode 100644 (file)
index 0000000..dc824a0
--- /dev/null
@@ -0,0 +1,58 @@
+{
+       "id": "61b7453f-15f4-39e5-8470-980d0805f9fb",
+       "name": "3 Node Cluster Setup Environment Variables",
+       "values": [
+               {
+                       "key": "NODE-1-IP",
+                       "value": "192.168.201.2",
+                       "type": "text",
+                       "name": "NODE-1-IP",
+                       "enabled": true
+               },
+               {
+                       "key": "NODE-2-IP",
+                       "value": "192.168.201.3",
+                       "type": "text",
+                       "name": "NODE-2-IP",
+                       "enabled": true
+               },
+               {
+                       "key": "NODE-3-IP",
+                       "value": "192.168.201.4",
+                       "type": "text",
+                       "name": "NODE-3-IP",
+                       "enabled": true
+               },
+               {
+                       "key": "HYPERVISOR-IP",
+                       "value": "192.168.201.128",
+                       "type": "text",
+                       "name": "HYPERVISOR-IP",
+                       "enabled": true
+               },
+               {
+                       "key": "HYPERVISOR-OVSDB-PORT",
+                       "value": "16640",
+                       "type": "text",
+                       "name": "HYPERVISOR-OVSDB-PORT",
+                       "enabled": true
+               },
+               {
+                       "key": "JOLOKIA-NODE-IP",
+                       "value": "192.168.201.2",
+                       "type": "text",
+                       "name": "JOLOKIA-NODE-IP",
+                       "enabled": true
+               },
+               {
+                       "key": "HYPERVISOR-NODE-ID",
+                       "value": "192.168.201.128:16640",
+                       "type": "text",
+                       "name": "HYPERVISOR-NODE-ID",
+                       "enabled": true
+               }
+       ],
+       "timestamp": 1443834815417,
+       "synced": false,
+       "syncedFilename": ""
+}
\ No newline at end of file
diff --git a/resources/commons/NetvirtSfc.json.postman_collection b/resources/commons/NetvirtSfc.json.postman_collection
new file mode 100644 (file)
index 0000000..f73f0cb
--- /dev/null
@@ -0,0 +1,189 @@
+{
+    "id": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+    "name": "NetvirtSfc",
+    "requests": [
+        {
+            "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": "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-access-control-list:access-lists",
+            "version": 2
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "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": "718ed9fd-f7f3-3862-4a53-b12d83c880ae",
+            "method": "PUT",
+            "name": "Classifier",
+            "time": 1444924721709,
+            "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                                \"permit\": {}\n                            }\n                        }\n                    ]\n                }\n            }\n        ]\n    }\n}",
+            "dataMode": "raw",
+            "description": "",
+            "headers": "Content-Type: application/json\n",
+            "id": "7412ee0c-b116-5cf1-0646-efa65f0da784",
+            "method": "GET",
+            "name": "ietf-acl",
+            "responses": [],
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/ietf-access-control-list:access-lists",
+            "version": 2
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "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": "99dc6bb5-f01a-64cd-a024-c333fdf82643",
+            "method": "DELETE",
+            "name": "ietf-acl redirect-sfc",
+            "responses": [],
+            "timestamp": 0,
+            "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
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "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": "b2d13061-80e0-ad8f-d0e6-d6939ea2b0a4",
+            "method": "GET",
+            "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    \"service-functions\": {\n        \"service-function\": [\n            {\n                \"name\": \"firewall-72\",\n                \"ip-mgmt-address\": \"192.168.50.72\",\n                \"type\": \"service-function-type:firewall\",\n                \"nsh-aware\": \"true\",\n                \"sf-data-plane-locator\": [\n                    {\n                        \"name\": \"2\",\n                        \"port\": 6633,\n                        \"ip\": \"192.168.50.72\",\n                        \"transport\": \"service-locator:vxlan-gpe\",\n                        \"service-function-forwarder\": \"SFF1\"\n                    }\n                ]\n            },\n            {\n                \"name\": \"dpi-74\",\n                \"ip-mgmt-address\": \"192.168.50.74\",\n                \"type\": \"service-function-type:dpi\",\n                \"nsh-aware\": \"true\",\n                \"sf-data-plane-locator\": [\n                    {\n                        \"name\": \"3\",\n                        \"port\": 6633,\n                        \"ip\": \"192.168.50.74\",\n                        \"transport\": \"service-locator:vxlan-gpe\",\n                        \"service-function-forwarder\": \"SFF2\"\n                    }\n                ]\n            }\n        ]\n    }\n}",
+            "dataMode": "raw",
+            "description": "",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "id": "bf4f1148-5192-fd7d-3026-5a11668db75d",
+            "method": "PUT",
+            "name": "service-functions",
+            "time": 1445302596335,
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/service-function:service-functions",
+            "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": "e6542ed1-832c-71c9-fe74-2d25c9e7f7ad",
+            "method": "GET",
+            "name": "service-function-forwarders",
+            "responses": [],
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/service-function-forwarder:service-function-forwarders",
+            "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": "ea1c70a0-6528-862c-cabc-a9b187d483c7",
+            "method": "PUT",
+            "name": "Sfc",
+            "responses": [],
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/netvirt-sfc:sfc/",
+            "version": 2
+        },
+        {
+            "collectionId": "bc172f70-35df-2cdf-50a4-8ad09b8f17a2",
+            "data": "{\n    \"service-functions\": {\n        \"service-function\": [\n            {\n                \"name\": \"firewall-72\",\n                \"ip-mgmt-address\": \"192.168.50.72\",\n                \"type\": \"service-function-type:firewall\",\n                \"nsh-aware\": \"true\",\n                \"sf-data-plane-locator\": [\n                    {\n                        \"name\": \"2\",\n                        \"port\": 6633,\n                        \"ip\": \"192.168.50.72\",\n                        \"transport\": \"service-locator:vxlan-gpe\",\n                        \"service-function-forwarder\": \"SFF1\"\n                    }\n                ]\n            },\n            {\n                \"name\": \"dpi-74\",\n                \"ip-mgmt-address\": \"192.168.50.74\",\n                \"type\": \"service-function-type:dpi\",\n                \"nsh-aware\": \"true\",\n                \"sf-data-plane-locator\": [\n                    {\n                        \"name\": \"3\",\n                        \"port\": 6633,\n                        \"ip\": \"192.168.50.74\",\n                        \"transport\": \"service-locator:vxlan-gpe\",\n                        \"service-function-forwarder\": \"SFF2\"\n                    }\n                ]\n            }\n        ]\n    }\n}",
+            "dataMode": "raw",
+            "description": "",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "id": "fff50fa7-aa2d-71a4-db49-4ea10b82937e",
+            "method": "GET",
+            "name": "service-functions",
+            "responses": [],
+            "timestamp": 0,
+            "url": "http://localhost:8181/restconf/config/service-function:service-functions",
+            "version": 2
+        }
+    ],
+    "timestamp": 1444922427094
+}
diff --git a/resources/commons/ODL-Clustering.json.postman_collection b/resources/commons/ODL-Clustering.json.postman_collection
new file mode 100644 (file)
index 0000000..f25bdc7
--- /dev/null
@@ -0,0 +1,74 @@
+{
+       "id": "429efdb8-6763-c457-43d3-0cae196dbe53",
+       "name": "ODL Clustering",
+       "description": "This collection contains request that fetch data related to clustering services, to check if cluster is up and running and topology/inventory shard related details.\n\nThis collection usage postman variables and it's defined in `3 Node Cluster Setup Environment Variables' file.",
+       "order": [
+               "95f3ebe4-dd38-9ef5-8822-f657c8d5cd4b",
+               "3d8fb5eb-7de9-022a-8cb0-943826c468ff",
+               "7fb9aad2-f55f-97d0-5ee1-74724f161f7d"
+       ],
+       "folders": [],
+       "timestamp": 0,
+       "owner": "128022",
+       "remoteLink": "https://www.getpostman.com/collections/d1e5b3ce64a3d58710ec",
+       "public": false,
+       "requests": [
+               {
+                       "folder": null,
+                       "id": "3d8fb5eb-7de9-022a-8cb0-943826c468ff",
+                       "name": "Inventory Shard Details",
+                       "dataMode": "params",
+                       "data": [],
+                       "rawModeData": null,
+                       "descriptionFormat": "html",
+                       "description": "This restconf request will fetch data about `Inventory Shard` from the clustering service.\nUser should direct this request to the controller where jolokia agent is installed.\n\nJOLOKIA-NODE-IP is defined in `3 Node Cluster Setup Environment Variables` file.",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "method": "GET",
+                       "pathVariables": {},
+                       "url": "http://{{JOLOKIA-NODE-IP}}:8181/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-inventory-config,type=DistributedConfigDatastore",
+                       "preRequestScript": "",
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "collectionId": "429efdb8-6763-c457-43d3-0cae196dbe53"
+               },
+               {
+                       "folder": null,
+                       "id": "7fb9aad2-f55f-97d0-5ee1-74724f161f7d",
+                       "name": "Topology Shard Details",
+                       "dataMode": "params",
+                       "data": [],
+                       "rawModeData": null,
+                       "descriptionFormat": "html",
+                       "description": "This restconf request will fetch data about `Topology Shard` from the clustering service.\nUser should direct this request to the controller where jolokia agent is installed.\n\nJOLOKIA-NODE-IP is defined in `3 Node Cluster Setup Environment Variables` file.",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "method": "GET",
+                       "pathVariables": {},
+                       "url": "http://{{JOLOKIA-NODE-IP}}:8181/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-topology-config,type=DistributedConfigDatastore",
+                       "preRequestScript": "",
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "collectionId": "429efdb8-6763-c457-43d3-0cae196dbe53"
+               },
+               {
+                       "folder": null,
+                       "id": "95f3ebe4-dd38-9ef5-8822-f657c8d5cd4b",
+                       "name": "Cluster details",
+                       "dataMode": "params",
+                       "data": [],
+                       "rawModeData": null,
+                       "descriptionFormat": "html",
+                       "description": "Fetch clustering related data and look for following details to make sure that cluster is up and running.\nMembers field should list all the cluster nodes added to the cluster.\nAlso the Unreachable fields should be empty.\nJOLOKIA-NODE-IP is defined in `3 Node Cluster Setup Environment Variables` file.\n",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "method": "GET",
+                       "pathVariables": {},
+                       "url": "http://{{JOLOKIA-NODE-IP}}:8181/jolokia/read/akka:type=Cluster",
+                       "preRequestScript": "",
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "collectionId": "429efdb8-6763-c457-43d3-0cae196dbe53"
+               }
+       ]
+}
\ No newline at end of file
diff --git a/resources/commons/OVSDB_Northbound_APIs.json.postman_collection b/resources/commons/OVSDB_Northbound_APIs.json.postman_collection
deleted file mode 100644 (file)
index 97a09e4..0000000
+++ /dev/null
@@ -1,792 +0,0 @@
-{
-       "id": "b4485302-3406-776b-fb0c-94d74c76dc36",
-       "name": "OVSDB Northbound APIs",
-       "description": "Northbound APIs exposed by ovsdb.northbound bundle",
-       "order": [
-               "1aaa544a-7d79-3159-84b5-89574ff7f3e2",
-               "190627e6-ef20-863f-998b-e019034874c4",
-               "d70a4755-d62a-dfcd-e363-dbe931af99a0"
-       ],
-       "folders": [
-               {
-                       "id": "f0bc8237-daf6-5584-4011-1549618623b5",
-                       "name": "01 BRIDGE",
-                       "description": "",
-                       "order": [
-                               "085fa6c6-1d5b-8afb-4e4a-56cafe5e8bd0",
-                               "aed6c263-4d42-ca35-669f-33a00c3d9c82",
-                               "6f5b8f9a-3e66-16b0-7a16-62a96313eab5",
-                               "7e41f2e4-6797-64f0-ebd2-b4b634b6a559",
-                               "2ced04cd-b934-9a0a-576d-8640b6a0b80e"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "d5c6f3fa-0354-d2db-a2e8-4cb29ade5580",
-                       "name": "02 PORT",
-                       "description": "",
-                       "order": [
-                               "2990bcf5-976b-413a-f732-9a21d26d2146",
-                               "618382e3-a833-04d1-f917-c40e70c176cb",
-                               "39cdc358-7c75-d1cc-34ff-081e74254748",
-                               "4945fedc-a9c9-5b38-478f-df9ea0d1248a"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "10aeabc5-bd4b-b64f-31b6-82cbe9c7e9de",
-                       "name": "03 INTERFACE",
-                       "description": "",
-                       "order": [
-                               "a37af20f-0e43-3fe1-9f3b-c42a264fa3a1",
-                               "4b21a8b1-1703-bc2c-8716-7dcdab57300a",
-                               "0753fa84-8a0e-7727-1d45-5b5eb8c74de0"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "704ce201-08b0-59b4-eba0-c0a22d14d64a",
-                       "name": "04 CONTROLLER",
-                       "description": "",
-                       "order": [
-                               "7fc7d8cd-244d-58a0-febf-9814729b9422",
-                               "646be7a5-a484-329a-1039-02b53e1b05fc",
-                               "d239a9ea-8247-3d47-0d3a-2a1063c0177a"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "c49bb77a-920b-9653-232b-6a35fae3229f",
-                       "name": "05 SSL",
-                       "description": "",
-                       "order": [
-                               "3c4a6bb9-30e8-fdf1-1cf3-a3e187537924",
-                               "6c1b9611-b195-c64c-684f-a639e7ae3946",
-                               "989d5e9c-47a9-206a-c225-dc0e796f096a"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "7d339efa-b5a2-ecb5-1639-7c99ab2beb08",
-                       "name": "06 sFlow",
-                       "description": "",
-                       "order": [
-                               "88f1ec23-5471-97a8-2633-c89c51c20071",
-                               "9b2eaefc-5cc0-958a-0926-2b18fea54b88",
-                               "5eab776e-dd13-2a7f-90c3-fabc4d98d481"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "75c166a9-e5de-c7bd-59b4-20e512c89ef4",
-                       "name": "07 Qos",
-                       "description": "",
-                       "order": [
-                               "5e1f52b7-3295-9485-377f-6988c401a8cd",
-                               "d565f3fb-4a9a-3e61-9e8e-87324427c979",
-                               "40323a39-f07f-695a-2428-e888dd9c7cf1",
-                               "c3c1dd3a-1f8e-947d-f729-2eef56795fef"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "ebb04a01-9318-78ba-7d7d-590688434f35",
-                       "name": "08 Queue",
-                       "description": "",
-                       "order": [
-                               "b1af09ee-f6b9-cddd-9087-6d8dc5b958a4",
-                               "d32420de-40fd-d407-59c5-e1c3b8ea359c",
-                               "2d670425-e1ae-c615-1fe1-b27c0ddf4c43",
-                               "9d887d97-a323-a847-a163-ca6e62ad96fe"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "dc13be48-4ea4-7d32-63df-d367c6df6e70",
-                       "name": "09 NetFlow",
-                       "description": "",
-                       "order": [
-                               "c7ab23bd-2d49-71a0-7a40-31ee0f44b2b0",
-                               "76c04544-3be0-e330-75e1-509919d781f0",
-                               "f8d9b165-7fa7-e0bd-b634-b45d550a3114"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "1fe328ce-a0f2-2512-36b2-21c854081873",
-                       "name": "10 Manager",
-                       "description": "",
-                       "order": [
-                               "3d34de25-8015-98e5-957b-eb3cef69175f",
-                               "1aaa544a-7d79-3159-84b5-89574ff7f3e2",
-                               "baab428a-b056-bd23-906d-290933aee25f"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               },
-               {
-                       "id": "40018e32-d0ca-4a2f-5f06-bff5c95382f8",
-                       "name": "11 IPFIX",
-                       "description": "",
-                       "order": [
-                               "a01a045e-e642-8e39-f2cc-baf37ec5dfc5",
-                               "485249a8-94d2-b61b-a6b9-addfe8fb1495",
-                               "8f74bdb1-1f10-69f4-da1d-cd878df784e5"
-                       ],
-                       "collection_name": "OVSDB Northbound APIs",
-                       "collection_id": "b4485302-3406-776b-fb0c-94d74c76dc36"
-               }
-       ],
-       "timestamp": 1384305639019,
-       "synced": false,
-       "requests": [
-               {
-                       "id": "0753fa84-8a0e-7727-1d45-5b5eb8c74de0",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows/45bf1633-1411-4c92-87f8-b1492eed2ff6",
-                       "data": "",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "raw",
-                       "method": "DELETE",
-                       "version": 2,
-                       "time": 1385442001088,
-                       "name": "DELETE interface row given UUID",
-                       "description": "package org.opendaylight.ovsdb.plugin\n\nclass ConfigurationService\n\nMethod: deleteInterfaceRow()",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "085fa6c6-1d5b-8afb-4e4a-56cafe5e8bd0",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows",
-                       "data": [],
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "params",
-                       "method": "GET",
-                       "version": 2,
-                       "time": 1384863804932,
-                       "name": "GET all bridge rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "190627e6-ef20-863f-998b-e019034874c4",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/open_vswitch/rows",
-                       "data": [],
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "params",
-                       "method": "GET",
-                       "version": 2,
-                       "time": 1384895597912,
-                       "name": "GET all open_vswitch rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "1aaa544a-7d79-3159-84b5-89574ff7f3e2",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows",
-                       "data": "{\n  \"parent_uuid\":\"8d3fb89b-5fac-4631-a990-f5a4e7f5383a\",\n    \"row\":{\n      \"Manager\":{\n        \"target\":\"a_string\",\n        \"is_connected\": true,\n        \"state\":\"active\"\n      }\n    }\n}",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "raw",
-                       "method": "POST",
-                       "version": 2,
-                       "time": 1384920841537,
-                       "name": "INSERT a Manager Row",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "2990bcf5-976b-413a-f732-9a21d26d2146",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows",
-                       "data": [],
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "params",
-                       "method": "GET",
-                       "version": 2,
-                       "time": 1384863858721,
-                       "name": "GET all port rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "2ced04cd-b934-9a0a-576d-8640b6a0b80e",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/66ad493c-23cf-45e7-b5a5-1901fb3165f4",
-                       "pathVariables": {},
-                       "method": "PUT",
-                       "data": "{\n    \"row\":{\n      \"Bridge\":{\n        \"netflow\": [\"55f5d382-17fd-4c42-850d-02c282a67c20\",\"60db8cde-26e6-4bf9-bb08-cd1da68d1fcc\"]\n                \n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386202840003,
-                       "name": "Update (PUT) Bridge table",
-                       "description": "Please note that the UUID used here must be one of the existing UUID of a Row in Bridge Table.\n\nAlso the Update must be done ONLY on the fields that needs update. Should NOT send all the immutable fields again. Update will fail in that case.",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "2d670425-e1ae-c615-1fe1-b27c0ddf4c43",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows/cd1d39f2-0e8d-4164-a5ab-926329cd1c61",
-                       "pathVariables": {},
-                       "method": "DELETE",
-                       "data": "",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386291032110,
-                       "name": "DELETE a Queue row given a UUID (ROOT TABLE)",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "39cdc358-7c75-d1cc-34ff-081e74254748",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows/2f93780e-ce56-4cce-9f7c-579be7996651",
-                       "data": "",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "raw",
-                       "method": "DELETE",
-                       "version": 2,
-                       "time": 1385084358582,
-                       "name": "DELETE port row given UUID",
-                       "description": "package org.opendaylight.ovsdb.plugin\n\nclass ConfigurationService\n\nMethod: deletePortRow()",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "3c4a6bb9-30e8-fdf1-1cf3-a3e187537924",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows",
-                       "pathVariables": {},
-                       "method": "GET",
-                       "data": [],
-                       "dataMode": "params",
-                       "version": 2,
-                       "time": 1385766024370,
-                       "name": "GET all SSL row",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "3d34de25-8015-98e5-957b-eb3cef69175f",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows",
-                       "data": [],
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "params",
-                       "method": "GET",
-                       "version": 2,
-                       "time": 1384920805653,
-                       "name": "GET all manager rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "40323a39-f07f-695a-2428-e888dd9c7cf1",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows/739f3929-3a3e-45b1-88ea-afc09df0ca5c",
-                       "pathVariables": {},
-                       "method": "DELETE",
-                       "data": "",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386292478840,
-                       "name": "DELETE a QoS row given a UUID (ROOT TABLE)",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "485249a8-94d2-b61b-a6b9-addfe8fb1495",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/ipfix/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\":\"2e5c0418-e70c-406b-9ad9-58585ac10c19\",\n    \"row\":{\n      \"IPFIX\":{\n        \"targets\":[\n          \"set\", [\"192.168.56.1:5555\"]]\n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "name": "Insert a IPFIX row",
-                       "description": "",
-                       "descriptionFormat": "html",
-                       "time": 1396821935199,
-                       "version": 2,
-                       "responses": [],
-                       "tests": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "synced": false
-               },
-               {
-                       "id": "4945fedc-a9c9-5b38-478f-df9ea0d1248a",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows/97a82ec9-e85e-4a48-9b77-ca4a41128b90",
-                       "pathVariables": {},
-                       "method": "PUT",
-                       "data": "{\n    \"row\":{\n      \"Port\":{\n        \"qos\": [\n          \"ab2b6f2d-5cb4-4dcf-ac1b-c989ae3d76ce\"\n                ]\n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386208729980,
-                       "name": "Update Port Table",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "4b21a8b1-1703-bc2c-8716-7dcdab57300a",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\":\"ea70e5b1-8b21-4caf-a102-0b85b6c63119\",\n    \"row\":{\n      \"Interface\":{\n        \"name\":\"s1-1125-1\",\n        \"mac\":[\"00:00:bb:bb:00:01\"],\n        \"admin_state\":\"up\"\n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396829465324,
-                       "name": "Create row: Interface Table",
-                       "description": "package org.opendaylight.ovsdb.plugin\npublic class ConfigurationService\n\nMethod: insertInterfaceRow\n",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "5e1f52b7-3295-9485-377f-6988c401a8cd",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows",
-                       "pathVariables": {},
-                       "method": "GET",
-                       "data": [],
-                       "dataMode": "params",
-                       "version": 2,
-                       "time": 1385833787440,
-                       "name": "GET all QoS rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "5eab776e-dd13-2a7f-90c3-fabc4d98d481",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows/",
-                       "pathVariables": {},
-                       "method": "DELETE",
-                       "data": "",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1385832734561,
-                       "name": "DELETE an sFlow row given a UUID",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "618382e3-a833-04d1-f917-c40e70c176cb",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\":\"6b3072ba-a120-4db9-82f8-a8ce4eae6942\",\n    \"row\":{\n      \"Port\":{\n        \"name\":\"krb1\",\n        \"mac\":[\"00:00:00:00:00:01\"],\n        \"tag\":[200]\n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396829482311,
-                       "name": "Create a Port and add it to a Bridge",
-                       "description": "Please note that the parent_uuid of this HTTP Data is the UUID of the Bridge that was created in the previous step.\n\nWatch out for the return value which is the UUID of the port that was just created. This UUID must be used as the parent_uuid for the interface addition. Also look out for the HTTP headers that is returned and it has a location field that can be used for both DELETE and UPDATE operations later.\n",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "646be7a5-a484-329a-1039-02b53e1b05fc",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows/68e97a9a-9f2c-497a-b39b-7f1e37c30c6f",
-                       "data": "",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "raw",
-                       "method": "DELETE",
-                       "version": 2,
-                       "time": 1385391658840,
-                       "name": "DELETE controller row given UUID",
-                       "description": "package org.opendaylight.ovsdb.plugin\n\nclass ConfigurationService\n\nMethod: deleteControllerRow()",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "6c1b9611-b195-c64c-684f-a639e7ae3946",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n    \"row\":{\n      \"SSL\":{\n        \"name\":\"mySSL\",\n        \"ca_cert\" : \"ca_cert\",\n        \"bootstrap_ca_cert\" : true,\n        \"certificate\":\"pieceofpaper\",\n        \"private_key\" : \"private\"\n      }\n    }\n}\n",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1385766215625,
-                       "name": "INSERT an SSL row",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "6f5b8f9a-3e66-16b0-7a16-62a96313eab5",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n    \"row\":{\n      \"Bridge\":{\n        \"name\":\"br25\",\n        \"datapath_type\":\"OPENFLOW\"\n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396829500172,
-                       "name": "Create a Bridge",
-                       "description": "Watch out for the return value which is the UUID of the bridge that was just created.\nThis UUID must be used as the parent_uuid for the port addition.\n\nAlso look out for the HTTP headers that is returned and it has a location field that can be used for both DELETE and UPDATE operations later.",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "76c04544-3be0-e330-75e1-509919d781f0",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\":\"817d2e33-448d-4f2e-b183-7f835e93922f\",\n  \"row\" : {\n    \"NetFlow\":{\n      \"targets\" : [\n        \"set\", [\"192.168.1.102:9998\"]],\n      \"active_timeout\" : \"0\"\n      }\n  } \n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396822912058,
-                       "name": "INSERT a NetFlow row",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "id": "7e41f2e4-6797-64f0-ebd2-b4b634b6a559",
-                       "name": "DELETE a Bridge row given UUID",
-                       "description": "Please note that the UUID used here must be one of the existing UUID of a Row in Bridge Table",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/45677cc9-bed2-4def-9986-b05a9b59f1f4",
-                       "method": "DELETE",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "data": "",
-                       "dataMode": "raw",
-                       "timestamp": 0,
-                       "version": 2,
-                       "time": 1384465149749,
-                       "synced": false
-               },
-               {
-                       "id": "7fc7d8cd-244d-58a0-febf-9814729b9422",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows",
-                       "data": [],
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "params",
-                       "method": "GET",
-                       "version": 2,
-                       "time": 1384898533812,
-                       "name": "GET all controller rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "88f1ec23-5471-97a8-2633-c89c51c20071",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows",
-                       "pathVariables": {},
-                       "method": "GET",
-                       "data": [],
-                       "dataMode": "params",
-                       "version": 2,
-                       "time": 1385832695823,
-                       "name": "GET all sFlow rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "8f74bdb1-1f10-69f4-da1d-cd878df784e5",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/ipfix/rows/715fb52c-63bb-495a-8dca-f3f824fbf8fb",
-                       "pathVariables": {},
-                       "method": "DELETE",
-                       "data": "",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396823075244,
-                       "name": "DELETE a IPFIX row given a UUID",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "989d5e9c-47a9-206a-c225-dc0e796f096a",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows/6c2a532c-96df-49ce-8f3f-f83c39e47122",
-                       "pathVariables": {},
-                       "method": "DELETE",
-                       "data": "",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1385766788123,
-                       "name": "DELETE an SSL row given a UUID",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "9b2eaefc-5cc0-958a-0926-2b18fea54b88",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\": \"a8c88ae9-fc08-498b-8ec8-2fd86627055d\",\n  \"row\": {\n    \"sFlow\": {\n      \"targets\": [\n        \"set\",\n        [\n          \"targets_string\"\n        ]\n      ]\n    }\n  }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396827237234,
-                       "name": "INSERT an sFlow row",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "9d887d97-a323-a847-a163-ca6e62ad96fe",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows/ab2b6f2d-5cb4-4dcf-ac1b-c989ae3d76ce",
-                       "pathVariables": {},
-                       "method": "PUT",
-                       "data": "{\n    \"row\":{\n      \"QoS\":{\n        \"queues\": {\n          \"1\" : { \"val\": \"0fbe6ced-16cf-4a39-8a79-e7c8c31f63a9\"}\n        }\n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386287453591,
-                       "name": "UPDATE a queue in QOS",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "a01a045e-e642-8e39-f2cc-baf37ec5dfc5",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/ipfix/rows",
-                       "pathVariables": {},
-                       "method": "GET",
-                       "data": [],
-                       "dataMode": "params",
-                       "name": "GET all IPFIX rows",
-                       "description": "",
-                       "descriptionFormat": "html",
-                       "time": 1396821857102,
-                       "version": 2,
-                       "responses": [],
-                       "tests": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "synced": false
-               },
-               {
-                       "id": "a37af20f-0e43-3fe1-9f3b-c42a264fa3a1",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows",
-                       "data": [],
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "dataMode": "params",
-                       "method": "GET",
-                       "version": 2,
-                       "time": 1384866802408,
-                       "name": "GET all interface rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "id": "aed6c263-4d42-ca35-669f-33a00c3d9c82",
-                       "name": "GET a bridge row given a UUID",
-                       "description": "Please note that the UUID used here must be one of the existing UUID of a Row in Bridge Table",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/45677cc9-bed2-4def-9986-b05a9b59f1f4",
-                       "method": "GET",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "data": "",
-                       "dataMode": "raw",
-                       "timestamp": 0,
-                       "version": 2,
-                       "time": 1384465185771,
-                       "synced": false
-               },
-               {
-                       "id": "b1af09ee-f6b9-cddd-9087-6d8dc5b958a4",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows",
-                       "pathVariables": {},
-                       "method": "GET",
-                       "data": [],
-                       "dataMode": "params",
-                       "version": 2,
-                       "time": 1385846165644,
-                       "name": "GET all Queue rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "baab428a-b056-bd23-906d-290933aee25f",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows/",
-                       "pathVariables": {},
-                       "method": "DELETE",
-                       "data": "",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1385866190653,
-                       "name": "DELETE a Manager row given UUID",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "c3c1dd3a-1f8e-947d-f729-2eef56795fef",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows/ab2b6f2d-5cb4-4dcf-ac1b-c989ae3d76ce",
-                       "pathVariables": {},
-                       "method": "PUT",
-                       "data": "{\n    \"row\":{\n      \"QoS\":{\n        \"Queues\": {\n          \"queue_value\" : \"5afa70b6-7c74-4972-9d98-874e6307807d\"\n        }\n      }\n    }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386212074539,
-                       "name": "UPDATE a QoS row ",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "c7ab23bd-2d49-71a0-7a40-31ee0f44b2b0",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows",
-                       "pathVariables": {},
-                       "method": "GET",
-                       "data": [],
-                       "dataMode": "params",
-                       "version": 2,
-                       "time": 1385853862100,
-                       "name": "GET all NetFlow rows",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "d239a9ea-8247-3d47-0d3a-2a1063c0177a",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\" : \"a8c88ae9-fc08-498b-8ec8-2fd86627055d\",\n  \"row\" : {\n  \t\"Controller\": {\n      \"target\": \"1.1.1.1\"\n    \t}\n\t}\t\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396828737787,
-                       "name": "Add Controller to Bridge",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "d32420de-40fd-d407-59c5-e1c3b8ea359c",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\": \"c5f7ce39-847c-4a69-bf8a-2a0181898581\",\n  \"row\": {\n    \"Queue\": {\n      \"dscp\" : [\n      \"set\",\n      [\n          25\n        ]\n      ]\n    }\n  }\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "tests": "",
-                       "time": 1396828046762,
-                       "name": "INSERT a Queue row",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "d565f3fb-4a9a-3e61-9e8e-87324427c979",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows",
-                       "pathVariables": {},
-                       "method": "POST",
-                       "data": "{\n  \"parent_uuid\" : \"b109dbcf-47bb-4121-b244-e623b3421d6e\",\n  \"row\" : {\n  \t\"QoS\": {\n      \"type\": \"linux-htb\"\n    \t}\n\t}\t\n}",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386291627774,
-                       "name": "INSERT a QoS row",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "d70a4755-d62a-dfcd-e363-dbe931af99a0",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/controller/nb/v2/connectionmanager/node/HOST1/address/192.168.1.102/port/6640/",
-                       "data": [],
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\n",
-                       "dataMode": "params",
-                       "method": "PUT",
-                       "version": 2,
-                       "time": 1385493381229,
-                       "name": "Connect controller to OVSDB server",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               },
-               {
-                       "id": "f8d9b165-7fa7-e0bd-b634-b45d550a3114",
-                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-                       "url": "http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows/60db8cde-26e6-4bf9-bb08-cd1da68d1fcc",
-                       "pathVariables": {},
-                       "method": "DELETE",
-                       "data": "",
-                       "dataMode": "raw",
-                       "version": 2,
-                       "time": 1386202872294,
-                       "name": "DELETE a NetFlow row given UUID",
-                       "description": "",
-                       "collectionId": "b4485302-3406-776b-fb0c-94d74c76dc36",
-                       "responses": [],
-                       "synced": false
-               }
-       ]
-}
\ No newline at end of file
diff --git a/resources/commons/OVSDB_Northbound_v3_APIs.json.postman_collection b/resources/commons/OVSDB_Northbound_v3_APIs.json.postman_collection
deleted file mode 100644 (file)
index d5af815..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-{
-    "id":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-    "name":"OVSDB Northbound v3 APIs",
-    "timestamp":1416933391257,
-    "requests":[
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"28f2c9fe-06a8-55fa-eb95-ae6d93fc271e",
-            "name":"GET node database table Manager info",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161/database/Open_vSwitch/table/Manager",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"2ceafd22-6467-e29b-f5b9-a947196a365d",
-            "name":"GET config",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/config",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"31423e07-7f63-cace-1d92-eade985c8058",
-            "name":"GET node database table list",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161/database/Open_vSwitch/table",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"52f720c9-424b-f48f-65aa-ef9a9bb29f40",
-            "name":"GET node",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"9d327275-fd29-6b72-9ac8-3bbd38c5364d",
-            "name":"GET node database list",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161/database",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"9f6858b9-198b-5368-7987-9468354ae06b",
-            "name":"GET node database table Open-vSwitch rows uuid",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161/database/Open_vSwitch/table/Open_vSwitch/row/626d6b88-821f-474c-9680-2b74dfafdcd1",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"b8fff80d-cb81-280a-2a88-e0b28d4d23d3",
-            "name":"GET node database table Open-vSwitch",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161/database/Open_vSwitch/table/Open_vSwitch",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"c508233b-ed4b-c03d-0446-3e206b513203",
-            "name":"GET node database table Open-vSwitch rows",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161/database/Open_vSwitch/table/Open_vSwitch/row",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"d8d420f8-826d-af7e-951b-2d29a51c6033",
-            "name":"GET node database info",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node/OVS|192.168.120.31:48161/database/Open_vSwitch",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        },
-        {
-            "collectionId":"4bc6df66-04c6-f750-e6a4-2518f667f85e",
-            "id":"e650b8cc-d983-f329-be2e-153a5601e34c",
-            "name":"GET all nodes",
-            "description":"",
-            "url":"http://{{controllerHost}}:{{controllerPort}}/ovsdb/nb/v3/node",
-            "method":"GET",
-            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nAccept: application/json\nContent-Type: application/json\n",
-            "data":[
-
-            ],
-            "dataMode":"params",
-            "timestamp":0,
-            "responses":[
-
-            ],
-            "version":2
-        }
-    ]
-}
\ No newline at end of file
diff --git a/resources/commons/OVSDB_Southbound.postman_collection b/resources/commons/OVSDB_Southbound.postman_collection
deleted file mode 100644 (file)
index b3a5225..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-{
-   "id":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-   "name":"Ovsdb Southbound Collection",
-   "timestamp":1424977469540,
-   "order":[
-      "da6876b9-d594-5e41-80b0-858e5a6b40b8",
-      "f930747d-8044-d544-5e81-1c1a492c80a3",
-      "eaf0abfa-820e-e554-a5df-7ee96bc0ef6a",
-      "e9e14494-2ff0-4bfe-2854-6100b91832ff",
-      "37f0baee-75a7-6b2f-0890-2b5d125110bc",
-      "ec2b5fdd-dfef-ad11-40e9-c9bbe235e845",
-      "b9064b3d-351d-d529-dc3a-b7907c76f134",
-      "fe956461-edb8-90ad-b9bc-5e95951fa757",
-      "d67eac2b-f77c-6ea5-ecfc-dab88c428c88"
-   ],
-   "owner":0,
-   "sharedWithTeam":false,
-   "synced":false,
-   "subscribed":false,
-   "hasRequests":true,
-   "requests":[
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"37f0baee-75a7-6b2f-0890-2b5d125110bc",
-         "name":"Get Config Topology",
-         "description":"Fetch the config topology from configuration data store.",
-         "url":"http://localhost:8080/restconf/config/network-topology:network-topology/",
-         "method":"GET",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
-         "data":[
-
-         ],
-         "dataMode":"params",
-         "timestamp":0,
-         "responses":[
-
-         ],
-         "version":2
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"b9064b3d-351d-d529-dc3a-b7907c76f134",
-         "name":"Create Specific Config Termination Point",
-         "description":"This restconf request creates port/interface and attach it to specific bridge. Using ovsdb:option, you can pass the optional input to port/interface create optional. E.g. remote_ip=xx.xx.xx.xx.",
-         "url":"http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222%2Fbridge%2Fbrtest/termination-point/vxlanport/",
-         "method":"PUT",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
-         "data":"{\n  \"network-topology:termination-point\": [\n    \t{\n  \t\t\t\"ovsdb:options\": [\n    \t\t\t{\n                  \"ovsdb:option\": \"remote_ip\",\n                  \"ovsdb:value\" : \"10.10.11.11\"\n\t\t    \t}\n\t  \t\t],\n\t  \t\t\"ovsdb:name\": \"vxlanport\",\n          \t\"ovsdb:interface-type\": \"ovsdb:interface-type-vxlan\",\n  \t\t\t\"tp-id\": \"vxlanport\",\n            \"vlan-tag\": \"1\",\n            \"trunks\": [\n                {\n                    \"trunk\": \"2\"\n                },\n                {\n                    \"trunk\": \"3\"\n                }\n            ],\n            \"vlan-mode\":\"access\"\n\t\t}\n    ]\n}",
-         "dataMode":"raw",
-         "timestamp":0,
-         "version":2
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"d67eac2b-f77c-6ea5-ecfc-dab88c428c88",
-         "name":"Get Specific Config Termination Point",
-         "description":"Fetch configuration for specific termination point of the bridge from config data store.",
-         "url":"http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222%2Fbridge%2Fbrtest/termination-point/vxlanport/",
-         "method":"GET",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
-         "data":[
-
-         ],
-         "dataMode":"params",
-         "timestamp":0,
-         "version":2
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"da6876b9-d594-5e41-80b0-858e5a6b40b8",
-         "name":"Create Specific Config OvsdbNode",
-         "description":"Fire this Restconf request if you want to initiate the connection to ovsdb node from controller. It assumes that ovsdb node is listening for tcp connection in passive mode. To configure the ovsdb node for listening incoming connection, please fire following command at ovsdb node machine\n\n\"ovs-vsctl set-manager tcp:16640\"",
-         "url":"http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:16640",
-         "method":"PUT",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
-         "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb://10.10.10.10:16640\",\n            \"connection-info\": {\n              \"ovsdb:remote-port\": 16640,\n              \"ovsdb:remote-ip\": \"127.0.0.1\"\n            }\n        }\n    ]\n}",
-         "dataMode":"raw",
-         "timestamp":0,
-         "version":2,
-         "time":1428968453378
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"e9e14494-2ff0-4bfe-2854-6100b91832ff",
-         "name":"Delete Specific Config OvsdbNode",
-         "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://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222%2Fbridge%2Fbrtest",
-         "method":"DELETE",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
-         "data":[
-
-         ],
-         "dataMode":"params",
-         "timestamp":0,
-         "version":2
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"eaf0abfa-820e-e554-a5df-7ee96bc0ef6a",
-         "name":"Create Specific Config Bridge",
-         "description":"This restconf request creates bridge on the specified ovsdb node.   Restconf URI contains node-id and this node-id has ip address and port. To determine the ip address and port information, fire \"Get Operational Topology\" restconf request and search for node where you want to create a bridge and then use the ip-address / port details from that output. Once you find out the ip-address/port, update the node-id and ovsdb:managed-by element in the restconf body.\n\n       Note: these %2F ('/') in the url are not there by mistake, those are there intentionally because node-id can contain '/'.\n\n    Note:Bridge name should not contain '-' in it, If you bridge name will contain '-', bridge creation will fail. It's know bug and under investigation.",
-         "url":"http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222%2Fbridge%2Fbrtest",
-         "method":"PUT",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
-         "data":"{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb://10.10.10.10:22222/bridge/brtest\",\n             \"ovsdb:bridge-name\": \"brtest\",\n             \"ovsdb:datapath-id\": \"00:00:b2:bf:48:25:f2:4b\",\n             \"ovsdb:protocol-entry\": [\n                {\n                  \"protocol\": \"ovsdb:ovsdb-bridge-protocol-openflow-13\"\n                }\n              ],\n              \"ovsdb:controller-entry\": [\n                {\n                  \"target\": \"tcp:11.11.11.11:6633\"\n                }\n              ],\n             \"ovsdb:managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb://10.10.10.10:22222']\"\n        }\n    ]\n}",
-         "dataMode":"raw",
-         "timestamp":0,
-         "version":2
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"ec2b5fdd-dfef-ad11-40e9-c9bbe235e845",
-         "name":"Get Specific Config OvsdbNode",
-         "description":"This restconf request fetch the configuration for specific node (ovsdb node or bridge node)",
-         "url":"http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222%2Fbridge%2Fbrtest",
-         "method":"GET",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
-         "data":[
-
-         ],
-         "dataMode":"params",
-         "timestamp":0,
-         "version":2
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"f930747d-8044-d544-5e81-1c1a492c80a3",
-         "name":"Get Operational Topology",
-         "description":"This restconf request will fetch the operational topology. Operational topology details are fetch by southbound plugin from all the connected ovsdb node.",
-         "url":"http://localhost:8080/restconf/operational/network-topology:network-topology/",
-         "method":"GET",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
-         "data":[
-
-         ],
-         "dataMode":"params",
-         "timestamp":0,
-         "responses":[
-
-         ],
-         "version":2
-      },
-      {
-         "collectionId":"ebc00c37-8a7e-f980-5b19-3f62212c5a58",
-         "id":"fe956461-edb8-90ad-b9bc-5e95951fa757",
-         "name":"Delete Specific ConfigTermination Point",
-         "description":"Delete configuration of specified termination point of bridge. ",
-         "url":"http://localhost:8080/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F10.10.10.10:22222%2Fbridge%2Fbrtest/termination-point/vxlanport/",
-         "method":"DELETE",
-         "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
-         "data":[
-
-         ],
-         "dataMode":"params",
-         "timestamp":0,
-         "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..c523adc
--- /dev/null
@@ -0,0 +1,828 @@
+{
+    "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",
+        "88789ac9-9de9-bab3-565b-307774e49f4d",
+        "e25f67e4-3a3f-5da7-f7c8-41b371156719",
+        "f7d33d50-7c8e-69e2-6d60-5c6155c5d210",
+        "233b5ab5-8177-4416-6912-2477520a0654",
+        "567d7827-628d-07a4-3b95-5a208a244c43",
+        "f906c48b-ba3c-a3da-36e8-34c453538e2e",
+        "5d0c4d49-44f7-4165-ca5f-00cf2a9fca8b",
+        "34167a78-7de4-91a9-ef40-7592b28ead5c",
+        "9bc22ca7-049c-af51-7c12-6bf71044b2ec",
+        "f6d300f7-380a-d090-0d4a-2b2ddefe5104",
+        "f9f71d74-a49d-b190-d929-b6772ce0ba73",
+        "18032e93-3bc5-9976-4525-fe1e77e98207",
+        "6f6addb7-6d48-e1ef-8cc2-c5841d71c2e5",
+        "20e8b57b-a5e7-a52f-01d6-7b66ea551078",
+        "7714d521-baf0-2dc2-e8ca-4f6228270099",
+        "92bb5645-1804-8174-5e73-2b0780feecfa",
+        "3c387234-5ae9-e589-2fe0-11666b00fec9",
+        "d01abaee-9f84-d625-4dc8-56da031255a1",
+        "6329fb56-9e3b-647f-141a-dad277c303fd",
+        "51384eb0-05f8-7636-90d8-6d55605f80e6",
+        "dd1cd03e-ab78-b6da-5cd8-271e1c6f9c75",
+        "0dba0439-6a45-88cf-802e-cd678f8541a8",
+        "63b2a578-04fd-803c-8327-2809cdf3fb6d",
+        "950426a5-e1e5-b907-a927-8ba96727232e",
+        "950b4c53-a6ab-7479-4fd8-7edb7a113c34",
+        "29d99111-06d1-3bb7-b482-2c492f072b31",
+        "112f40f9-05b8-d6f0-fcb2-7b9d50fb8fdc",
+        "14fbdff8-1255-5c24-7483-fba3d217d51c",
+        "daafe0e1-62d7-8040-b6b1-0956b937a233",
+        "22354294-1d01-cebf-180c-d609747be9bc",
+        "c8e8f3fd-3bfb-aafa-e3ec-a671a942f426",
+        "d362ddc4-1c5f-67d5-e354-c2a8d2ba9d79",
+        "538c71b3-e3e6-f01b-cc4c-d2b686686aa8",
+        "a13e6877-997e-84e1-c8e8-e83ef5e9a002",
+        "3c86ab7c-a7ee-6b71-3ec1-da7d20f97d1a",
+        "4602c331-5850-0813-c276-d4ec3ae7b3d6",
+        "3b8a86df-fe33-5104-2da7-5e0cbdb7a881",
+        "4e706a35-365a-13e4-f2ec-eee027148450",
+        "06025ed3-7251-5ee4-3d6b-c01557eb3dd2"
+    ],
+    "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/logical-switches/ls0",
+            "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/logical-switches/ls0",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":[],
+            "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/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "method":"POST",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "data":"{\n  \"logical-switches\": [\n        {\n            \"hwvtep-node-name\": \"ls0\",\n            \"hwvtep-node-description\": \"\",\n            \"tunnel-key\": \"10000\"\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":[],
+            "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/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":"Update 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/logical-switches/ls0",
+            "method":"PUT",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "data":"{\n  \"logical-switches\": [\n        {\n            \"hwvtep-node-name\": \"ls0\",\n            \"hwvtep-node-description\": \"\",\n            \"tunnel-key\": \"10000\"\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/logical-switches/ls0",
+            "method":"GET",
+            "headers":"Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data":[],
+            "dataMode":"raw",
+            "timestamp":0,
+            "version":2,
+            "time":1447335408595
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "88789ac9-9de9-bab3-565b-307774e49f4d",
+            "name": "Create Specific Config Physical Switch",
+            "description": "Fire this Restconf request if you want to create a physical 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": [],
+            "dataMode": "raw",
+            "timestamp": 0,
+            "version": 2,
+            "time": 1447909152443,
+            "preRequestScript": "",
+            "tests": "",
+            "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/physicalswitch/ps0\",\n            \"hwvtep-node-name\": \"ps0\",\n            \"hwvtep-node-description\": \"\",\n            \"management-ips\": [\n              {\n                \"management-ips-key\": \"{{managementIp}}\"\n              }\n            ],\n            \"tunnel-ips\": [\n              {\n                \"tunnel-ips-key\": \"{{tunnleIp}}\"\n              }\n            ],\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}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "e25f67e4-3a3f-5da7-f7c8-41b371156719",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%phsicalswitch%2Fps0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448552632013,
+            "name": "Update Specific Config Physical Switch",
+            "description": "Fire this Restconf request if you want to update a exsiting physical switch.",
+            "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"hwvtep://{{hwvtepNodeIp}}:6640/physicalswitch/ps0\",\n            \"hwvtep-node-name\": \"ps0\",\n            \"hwvtep-node-description\": \"\",\n            \"management-ips\": [\n              {\n                \"management-ips-key\": \"{{managementIp}}\"\n              }\n            ],\n            \"tunnel-ips\": [\n              {\n                \"tunnel-ips-key\": \"{{tunnleIp}}\"\n              }\n            ],\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}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "f7d33d50-7c8e-69e2-6d60-5c6155c5d210",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%phsicalswitch%2Fps0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448548819543,
+            "name": "Get Specific Config Physical Switch",
+            "description": "Fire this Restconf request if you want to get a exsiting physical switch."
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "233b5ab5-8177-4416-6912-2477520a0654",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%phsicalswitch%2Fps0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448552707318,
+            "name": "Delete Specific Config Physical Switch",
+            "description": "Fire this Restconf request if you want to delete a physical switch.",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "a13e6877-997e-84e1-c8e8-e83ef5e9a002",
+            "name": "Get Specific Operational Physical Switch",
+            "description": "",
+            "url": "http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Fphysicalswitch%2Fps0",
+            "method": "GET",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+            "data": [],
+            "dataMode": "raw",
+            "timestamp": 0,
+            "responses": [],
+            "version": 2,
+            "preRequestScript": "",
+            "tests": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "567d7827-628d-07a4-3b95-5a208a244c43",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Fphysicalswitch%2Fbr0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448641495086,
+            "name": "Create Specific Config Physical Port",
+            "description": "",
+            "rawModeData": "{\n  \"network-topology:termination-point\": [\n        {\n            \"tp-id\": \"port0\",\n          \t\"hwvtep-node-name\": \"port0\",\n            \"hwvtep-node-description\": \"\",\n            \"vlan-bindings\": [\n          \t\t{\n                  \"vlan-id-key\": \"100\",\n                  \"logical-switch-ref\": \"ls0\"\n            \t}\n          \t]\n\t\t}\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "f906c48b-ba3c-a3da-36e8-34c453538e2e",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Fphysicalswitch%2Fbr0/termination-point/port0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448643757985,
+            "name": "Update Specific Config Physical Port",
+            "description": "",
+            "rawModeData": "{\n  \"network-topology:termination-point\": [\n        {\n            \"tp-id\": \"port0\",\n          \t\"hwvtep-node-name\": \"port0\",\n            \"hwvtep-node-description\": \"\",\n            \"vlan-bindings\": [\n          \t\t{\n                  \"vlan-id-key\": \"100\",\n                  \"logical-switch-ref\": \"ls0\"\n            \t}\n          \t]\n\t\t}\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "5d0c4d49-44f7-4165-ca5f-00cf2a9fca8b",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Fphysicalswitch%2Fbr0/termination-point/port0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448643846609,
+            "name": "Get Specific Config Physical Port",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "34167a78-7de4-91a9-ef40-7592b28ead5c",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Fphysicalswitch%2Fbr0/termination-point/port0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448643860663,
+            "name": "Delete Specific Config Physical Port",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "3c86ab7c-a7ee-6b71-3ec1-da7d20f97d1a",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640%2Fphysicalswitch%2Fbr0/termination-point/port0",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448718837283,
+            "name": "Get Specific Operational Physical Port",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "20e8b57b-a5e7-a52f-01d6-7b66ea551078",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449132978312,
+            "name": "Create Specific Config UcastMacRemote",
+            "description": "",
+            "rawModeData": "{\n  \"remote-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"11:11:11:11:11:11\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"1.1.1.1\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"             \n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "7714d521-baf0-2dc2-e8ca-4f6228270099",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449310821724,
+            "name": "Update Specific Config UcastMacRemote",
+            "description": "",
+            "rawModeData": "{\n  \"remote-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"11:11:11:11:11:11\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"1.1.1.1\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "92bb5645-1804-8174-5e73-2b0780feecfa",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311389212,
+            "name": "Get Specific Config UcastMacRemote",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "3c387234-5ae9-e589-2fe0-11666b00fec9",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311417267,
+            "name": "Delete Specific Config UcastMacRemote",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "4602c331-5850-0813-c276-d4ec3ae7b3d6",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/operational/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-ucast-macs/11:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449314879742,
+            "name": "Get Specific Operational UcastMacRemote",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "6f6addb7-6d48-e1ef-8cc2-c5841d71c2e5",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1448972198808,
+            "name": "Create Specific Config Locator",
+            "description": "",
+            "rawModeData": "{\n  \"termination-point\": [\n        {\n            \"tp-id\": \"vxlan_over_ipv4:{{LocatorIp}}\",\n            \"encapsulation-type\": \"encapsulation-type-vxlan-over-ipv4\",\n          \t\"dst-ip\": \"{{LocatorIp}}\"\n\t\t}\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "d01abaee-9f84-d625-4dc8-56da031255a1",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449286080233,
+            "name": "Create Specific Config UcastMacLocal",
+            "description": "",
+            "rawModeData": "{\n  \"local-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"22:22:22:22:22:22\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"2.2.2.2\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"             \n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "6329fb56-9e3b-647f-141a-dad277c303fd",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:11:11:11:11:11",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449310498424,
+            "name": "Update Specific Config UcastMacLocal",
+            "description": "",
+            "rawModeData": "{\n  \"local-ucast-macs\": [\n        {\n            \"mac-entry-key\": \"22:22:22:22:22:22\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"2.2.2.2\",\n            \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:{{LocatorIp}}']\"\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "51384eb0-05f8-7636-90d8-6d55605f80e6",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:22:22:22:22:22",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311223998,
+            "name": "Get Specific Config UcastMacLocal ",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "dd1cd03e-ab78-b6da-5cd8-271e1c6f9c75",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:22:22:22:22:22",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449311421493,
+            "name": "Delete Specific Config UcastMacLocal",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "3b8a86df-fe33-5104-2da7-5e0cbdb7a881",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-ucast-macs/22:22:22:22:22:22",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449315928725,
+            "name": "Get Specific Operational UcastMacLocal ",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "0dba0439-6a45-88cf-802e-cd678f8541a8",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449468092415,
+            "name": "Create Specific Config McastMacRemote",
+            "description": "",
+            "rawModeData": "{\n  \"remote-mcast-macs\": [\n        {\n            \"mac-entry-key\": \"33:33:33:33:33:55\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"3.3.3.5\",\n            \"locator-set\": [\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.49']\"\n                },\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.48']\"\n                }\n            ]\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "63b2a578-04fd-803c-8327-2809cdf3fb6d",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-mcast-macs/33:33:33:33:33:33",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449468318065,
+            "name": "Update Specific Config McastMacRemote ",
+            "description": "",
+            "rawModeData": "{\n  \"remote-mcast-macs\": [\n        {\n            \"mac-entry-key\": \"33:33:33:33:33:33\",\n            \"logical-switch-ref\": \"ls1\",\n            \"ipaddr\": \"3.3.3.3\",\n            \"locator-set\": [\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.49']\"\n                },\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.48']\"\n                }\n            ]\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "950426a5-e1e5-b907-a927-8ba96727232e",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-mcast-macs/33:33:33:33:33:33",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449553538252,
+            "name": "Get Specific Config McastMacRemote ",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "950b4c53-a6ab-7479-4fd8-7edb7a113c34",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-mcast-macs/33:33:33:33:33:33",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449553525974,
+            "name": "delete Specific Config McastMacRemote ",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "4e706a35-365a-13e4-f2ec-eee027148450",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/remote-mcast-macs/33:33:33:33:33:33",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449553579687,
+            "name": "Get Specific Operational McastMacRemote ",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "29d99111-06d1-3bb7-b482-2c492f072b31",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "POST",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449468010690,
+            "name": "Create Specific Config McastMacLocal",
+            "description": "",
+            "rawModeData": "{\n  \"local-mcast-macs\": [\n        {\n            \"mac-entry-key\": \"44:44:44:44:44:66\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"4.4.4.6\",\n            \"locator-set\": [\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.49']\"\n                },\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.48']\"\n                }\n            ]\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "112f40f9-05b8-d6f0-fcb2-7b9d50fb8fdc",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-mcast-macs/44:44:44:44:44:44",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "PUT",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449468504628,
+            "name": "Update Specific Config McastMacLocal",
+            "description": "",
+            "rawModeData": "{\n  \"local-mcast-macs\": [\n        {\n            \"mac-entry-key\": \"44:44:44:44:44:44\",\n            \"logical-switch-ref\": \"ls0\",\n            \"ipaddr\": \"4.4.4.4\",\n            \"locator-set\": [\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.49']\"\n                },\n                {\n                    \"locator-ref\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='hwvtep:1']/network-topology:node[network-topology:node-id='hwvtep://{{hwvtepNodeIp}}:6640']/network-topology:termination-point[network-topology:tp-id='vxlan_over_ipv4:219.141.189.48']\"\n                }\n            ]\n        }\n    ]\n}"
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "14fbdff8-1255-5c24-7483-fba3d217d51c",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-mcast-macs/44:44:44:44:44:44",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449553697904,
+            "name": "Get Specific Config McastMacLocal ",
+            "description": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "daafe0e1-62d7-8040-b6b1-0956b937a233",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/config/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-mcast-macs/44:44:44:44:44:44",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "DELETE",
+            "data": [],
+            "dataMode": "raw",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449553714791,
+            "name": "Delete Specific Config McastMacLocal ",
+            "description": "",
+            "rawModeData": ""
+        },
+        {
+            "collectionId": "19f6b1a8-4d54-62f8-6bd6-f52e0b6e40b8",
+            "id": "06025ed3-7251-5ee4-3d6b-c01557eb3dd2",
+            "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+            "url": "http://{{controllerHost}}:8181/restconf/operational/network-topology:network-topology/topology/hwvtep:1/node/hwvtep:%2F%2F{{hwvtepNodeIp}}:6640/local-mcast-macs/44:44:44:44:44:44",
+            "preRequestScript": "",
+            "pathVariables": {},
+            "method": "GET",
+            "data": [],
+            "dataMode": "params",
+            "version": 2,
+            "tests": "",
+            "currentHelper": "normal",
+            "helperAttributes": {},
+            "time": 1449553741834,
+            "name": "Get Specific Operational McastMacLocal ",
+            "description": ""
+        }
+    ]
+}
diff --git a/resources/commons/Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection b/resources/commons/Ovsdb-Southbound-Collection-for-3-Node-Cluster.json.postman_collection
new file mode 100644 (file)
index 0000000..a79dd4f
--- /dev/null
@@ -0,0 +1,821 @@
+{
+       "id": "4cd83ae0-a164-c12a-a872-c2205817594a",
+       "name": "Ovsdb Southbound Collection for 3 Node Cluster",
+       "description": "All the rest conf request present in this collection depends on the \"3 Node Cluster Setup Environment Variables\" file.\n\nYou need to import this file, using the \"Manager Environment\" option present in the right top cornor of the postman window.",
+       "order": [
+               "be720a0e-5a69-91e2-93fb-5ffc4efe7f8c",
+               "4980abaf-b36a-42c7-4cde-cdc3d0ef594d",
+               "783d6e22-bfb0-9bec-bc24-da5d75b82123",
+               "2be310a1-3741-8881-fca1-b8bbc7daae7e",
+               "843e0282-c43e-4754-d415-f2a59b3eeb65",
+               "001d0bb8-5918-db89-e360-2fa5d5747cf3",
+               "a51f9d53-7917-7d2a-655c-d7f772045122",
+               "87269c7c-4a76-6dc1-036a-91be949477b0",
+               "24afe1e9-d235-0eec-2b3d-465168b30242",
+               "47fa5fbe-2b71-aae5-1859-fb42090efd24",
+               "319fede8-b756-8c67-b0b2-bf1cf6a4070b",
+               "dcafada2-2452-3701-f26c-c189e18f3ab0",
+               "9ff5feea-b08d-b0b7-2934-1cf6c10ab643",
+               "821cc80a-d417-a2ea-36e5-6138252a8ecb",
+               "3f4c1bd6-8b5e-9e0c-577f-7e0dcfa84cdd",
+               "d7e5948a-cab1-a6eb-32bd-a9220691a6d6",
+               "b9748414-6b9d-4fcc-2f43-b6be86a4e4be",
+               "c9430389-323d-452f-a204-c8c0ef12dcf6",
+               "35c25342-e126-393b-f74b-d3f828983ba1",
+               "c60b33eb-c776-06fc-1f28-551c429ad196",
+               "01cdfc13-82a8-5989-12d0-0e029609f1b8",
+               "b0592ca5-7d6a-ebd4-6f98-c431d1c11ce7",
+               "d9b65865-d54b-408b-f868-3e71fee53593",
+               "5e628d2c-cadf-4ca8-1800-6517c07cb917",
+               "cef78015-fff6-62f0-698b-76f26505e6df",
+               "f42c21e0-116d-5428-1dfb-9b01e8ad72fa",
+               "b592f176-36a7-6830-f3a9-0547f18bcd2d",
+               "499c888c-0868-3241-603e-5c775f9cd678",
+               "c24aebbf-bb85-3201-f605-21e7fef17ae1",
+               "7ee803d2-3326-5f61-8fc0-5ebd8ac2c56c",
+               "11dd55f7-7f0c-f6ce-8377-4b08919b073e",
+               "bd270450-ee6a-6ebb-f7f1-8e0461ee4f56",
+               "c01d85a0-5f9a-54ef-f2ff-3aefef8c465e",
+               "38b350e8-4349-f5a0-5d42-61ef885a4d9d",
+               "92688f6e-dd8b-5b2f-4525-ecfccf4d6248",
+               "ff01de93-1b51-200a-87d0-443091fdfb78",
+               "6cf9fe58-77ca-fac5-bf9a-b5294254a9ef",
+               "b4f9dbc2-ab25-e45b-302f-cd058367d8a9",
+               "36fe5adc-41a9-859d-6986-205685fc832d",
+               "70f19c4e-9c96-7774-36ec-424566c24597",
+               "a110b75d-6445-2618-09e6-2f4ff0ab387d",
+               "939becd9-43d9-be67-0cec-49caf45aaef8"
+       ],
+       "folders": [],
+       "timestamp": 1443832335637,
+       "owner": "128022",
+       "remoteLink": "",
+       "public": false,
+       "requests": [
+               {
+                       "id": "001d0bb8-5918-db89-e360-2fa5d5747cf3",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834393294,
+                       "name": "Node-3-OVSDB Operational Topology",
+                       "description": "This restconf request fetches the topology details from the `Operational` data store that contains details about all the connected hypervisor, bridges present on the hypervisor and termination point connected to each bridge.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "01cdfc13-82a8-5989-12d0-0e029609f1b8",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834419934,
+                       "name": "Node-3-OVSDB Bridge Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for specific bridge (`brtest`) present on the given ovsdb server/hypervisor(`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "11dd55f7-7f0c-f6ce-8377-4b08919b073e",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834274756,
+                       "name": "Node-1-Termination Point Configuration Data",
+                       "description": "This restconf request fetch data from `Configuration` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "24afe1e9-d235-0eec-2b3d-465168b30242",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834401766,
+                       "name": "Node-3-OVSDB Server Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "2be310a1-3741-8881-fca1-b8bbc7daae7e",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834214050,
+                       "name": "Node-1-OVSDB Operational Topology",
+                       "description": "This restconf request fetches the topology details from the `Operational` data store that contains details about all the connected hypervisor, bridges present on the hypervisor and termination point connected to each bridge.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "319fede8-b756-8c67-b0b2-bf1cf6a4070b",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834321665,
+                       "name": "Node-2-OVSDB Server Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "35c25342-e126-393b-f74b-d3f828983ba1",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834250855,
+                       "name": "Node-1-OVSDB Bridge Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for specific bridge (`brtest`) present on the given ovsdb server/hypervisor(`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "36fe5adc-41a9-859d-6986-205685fc832d",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834453771,
+                       "name": "Node-3-Create Termination Point on Given Bridge",
+                       "description": "This restconf request creates port/interface (`testport`) and attach it to give bridge (`HYPERVISOR-NODE-ID`). Using ovsdb:option, you can pass the optional input to port/interface create optional. E.g. remote_ip=xx.xx.xx.xx.\n\n    Note: Please change the attributes of the interface if you don't want to create this default termination point.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n  \t\t\t\"ovsdb:options\": [\n    \t\t\t{\n                  \"ovsdb:option\": \"remote_ip\",\n                  \"ovsdb:value\" : \"10.10.14.11\"\n\t\t    \t}\n\t  \t\t],\n\t  \t\t\"ovsdb:name\": \"testport\",\n          \t\"ovsdb:interface-type\": \"ovsdb:interface-type-vxlan\",\n  \t\t\t\"tp-id\": \"testport\",\n            \"vlan-tag\": \"1\",\n            \"trunks\": [\n                {\n                    \"trunk\": \"5\"\n                }\n            ],\n            \"vlan-mode\":\"access\"\n\t\t}\n    ]\n}"
+               },
+               {
+                       "id": "38b350e8-4349-f5a0-5d42-61ef885a4d9d",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834281860,
+                       "name": "Node-1-Termination Point Operational Data",
+                       "description": "This restconf request fetch data from `Operational` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "3f4c1bd6-8b5e-9e0c-577f-7e0dcfa84cdd",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834410953,
+                       "name": "Node-3-Connect to the OVSDB Server",
+                       "description": "This Restconf request will ask controller to initiate the connection to ovsdb server running on hypervisor. Controller assumes that ovsdb server is listening for tcp connection in passive mode. To configure the ovsdb server to listen in passive mode, please fire following command on hypervisor\n\n`ovs-vsctl set-manager ptcp:16640`\n\nwhatever port number you use here, you should use the same port number for HYPERVISOR-OVSDB-PORT key in \"Single Node Cluster Setup Environment\" Environmen file.\n\n        Note: Please set the environment variable `HYPERVISOR-IP` to the hypervisor ip that is running OVSDB server and `HYPERVISOR-OVSDB-PORT` to the port number on which OVSDB server is listening. Both of these environment variables are present in the \"Single Node Cluster Setup Enviornment\" file. ",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}\",\n            \"connection-info\": {\n              \"ovsdb:remote-port\": \"{{HYPERVISOR-OVSDB-PORT}}\",\n              \"ovsdb:remote-ip\": \"{{HYPERVISOR-IP}}\"\n            }\n        }\n    ]\n}"
+               },
+               {
+                       "id": "47fa5fbe-2b71-aae5-1859-fb42090efd24",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834223225,
+                       "name": "Node-1-OVSDB Server Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "4980abaf-b36a-42c7-4cde-cdc3d0ef594d",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834302452,
+                       "name": "Node-2-OVSDB Configuration Topology",
+                       "description": "This restconf request fetch the topology details from `Configuration` data store that is pushed by user..",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "499c888c-0868-3241-603e-5c775f9cd678",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834269373,
+                       "name": "Node-1-Delete OVS Bridge on Hypervisor",
+                       "description": "This restconf request deletes OVS bridge (`brtest`) on the hypervisor with the node-id provided through `HYPERVISOR-NODE-ID` environment variable set in the `Single Node Cluster Setup Environment` file.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "5e628d2c-cadf-4ca8-1800-6517c07cb917",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834426689,
+                       "name": "Node-3-OVSDB Bridge Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for specific bridge (`brtest`) present on given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "6cf9fe58-77ca-fac5-bf9a-b5294254a9ef",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834286293,
+                       "name": "Node-1-Create Termination Point on Given Bridge",
+                       "description": "This restconf request creates port/interface (`testport`) and attach it to give bridge (`HYPERVISOR-NODE-ID`). Using ovsdb:option, you can pass the optional input to port/interface create optional. E.g. remote_ip=xx.xx.xx.xx.\n\n    Note: Please change the attributes of the interface if you don't want to create this default termination point.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n  \t\t\t\"ovsdb:options\": [\n    \t\t\t{\n                  \"ovsdb:option\": \"remote_ip\",\n                  \"ovsdb:value\" : \"10.10.14.11\"\n\t\t    \t}\n\t  \t\t],\n\t  \t\t\"ovsdb:name\": \"testport\",\n          \t\"ovsdb:interface-type\": \"ovsdb:interface-type-vxlan\",\n  \t\t\t\"tp-id\": \"testport\",\n            \"vlan-tag\": \"1\",\n            \"trunks\": [\n                {\n                    \"trunk\": \"5\"\n                }\n            ],\n            \"vlan-mode\":\"access\"\n\t\t}\n    ]\n}"
+               },
+               {
+                       "id": "70f19c4e-9c96-7774-36ec-424566c24597",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834290451,
+                       "name": "Node-1-Delete Termination Point on Given Bridge",
+                       "description": "Delete termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`). ",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "783d6e22-bfb0-9bec-bc24-da5d75b82123",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834389570,
+                       "name": "Node-3-OVSDB Configuration Topology",
+                       "description": "This restconf request fetch the topology details from `Configuration` data store that is pushed by user..",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "7ee803d2-3326-5f61-8fc0-5ebd8ac2c56c",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834438109,
+                       "name": "Node-3-Delete OVS Bridge on Hypervisor",
+                       "description": "This restconf request deletes OVS bridge (`brtest`) on the hypervisor with the node-id provided through `HYPERVISOR-NODE-ID` environment variable set in the `Single Node Cluster Setup Environment` file.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "821cc80a-d417-a2ea-36e5-6138252a8ecb",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834326599,
+                       "name": "Node-2-Connect to the OVSDB Server",
+                       "description": "This Restconf request will ask controller to initiate the connection to ovsdb server running on hypervisor. Controller assumes that ovsdb server is listening for tcp connection in passive mode. To configure the ovsdb server to listen in passive mode, please fire following command on hypervisor\n\n`ovs-vsctl set-manager ptcp:16640`\n\nwhatever port number you use here, you should use the same port number for HYPERVISOR-OVSDB-PORT key in \"Single Node Cluster Setup Environment\" Environmen file.\n\n        Note: Please set the environment variable `HYPERVISOR-IP` to the hypervisor ip that is running OVSDB server and `HYPERVISOR-OVSDB-PORT` to the port number on which OVSDB server is listening. Both of these environment variables are present in the \"Single Node Cluster Setup Enviornment\" file. ",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}\",\n            \"connection-info\": {\n              \"ovsdb:remote-port\": \"{{HYPERVISOR-OVSDB-PORT}}\",\n              \"ovsdb:remote-ip\": \"{{HYPERVISOR-IP}}\"\n            }\n        }\n    ]\n}"
+               },
+               {
+                       "id": "843e0282-c43e-4754-d415-f2a59b3eeb65",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834311880,
+                       "name": "Node-2-OVSDB Operational Topology",
+                       "description": "This restconf request fetches the topology details from the `Operational` data store that contains details about all the connected hypervisor, bridges present on the hypervisor and termination point connected to each bridge.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "87269c7c-4a76-6dc1-036a-91be949477b0",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834316676,
+                       "name": "Node-2-OVSDB Server Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "92688f6e-dd8b-5b2f-4525-ecfccf4d6248",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834361798,
+                       "name": "Node-2-Termination Point Operational Data",
+                       "description": "This restconf request fetch data from `Operational` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "939becd9-43d9-be67-0cec-49caf45aaef8",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834458122,
+                       "name": "Node-3-Delete Termination Point on Given Bridge",
+                       "description": "Delete termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`). ",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "9ff5feea-b08d-b0b7-2934-1cf6c10ab643",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834229957,
+                       "name": "Node-1-Connect to the OVSDB Server",
+                       "description": "This Restconf request will ask controller to initiate the connection to ovsdb server running on hypervisor. Controller assumes that ovsdb server is listening for tcp connection in passive mode. To configure the ovsdb server to listen in passive mode, please fire following command on hypervisor\n\n`ovs-vsctl set-manager ptcp:16640`\n\nwhatever port number you use here, you should use the same port number for HYPERVISOR-OVSDB-PORT key in \"Single Node Cluster Setup Environment\" Environmen file.\n\n        Note: Please set the environment variable `HYPERVISOR-IP` to the hypervisor ip that is running OVSDB server and `HYPERVISOR-OVSDB-PORT` to the port number on which OVSDB server is listening. Both of these environment variables are present in the \"Single Node Cluster Setup Enviornment\" file. ",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}\",\n            \"connection-info\": {\n              \"ovsdb:remote-port\": \"{{HYPERVISOR-OVSDB-PORT}}\",\n              \"ovsdb:remote-ip\": \"{{HYPERVISOR-IP}}\"\n            }\n        }\n    ]\n}"
+               },
+               {
+                       "id": "a110b75d-6445-2618-09e6-2f4ff0ab387d",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834373402,
+                       "name": "Node-2-Delete Termination Point on Given Bridge",
+                       "description": "Delete termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`). ",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "a51f9d53-7917-7d2a-655c-d7f772045122",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834218789,
+                       "name": "Node-1-OVSDB Server Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "b0592ca5-7d6a-ebd4-6f98-c431d1c11ce7",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834257622,
+                       "name": "Node-1-OVSDB Bridge Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for specific bridge (`brtest`) present on given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "b4f9dbc2-ab25-e45b-302f-cd058367d8a9",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834368804,
+                       "name": "Node-2-Create Termination Point on Given Bridge",
+                       "description": "This restconf request creates port/interface (`testport`) and attach it to give bridge (`HYPERVISOR-NODE-ID`). Using ovsdb:option, you can pass the optional input to port/interface create optional. E.g. remote_ip=xx.xx.xx.xx.\n\n    Note: Please change the attributes of the interface if you don't want to create this default termination point.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n  \t\t\t\"ovsdb:options\": [\n    \t\t\t{\n                  \"ovsdb:option\": \"remote_ip\",\n                  \"ovsdb:value\" : \"10.10.14.11\"\n\t\t    \t}\n\t  \t\t],\n\t  \t\t\"ovsdb:name\": \"testport\",\n          \t\"ovsdb:interface-type\": \"ovsdb:interface-type-vxlan\",\n  \t\t\t\"tp-id\": \"testport\",\n            \"vlan-tag\": \"1\",\n            \"trunks\": [\n                {\n                    \"trunk\": \"5\"\n                }\n            ],\n            \"vlan-mode\":\"access\"\n\t\t}\n    ]\n}"
+               },
+               {
+                       "id": "b592f176-36a7-6830-f3a9-0547f18bcd2d",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834432527,
+                       "name": "Node-3-Create OVS   Bridge on Hypervisor",
+                       "description": "This restconf request creates bridge (`brtest`) on the specified hypervisor running ovsdb server. Restconf URI need the node-id of the OVSDB server (hypervisor) where you need to get the bridge. You can find out the node id by using the \"GET Operational Topology\" request.\n\n       Note: these %2F ('/') in the url are not there by mistake, those are there intentionally because node-id can contain '/'.\n",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n          \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}/bridge/brtest\",\n             \"ovsdb:bridge-name\": \"brtest\",\n             \"ovsdb:datapath-id\": \"00:00:b2:bf:48:25:f2:4b\",\n             \"ovsdb:protocol-entry\": [\n                {\n                  \"protocol\": \"ovsdb:ovsdb-bridge-protocol-openflow-13\"\n                }\n              ],\n              \"ovsdb:controller-entry\": [\n                {\n                  \"target\": \"tcp:11.11.11.11:6633\"\n                }\n              ],\n             \"ovsdb:managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb://{{HYPERVISOR-NODE-ID}}']\"\n        }\n    ]\n}"
+               },
+               {
+                       "id": "b9748414-6b9d-4fcc-2f43-b6be86a4e4be",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834331946,
+                       "name": "Node-2-Disconnect from OVSDB Server",
+                       "description": "This restconf request ask controller to disconnect from the OVSDB server/hypervisor (`HYPERVISOR-NODE-ID`).\n",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "bd270450-ee6a-6ebb-f7f1-8e0461ee4f56",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834357784,
+                       "name": "Node-2-Termination Point Configuration Data",
+                       "description": "This restconf request fetch data from `Configuration` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "be720a0e-5a69-91e2-93fb-5ffc4efe7f8c",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834199359,
+                       "name": "Node-1-OVSDB Configuration Topology",
+                       "description": "This restconf request fetch the topology details from `Configuration` data store that is pushed by user..",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "c01d85a0-5f9a-54ef-f2ff-3aefef8c465e",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834442134,
+                       "name": "Node-3-Termination Point Configuration Data",
+                       "description": "This restconf request fetch data from `Configuration` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "c24aebbf-bb85-3201-f605-21e7fef17ae1",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834353913,
+                       "name": "Node-2-Delete OVS Bridge on Hypervisor",
+                       "description": "This restconf request deletes OVS bridge (`brtest`) on the hypervisor with the node-id provided through `HYPERVISOR-NODE-ID` environment variable set in the `Single Node Cluster Setup Environment` file.",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "c60b33eb-c776-06fc-1f28-551c429ad196",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834337153,
+                       "name": "Node-2-OVSDB Bridge Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for specific bridge (`brtest`) present on the given ovsdb server/hypervisor(`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "c9430389-323d-452f-a204-c8c0ef12dcf6",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834415258,
+                       "name": "Node-3-Disconnect from OVSDB Server",
+                       "description": "This restconf request ask controller to disconnect from the OVSDB server/hypervisor (`HYPERVISOR-NODE-ID`).\n",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "cef78015-fff6-62f0-698b-76f26505e6df",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834262569,
+                       "name": "Node-1-Create OVS   Bridge on Hypervisor",
+                       "description": "This restconf request creates bridge (`brtest`) on the specified hypervisor running ovsdb server. Restconf URI need the node-id of the OVSDB server (hypervisor) where you need to get the bridge. You can find out the node id by using the \"GET Operational Topology\" request.\n\n       Note: these %2F ('/') in the url are not there by mistake, those are there intentionally because node-id can contain '/'.\n",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n          \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}/bridge/brtest\",\n             \"ovsdb:bridge-name\": \"brtest\",\n             \"ovsdb:datapath-id\": \"00:00:b2:bf:48:25:f2:4b\",\n             \"ovsdb:protocol-entry\": [\n                {\n                  \"protocol\": \"ovsdb:ovsdb-bridge-protocol-openflow-13\"\n                }\n              ],\n              \"ovsdb:controller-entry\": [\n                {\n                  \"target\": \"tcp:11.11.11.11:6633\"\n                }\n              ],\n             \"ovsdb:managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb://{{HYPERVISOR-NODE-ID}}']\"\n        }\n    ]\n}"
+               },
+               {
+                       "id": "d7e5948a-cab1-a6eb-32bd-a9220691a6d6",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-1-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834244138,
+                       "name": "Node-1-Disconnect from OVSDB Server",
+                       "description": "This restconf request ask controller to disconnect from the OVSDB server/hypervisor (`HYPERVISOR-NODE-ID`).\n",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "d9b65865-d54b-408b-f868-3e71fee53593",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834342352,
+                       "name": "Node-2-OVSDB Bridge Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for specific bridge (`brtest`) present on given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "dcafada2-2452-3701-f26c-c189e18f3ab0",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834405872,
+                       "name": "Node-3-OVSDB Server Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               },
+               {
+                       "id": "f42c21e0-116d-5428-1dfb-9b01e8ad72fa",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{NODE-2-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834350002,
+                       "name": "Node-2-Create OVS   Bridge on Hypervisor",
+                       "description": "This restconf request creates bridge (`brtest`) on the specified hypervisor running ovsdb server. Restconf URI need the node-id of the OVSDB server (hypervisor) where you need to get the bridge. You can find out the node id by using the \"GET Operational Topology\" request.\n\n       Note: these %2F ('/') in the url are not there by mistake, those are there intentionally because node-id can contain '/'.\n",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n          \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}/bridge/brtest\",\n             \"ovsdb:bridge-name\": \"brtest\",\n             \"ovsdb:datapath-id\": \"00:00:b2:bf:48:25:f2:4b\",\n             \"ovsdb:protocol-entry\": [\n                {\n                  \"protocol\": \"ovsdb:ovsdb-bridge-protocol-openflow-13\"\n                }\n              ],\n              \"ovsdb:controller-entry\": [\n                {\n                  \"target\": \"tcp:11.11.11.11:6633\"\n                }\n              ],\n             \"ovsdb:managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb://{{HYPERVISOR-NODE-ID}}']\"\n        }\n    ]\n}"
+               },
+               {
+                       "id": "ff01de93-1b51-200a-87d0-443091fdfb78",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{NODE-3-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443834446829,
+                       "name": "Node-3-Termination Point Operational Data",
+                       "description": "This restconf request fetch data from `Operational` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "4cd83ae0-a164-c12a-a872-c2205817594a"
+               }
+       ]
+}
\ No newline at end of file
diff --git a/resources/commons/Ovsdb-Southbound-Collection-for-Single-Node-Cluster.json.postman_collection b/resources/commons/Ovsdb-Southbound-Collection-for-Single-Node-Cluster.json.postman_collection
new file mode 100644 (file)
index 0000000..84e1976
--- /dev/null
@@ -0,0 +1,285 @@
+{
+       "id": "2de57d6a-ec2c-a568-c3a9-761f712622d3",
+       "name": "Ovsdb Southbound Collection for Single Node Cluster",
+       "description": "All the rest conf request present in this collection depends on the \"Single Node Cluster Setup Environment\" file.\nYou need to import this file, using the \"Manager Environment\" option present in the right top cornor of the postman window.",
+       "order": [
+               "dc447867-22db-fd3a-b482-6186bd3d190a",
+               "b09f9ed0-4df7-35d3-e81d-b9447313d722",
+               "8b2d3563-28d4-91c8-5f2b-ce959c348f2d",
+               "933a4c6d-cd57-1a68-012e-1d08a9c34bc6",
+               "31a9b08f-051b-c42d-9abd-612e8056c3b0",
+               "655ce1b6-dc16-d38c-6ab4-4b8b9515e1ce",
+               "2cc24c37-d5f2-2ef3-d946-8cfe44eabf56",
+               "22815a0a-75ca-f191-92b5-ca3b2fb67bd7",
+               "88edd164-76a3-c5a5-2b89-613ec89e82a4",
+               "58ee801a-3fa3-0d48-7672-14a390a0ea6d",
+               "b25cd26b-dd0b-369d-a246-ed1a29d0189b",
+               "8fb3e047-f00a-1dff-df9c-c548b2749c1e",
+               "001b745f-fad9-3f41-38f1-6ef5baf011a6",
+               "c7cb64ce-db7b-0c95-6268-bc265766a597"
+       ],
+       "folders": [],
+       "timestamp": 0,
+       "owner": "128022",
+       "remoteLink": "",
+       "public": false,
+       "requests": [
+               {
+                       "id": "001b745f-fad9-3f41-38f1-6ef5baf011a6",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443830363372,
+                       "name": "Create Termination Point on Given Bridge",
+                       "description": "This restconf request creates port/interface (`testport`) and attach it to give bridge (`HYPERVISOR-NODE-ID`). Using ovsdb:option, you can pass the optional input to port/interface create optional. E.g. remote_ip=xx.xx.xx.xx.\n\n    Note: Please change the attributes of the interface if you don't want to create this default termination point.",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3",
+                       "rawModeData": "{\n  \"network-topology:termination-point\": [\n    \t{\n  \t\t\t\"ovsdb:options\": [\n    \t\t\t{\n                  \"ovsdb:option\": \"remote_ip\",\n                  \"ovsdb:value\" : \"10.10.14.11\"\n\t\t    \t}\n\t  \t\t],\n\t  \t\t\"ovsdb:name\": \"testport\",\n          \t\"ovsdb:interface-type\": \"ovsdb:interface-type-vxlan\",\n  \t\t\t\"tp-id\": \"testport\",\n            \"vlan-tag\": \"1\",\n            \"trunks\": [\n                {\n                    \"trunk\": \"5\"\n                }\n            ],\n            \"vlan-mode\":\"access\"\n\t\t}\n    ]\n}"
+               },
+               {
+                       "id": "22815a0a-75ca-f191-92b5-ca3b2fb67bd7",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443831851013,
+                       "name": "OVSDB Bridge Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for specific bridge (`brtest`) present on given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "2cc24c37-d5f2-2ef3-d946-8cfe44eabf56",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443828713776,
+                       "name": "OVSDB Bridge Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for specific bridge (`brtest`) present on the given ovsdb server/hypervisor(`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "31a9b08f-051b-c42d-9abd-612e8056c3b0",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443827769663,
+                       "name": "Connect to the OVSDB Server",
+                       "description": "This Restconf request will ask controller to initiate the connection to ovsdb server running on hypervisor. Controller assumes that ovsdb server is listening for tcp connection in passive mode. To configure the ovsdb server to listen in passive mode, please fire following command on hypervisor\n\n`ovs-vsctl set-manager ptcp:16640`\n\nwhatever port number you use here, you should use the same port number for HYPERVISOR-OVSDB-PORT key in \"Single Node Cluster Setup Environment\" Environmen file.\n\n        Note: Please set the environment variable `HYPERVISOR-IP` to the hypervisor ip that is running OVSDB server and `HYPERVISOR-OVSDB-PORT` to the port number on which OVSDB server is listening. Both of these environment variables are present in the \"Single Node Cluster Setup Enviornment\" file. ",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n            \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}\",\n            \"connection-info\": {\n              \"ovsdb:remote-port\": \"{{HYPERVISOR-OVSDB-PORT}}\",\n              \"ovsdb:remote-ip\": \"{{HYPERVISOR-IP}}\"\n            }\n        }\n    ]\n}"
+               },
+               {
+                       "id": "58ee801a-3fa3-0d48-7672-14a390a0ea6d",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443828628211,
+                       "name": "Delete OVS Bridge on Hypervisor",
+                       "description": "This restconf request deletes OVS bridge (`brtest`) on the hypervisor with the node-id provided through `HYPERVISOR-NODE-ID` environment variable set in the `Single Node Cluster Setup Environment` file.",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "655ce1b6-dc16-d38c-6ab4-4b8b9515e1ce",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443830167496,
+                       "name": "Disconnect from OVSDB Server",
+                       "description": "This restconf request ask controller to disconnect from the OVSDB server/hypervisor (`HYPERVISOR-NODE-ID`).\n",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "88edd164-76a3-c5a5-2b89-613ec89e82a4",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "PUT",
+                       "data": [],
+                       "dataMode": "raw",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443827829511,
+                       "name": "Create OVS   Bridge on Hypervisor",
+                       "description": "This restconf request creates bridge (`brtest`) on the specified hypervisor running ovsdb server. Restconf URI need the node-id of the OVSDB server (hypervisor) where you need to get the bridge. You can find out the node id by using the \"GET Operational Topology\" request.\n\n       Note: these %2F ('/') in the url are not there by mistake, those are there intentionally because node-id can contain '/'.\n",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3",
+                       "rawModeData": "{\n  \"network-topology:node\": [\n        {\n          \"node-id\": \"ovsdb://{{HYPERVISOR-NODE-ID}}/bridge/brtest\",\n             \"ovsdb:bridge-name\": \"brtest\",\n             \"ovsdb:datapath-id\": \"00:00:b2:bf:48:25:f2:4b\",\n             \"ovsdb:protocol-entry\": [\n                {\n                  \"protocol\": \"ovsdb:ovsdb-bridge-protocol-openflow-13\"\n                }\n              ],\n              \"ovsdb:controller-entry\": [\n                {\n                  \"target\": \"tcp:11.11.11.11:6633\"\n                }\n              ],\n             \"ovsdb:managed-by\": \"/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb://{{HYPERVISOR-NODE-ID}}']\"\n        }\n    ]\n}"
+               },
+               {
+                       "id": "8b2d3563-28d4-91c8-5f2b-ce959c348f2d",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443829913657,
+                       "name": "OVSDB Server Configuration Data",
+                       "description": "This restconf request fetch the data from `Configuration` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "8fb3e047-f00a-1dff-df9c-c548b2749c1e",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443831912311,
+                       "name": "Termination Point Operational Data",
+                       "description": "This restconf request fetch data from `Operational` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "933a4c6d-cd57-1a68-012e-1d08a9c34bc6",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443831731294,
+                       "name": "OVSDB Server Operational Data",
+                       "description": "This restconf request fetch the data from `Operational` data store for given ovsdb server/hypervisor (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "folder": null,
+                       "id": "b09f9ed0-4df7-35d3-e81d-b9447313d722",
+                       "name": "OVSDB Operational Topology",
+                       "dataMode": "params",
+                       "data": [],
+                       "rawModeData": "  {\n    \"network-topology:node\": [\n          {\n              \"node-id\": \"ovsdb:node3\",\n              \"connection-info\": {\n                \"ovsdb:remote-port\": 16640,\n                \"ovsdb:remote-ip\": \"192.168.201.129\"\n              }\n          }\n      ]\n  }",
+                       "descriptionFormat": null,
+                       "description": "This restconf request fetches the topology details from the `Operational` data store that contains details about all the connected hypervisor, bridges present on the hypervisor and termination point connected to each bridge.",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "method": "GET",
+                       "pathVariables": {},
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/",
+                       "preRequestScript": "",
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "b25cd26b-dd0b-369d-a246-ed1a29d0189b",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "GET",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443831899373,
+                       "name": "Termination Point Configuration Data",
+                       "description": "This restconf request fetch data from `Configuration` data store for specific termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`).",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "id": "c7cb64ce-db7b-0c95-6268-bc265766a597",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\n",
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:%2F%2F{{HYPERVISOR-NODE-ID}}%2Fbridge%2Fbrtest/termination-point/testport/",
+                       "preRequestScript": "",
+                       "pathVariables": {},
+                       "method": "DELETE",
+                       "data": [],
+                       "dataMode": "params",
+                       "version": 2,
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "time": 1443831952250,
+                       "name": "Delete Termination Point on Given Bridge",
+                       "description": "Delete termination point (`testport`) present on the given bridge (`HYPERVISOR-NODE-ID`). ",
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               },
+               {
+                       "folder": null,
+                       "id": "dc447867-22db-fd3a-b482-6186bd3d190a",
+                       "name": "OVSDB Configuration Topology",
+                       "dataMode": "params",
+                       "data": [],
+                       "rawModeData": null,
+                       "descriptionFormat": null,
+                       "description": "This restconf request fetch the topology details from `Configuration` data store that is pushed by user..",
+                       "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\nAccept: application/json\n",
+                       "method": "GET",
+                       "pathVariables": {},
+                       "url": "http://{{CONTROLLER-IP}}:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1",
+                       "preRequestScript": "",
+                       "tests": "",
+                       "currentHelper": "normal",
+                       "helperAttributes": {},
+                       "collectionId": "2de57d6a-ec2c-a568-c3a9-761f712622d3"
+               }
+       ]
+}
\ No newline at end of file
index 0e34991087dd6a6e1b9aa644f1b300a78f2f609d..0cad7271a01ba6b95242b5232038e55125f7d4bb 100644 (file)
@@ -5,14 +5,28 @@ administrators working on ovsdb project in general.
 Contents
 --------
 
-1. localhost.json.postman_environment : Environment that associates address and port to localhost:8080 in templates for the collections below.
+- localhost.json.postman_environment : Environment that associates address and port to localhost:8080 in templates for the collections below.
 
-2. Mininet_Demo_OVSDB_OF.json.postman_collection : Collection of REST-APIs used in the Mininet demo (http://www.youtube.com/watch?v=8iWhMVlflwE)
+- Mininet_Demo_OVSDB_OF.json.postman_collection : Collection of REST-APIs used in the Mininet demo (http://www.youtube.com/watch?v=8iWhMVlflwE)
 
-3. OVSDB_Northbound_APIs.json.postman_collection : Collection of REST-APIs detailing on all the ovsdb.northbound APIs.
+- Neutron-v2.0-LBaaS-API-Examples_July15.json.postman_collection.txt : Collection of REST-APIs to interact with LBaas pool/pool member/loadbalancer.
 
-4. OVSDB_Southbound.postman_collection : Collection of RESTCONF APIs for using the OVSDB MD-SAL Southbound
+- showOvsdbMdsal.py : Dumps mdsal related info from running ODL that is related to ovsdb and netvirt. Use 'showOvsdbMdsal.py -h' for usage
 
-5. Neutron-v2.0-LBaaS-API-Examples_July15.json.postman_collection.txt : Collection of REST-APIs to interact with LBaas pool/pool member/loadbalancer.
+- 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.
 
-6. showOvsdbMdsal.py : Dumps mdsal related info from running ODL that is related to ovsdb and netvirt. Use 'showOvsdbMdsal.py -h' for usage
+- 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.
+
+- 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
+
+- 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.
diff --git a/resources/commons/Single-Node-Cluster-Setup-Environment-Variables.postman_environment b/resources/commons/Single-Node-Cluster-Setup-Environment-Variables.postman_environment
new file mode 100644 (file)
index 0000000..dd83040
--- /dev/null
@@ -0,0 +1,37 @@
+{
+       "id": "76b6f656-7d9c-e4cd-80a4-5d6a42f07cd3",
+       "name": "Single Node Cluster Setup Environment Variables",
+       "values": [
+               {
+                       "key": "CONTROLLER-IP",
+                       "value": "localhost",
+                       "type": "text",
+                       "name": "CONTROLLER-IP",
+                       "enabled": true
+               },
+               {
+                       "key": "HYPERVISOR-NODE-ID",
+                       "value": "192.168.201.128:16640",
+                       "type": "text",
+                       "name": "HYPERVISOR-NODE-ID",
+                       "enabled": true
+               },
+               {
+                       "key": "HYPERVISOR-IP",
+                       "value": "192.168.201.128",
+                       "type": "text",
+                       "name": "HYPERVISOR-IP",
+                       "enabled": true
+               },
+               {
+                       "key": "HYPERVISOR-OVSDB-PORT",
+                       "value": "16640",
+                       "type": "text",
+                       "name": "HYPERVISOR-OVSDB-PORT",
+                       "enabled": true
+               }
+       ],
+       "timestamp": 1443832146164,
+       "synced": false,
+       "syncedFilename": ""
+}
\ No newline at end of file
diff --git a/resources/demo/netvirtsfc-env/README.md b/resources/demo/netvirtsfc-env/README.md
new file mode 100755 (executable)
index 0000000..e993674
--- /dev/null
@@ -0,0 +1,147 @@
+#SETUP
+
+This is a demonstration / development environment for show-casing OpenDaylight OVSDB NETVIRT with ServiceFunctionChaining (SFC)
+
+git clone https://github.com/flavio-fernandes/netvirtsfc-env.git
+
+This demo setup can also be found under the the ovsdb repo of the Opendaylight project:
+
+```
+https://github.com/opendaylight/ovsdb/tree/master/resources/demo/netvirtsfc-env
+```
+
+This demo is analogous to the demo done by the group-based-policy project of Opendaylight. In fact, the kudos
+for initially putting it together goes to our friends Keith, Thomas, and others responsible for GBP:
+
+```
+https://github.com/alagalah/gbpsfc-env
+```
+
+The initial installation may take some time, with vagrant and docker image downloads. 
+
+After the first time it is very quick.
+
+1. Set up Vagrant. 
+  * Edit env.sh for NUM_NODES. (Keep all other vars the same for this version)
+    Also set 'ODL_ROOT_DIR' to point to the directory ./openstack/net-virt-sfc/karaf/target/assembly
+
+    That directory will be available when you build the ovsdb project, or where the karaf distro
+    got unzipped.
+
+  * Each VM takes approximately 1G RAM, 2GB used HDD (40GB)
+
+  * demo-asymmetric-chain: 6 VMs.
+
+2. From the 'netvirtsfc-env' directory do:
+```
+source ./env.sh
+vagrant up
+```
+  * This takes quite some time initially. 
+
+3. Start controller.
+  * Currently it is expected that that controller runs on the machine hosting the vagrant VMs.
+  * Tested using ovsdb netvirt beryllium.
+
+  * Set config for your setup:
+
+    Use the script 'setsfc.sh' to make the changes below. You only need to do it once after build.
+
+    * Modify the NetvirtSfc config.xml to start in standalone mode. (i.e. set of13provider to standalone)
+    * Modify the logging levels to help with troubleshooting
+    * Start ODL with the following feature loaded:  odl-ovsdb-sfc-ui
+
+  * Start controller by running bin/karaf and make sure the following features are installed
+```
+    cd $ODL_ROOT_DIR ; ./bin/karaf
+```
+
+```
+    opendaylight-user@root>feature:list -i | grep ovsdb-sfc
+    odl-ovsdb-sfc-test                   | 1.2.1-SNAPSHOT   | x         | odl-ovsdb-sfc-test1.2.1-SNAPSHOT        | OpenDaylight :: ovsdb-sfc-test
+    odl-ovsdb-sfc-api                    | 1.2.1-SNAPSHOT   | x         | odl-ovsdb-sfc-1.2.1-SNAPSHOT            | OpenDaylight :: ovsdb-sfc :: api
+    odl-ovsdb-sfc                        | 1.2.1-SNAPSHOT   | x         | odl-ovsdb-sfc-1.2.1-SNAPSHOT            | OpenDaylight :: ovsdb-sfc
+    odl-ovsdb-sfc-rest                   | 1.2.1-SNAPSHOT   | x         | odl-ovsdb-sfc-1.2.1-SNAPSHOT            | OpenDaylight :: ovsdb-sfc :: REST
+    odl-ovsdb-sfc-ui                     | 1.2.1-SNAPSHOT   | x         | odl-ovsdb-sfc-1.2.1-SNAPSHOT            | OpenDaylight :: ovsdb-sfc :: UI
+```
+
+    Note that if you missed running 'setsfc.sh' ODL will operate in non-standalone mode, which is going
+    to make ovsdb netvirt work with openstack/tacker environments.
+
+  * Run `log:tail | grep SfcL2Renderer` and wait until the following message appears in the log:
+```
+ successfully started the SfcL2Renderer plugin
+```
+  * Now you can ^C the log:tail if you wish
+
+##demo-asymmetric-chain
+
+  * Service Chain classifying HTTP traffic.
+  * Traffic in the forward direction is chained and in the reverse direction the traffic uses the normal VxLAN tunnel
+  * 2 docker containers in the same tenant space
+
+![asymmetric-chain demo diag](https://raw.githubusercontent.com/flavio-fernandes/netvirtsfc-env/master/images/asymmetric-sfc-demo.png)
+
+VMs:
+* netvirtsfc1: netvirt (client initiates transactions from here)
+* netvirtsfc2: sff
+* netvirtsfc3: "sf"
+* netvirtsfc4: sff
+* netvirtsfc5: "sf"
+* netvirtsfc6: netvirt (run a server here)
+
+Containers:
+* h35_2 is on netvirtsfc1. This host serves as the client.
+* h35_4 is netvirtsfc6. This host serves as the webserver.
+
+To run, from host folder where Vagrantfile located do:
+
+`./startdemo.sh demo-asymmetric-chain`
+
+### To test by sending traffic:
+Start a test HTTP server on h35_4 in VM 6.
+
+*(don't) forget double ENTER after `docker attach`*
+```bash
+vagrant ssh netvirtsfc6
+docker ps
+docker attach h35_4
+python -m SimpleHTTPServer 80
+```
+
+Ctrl-P-Q to detach from docker without stopping the SimpleHTTPServer, and logoff netvirtsfc6.
+
+Now start client traffic, either ping or make HTTP requests to the server on h36_4.
+
+```bash
+vagrant ssh netvirtsfc1
+docker ps
+docker attach h35_2
+ping 10.0.35.4
+curl 10.0.35.4
+while true; do curl 10.0.35.4; sleep 1; done
+```
+
+Ctrl-P-Q to detach from docker, leaving the client making HTTP requests, and logoff netvirtsfc1.
+
+Look around: use "vagrant ssh" to the various machines. To run wireshark, ssh to the vms using the -XY flags:
+```
+vagrant ssh netvirtsfcX -- -XY   (e.g.: vagrant ssh netvirtsfc1 -- -XY)
+sudo wireshark &
+```
+
+ * take packet captures on eth1, as that is the interface used for communication between vms.
+ * sudo ovs-dpctl dump-flows
+
+
+### When finished from host folder where Vagrantfile located do:
+
+`./cleandemo.sh`
+
+If you like `vagrant destroy` will remove all VMs
+
+##Preparing to run another demo
+1. In the vagrant directory, run cleandemo.sh
+2. stop controller (logout of karaf)
+3. Remove data, journal and snapshot directories from controller directory.
+4. Restart tests starting with restarting the controller, install features, wait, as above.
diff --git a/resources/demo/netvirtsfc-env/Vagrantfile b/resources/demo/netvirtsfc-env/Vagrantfile
new file mode 100644 (file)
index 0000000..3811901
--- /dev/null
@@ -0,0 +1,34 @@
+
+# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
+VAGRANTFILE_API_VERSION = "2"
+
+Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
+  odl=ENV['ODL']
+  config.vm.provider "virtualbox" do |vb|
+    vb.memory = "512"
+  end
+
+  # run our bootstrapping for the system
+  config.vm.provision 'shell', path: 'bootstrap.sh', :args => odl
+
+  num_nodes = (ENV['NUM_NODES'] || 1).to_i
+
+  # ip configuration
+  ip_base = (ENV['SUBNET'] || "192.168.50.")
+  ips = num_nodes.times.collect { |n| ip_base + "#{n+70}" }
+
+  num_nodes.times do |n|
+    config.vm.define "netvirtsfc#{n+1}", autostart: true do |compute|
+      vm_ip = ips[n]
+      vm_index = n+1
+      compute.vm.box = "ubuntu/trusty64"
+      compute.vm.hostname = "netvirtsfc#{vm_index}"
+      compute.vm.network "private_network", ip: "#{vm_ip}"
+      compute.vm.provider :virtualbox do |vb|
+        vb.memory = 512
+        vb.customize ["modifyvm", :id, "--ioapic", "on"]      
+        vb.cpus = 1
+      end
+    end
+  end
+end
diff --git a/resources/demo/netvirtsfc-env/bootstrap.sh b/resources/demo/netvirtsfc-env/bootstrap.sh
new file mode 100644 (file)
index 0000000..a11d562
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# vim: sw=4 ts=4 sts=4 et tw=72 :
+
+echo "---> Updating operating system"
+apt update -qq
+
+echo "---> Installing OVSDB Netvirt requirements"
+apt install -y software-properties-common -qq
+apt install -y python-software-properties -qq
+apt install -y python-pip -qq
+apt install -y git-core git -qq
+apt install -y curl -qq
+
+echo "---> Installing wireshark"
+apt install -y xbase-clients -qq
+apt install -y wireshark -qq
+
+# docker
+curl -sSL https://get.docker.com/ | sh
+
+cat <<EOL > /etc/default/docker
+  DOCKER_NETWORK_OPTIONS='--bip=10.250.0.254/24'
+EOL
+
+docker pull alagalah/odlpoc_ovs230
+# OVS
+curl https://raw.githubusercontent.com/pritesh/ovs/nsh-v8/third-party/start-ovs-deb.sh | bash
+
+# this part is just for local spinup DON'T copy it to releng bootstrap.sh
+pip install ipaddr
+echo "export PATH=$PATH:/vagrant" >> /home/vagrant/.profile
+echo "export ODL=$1" >> /home/vagrant/.profile
+usermod -aG docker vagrant
diff --git a/resources/demo/netvirtsfc-env/checkdemo.sh b/resources/demo/netvirtsfc-env/checkdemo.sh
new file mode 100755 (executable)
index 0000000..0e08495
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+set -e
+
+
+echo "Checking demo from $demo with vars:"
+echo "Number of nodes: " $NUM_NODES
+echo "Opendaylight Controller: " $ODL
+echo "Base subnet: " $SUBNET
+
+for i in `seq 1 $NUM_NODES`; do
+  hostname="netvirtsfc"$i
+  echo $hostname "flow count: "
+  vagrant ssh $hostname -c "sudo ovs-ofctl dump-flows sw$i -OOpenFlow13 | wc -l "
+done
+
diff --git a/resources/demo/netvirtsfc-env/cleandemo.sh b/resources/demo/netvirtsfc-env/cleandemo.sh
new file mode 100755 (executable)
index 0000000..3c494a3
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -e
+
+for i in `seq 1 $NUM_NODES`; do
+  hostname="netvirtsfc"$i
+  switchname="sw"$i
+  echo $hostname
+  vagrant ssh $hostname -c "sudo ovs-vsctl del-br $switchname; sudo ovs-vsctl del-manager; sudo /vagrant/vmclean.sh"
+
+done
+./rest-clean.py
+
+if [ -f "demo.lock" ] ; then
+  rm demo.lock
+fi
diff --git a/resources/demo/netvirtsfc-env/cleanodl.sh b/resources/demo/netvirtsfc-env/cleanodl.sh
new file mode 100755 (executable)
index 0000000..95a9f0f
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+rm -rf ${ODL_ROOT_DIR}/{data,journal,snapshots}/*
diff --git a/resources/demo/netvirtsfc-env/demo-asymmetric-chain/rest.py b/resources/demo/netvirtsfc-env/demo-asymmetric-chain/rest.py
new file mode 100755 (executable)
index 0000000..c3355e6
--- /dev/null
@@ -0,0 +1,346 @@
+#!/usr/bin/python
+import argparse
+import requests,json
+from requests.auth import HTTPBasicAuth
+from subprocess import call
+import time
+import sys
+import os
+
+
+DEFAULT_PORT='8181'
+
+
+USERNAME='admin'
+PASSWORD='admin'
+
+
+OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
+CONF_TENANT='/restconf/config/policy:tenants'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    #print url
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    jsondata=json.loads(r.text)
+    return jsondata
+
+def put(host, port, uri, data, debug=False):
+    '''Perform a PUT rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "PUT %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def post(host, port, uri, data, debug=False):
+    '''Perform a POST rest operation, using the URL and data provided'''
+
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "POST %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def get_service_functions_uri():
+    return "/restconf/config/service-function:service-functions"
+
+def get_service_functions_data():
+    return {
+    "service-functions": {
+        "service-function": [
+            {
+                "name": "firewall-72",
+                "ip-mgmt-address": "192.168.50.72",
+                "type": "service-function-type:firewall",
+                "nsh-aware": "true",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "sf1Dpl",
+                        "port": 6633,
+                        "ip": "192.168.50.72",
+                        "transport": "service-locator:vxlan-gpe",
+                        "service-function-forwarder": "SFF1"
+                    }
+                ]
+            },
+            {
+                "name": "dpi-74",
+                "ip-mgmt-address": "192.168.50.74",
+                "type": "service-function-type:dpi",
+                "nsh-aware": "true",
+                "sf-data-plane-locator": [
+                    {
+                        "name": "sf2Dpl",
+                        "port": 6633,
+                        "ip": "192.168.50.74",
+                        "transport": "service-locator:vxlan-gpe",
+                        "service-function-forwarder": "SFF2"
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_forwarders_uri():
+    return "/restconf/config/service-function-forwarder:service-function-forwarders"
+
+def get_service_function_forwarders_data():
+    return {
+    "service-function-forwarders": {
+        "service-function-forwarder": [
+            {
+                "name": "SFF1",
+                "service-node": "OVSDB2",
+                "service-function-forwarder-ovs:ovs-bridge": {
+                    "bridge-name": "sw2"
+                },
+                "service-function-dictionary": [
+                    {
+                        "name": "firewall-72",
+                        "sff-sf-data-plane-locator": {
+                            "sff-dpl-name": "sfc-tun2",
+                            "sf-dpl-name": "sf1Dpl"
+                        }
+                    }
+                ],
+                "sff-data-plane-locator": [
+                    {
+                        "name": "sfc-tun2",
+                        "data-plane-locator": {
+                            "transport": "service-locator:vxlan-gpe",
+                            "port": 6633,
+                            "ip": "192.168.50.71"
+                        },
+                        "service-function-forwarder-ovs:ovs-options": {
+                            "remote-ip": "flow",
+                            "dst-port": "6633",
+                            "key": "flow",
+                            "nsp": "flow",
+                            "nsi": "flow",
+                            "nshc1": "flow",
+                            "nshc2": "flow",
+                            "nshc3": "flow",
+                            "nshc4": "flow"
+                        }
+                    }
+                ]
+            },
+            {
+                "name": "SFF2",
+                "service-node": "OVSDB2",
+                "service-function-forwarder-ovs:ovs-bridge": {
+                    "bridge-name": "sw4"
+                },
+                "service-function-dictionary": [
+                    {
+                        "name": "dpi-74",
+                        "sff-sf-data-plane-locator": {
+                            "sff-dpl-name": "sfc-tun4",
+                            "sf-dpl-name": "sf2Dpl"
+                        }
+                    }
+                ],
+                "sff-data-plane-locator": [
+                    {
+                        "name": "sfc-tun4",
+                        "data-plane-locator": {
+                            "transport": "service-locator:vxlan-gpe",
+                            "port": 6633,
+                            "ip": "192.168.50.73"
+                        },
+                        "service-function-forwarder-ovs:ovs-options": {
+                            "remote-ip": "flow",
+                            "dst-port": "6633",
+                            "key": "flow",
+                            "nsp": "flow",
+                            "nsi": "flow",
+                            "nshc1": "flow",
+                            "nshc2": "flow",
+                            "nshc3": "flow",
+                            "nshc4": "flow"
+                        }
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_chains_uri():
+    return "/restconf/config/service-function-chain:service-function-chains/"
+
+def get_service_function_chains_data():
+    return {
+    "service-function-chains": {
+        "service-function-chain": [
+            {
+                "name": "SFCNETVIRT",
+                "symmetric": "false",
+                "sfc-service-function": [
+                    {
+                        "name": "firewall-abstract1",
+                        "type": "service-function-type:firewall"
+                    },
+                    {
+                        "name": "dpi-abstract1",
+                        "type": "service-function-type:dpi"
+                    }
+                ]
+            }
+        ]
+    }
+}
+
+def get_service_function_paths_uri():
+    return "/restconf/config/service-function-path:service-function-paths/"
+
+def get_service_function_paths_data():
+    return {
+    "service-function-paths": {
+        "service-function-path": [
+            {
+                "name": "SFCNETVIRT-Path",
+                "service-chain-name": "SFCNETVIRT",
+                "starting-index": 255,
+                "symmetric": "false"
+
+            }
+        ]
+    }
+}
+
+def get_ietf_acl_uri():
+    return "/restconf/config/ietf-access-control-list:access-lists"
+
+def get_ietf_acl_data():
+    return {
+        "access-lists": {
+            "acl": [
+                {
+                    "acl-name": "http-acl",
+                    "access-list-entries": {
+                        "ace": [
+                            {
+                                "rule-name": "http-rule",
+                                "matches": {
+                                    "protocol": "6",
+                                    "destination-port-range": {
+                                        "lower-port": "80",
+                                        "upper-port": "80"
+                                    },
+                                },
+                                "actions": {
+                                    "netvirt-sfc-acl:sfc-name": "SFCNETVIRT"
+                                }
+                            }
+                        ]
+                    }
+                }
+            ]
+        }
+    }
+
+def get_classifier_uri():
+    return "/restconf/config/netvirt-sfc-classifier:classifiers"
+
+def get_classifier_data():
+    return {
+        "classifiers": {
+            "classifier": [
+                {
+                    "name": "http-classifier",
+                    "acl": "http-acl",
+                    "sffs": {
+                        "sff": [
+                            {
+                                "name": "SFF1"
+                            }
+                        ]
+                    },
+                    "bridges": {
+                        "bridge": [
+                            {
+                                "name": "sw1",
+                                "direction": "ingress"
+                            },
+                            {
+                                "name": "sw6",
+                                "direction": "egress"
+                            }
+                        ]
+                    }
+                }
+            ]
+        }
+    }
+
+def get_netvirt_sfc_uri():
+    return "/restconf/config/netvirt-sfc:sfc/"
+
+def get_netvirt_sfc_data():
+    return {
+        "sfc": {
+            "name": "sfc1"
+        }
+    }
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+    else:
+       print "Contacting controller at %s" % controller
+
+    #tenants=get(controller,DEFAULT_PORT,CONF_TENANT)
+
+    print "sending service functions"
+    put(controller, DEFAULT_PORT, get_service_functions_uri(), get_service_functions_data(), True)
+    print "sending service function forwarders"
+    put(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), get_service_function_forwarders_data(), True)
+
+    print "sf's and sff's created"
+    time.sleep(5)
+    print "sending service function chains"
+    put(controller, DEFAULT_PORT, get_service_function_chains_uri(), get_service_function_chains_data(), True)
+    print "sending service function paths"
+    put(controller, DEFAULT_PORT, get_service_function_paths_uri(), get_service_function_paths_data(), True)
+
+    print "sfc's and sfp's created"
+    time.sleep(5)
+    print "sending netvirt-sfc"
+    put(controller, DEFAULT_PORT, get_netvirt_sfc_uri(), get_netvirt_sfc_data(), True)
+    time.sleep(1)
+    print "sending ietf-acl"
+    put(controller, DEFAULT_PORT, get_ietf_acl_uri(), get_ietf_acl_data(), True)
+    time.sleep(1)
+    print "sending classifier"
+    put(controller, DEFAULT_PORT, get_classifier_uri(), get_classifier_data(), True)
+
+
+    # print "sending tunnel -- SKIPPED"
+    ## put(controller, DEFAULT_PORT, get_tunnel_uri(), get_tunnel_data(), True)
+    # print "sending tenant -- SKIPPED"
+    ## put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
+    # print "registering endpoints -- SKIPPED"
+    ## for endpoint in get_endpoint_data():
+    ##    post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)
+
+
diff --git a/resources/demo/netvirtsfc-env/dpdumpflows.py b/resources/demo/netvirtsfc-env/dpdumpflows.py
new file mode 100755 (executable)
index 0000000..a920344
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+from subprocess import check_output
+
+
+def call_dpctl():
+       cmd="ovs-dpctl dump-flows"
+       listcmd=cmd.split()
+       return check_output(listcmd)
+
+if __name__ == "__main__" :
+       flows=call_dpctl().split("recirc_id")
+       for flow in flows:
+               print flow
+
+
+
diff --git a/resources/demo/netvirtsfc-env/dumpflows.sh b/resources/demo/netvirtsfc-env/dumpflows.sh
new file mode 100755 (executable)
index 0000000..fa27cc2
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -e
+hostnum=${HOSTNAME#"netvirtsfc"}
+sw="sw$hostnum"
+
+TABLE=$1
+
+clear
+ovs-ofctl dump-groups $sw -OOpenFlow13
+if [ "$TABLE" ]
+then
+        ovs-ofctl dump-flows $sw -OOpenFlow13 table=$TABLE
+else
+        ovs-ofctl dump-flows $sw -OOpenFlow13
+fi
+
diff --git a/resources/demo/netvirtsfc-env/env.sh b/resources/demo/netvirtsfc-env/env.sh
new file mode 100755 (executable)
index 0000000..dac82d8
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+export NUM_NODES=6
+export ODL="192.168.50.1"
+export SUBNET="192.168.50."
+
+#rootdir="/home/shague/git/ovsdb/openstack/net-virt-sfc/karaf/target/assembly"
+rootdir="/Users/ffernand/ODL/projects/ovsdb.git/openstack/net-virt-sfc/karaf/target/assembly"
+
+export ODL_ROOT_DIR=$rootdir
diff --git a/resources/demo/netvirtsfc-env/flowcount.sh b/resources/demo/netvirtsfc-env/flowcount.sh
new file mode 100755 (executable)
index 0000000..1b8ca93
--- /dev/null
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+hostnum=${HOSTNAME#"netvirtsfc"}
+sw="sw$hostnum"
+set -e
+if [ "$1" ]
+then
+    echo;echo "FLOWS:";ovs-ofctl dump-flows $sw -OOpenFlow13 table=$1 --rsort=priority
+    echo
+    printf "Flow count: "
+    echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=$1 | wc -l)-1))
+else
+    echo;echo "FLOWS:";ovs-ofctl dump-flows $sw -OOpenFlow13
+    printf "No table entered. $sw flow count: ";
+    echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 | wc -l)-1))
+    printf "\nTable0: base:  "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=0| wc -l)-1))
+    printf "\nTable50: sfc:   "; echo $(($(ovs-ofctl dump-flows $sw -OOpenFlow13 table=6| wc -l)-1))
+fi
+
diff --git a/resources/demo/netvirtsfc-env/images/asymmetric-sfc-demo.png b/resources/demo/netvirtsfc-env/images/asymmetric-sfc-demo.png
new file mode 100644 (file)
index 0000000..5ccf548
Binary files /dev/null and b/resources/demo/netvirtsfc-env/images/asymmetric-sfc-demo.png differ
diff --git a/resources/demo/netvirtsfc-env/infrastructure_launch.py b/resources/demo/netvirtsfc-env/infrastructure_launch.py
new file mode 100755 (executable)
index 0000000..81ab714
--- /dev/null
@@ -0,0 +1,167 @@
+#!/usr/bin/python
+
+import socket
+import os
+import re
+import time
+import sys
+import ipaddr
+import commands
+from subprocess import call
+from subprocess import check_output
+from infrastructure_config import *
+
+def addController(sw, ip):
+    call(['ovs-vsctl', 'set-controller', sw, 'tcp:%s:6653' % ip ])
+
+def addManager(ip):
+    cmd="ovs-vsctl set-manager tcp:%s:6640" % ip
+    listcmd=cmd.split()
+    print check_output(listcmd)
+
+def addSwitch(name, dpid=None):
+    call(['ovs-vsctl', 'add-br', name]) #Add bridge
+    if dpid:
+        if len(dpid) < 16: #DPID must be 16-bytes in later versions of OVS
+            filler='0000000000000000'
+            dpid=filler[:len(filler)-len(dpid)]+dpid
+        elif len(dpid) > 16:
+            print 'DPID: %s is too long' % dpid
+            sys.exit(3)
+        call(['ovs-vsctl','set','bridge', name,'other-config:datapath-id=%s'%dpid])
+
+def addHost(net, switch, name, ip, mac):
+    containerID=launchContainer()
+
+#,OpenFlow12,OpenFlow10
+def setOFVersion(sw, version='OpenFlow13'):
+    call(['ovs-vsctl', 'set', 'bridge', sw, 'protocols={}'.format(version)])
+
+def addTunnel(sw, port, sourceIp=None, remoteIp=None):
+    ifaceName = '{}-vxlan-0'.format(sw)
+    cmd = ['ovs-vsctl', 'add-port', sw, ifaceName,
+           '--', 'set', 'Interface', ifaceName,
+           'type=vxlan',
+           'options:local_ip=%s'%sourceIp,
+           'options:remote_ip=%s'%remoteIp,
+           'options:key=4096',
+           'ofport_request=%s'%port]
+#    if sourceIp is not None:
+#        cmd.append('options:source_ip={}'.format(sourceIp))
+    call(cmd)
+
+def addGpeTunnel(sw, sourceIp=None):
+    ifaceName = '{}-vxlangpe-0'.format(sw)
+    cmd = ['ovs-vsctl', 'add-port', sw, ifaceName,
+           '--', 'set', 'Interface', ifaceName,
+           'type=vxlan',
+           'options:remote_ip=flow',
+           'options:dst_port=6633',
+           'options:nshc1=flow',
+           'options:nshc2=flow',
+           'options:nshc3=flow',
+           'options:nshc4=flow',
+           'options:nsp=flow',
+           'options:nsi=flow',
+           'options:key=flow',
+           'ofport_request=7']
+#    if sourceIp is not None:
+#        cmd.append('options:source_ip={}'.format(sourceIp))
+    call(cmd)
+
+def launchContainer(host,containerImage):
+    containerID= check_output(['docker','run','-d','--net=none','--name=%s'%host['name'],'-h',host['name'],'-t', '-i','--privileged=True',containerImage,'/bin/bash']) #docker run -d --net=none --name={name} -h {name} -t -i {image} /bin/bash
+    #print "created container:", containerID[:-1]
+    return containerID[:-1] #Remove extraneous \n from output of above
+
+def connectContainerToSwitch(sw,host,containerID,of_port):
+    hostIP=host['ip']
+    mac=host['mac']
+    nw = ipaddr.IPv4Network(hostIP)
+    broadcast = "{}".format(nw.broadcast)
+    router = "{}".format(nw.network + 1)
+    cmd=['/vagrant/ovswork.sh',sw,containerID,hostIP,broadcast,router,mac,of_port,host['name']]
+    if host.has_key('vlan'):
+        cmd.append(host['vlan'])
+    call(cmd)
+
+def doCmd(cmd):
+    listcmd=cmd.split()
+    print check_output(listcmd)
+
+def launch(switches, hosts, contIP='127.0.0.1'):
+
+    for sw in switches:
+        addManager(contIP)
+        ports=0
+        first_host=True
+        for host in hosts:
+            if host['switch'] == sw['name']:
+                if first_host:
+                    dpid=sw['dpid']
+                    addSwitch(sw['name'],sw['dpid'])
+                    setOFVersion(sw['name'])
+                    addController(sw['name'], contIP)
+                    addGpeTunnel(sw['name'])
+                    if host['switch'] == "sw1":
+                        addTunnel(sw['name'], 5, "192.168.50.70", "192.168.50.75")
+                    if host['switch'] == "sw6":
+                        addTunnel(sw['name'], 5, "192.168.50.75", "192.168.50.70")
+                first_host=False
+                containerImage=defaultContainerImage #from Config
+                if host.has_key('container_image'): #from Config
+                    containerImage=host['container_image']
+                containerID=launchContainer(host,containerImage)
+                ports+=1
+                connectContainerToSwitch(sw['name'],host,containerID,str(ports))
+                host['port-name']='vethl-'+host['name']
+                print "Created container: %s with IP: %s. Connect using 'docker attach %s', disconnect with ctrl-p-q." % (host['name'],host['ip'],host['name'])
+
+if __name__ == "__main__" :
+#    print "Cleaning environment..."
+#    doCmd('/vagrant/clean.sh')
+    sw_index=int(socket.gethostname().split("netvirtsfc",1)[1])-1
+    if sw_index in range(0,len(switches)+1):
+
+       controller=os.environ.get('ODL')
+       sw_type = switches[sw_index]['type']
+       sw_name = switches[sw_index]['name']
+       if sw_type == 'netvirt':
+           print "*****************************"
+           print "Configuring %s as a NETVIRT node." % sw_name
+           print "*****************************"
+           print
+           launch([switches[sw_index]],hosts,controller)
+           print "*****************************"
+           doCmd('sudo /vagrant/utils/overlay-flows.sh')
+           print "*****************************"
+           print "OVS status:"
+           print "-----------"
+           print
+           doCmd('ovs-vsctl show')
+           doCmd('ovs-ofctl -O OpenFlow13 dump-flows %s'%sw_name)
+           print
+           print "Docker containers:"
+           print "------------------"
+           doCmd('docker ps')
+           print "*****************************"
+       elif sw_type == 'sff':
+           print "*****************************"
+           print "Configuring %s as an SFF." % sw_name
+           print "*****************************"
+           doCmd('sudo ovs-vsctl set-manager tcp:%s:6640' % controller)
+           time.sleep(1)
+           dpid=switches[sw_index]['dpid']
+           addSwitch(sw_name,dpid)
+           setOFVersion(sw_name)
+           addController(sw_name, controller)
+           #addGpeTunnel(sw_name)
+           #doCmd('sudo ovs-vsctl set-manager tcp:%s:6640' % controller)
+           print
+       elif sw_type == 'sf':
+           print "*****************************"
+           print "Configuring %s as an SF." % sw_name
+           print "*****************************"
+           doCmd('sudo /vagrant/sf-config.sh')
+           #addGpeTunnel(switches[sw_index]['name'])
+
diff --git a/resources/demo/netvirtsfc-env/ovswork.sh b/resources/demo/netvirtsfc-env/ovswork.sh
new file mode 100755 (executable)
index 0000000..b19835b
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/env bash
+set -e
+
+BRIDGE=$1
+GUEST_ID=$2
+IPADDR=$3
+BROADCAST=$4
+GWADDR=$5
+MAC=$6
+OF_PORT=$7
+GUESTNAME=$8
+VLANTAG=$9
+
+[ "$IPADDR" ] || {
+    echo "Syntax:"
+    echo "pipework <hostinterface> <guest> <ipaddr>/<subnet> <broadcast> <gateway> [vlan tag]"
+    exit 1
+}
+
+# Step 1: Find the guest (for now, we only support LXC containers)
+while read dev mnt fstype options dump fsck
+do
+    [ "$fstype" != "cgroup" ] && continue
+    echo $options | grep -qw devices || continue
+    CGROUPMNT=$mnt
+done < /proc/mounts
+
+[ "$CGROUPMNT" ] || {
+    echo "Could not locate cgroup mount point."
+    exit 1
+}
+
+N=$(find "$CGROUPMNT" -name "$GUEST_ID*" | wc -l)
+case "$N" in
+    0)
+       echo "Could not find any container matching $GUEST_ID"
+       exit 1
+       ;;
+    1)
+       true
+       ;;
+    *)
+       echo "Found more than one container matching $GUEST_ID"
+       exit 1
+       ;;
+esac
+
+NSPID=$(head -n 1 $(find "$CGROUPMNT" -name "$GUEST_ID*" | head -n 1)/tasks)
+[ "$NSPID" ] || {
+    echo "Could not find a process inside container $GUEST_ID"
+    exit 1
+}
+
+# Step 2: Prepare the working directory
+mkdir -p /var/run/netns
+rm -f /var/run/netns/$NSPID
+ln -s /proc/$NSPID/ns/net /var/run/netns/$NSPID
+
+# Step 3: Creating virtual interfaces
+LOCAL_IFNAME=vethl-$GUESTNAME #$NSPID
+GUEST_IFNAME=vethg-$GUESTNAME #$NSPID
+ip link add name $LOCAL_IFNAME type veth peer name $GUEST_IFNAME
+ip link set $LOCAL_IFNAME up
+
+# Step 4: Adding the virtual interface to the bridge
+ip link set $GUEST_IFNAME netns $NSPID
+if [ "$VLANTAG" ]
+then
+       ovs-vsctl add-port $BRIDGE $LOCAL_IFNAME tag=$VLANTAG 
+       echo $LOCAL_IFNAME 
+else
+       ovs-vsctl add-port $BRIDGE $LOCAL_IFNAME 
+       echo $LOCAL_IFNAME
+fi
+
+# Step 5: Configure netwroking within the container
+ip netns exec $NSPID ip link set $GUEST_IFNAME name eth0
+ip netns exec $NSPID ip addr add $IPADDR broadcast $BROADCAST dev eth0
+ip netns exec $NSPID ifconfig eth0 hw ether $MAC 
+ip netns exec $NSPID ip addr add 127.0.0.1 dev lo
+ip netns exec $NSPID ip link set eth0 up
+ip netns exec $NSPID ip link set lo up
+ip netns exec $NSPID ip route add default via $GWADDR 
+
diff --git a/resources/demo/netvirtsfc-env/pollflows.sh b/resources/demo/netvirtsfc-env/pollflows.sh
new file mode 100755 (executable)
index 0000000..cb5569d
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+TABLE=$1
+watch -n 1 -d "sudo /vagrant/flowcount.sh $1"
+
diff --git a/resources/demo/netvirtsfc-env/resetcontroller.sh b/resources/demo/netvirtsfc-env/resetcontroller.sh
new file mode 100755 (executable)
index 0000000..07ff657
--- /dev/null
@@ -0,0 +1,11 @@
+hostnum=${HOSTNAME#"netvirtsfc"}
+sw="sw$hostnum"
+echo "Deleting controller for $sw"
+ovs-vsctl del-controller $sw;
+if [[ $? -ne 0 ]] ; then
+    exit 1
+fi
+echo "Sleeping for 6sec..."
+sleep 6
+echo "Setting controller to $ODL"
+ovs-vsctl set-controller $sw tcp:$ODL:6653
diff --git a/resources/demo/netvirtsfc-env/rest-clean.py b/resources/demo/netvirtsfc-env/rest-clean.py
new file mode 100755 (executable)
index 0000000..a70544a
--- /dev/null
@@ -0,0 +1,141 @@
+#!/usr/bin/python
+import argparse
+import requests,json
+from requests.auth import HTTPBasicAuth
+from subprocess import call
+import time
+import sys
+import os
+
+
+DEFAULT_PORT='8181'
+
+
+USERNAME='admin'
+PASSWORD='admin'
+
+
+OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
+CONF_TENANT='/restconf/config/policy:tenants'
+
+def get(host, port, uri):
+    url='http://'+host+":"+port+uri
+    #print url
+    r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    jsondata=json.loads(r.text)
+    return jsondata
+
+def rest_delete(host, port, uri, debug=False):
+    '''Perform a DELETE rest operation, using the URL and data provided'''
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "DELETE %s" % url
+    try:
+        r = requests.delete(url, headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as e:
+        print "oops: ", e
+        return
+    if debug == True:
+        print r.text
+    try:
+        r.raise_for_status()
+    except:
+        print "oops: ", sys.exc_info()[0]
+
+
+def post(host, port, uri, data, debug=False):
+    '''Perform a POST rest operation, using the URL and data provided'''
+    url='http://'+host+":"+port+uri
+    headers = {'Content-type': 'application/yang.data+json',
+               'Accept': 'application/yang.data+json'}
+    if debug == True:
+        print "POST %s" % url
+        print json.dumps(data, indent=4, sort_keys=True)
+    r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
+    if debug == True:
+        print r.text
+    r.raise_for_status()
+
+def get_service_functions_uri():
+    return "/restconf/config/service-function:service-functions"
+
+def get_service_function_forwarders_uri():
+    return "/restconf/config/service-function-forwarder:service-function-forwarders"
+
+def get_service_function_chains_uri():
+    return "/restconf/config/service-function-chain:service-function-chains/"
+
+def get_service_function_paths_uri():
+    return "/restconf/config/service-function-path:service-function-paths/"
+
+def get_tenant_uri():
+    return "/restconf/config/policy:tenants/policy:tenant/f5c7d344-d1c7-4208-8531-2c2693657e12"
+
+def get_tunnel_uri():
+    return "/restconf/config/opendaylight-inventory:nodes"
+
+def get_endpoint_uri():
+    return "/restconf/operations/endpoint:unregister-endpoint"
+
+def get_ietf_acl_uri():
+    return "/restconf/config/ietf-access-control-list:access-lists"
+
+def get_classifier_uri():
+    return "/restconf/config/netvirt-sfc-classifier:classifiers"
+
+def get_netvirt_sfc_uri():
+    return "/restconf/config/netvirt-sfc:sfc/"
+
+if __name__ == "__main__":
+    # Launch main menu
+
+
+    # Some sensible defaults
+    controller=os.environ.get('ODL')
+    if controller == None:
+        sys.exit("No controller set.")
+    else:
+       print "Contacting controller at %s" % controller
+
+    #resp=get(controller,DEFAULT_PORT,'/restconf/operational/endpoint:endpoints')
+    #l2_eps=resp['endpoints']['endpoint']
+    #l3_eps=resp['endpoints']['endpoint-l3']
+
+    print "deleting service function paths"
+    rest_delete(controller, DEFAULT_PORT, get_service_function_paths_uri(), True)
+
+    print "deleting service function chains"
+    rest_delete(controller, DEFAULT_PORT, get_service_function_chains_uri(), True)
+
+    print "deleting service functions"
+    rest_delete(controller, DEFAULT_PORT, get_service_functions_uri(), True)
+
+    print "deleting service function forwarders"
+    rest_delete(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), True)
+
+    #print "deleting tunnel"
+    #rest_delete(controller, DEFAULT_PORT, get_tunnel_uri(), True)
+
+    #print "deleting tenant"
+    #rest_delete(controller, DEFAULT_PORT, get_tenant_uri(), True)
+
+    #print "unregistering L2 endpoints"
+    #for endpoint in l2_eps:
+    #data={ "input": { "l2": [ { "l2-context": endpoint['l2-context'] ,"mac-address": endpoint['mac-address'] } ] } }
+    #    post(controller, DEFAULT_PORT, get_endpoint_uri(),data,True)
+
+    #print "unregistering L3 endpoints"
+    #for endpoint in l3_eps:
+    #data={ "input": { "l3": [ { "l3-context": endpoint['l3-context'] ,"ip-address": endpoint['ip-address'] } ] } }
+    #    post(controller, DEFAULT_PORT, get_endpoint_uri(),data,True)
+
+    print "deleting acl"
+    rest_delete(controller, DEFAULT_PORT, get_ietf_acl_uri(), True)
+
+    print "deleting classifier"
+    rest_delete(controller, DEFAULT_PORT, get_classifier_uri(), True)
+
+    print "deleting netvirt sfc"
+    rest_delete(controller, DEFAULT_PORT, get_netvirt_sfc_uri(), True)
diff --git a/resources/demo/netvirtsfc-env/setsfc.sh b/resources/demo/netvirtsfc-env/setsfc.sh
new file mode 100755 (executable)
index 0000000..b9f7e7b
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+ovsdbversion="1.2.1-SNAPSHOT"
+
+# Attempt to keep l2switch from monkeying with the flows
+#sed -i 's/<is-proactive-flood-mode>true<\/is-proactive-flood-mode>/<is-proactive-flood-mode>false<\/is-proactive-flood-mode>/' ${ODL_ROOT_DIR}/system/org/opendaylight/l2switch/arphandler/arphandler-config/$l2switchversion/arphandler-config-$l2switchversion-config.xml
+#sed -i 's/<is-install-lldp-flow>true<\/is-install-lldp-flow>/<is-install-lldp-flow>false<\/is-install-lldp-flow>/' ${ODL_ROOT_DIR}/system/org/opendaylight/l2switch/loopremover/loopremover-config/$l2switchversion/loopremover-config-$l2switchversion-config.xml
+
+# enable NetvirtSfc for standalone mode
+sed -i -e 's/<of13provider>[a-z]\{1,\}<\/of13provider>/<of13provider>standalone<\/of13provider>/g' ${ODL_ROOT_DIR}/system/org/opendaylight/ovsdb/openstack.net-virt-sfc-impl/$ovsdbversion/openstack.net-virt-sfc-impl-$ovsdbversion-config.xml
+
+# Automatically install the feature odl-ovsdb-sfc-ui upon ODL start
+ODL_NETVIRT_SFC_KARAF_FEATURE='odl-ovsdb-sfc-ui'
+ODLFEATUREMATCH=$(cat ${ODL_ROOT_DIR}/etc/org.apache.karaf.features.cfg | \
+                            grep -e "featuresBoot=" -e "featuresBoot =" | grep $ODL_NETVIRT_SFC_KARAF_FEATURE)
+if [ "$ODLFEATUREMATCH" == "" ]; then
+   sed -i -e "/^featuresBoot[ ]*=/ s/$/,$ODL_NETVIRT_SFC_KARAF_FEATURE/" \
+       ${ODL_ROOT_DIR}/etc/org.apache.karaf.features.cfg
+fi
+
+# Set the logging levels for troubleshooting
+logcfg=${ODL_ROOT_DIR}/etc/org.ops4j.pax.logging.cfg
+echo "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc = TRACE" >> $logcfg
+#echo "log4j.logger.org.opendaylight.ovsdb.lib = INFO" >> $logcfg
+echo "log4j.logger.org.opendaylight.sfc = TRACE" >> $logcfg
+echo "log4j.logger.org.opendaylight.openflowplugin.applications.statistics.manager.impl.StatListenCommitFlow = ERROR" >> $logcfg
+
diff --git a/resources/demo/netvirtsfc-env/startdemo.sh b/resources/demo/netvirtsfc-env/startdemo.sh
new file mode 100755 (executable)
index 0000000..c0251af
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/env bash
+
+set -e
+
+demo=${1%/}
+
+echo $demo
+
+if [ -f "demo.lock" ]; then
+    echo "There is already a demo running:"
+    cat demo.lock
+    exit
+fi
+
+cp $demo/infrastructure_config.py .
+cp $demo/sf-config.sh .
+
+echo "Starting demo from $demo with vars:"
+echo "Number of nodes: " $NUM_NODES
+echo "Opendaylight Controller: " $ODL
+echo "Base subnet: " $SUBNET
+
+for i in `seq 1 $NUM_NODES`; do
+#for i in 1 6; do
+  hostname="netvirtsfc"$i
+  echo $hostname
+  vagrant ssh $hostname -c "sudo -E /vagrant/infrastructure_launch.py"
+done
+
+# Looks like SFC is not including l2switch anymore so this is not needed. But just in case...
+#sleep 5
+#echo "Clean l2switch flows"
+#for i in 1 2 4 6; do
+#  hostname="netvirtsfc"$i
+#  sw="sw"$i
+#  echo $hostname
+#  vagrant ssh $hostname -c "sudo ovs-ofctl -O OpenFlow13 --strict del-flows br-int priority=1,arp"
+#  vagrant ssh $hostname -c "sudo ovs-ofctl -O OpenFlow13 --strict del-flows $sw priority=1,arp"
+#done
+
+echo "Configuring controller..."
+./$demo/rest.py
+
+sleep 5
+for i in 1 6; do
+  hostname="netvirtsfc"$i
+  sw="sw"$i
+  echo $hostname
+  vagrant ssh $hostname -c "sudo ovs-vsctl show; sudo ovs-ofctl -O OpenFlow13 dump-flows $sw"
+done
+
+echo "$demo" > demo.lock
+
diff --git a/resources/demo/netvirtsfc-env/traceflow.sh b/resources/demo/netvirtsfc-env/traceflow.sh
new file mode 100755 (executable)
index 0000000..ca2426e
--- /dev/null
@@ -0,0 +1 @@
+ovs-appctl ofproto/trace $1
diff --git a/resources/demo/netvirtsfc-env/utils/hosts b/resources/demo/netvirtsfc-env/utils/hosts
new file mode 100644 (file)
index 0000000..1ed1fb4
--- /dev/null
@@ -0,0 +1,12 @@
+127.0.0.1      localhost
+192.168.50.70  netvirtsfc1
+192.168.50.71  netvirtsfc2
+192.168.50.72  netvirtsfc3
+192.168.50.73   netvirtsfc4
+192.168.50.74   netvirtsfc5
+192.168.50.75   netvirtsfc6
+
+# The following lines are desirable for IPv6 capable hosts
+::1     localhost ip6-localhost ip6-loopback
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
diff --git a/resources/demo/netvirtsfc-env/utils/overlay-flows.sh b/resources/demo/netvirtsfc-env/utils/overlay-flows.sh
new file mode 100755 (executable)
index 0000000..ed9050a
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+# Add flows for the normal overlay that Netvirt would have added
+# sw1: h35_2, dl_src=00:00:00:00:35:02
+# sw6: h35_4, dl_src=00:00:00:00:35:04
+
+set -e
+hostnum=${HOSTNAME#"netvirtsfc"}
+sw="sw$hostnum"
+
+if [ "$hostnum" -eq "1" ]; then
+    # ARP responder for h35_4
+    sudo ovs-ofctl -O OpenFlow13 add-flow $sw "table=0,arp,arp_tpa=10.0.35.4,arp_op=1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],set_field:00:00:00:00:35:04->eth_src,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],load:0x000000003504->NXM_NX_ARP_SHA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0x0a002304->NXM_OF_ARP_SPA[],IN_PORT"
+
+    #port=$(ip -o link | grep veth | awk '{print$2}' | sed 's/://')
+    # l2 forward of local traffic to the normal vxlan
+    sudo ovs-ofctl -O OpenFlow13 add-flow $sw "table=0,priority=150,in_port=1,dl_src=00:00:00:00:35:02,dl_dst=00:00:00:00:35:04,actions=output:5"
+
+    # l2 forward of incoming vxlan traffic to the local port
+    sudo ovs-ofctl -O OpenFlow13 add-flow $sw "table=0,priority=150,in_port=5,dl_src=00:00:00:00:35:04,dl_dst=00:00:00:00:35:02,actions=output:1"
+
+elif [ "$hostnum" -eq "6" ]; then
+    # ARP responder for h35_4
+    sudo ovs-ofctl -O OpenFlow13 add-flow $sw "table=0,arp,arp_tpa=10.0.35.2,arp_op=1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],set_field:00:00:00:00:35:02->eth_src,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],load:0x000000003502->NXM_NX_ARP_SHA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0x0a002302->NXM_OF_ARP_SPA[],IN_PORT"
+
+    # l2 forward of local traffic to the normal vxlan
+    sudo ovs-ofctl -O OpenFlow13 add-flow $sw "table=0,priority=150,in_port=1,dl_src=00:00:00:00:35:04,dl_dst=00:00:00:00:35:02,actions=output:5"
+
+    # l2 forward of incoming vxlan traffic to the local port
+    sudo ovs-ofctl -O OpenFlow13 add-flow $sw "table=0,priority=150,in_port=5,dl_src=00:00:00:00:35:02,dl_dst=00:00:00:00:35:04,actions=output:1"
+
+else
+    echo "Invalid SF for this demo";
+    exit
+fi
diff --git a/resources/demo/netvirtsfc-env/utils/setuphosts.sh b/resources/demo/netvirtsfc-env/utils/setuphosts.sh
new file mode 100755 (executable)
index 0000000..eee7ef1
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+set -e
+
+for i in `seq 1 $NUM_NODES`; do
+  hostname="netvirtsfc"$i
+  echo $hostname
+  vagrant ssh $hostname -c "sudo cp /vagrant/utils/hosts /etc/hosts"
+done
+
diff --git a/resources/demo/netvirtsfc-env/vmclean.sh b/resources/demo/netvirtsfc-env/vmclean.sh
new file mode 100755 (executable)
index 0000000..3974b38
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+docker stop -t=1 $(docker ps -a -q) > /dev/null 2>&1
+docker rm $(docker ps -a -q) > /dev/null 2>&1
+
+/etc/init.d/openvswitch-switch stop > /dev/null
+rm /etc/openvswitch/conf.db > /dev/null
+/etc/init.d/openvswitch-switch start > /dev/null
+
+
+ovs-vsctl show
+
index 51ce6f22faabdad69d87a13546d649cfe8060850..a23f616d6b220800eb247b56e2891c3194979252 100644 (file)
@@ -82,6 +82,33 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>opendaylight-l2-types</artifactId>
     </dependency>
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <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>
+<!--
   <build>
     <plugins>
       <plugin>
@@ -98,5 +125,5 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       </plugin>
     </plugins>
   </build>
-
+-->
 </project>
index 98011d96b50b1eaa4edfbd89825f5de515f355a6..a4102f0fda142afff9ab0c6b4c0e5955f3ba0831 100644 (file)
@@ -45,6 +45,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <properties>
     <powermock.version>1.5.2</powermock.version>
     <openflow.plugin.version>0.2.0-SNAPSHOT</openflow.plugin.version>
+    <sonar.jacoco.itReportPath>../southbound-it/target/jacoco-it.exec</sonar.jacoco.itReportPath>
   </properties>
 
   <dependencies>
@@ -111,6 +112,42 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <scope>test</scope>
     </dependency>
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.ovsdb.routemgr,
+              org.opendaylight.ovsdb.routemgr.*,
+              org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.routemgr.impl.rev141210.*</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <failsOnError>true</failsOnError>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <properties>
+            <property>
+              <name>listener</name>
+              <value>org.sonar.java.jacoco.JUnitListener</value>
+            </property>
+          </properties>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+<!--
   <build>
     <plugins>
       <plugin>
@@ -179,5 +216,5 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       </plugin>
     </plugins>
   </build>
-
+-->
 </project>
index 2a5afc530b4356dfb1c324a9bbf6c6e2f4898df5..8e414710ba9d4377a69b99f0f8624443f9025734 100644 (file)
@@ -12,12 +12,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>utils.config</artifactId>
   <name>${project.artifactId}</name>
   <version>1.2.1-SNAPSHOT</version>
@@ -44,16 +45,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
   </scm>
 
+  <properties>
+    <powermock.version>1.5.2</powermock.version>
+  </properties>
+
   <dependencies>
-    <dependency>
-      <groupId>org.osgi</groupId>
-      <artifactId>org.osgi.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
+    <!-- testing dependencies -->
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
@@ -63,6 +60,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.powermock</groupId>
       <artifactId>powermock-api-mockito</artifactId>
       <scope>test</scope>
+      <version>${powermock.version}</version>
     </dependency>
     <dependency>
       <groupId>org.powermock</groupId>
@@ -74,18 +72,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.powermock</groupId>
       <artifactId>powermock-module-junit4</artifactId>
       <scope>test</scope>
+      <version>${powermock.version}</version>
     </dependency>
   </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
 </project>
index 91d7817323decc7339d7431dfbdca5b6b7377ea7..d0fac74adc426fa3284a3f3aa3a8d7335e9f93bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2014 Red Hat, Inc.
+* Copyright (C) 2014 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,
index 444d5d1ef35f25357d4c0190c5c2715abe99ebdd..f8d3347da881aba1bc5d49dd9170a97560c39c07 100644 (file)
@@ -12,12 +12,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>utils.mdsal-node</artifactId>
   <name>${project.artifactId}</name>
   <version>1.2.1-SNAPSHOT</version>
@@ -45,42 +46,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   </scm>
 
   <dependencies>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.dependencymanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
+    <!-- controller dependencies -->
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-inventory</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
+    <!-- testing dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
 </project>
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 291b2349bb96dc9441a17f2eb3b2febcb8f0d226..c6b0a2bfa1adc7a871e6b24864a8d4389e127647 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2015 Red Hat, Inc.
+ *  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,
index c819d7729f9031c4ca7647f776db5b636c30317a..430acd0a5da4125f728eb2cf16d608d8b0aaad2d 100644 (file)
@@ -12,12 +12,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>utils.mdsal-openflow</artifactId>
   <name>${project.artifactId}</name>
   <version>1.2.1-SNAPSHOT</version>
@@ -44,19 +45,20 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
   </scm>
 
+  <properties>
+    <openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+  </properties>
+
   <dependencies>
-    <!-- Yang Models -->
-    <dependency>
-      <groupId>org.opendaylight.mdsal.model</groupId>
-      <artifactId>ietf-inet-types</artifactId>
-    </dependency>
+    <!-- controller dependencies -->
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-inventory</artifactId>
     </dependency>
+    <!-- mdsal dependencies -->
     <dependency>
-      <groupId>org.opendaylight.openflowplugin.model</groupId>
-      <artifactId>model-flow-base</artifactId>
+      <groupId>org.opendaylight.mdsal.model</groupId>
+      <artifactId>ietf-inet-types</artifactId>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
@@ -66,27 +68,28 @@ 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 -->
+    <!-- openflowplugin dependencies -->
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin.model</groupId>
+      <artifactId>model-flow-base</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</groupId>
       <artifactId>openflowplugin-extension-api</artifactId>
+      <version>${openflowplugin.version}</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.openflowplugin</groupId>
       <artifactId>openflowplugin-extension-nicira</artifactId>
+      <version>${openflowplugin.version}</version>
     </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
+    <!-- testing dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
@@ -96,12 +99,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
+        <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>
     </plugins>
   </build>
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..74fea32
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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.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 flowName = "DEFAULT_PIPELINE_FLOW_" + table;
+        return initFlowBuilder(flowBuilder, flowName, table)
+                .setPriority(0);
+    }
+
+    /**
+     * Sets up common defaults for the given flow builder: a flow identifier and key based on the given flow name,
+     * strict, no barrier, the given table identifier, no hard timeout and no idle timeout.
+     *
+     * @param flowBuilder The flow builder.
+     * @param flowName The flow name.
+     * @param table The table.
+     * @return The flow builder.
+     */
+    public static FlowBuilder initFlowBuilder(FlowBuilder flowBuilder, String flowName, short table) {
+        final FlowId flowId = new FlowId(flowName);
+        flowBuilder
+                .setId(flowId)
+                .setStrict(true)
+                .setBarrier(false)
+                .setTableId(table)
+                .setKey(new FlowKey(flowId))
+                .setFlowName(flowName)
+                .setHardTimeout(0)
+                .setIdleTimeout(0);
+        return flowBuilder;
+    }
+}
index 627849b2e88f8e4eabd1e4551c2a5c37ce68fae5..4c59d45c555d382d70361647de70c6ff9620d4c6 100644 (file)
@@ -43,6 +43,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 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.action.types.rev131112.address.address.Ipv4Builder;
+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.types.rev131026.OutputPortValues;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
@@ -68,13 +70,12 @@ 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;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 public class InstructionUtils {
@@ -91,7 +92,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 +125,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 +147,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 +190,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 +226,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 +272,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 +375,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 +410,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 +437,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 +470,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 +514,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 +554,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 +585,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 +616,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 +647,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 +678,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 +710,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 +740,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 +777,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 +798,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 +828,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 +857,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 +885,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 +913,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 +947,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 +1004,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 +1029,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 +1054,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) {
@@ -1067,6 +1097,37 @@ public class InstructionUtils {
         return getInstructions(applyActionIns(dropAction()));
     }
 
+    /**
+     * Extracts the existing instructions (if any) from the flow.
+     *
+     * @param flow The flow.
+     * @return The instructions in the flow (empty if none).
+     */
+    public static List<Instruction> extractExistingInstructions(Flow flow) {
+        if (flow != null) {
+            Instructions ins = flow.getInstructions();
+            if (ins != null) {
+                return ins.getInstruction();
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Configures the flow builder to have the single given instruction.
+     *
+     * @param flowBuilder The flow builder.
+     * @param instruction The instruction.
+     * @return The flow builder.
+     */
+    public static FlowBuilder setFlowBuilderInstruction(FlowBuilder flowBuilder, Instruction instruction) {
+        flowBuilder.setInstructions(
+                new InstructionsBuilder()
+                        .setInstruction(Collections.singletonList(instruction))
+                        .build());
+        return flowBuilder;
+    }
+
     /**
      * Get a list of Instructions containing Nicira extensions that can have
      * additional OF/OXM instructions added to the returned Instruction list
index 0df0937d2c979b7e7b072dd60a133d5c1ee2103f..930a1d507b8f25a70e7aee8f517819346630e24f 100644 (file)
@@ -80,6 +80,8 @@ public class MatchUtils {
     public static final String TCP = "tcp";
     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
@@ -99,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
      *
@@ -193,19 +206,13 @@ public class MatchUtils {
     /**
      * Match ICMP code and type
      *
-     * @param matchBuilder MatchBuilder Object without a match yet
+     * @param matchBuilder MatchBuilder Object
      * @param type         short representing an ICMP type
      * @param code         short representing an ICMP code
      * @return matchBuilder Map MatchBuilder Object with a match
      */
     public static MatchBuilder createICMPv4Match(MatchBuilder matchBuilder, short type, short code) {
 
-        EthernetMatchBuilder eth = new EthernetMatchBuilder();
-        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
-        ethTypeBuilder.setType(new EtherType(0x0800L));
-        eth.setEthernetType(ethTypeBuilder.build());
-        matchBuilder.setEthernetMatch(eth.build());
-
         // Build the IPv4 Match requied per OVS Syntax
         IpMatchBuilder ipmatch = new IpMatchBuilder();
         ipmatch.setIpProtocol((short) 1);
@@ -213,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;
@@ -249,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;
@@ -1080,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;
@@ -1104,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();
@@ -1174,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 886ae541eed9f9cf8058f8226f9b0393c555d873..807895c9e7d703de699b1a4b2e04f3d787ae5289 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2014 Red Hat, Inc.
+ *  Copyright (C) 2014 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,
index c218c8b319aaf7b4c90b343350a5441af86e5c62..caf272a63c2d986e5af99cc17499e1264d835ddd 100644 (file)
@@ -4,36 +4,33 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
-    <groupId>org.opendaylight.mdsal</groupId>
-    <artifactId>binding-parent</artifactId>
-    <version>0.8.0-SNAPSHOT</version>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
     <relativePath/>
   </parent>
 
   <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>utils.mdsal-utils</artifactId>
-  <version>1.2.0-SNAPSHOT</version>
+  <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>
+
   <dependencies>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-binding-api</artifactId>
-      <version>1.3.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <scope>test</scope>
-    </dependency>
+    <!-- testing dependencies -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </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/neutron-utils/pom.xml b/utils/neutron-utils/pom.xml
new file mode 100644 (file)
index 0000000..465f4c4
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>config-parent</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+      <relativePath/>
+    </parent>
+
+    <groupId>org.opendaylight.ovsdb</groupId>
+    <artifactId>utils.neutron-utils</artifactId>
+    <version>1.2.1-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+    <!-- project specific dependencies -->
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>utils.mdsal-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    <!-- neutron dependencies -->
+        <dependency>
+            <groupId>org.opendaylight.neutron</groupId>
+            <artifactId>model</artifactId>
+            <version>0.6.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/utils/neutron-utils/src/main/java/org/opendaylight/ovsdb/utils/neutron/utils/NeutronModelsDataStoreHelper.java b/utils/neutron-utils/src/main/java/org/opendaylight/ovsdb/utils/neutron/utils/NeutronModelsDataStoreHelper.java
new file mode 100644 (file)
index 0000000..30bd0fb
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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.neutron.utils;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
+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 2d57c9aa9aac49558bb09fbba3b301ee6abdef0b..d3a05cf4b4c076f1bbbf06a02827d83e91798624 100644 (file)
@@ -12,14 +12,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.odlparent</groupId>
+    <artifactId>odlparent-lite</artifactId>
+    <version>1.6.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>utils</artifactId>
-  <version>1.1.0-SNAPSHOT</version>
+  <version>1.2.1-SNAPSHOT</version>
   <name>${project.artifactId}</name>
   <packaging>pom</packaging>
   <description>The OVSDB Plugin integration project is a project for OpenDaylight that will implement the Open vSwitch Database RFC 7047 management protocol allowing the Southbound configuration of vSwitches and a network virtualization implementation.</description>
@@ -51,7 +52,29 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <module>config</module>
     <module>mdsal-node</module>
     <module>mdsal-openflow</module>
-    <module>servicehelper</module>
     <module>mdsal-utils</module>
+    <module>neutron-utils</module>
+    <module>servicehelper</module>
+    <module>southbound-utils</module>
   </modules>
+
+<!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-install-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
index 73da69da6b0cc0a8ee2460ec83ef91d84f6ad04f..fba5f0902d7711c1a888e0a4e5c3a8b0e8d0d920 100644 (file)
@@ -12,12 +12,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <artifactId>commons</artifactId>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../../commons/parent/pom.xml</relativePath>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath/>
   </parent>
 
+  <groupId>org.opendaylight.ovsdb</groupId>
   <artifactId>utils.servicehelper</artifactId>
   <version>1.2.1-SNAPSHOT</version>
   <packaging>bundle</packaging>
@@ -43,6 +44,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <url>https://wiki.opendaylight.org/view/OVSDB_Integration:Main</url>
   </scm>
 
+  <properties>
+    <powermock.version>1.5.2</powermock.version>
+  </properties>
+
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -66,16 +71,19 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>org.powermock</groupId>
       <artifactId>powermock-api-mockito</artifactId>
       <scope>test</scope>
+      <version>${powermock.version}</version>
     </dependency>
     <dependency>
       <groupId>org.powermock</groupId>
       <artifactId>powermock-core</artifactId>
       <scope>test</scope>
+      <version>${powermock.version}</version>
     </dependency>
     <dependency>
       <groupId>org.powermock</groupId>
       <artifactId>powermock-module-junit4</artifactId>
       <scope>test</scope>
+      <version>${powermock.version}</version>
     </dependency>
     <dependency>
       <groupId>org.springframework.osgi</groupId>
@@ -95,14 +103,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>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-      </plugin>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.opendaylight.ovsdb.utils.servicehelper
+            </Export-Package>
+          </instructions>
+        </configuration>
       </plugin>
     </plugins>
   </build>
index 72a837e34bfdea08b6b8d8562beab6535bc258fa..d04b15a970067771ac20cc2d613dc6f6f6786a59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2015 Red Hat, Inc.
+ *  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,
diff --git a/utils/southbound-utils/pom.xml b/utils/southbound-utils/pom.xml
new file mode 100644 (file)
index 0000000..707bb3c
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>config-parent</artifactId>
+    <version>0.4.0-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>org.opendaylight.ovsdb</groupId>
+  <artifactId>utils.southbound-utils</artifactId>
+  <version>1.2.1-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <dependencies>
+    <!-- project specific dependencies -->
+    <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>
+      <version>${project.version}</version>
+    </dependency>
+    <!-- testing dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/utils/southbound-utils/src/main/java/org/opendaylight/ovsdb/utils/southbound/utils/SouthboundUtils.java b/utils/southbound-utils/src/main/java/org/opendaylight/ovsdb/utils/southbound/utils/SouthboundUtils.java
new file mode 100644 (file)
index 0000000..1933f23
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * 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.southbound.utils;
+
+import com.google.common.collect.ImmutableBiMap;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+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;
+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.*;
+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;
+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;
+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;
+
+public class SouthboundUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
+    private static final int OVSDB_UPDATE_TIMEOUT = 1000;
+    public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
+    private final MdsalUtils mdsalUtils;
+
+    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 static NodeId createNodeId(IpAddress ip, PortNumber port) {
+        String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
+                + String.valueOf(ip.getValue()) + ":" + port.getValue();
+        Uri uri = new Uri(uriString);
+        return new NodeId(uri);
+    }
+
+    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();
+    }
+
+    public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
+        OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
+        ovsdbNodeBuilder.setConnectionInfo(key);
+        return ovsdbNodeBuilder.build();
+    }
+
+    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
+        return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
+    }
+
+    public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
+        InstanceIdentifier<Node> path = InstanceIdentifier
+                .create(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
+                .child(Node.class,createNodeKey(ip,port));
+        LOG.debug("Created ovsdb path: {}",path);
+        return path;
+    }
+
+    public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
+        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 static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
+        return new NodeKey(createNodeId(ip, port));
+    }
+
+    public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
+        return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
+    }
+
+    public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
+        return new NodeId(createNodeId(ip,port).getValue()
+                + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
+    }
+
+    public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
+        NodeKey nodeKey = iid.firstKeyOf(Node.class);
+        return nodeKey.getNodeId();
+    }
+
+    public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
+        InetAddress inetAddress = null;
+        try {
+            inetAddress = InetAddress.getByName(addressStr);
+        } catch (UnknownHostException e) {
+            LOG.warn("Could not allocate InetAddress");
+        }
+
+        IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
+        PortNumber port = new PortNumber(Integer.parseInt(portStr));
+
+        LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
+                .setRemoteIp(address)
+                .setRemotePort(port)
+                .build());
+        return new ConnectionInfoBuilder()
+                .setRemoteIp(address)
+                .setRemotePort(port)
+                .build();
+    }
+
+    public static String connectionInfoToString(final ConnectionInfo connectionInfo) {
+        return String.valueOf(
+                connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
+    }
+
+    public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
+        boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
+                createInstanceIdentifier(connectionInfo),
+                createNode(connectionInfo));
+        try {
+            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+        } catch (InterruptedException e) {
+            LOG.warn("Interrupted while waiting after adding OVSDB node {}", connectionInfoToString(connectionInfo), e);
+        }
+        return result;
+    }
+
+    public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
+        return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
+                createInstanceIdentifier(connectionInfo));
+    }
+
+    public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
+        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
+                createInstanceIdentifier(connectionInfo));
+        try {
+            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+        } catch (InterruptedException e) {
+            LOG.warn("Interrupted while waiting after deleting OVSDB node {}", connectionInfoToString(connectionInfo),
+                    e);
+        }
+        return result;
+    }
+
+    public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
+        addOvsdbNode(connectionInfo);
+        Node node = getOvsdbNode(connectionInfo);
+        LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
+        return node;
+    }
+
+    public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
+        deleteOvsdbNode(connectionInfo);
+        LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
+        return true;
+    }
+
+    public List<ControllerEntry> createControllerEntry(String controllerTarget) {
+        List<ControllerEntry> controllerEntriesList = new ArrayList<>();
+        controllerEntriesList.add(new ControllerEntryBuilder()
+                .setTarget(new Uri(controllerTarget))
+                .build());
+        return controllerEntriesList;
+    }
+
+    /**
+     * Extract the <code>store</code> type data store contents for the particular bridge identified by
+     * <code>bridgeName</code>.
+     *
+     * @param connectionInfo address for the node
+     * @param bridgeName name of the bridge
+     * @param store defined by the <code>LogicalDatastoreType</code> enumeration
+     * @return <code>store</code> type data store contents
+     */
+    public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
+                                              LogicalDatastoreType store) {
+        OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
+        Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
+        if (bridgeNode != null) {
+            ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
+        }
+        return ovsdbBridgeAugmentation;
+    }
+
+    /**
+     * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
+     * identified by <code>bridgeName</code>
+     *
+     * @param connectionInfo address for the node
+     * @param bridgeName name of the bridge
+     * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
+     * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
+     */
+    public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
+        return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
+    }
+
+    /**
+     * Extract the node contents from <code>store</code> type data store for the
+     * bridge identified by <code>bridgeName</code>.
+     *
+     * @param connectionInfo address for the node
+     * @param bridgeName name of the bridge
+     * @param store defined by the <code>LogicalDatastoreType</code> enumeration
+     * @return <code>store</code> type data store contents
+     */
+    public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
+        InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
+        return mdsalUtils.read(store, bridgeIid);
+    }
+
+    public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
+
+        boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
+                createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
+        try {
+            Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+        } catch (InterruptedException e) {
+            LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
+        }
+        return result;
+    }
+
+    public List<ProtocolEntry> createMdsalProtocols() {
+        List<ProtocolEntry> protocolList = new ArrayList<>();
+        ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
+                SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
+        protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
+        return protocolList;
+    }
+
+    /*
+     * 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
+     */
+    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,
+                             final String dpid) 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) {
+            ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
+        }
+        if (setManagedBy) {
+            setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
+        }
+        if (dpType != null) {
+            ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
+        }
+        if (externalIds != null) {
+            ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
+        }
+        if (controllerEntries != null) {
+            ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
+        }
+        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());
+        boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+                bridgeIid, bridgeNodeBuilder.build());
+        Thread.sleep(OVSDB_UPDATE_TIMEOUT);
+        return result;
+    }
+
+    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 portName, String type, Map<String, String> options,
+            Map<String, String> externalIds) {
+        return addTerminationPoint(bridgeNode, portName, type, options, externalIds, null);
+    }
+
+    public boolean addTerminationPoint(
+            Node bridgeNode, String portName, String type, Map<String, String> options, Map<String, String> externalIds,
+            Long ofPort) {
+        InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
+        OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
+
+        tpAugmentationBuilder.setName(portName);
+        tpAugmentationBuilder.setOfport(ofPort);
+        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 Boolean addTerminationPoint(Node bridgeNode, String portName, String type) {
+        return addTerminationPoint(bridgeNode, portName, type, null, null);
+    }
+}
diff --git a/utils/southbound-utils/src/test/java/SouthboundUtilsTest.java b/utils/southbound-utils/src/test/java/SouthboundUtilsTest.java
new file mode 100644 (file)
index 0000000..149a619
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * 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
+ */
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class SouthboundUtilsTest {
+    @Test
+    public void testDefault() {
+        assertTrue(true);
+    }
+}