aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/apps')
-rw-r--r--framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java1
-rw-r--r--framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java68
-rw-r--r--framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java19
-rw-r--r--framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java2
-rw-r--r--framework/src/onos/apps/dhcp/api/pom.xml64
-rw-r--r--framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java)0
-rw-r--r--framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java)0
-rw-r--r--framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java)0
-rw-r--r--framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java)0
-rw-r--r--framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java (renamed from framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/app.xml23
-rw-r--r--framework/src/onos/apps/dhcp/app/features.xml25
-rw-r--r--framework/src/onos/apps/dhcp/app/pom.xml166
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java (renamed from framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml (renamed from framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css (renamed from framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html (renamed from framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js (renamed from framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html (renamed from framework/src/onos/apps/dhcp/src/main/resources/gui/css.html)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html (renamed from framework/src/onos/apps/dhcp/src/main/resources/gui/js.html)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml (renamed from framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java (renamed from framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java)0
-rw-r--r--framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json (renamed from framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json)0
-rw-r--r--framework/src/onos/apps/dhcp/pom.xml143
-rw-r--r--framework/src/onos/apps/igmp/src/main/java/org/onosproject/igmp/impl/package-info.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/package-info.java)4
-rw-r--r--framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java20
-rw-r--r--framework/src/onos/apps/mlb/src/main/java/org/onosproject/mlb/package-info.java20
-rw-r--r--framework/src/onos/apps/openstackswitching/pom.xml121
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java51
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java45
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java112
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java350
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java437
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java228
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java49
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java20
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java64
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java62
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java104
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java106
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java20
-rw-r--r--framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml44
-rw-r--r--framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java18
-rw-r--r--framework/src/onos/apps/pom.xml6
-rw-r--r--framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java58
-rw-r--r--framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java5
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java5
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java24
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java164
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java4
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java104
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java190
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java66
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java9
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java81
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java9
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java18
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java10
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java78
-rw-r--r--framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java12
-rw-r--r--framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java12
-rw-r--r--framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java23
-rw-r--r--framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/ConnectPointConfiguration.java55
-rw-r--r--framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java27
-rw-r--r--framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java28
-rw-r--r--framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java12
-rw-r--r--framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java49
-rw-r--r--framework/src/onos/apps/vtn/pom.xml17
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/SfcService.java52
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/SfcManager.java69
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java413
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java201
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPair.java198
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java183
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifier.java259
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifierId.java91
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java148
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChainId.java95
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPair.java139
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java126
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroupId.java95
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairId.java95
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java72
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java108
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java80
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java80
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java72
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java40
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FlowClassifierCodec.java134
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierIdTest.java68
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultAllocationPoolTest.java68
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultHostRouteTest.java68
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/SubnetIdTest.java64
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/DefaultNeutronNetworkTest.java83
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/PhysicalNetworkTest.java65
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/SegmentationIdTest.java64
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantIdTest.java64
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkIdTest.java64
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/AllowedAddressPairTest.java76
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/DefaultVirtualPortTest.java142
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/FixedIpTest.java72
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/SecurityGroupTest.java66
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/VirtualPortIdTest.java66
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java192
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllocationPoolsCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllowedAddressPairCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FixedIpCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/HostRoutesCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/PortChainCodec.java105
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SecurityGroupCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SubnetCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/TenantNetworkCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VirtualPortCodec.java (renamed from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java)2
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/package-info.java20
137 files changed, 7176 insertions, 515 deletions
diff --git a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java
index 72a5b122..567944a6 100644
--- a/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java
+++ b/framework/src/onos/apps/aaa/src/main/java/org/onosproject/aaa/AAA.java
@@ -419,6 +419,7 @@ public class AAA {
* Handles RADIUS packets.
*
* @param radiusPacket RADIUS packet coming from the RADIUS server.
+ * @throws StateMachineException if an illegal state transition is triggered
*/
protected void handleRadiusPacket(RADIUS radiusPacket) throws StateMachineException {
StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier());
diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
index 4b28a14b..e15bc763 100644
--- a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
+++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
@@ -23,17 +23,27 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.ItemNotFoundException;
import org.onlab.util.KryoNamespace;
import org.onosproject.cluster.ClusterService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
+import org.onosproject.net.behaviour.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.behaviour.ControllerInfo;
+import org.onosproject.net.behaviour.DefaultTunnelDescription;
+import org.onosproject.net.behaviour.TunnelConfig;
+import org.onosproject.net.behaviour.TunnelDescription;
+import org.onosproject.net.behaviour.TunnelName;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
@@ -58,6 +68,7 @@ import java.util.concurrent.Executors;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.Device.Type.SWITCH;
+import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -79,7 +90,6 @@ public class CordVtn implements CordVtnService {
private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() {
{
put("key", "flow");
- put("local_ip", "flow");
put("remote_ip", "flow");
}
};
@@ -99,6 +109,9 @@ public class CordVtn implements CordVtnService {
protected HostService hostService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DriverService driverService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OvsdbController controller;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -213,8 +226,8 @@ public class CordVtn implements CordVtnService {
if (deviceService.getDevice(ovsdb.intBrId()) == null ||
!deviceService.isAvailable(ovsdb.intBrId())) {
createIntegrationBridge(ovsdb);
- } else if (!checkVxlanPort(ovsdb)) {
- createVxlanPort(ovsdb);
+ } else if (!checkVxlanInterface(ovsdb)) {
+ createVxlanInterface(ovsdb);
}
}
@@ -272,26 +285,41 @@ public class CordVtn implements CordVtnService {
});
String dpid = ovsdb.intBrId().toString().substring(DPID_BEGIN);
- // TODO change to use bridge config
- OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb);
- ovsdbClient.createBridge(DEFAULT_BRIDGE_NAME, dpid, controllers);
+ try {
+ DriverHandler handler = driverService.createHandler(ovsdb.deviceId());
+ BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
+ bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, controllers);
+ } catch (ItemNotFoundException e) {
+ log.warn("Failed to create integration bridge on {}", ovsdb.deviceId());
+ }
}
- private void createVxlanPort(OvsdbNode ovsdb) {
- // TODO change to use tunnel config and tunnel description
- OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb);
- ovsdbClient.createTunnel(DEFAULT_BRIDGE_NAME, DEFAULT_TUNNEL,
- DEFAULT_TUNNEL, DEFAULT_TUNNEL_OPTIONS);
+ private void createVxlanInterface(OvsdbNode ovsdb) {
+ DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder();
+ for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) {
+ optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key));
+ }
+ TunnelDescription description =
+ new DefaultTunnelDescription(null, null, VXLAN,
+ TunnelName.tunnelName(DEFAULT_TUNNEL),
+ optionBuilder.build());
+ try {
+ DriverHandler handler = driverService.createHandler(ovsdb.deviceId());
+ TunnelConfig tunnelConfig = handler.behaviour(TunnelConfig.class);
+ tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), description);
+ } catch (ItemNotFoundException e) {
+ log.warn("Failed to create VXLAN interface on {}", ovsdb.deviceId());
+ }
}
- private boolean checkVxlanPort(OvsdbNode ovsdb) {
- // TODO change to use tunnel config
- OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb);
+ private boolean checkVxlanInterface(OvsdbNode ovsdb) {
try {
- ovsdbClient.getPorts().stream()
- .filter(p -> p.portName().value().equals(DEFAULT_TUNNEL))
- .findFirst().get();
- } catch (NoSuchElementException e) {
+ DriverHandler handler = driverService.createHandler(ovsdb.deviceId());
+ BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
+ bridgeConfig.getPorts().stream()
+ .filter(p -> p.annotations().value("portName").equals(DEFAULT_TUNNEL))
+ .findAny().get();
+ } catch (ItemNotFoundException | NoSuchElementException e) {
return false;
}
return true;
@@ -374,8 +402,8 @@ public class CordVtn implements CordVtnService {
return;
}
- if (!checkVxlanPort(ovsdb)) {
- createVxlanPort(ovsdb);
+ if (!checkVxlanInterface(ovsdb)) {
+ createVxlanInterface(ovsdb);
}
}
diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java
index 287f2a34..274ca9b4 100644
--- a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java
+++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnConfigManager.java
@@ -72,8 +72,6 @@ public class CordVtnConfigManager {
configService.addListener(configListener);
configRegistry.registerConfigFactory(configFactory);
-
- readConfiguration();
}
@Deactivate
@@ -101,7 +99,22 @@ public class CordVtnConfigManager {
@Override
public void event(NetworkConfigEvent event) {
- // TODO handle update event
+ if (!event.configClass().equals(CordVtnConfig.class)) {
+ return;
+ }
+
+ switch (event.type()) {
+ case CONFIG_ADDED:
+ log.info("Network configuration added");
+ readConfiguration();
+ break;
+ case CONFIG_UPDATED:
+ log.info("Network configuration updated");
+ readConfiguration();
+ break;
+ default:
+ break;
+ }
}
}
}
diff --git a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java
index eba52108..46f6e29c 100644
--- a/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java
+++ b/framework/src/onos/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DefaultOvsdbNode.java
@@ -61,7 +61,7 @@ public class DefaultOvsdbNode implements OvsdbNode {
@Override
public DeviceId deviceId() {
- return DeviceId.deviceId("ovsdb:" + this.ip.toString() + ":" + this.port.toString());
+ return DeviceId.deviceId("ovsdb:" + this.ip.toString());
}
@Override
diff --git a/framework/src/onos/apps/dhcp/api/pom.xml b/framework/src/onos/apps/dhcp/api/pom.xml
new file mode 100644
index 00000000..fb5246f7
--- /dev/null
+++ b/framework/src/onos/apps/dhcp/api/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2014 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>onos-dhcp</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-app-dhcp-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <url>http://onosproject.org</url>
+
+ <description>DHCP Server application API</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-core-serializers</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+
+</project>
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
index 7c2127f9..7c2127f9 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java
+++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
index e263b3a2..e263b3a2 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java
+++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
index 9b3aa686..9b3aa686 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java
+++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java
index 56778a35..56778a35 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java
+++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java
diff --git a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java b/framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java
index 3ecc5cfa..3ecc5cfa 100644
--- a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java
+++ b/framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java
diff --git a/framework/src/onos/apps/dhcp/app/app.xml b/framework/src/onos/apps/dhcp/app/app.xml
new file mode 100644
index 00000000..bf324b19
--- /dev/null
+++ b/framework/src/onos/apps/dhcp/app/app.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<app name="org.onosproject.dhcp" origin="ON.Lab" version="${project.version}"
+ featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+ features="${project.artifactId}">
+ <description>${project.description}</description>
+ <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+ <artifact>mvn:${project.groupId}/onos-app-dhcp-api/${project.version}</artifact>
+</app>
diff --git a/framework/src/onos/apps/dhcp/app/features.xml b/framework/src/onos/apps/dhcp/app/features.xml
new file mode 100644
index 00000000..0b277dea
--- /dev/null
+++ b/framework/src/onos/apps/dhcp/app/features.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+ <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository>
+ <feature name="${project.artifactId}" version="${project.version}"
+ description="${project.description}">
+ <feature>onos-api</feature>
+ <bundle>mvn:${project.groupId}/onos-app-dhcp-api/${project.version}</bundle>
+ <bundle>mvn:${project.groupId}/onos-app-dhcp/${project.version}</bundle>
+ </feature>
+</features>
diff --git a/framework/src/onos/apps/dhcp/app/pom.xml b/framework/src/onos/apps/dhcp/app/pom.xml
new file mode 100644
index 00000000..6589402a
--- /dev/null
+++ b/framework/src/onos/apps/dhcp/app/pom.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2014 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ --><project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <artifactId>onos-dhcp</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-app-dhcp</artifactId>
+ <packaging>bundle</packaging>
+
+ <url>http://onosproject.org</url>
+
+ <description>DHCP Server application</description>
+
+ <properties>
+ <onos.app.name>org.onosproject.dhcp</onos.app.name>
+ <web.context>/onos/dhcp</web.context>
+ <api.version>1.0.0</api.version>
+ <api.title>DHCP Server REST API</api.title>
+ <api.description>
+ APIs for interacting with the DHCP Server application.
+ </api.description>
+ <api.package>org.onosproject.dhcp.rest</api.package>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-dhcp-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-cli</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-core-serializers</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-rest</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-rest</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <_wab>src/main/webapp/</_wab>
+ <Include-Resource>
+ WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
+ {maven-resources}
+ </Include-Resource>
+ <Bundle-SymbolicName>
+ ${project.groupId}.${project.artifactId}
+ </Bundle-SymbolicName>
+ <Import-Package>
+ org.slf4j,
+ org.osgi.framework,
+ javax.ws.rs,
+ javax.ws.rs.core,
+ com.sun.jersey.api.core,
+ com.sun.jersey.spi.container.servlet,
+ com.sun.jersey.server.impl.container.servlet,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.databind.node,
+ com.fasterxml.jackson.core,
+ org.apache.karaf.shell.commands,
+ org.apache.karaf.shell.console,
+ com.google.common.*,
+ org.onlab.packet.*,
+ org.onlab.rest.*,
+ org.onosproject.*,
+ org.onlab.util.*,
+ org.jboss.netty.util.*
+ </Import-Package>
+ <Web-ContextPath>${web.context}</Web-ContextPath>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java
index 95f49e69..95f49e69 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java
index 209ba683..209ba683 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java
index a92cd250..a92cd250 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java
index 9f4f6580..9f4f6580 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java
index 228d70fd..228d70fd 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java
index d6cd73a7..d6cd73a7 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java
index f8780195..f8780195 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java
index 4353d623..4353d623 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
index 96d94a2b..96d94a2b 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java
index bb2bd2c2..bb2bd2c2 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java
index 9ce65d5e..9ce65d5e 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
index 63f69d40..63f69d40 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java
index 12e14e48..12e14e48 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java
index 646ab7ea..646ab7ea 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java
diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java
index 73173c55..73173c55 100644
--- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java
+++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java
diff --git a/framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index ce716315..ce716315 100644
--- a/framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css
index e0a29314..e0a29314 100644
--- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css
+++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css
diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html
index 5782badf..5782badf 100644
--- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html
+++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html
diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js
index 061d0de6..061d0de6 100644
--- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js
+++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js
diff --git a/framework/src/onos/apps/dhcp/src/main/resources/gui/css.html b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html
index d02ad44a..d02ad44a 100644
--- a/framework/src/onos/apps/dhcp/src/main/resources/gui/css.html
+++ b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html
diff --git a/framework/src/onos/apps/dhcp/src/main/resources/gui/js.html b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html
index d37b5768..d37b5768 100644
--- a/framework/src/onos/apps/dhcp/src/main/resources/gui/js.html
+++ b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html
diff --git a/framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml
index 27504548..27504548 100644
--- a/framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml
+++ b/framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml
diff --git a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
index fd4701c6..fd4701c6 100644
--- a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
+++ b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
diff --git a/framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json b/framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json
index abc48a83..abc48a83 100644
--- a/framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json
+++ b/framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json
diff --git a/framework/src/onos/apps/dhcp/pom.xml b/framework/src/onos/apps/dhcp/pom.xml
index 0daa4f7b..7a10776e 100644
--- a/framework/src/onos/apps/dhcp/pom.xml
+++ b/framework/src/onos/apps/dhcp/pom.xml
@@ -13,149 +13,30 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
- --><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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <artifactId>onos-apps</artifactId>
<groupId>org.onosproject</groupId>
+ <artifactId>onos-apps</artifactId>
<version>1.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>onos-app-dhcp</artifactId>
- <packaging>bundle</packaging>
-
- <url>http://onosproject.org</url>
+ <artifactId>onos-dhcp</artifactId>
+ <packaging>pom</packaging>
- <description>DHCP Server application</description>
+ <description>ONOS sample applications</description>
- <properties>
- <onos.app.name>org.onosproject.dhcp</onos.app.name>
- <web.context>/onos/dhcp</web.context>
- <api.version>1.0.0</api.version>
- <api.title>DHCP Server REST API</api.title>
- <api.description>
- APIs for interacting with the DHCP Server application.
- </api.description>
- <api.package>org.onosproject.dhcp.rest</api.package>
- </properties>
+ <modules>
+ <module>api</module>
+ <module>app</module>
+ </modules>
<dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-cli</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.console</artifactId>
- <scope>compile</scope>
- </dependency>
-
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-core-serializers</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-incubator-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-api</artifactId>
- <version>${project.version}</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-rest</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-rest</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>javax.ws.rs</groupId>
- <artifactId>jsr311-api</artifactId>
- <version>1.1.1</version>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-servlet</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- </dependency>
</dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <_wab>src/main/webapp/</_wab>
- <Include-Resource>
- WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
- {maven-resources}
- </Include-Resource>
- <Bundle-SymbolicName>
- ${project.groupId}.${project.artifactId}
- </Bundle-SymbolicName>
- <Import-Package>
- org.slf4j,
- org.osgi.framework,
- javax.ws.rs,
- javax.ws.rs.core,
- com.sun.jersey.api.core,
- com.sun.jersey.spi.container.servlet,
- com.sun.jersey.server.impl.container.servlet,
- com.fasterxml.jackson.databind,
- com.fasterxml.jackson.databind.node,
- com.fasterxml.jackson.core,
- org.apache.karaf.shell.commands,
- org.apache.karaf.shell.console,
- com.google.common.*,
- org.onlab.packet.*,
- org.onlab.rest.*,
- org.onosproject.*,
- org.onlab.util.*,
- org.jboss.netty.util.*
- </Import-Package>
- <Web-ContextPath>${web.context}</Web-ContextPath>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
</project>
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/package-info.java b/framework/src/onos/apps/igmp/src/main/java/org/onosproject/igmp/impl/package-info.java
index 3a84e6e3..7d420198 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/package-info.java
+++ b/framework/src/onos/apps/igmp/src/main/java/org/onosproject/igmp/impl/package-info.java
@@ -15,6 +15,6 @@
*/
/**
- * Service for interacting with the inventory of subnets.
+ * IGMP implementation.
*/
-package org.onosproject.vtnrsc.tunnel;
+package org.onosproject.igmp.impl;
diff --git a/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java b/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java
new file mode 100644
index 00000000..b42586fe
--- /dev/null
+++ b/framework/src/onos/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * REST API for multicase forwarding.
+ */
+package org.onosproject.mfwd.rest;
diff --git a/framework/src/onos/apps/mlb/src/main/java/org/onosproject/mlb/package-info.java b/framework/src/onos/apps/mlb/src/main/java/org/onosproject/mlb/package-info.java
new file mode 100644
index 00000000..a7d83757
--- /dev/null
+++ b/framework/src/onos/apps/mlb/src/main/java/org/onosproject/mlb/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Mastership load balancer.
+ */
+package org.onosproject.mlb;
diff --git a/framework/src/onos/apps/openstackswitching/pom.xml b/framework/src/onos/apps/openstackswitching/pom.xml
new file mode 100644
index 00000000..245b9e80
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/pom.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-apps</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-app-openstackswitching</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>SONA Openstack Switching applications</description>
+ <properties>
+ <onos.version>1.4.0-SNAPSHOT</onos.version>
+ <onos.app.name>org.onosproject.openstackswitching</onos.app.name>
+ <web.context>/onos/openstackswitching</web.context>
+ <api.version>1.0.0</api.version>
+ <api.title>ONOS OpenStack Switching REST API</api.title>
+ <api.description>
+ APIs for receiving Neutron information.
+ </api.description>
+ <api.package>org.onosproject.openstackswitching.web</api.package>
+ <onos.app.origin>SKT, Inc.</onos.app.origin>
+ </properties>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-rest</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-rest</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <_wab>src/main/webapp/</_wab>
+ <Bundle-SymbolicName>
+ ${project.groupId}.${project.artifactId}
+ </Bundle-SymbolicName>
+ <Import-Package>
+ org.slf4j,
+ org.osgi.framework,
+ javax.ws.rs,
+ javax.ws.rs.core,
+ com.sun.jersey.api.core,
+ com.sun.jersey.spi.container.servlet,
+ com.sun.jersey.server.impl.container.servlet,
+ com.fasterxml.jackson.databind,
+ com.fasterxml.jackson.databind.node,
+ com.fasterxml.jackson.core,
+ org.apache.karaf.shell.commands,
+ com.google.common.*,
+ org.onlab.packet.*,
+ org.onosproject.*
+ </Import-Package>
+ <Web-ContextPath>${web.context}</Web-ContextPath>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+</project>
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java
new file mode 100644
index 00000000..afaf7a22
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java
@@ -0,0 +1,51 @@
+/*
+* Copyright 2015 Open Networking Laboratory
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.onosproject.openstackswitching;
+
+import org.onosproject.net.packet.InboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+
+/**
+ * It handles ARP packet from VMs.
+ */
+public class OpenstackArpHandler {
+
+ private static Logger log = LoggerFactory
+ .getLogger(OpenstackArpHandler.class);
+
+ HashMap<String, OpenstackPort> openstackPortHashMap;
+
+ /**
+ * Constructs an OpenstackArpHandler.
+ *
+ * @param openstackPortMap port map
+ */
+ public OpenstackArpHandler(HashMap<String, OpenstackPort> openstackPortMap) {
+ this.openstackPortHashMap = openstackPortMap;
+ }
+
+ /**
+ * Processes ARP packets.
+ *
+ * @param pkt ARP request packet
+ */
+ public void processPacketIn(InboundPacket pkt) {
+ log.warn("Received an ARP packet");
+ }
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java
new file mode 100644
index 00000000..9c3641c1
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java
@@ -0,0 +1,45 @@
+/*
+* Copyright 2015 Open Networking Laboratory
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.onosproject.openstackswitching;
+
+import org.onosproject.net.packet.InboundPacket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * It handles DHCP request packets.
+ */
+public class OpenstackDhcpHandler {
+
+ private static Logger log = LoggerFactory
+ .getLogger(OpenstackDhcpHandler.class);
+
+ /**
+ * Returns OpenstackDhcpHandler reference.
+ */
+ public OpenstackDhcpHandler() {
+
+ }
+
+ /**
+ * Processes DHCP request packets.
+ *
+ * @param pkt DHCP request packet
+ */
+ public void processPacketIn(InboundPacket pkt) {
+ log.warn("Received a DHCP packet");
+ }
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java
new file mode 100644
index 00000000..dc7c0263
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+
+/**
+ * Represents the network information given by Neutron.
+ */
+public final class OpenstackNetwork {
+
+ private String name;
+ private String tenantId;
+ private String segmentId;
+ private String networkType;
+ private String id;
+
+ /**
+ * Returns the builder object of the OpenstackNetwork class.
+ *
+ * @return OpenstackNetwork builder object
+ */
+ public static OpenstackNetwork.Builder builder() {
+ return new Builder();
+ }
+
+ private OpenstackNetwork(String name, String tenantId, String id, String sid,
+ String type) {
+ this.name = checkNotNull(name);
+ this.tenantId = checkNotNull(tenantId);
+ this.segmentId = checkNotNull(sid);
+ this.id = checkNotNull(id);
+ this.networkType = checkNotNull(type);
+ }
+
+ public String name() {
+ return this.name;
+ }
+
+ public String tenantId() {
+ return this.tenantId;
+ }
+
+ public String id() {
+ return this.id;
+ }
+
+ public String segmentId() {
+ return this.segmentId;
+ }
+
+ public String networkType() {
+ return this.networkType;
+ }
+
+ public static final class Builder {
+ private String name;
+ private String tenantId;
+ private String id;
+ private String sid;
+ private String networkType;
+
+ public Builder name(String name) {
+ this.name = name;
+
+ return this;
+ }
+
+ public Builder tenantId(String tenantId) {
+ this.tenantId = tenantId;
+
+ return this;
+ }
+
+ public Builder id(String id) {
+ this.id = id;
+
+ return this;
+ }
+
+ public Builder segmentId(String sid) {
+ this.sid = sid;
+
+ return this;
+ }
+
+ public Builder networkType(String type) {
+ this.networkType = type;
+
+ return this;
+ }
+
+ public OpenstackNetwork build() {
+ return new OpenstackNetwork(name, tenantId, id, sid, networkType);
+ }
+
+ }
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java
new file mode 100644
index 00000000..4326b4fc
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching;
+
+import com.google.common.collect.Lists;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+
+import java.util.HashMap;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * It represents the Openstack Port information.
+ */
+public final class OpenstackPort {
+
+ public enum PortStatus {
+ UP,
+ DOWN
+ }
+
+ private PortStatus status;
+ private String name;
+ // FIX_ME
+ private String allowedAddressPairs;
+ private boolean adminStateUp;
+ private String networkId;
+ private String tenantId;
+ private String deviceOwner;
+ private MacAddress macAddress;
+ // <subnet id, ip address>
+ private HashMap<String, Ip4Address> fixedIps;
+ private String id;
+ private List<String> securityGroups;
+ private String deviceId;
+
+ private OpenstackPort(PortStatus status, String name, boolean adminStateUp,
+ String networkId, String tenantId, String deviceOwner,
+ MacAddress macAddress, HashMap fixedIps, String id,
+ List<String> securityGroups, String deviceId) {
+
+ this.status = status;
+ this.name = name;
+ this.adminStateUp = adminStateUp;
+ this.networkId = checkNotNull(networkId);
+ this.tenantId = checkNotNull(tenantId);
+ this.deviceOwner = deviceOwner;
+ this.macAddress = checkNotNull(macAddress);
+ this.fixedIps = checkNotNull(fixedIps);
+ this.id = checkNotNull(id);
+ this.securityGroups = securityGroups;
+ this.deviceId = deviceId;
+ }
+
+
+
+ /**
+ * Returns OpenstackPort builder object.
+ *
+ * @return OpenstackPort builder
+ */
+ public static OpenstackPort.Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns port status.
+ *
+ * @return port status
+ */
+ public PortStatus status() {
+ return status;
+ }
+
+ /**
+ * Returns port name.
+ *
+ * @return port name
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns whether admin state up or not.
+ *
+ * @return true if admin state up, false otherwise
+ */
+ public boolean isAdminStateUp() {
+ return adminStateUp;
+ }
+
+ /**
+ * Returns network ID.
+ *
+ * @return network ID
+ */
+ public String networkId() {
+ return networkId;
+ }
+
+ /**
+ * Returns device owner.
+ *
+ * @return device owner
+ */
+ public String deviceOwner() {
+ return deviceOwner;
+ }
+
+ /**
+ * Returns mac address.
+ *
+ * @return mac address
+ */
+ public MacAddress macAddress() {
+ return macAddress;
+ }
+
+ /**
+ * Returns the fixed IP information.
+ *
+ * @return fixed IP info
+ */
+ public HashMap fixedIps() {
+ return fixedIps;
+ }
+
+ /**
+ * Returns port ID.
+ *
+ * @return port ID
+ */
+ public String id() {
+ return id;
+ }
+
+ /**
+ * Returns security group information.
+ *
+ * @return security group info
+ */
+ public List<String> securityGroups() {
+ return securityGroups;
+ }
+
+ /**
+ * Returns device ID.
+ *
+ * @return device ID
+ */
+ public String deviceId() {
+ return deviceId;
+ }
+
+ // TODO : Implement the following functions when necessary
+ //@Override
+ //public void equals(Object that) {
+ //
+ //}
+ //
+ //@Override
+ //public int hashCode() {
+ //
+ //}
+
+ /**
+ * OpenstackPort Builder class.
+ */
+ public static final class Builder {
+
+ private PortStatus status;
+ private String name;
+ // FIX_ME
+ private String allowedAddressPairs;
+ private boolean adminStateUp;
+ private String networkId;
+ private String tenantId;
+ private String deviceOwner;
+ private MacAddress macAddress;
+ // list of hash map <subnet id, ip address>
+ private HashMap<String, Ip4Address> fixedIps;
+ private String id;
+ private List<String> securityGroups;
+ private String deviceId;
+
+ Builder() {
+ fixedIps = new HashMap<>();
+ securityGroups = Lists.newArrayList();
+ }
+
+ /**
+ * Sets port status.
+ *
+ * @param status port status
+ * @return Builder object
+ */
+ public Builder portStatus(PortStatus status) {
+ this.status = status;
+
+ return this;
+ }
+
+ /**
+ * Sets port name.
+ *
+ * @param name port name
+ * @return Builder object
+ */
+ public Builder name(String name) {
+ this.name = name;
+
+ return this;
+ }
+
+ /**
+ * Sets whether admin state up or not.
+ *
+ * @param isAdminStateUp true if admin state is up, false otherwise
+ * @return Builder object
+ */
+ public Builder adminState(boolean isAdminStateUp) {
+ this.adminStateUp = isAdminStateUp;
+
+ return this;
+ }
+
+ /**
+ * Sets network ID.
+ *
+ * @param networkId network ID
+ * @return Builder object
+ */
+ public Builder netwrokId(String networkId) {
+ this.networkId = networkId;
+
+ return this;
+ }
+
+ /**
+ * Sets tenant ID.
+ *
+ * @param tenantId tenant ID
+ * @return Builder object
+ */
+ public Builder tenantId(String tenantId) {
+ this.tenantId = tenantId;
+
+ return this;
+ }
+
+ /**
+ * Sets device owner.
+ *
+ * @param owner device owner
+ * @return Builder object
+ */
+ public Builder deviceOwner(String owner) {
+ this.deviceOwner = owner;
+
+ return this;
+ }
+
+ /**
+ * Sets MAC address of the port.
+ *
+ * @param mac MAC address
+ * @return Builder object
+ */
+ public Builder macAddress(MacAddress mac) {
+ this.macAddress = mac;
+
+ return this;
+ }
+
+ /**
+ * Sets Fixed IP address information.
+ *
+ * @param fixedIpList Fixed IP info
+ * @return Builder object
+ */
+ public Builder fixedIps(HashMap<String, Ip4Address> fixedIpList) {
+ fixedIps.putAll(fixedIpList);
+
+ return this;
+ }
+
+ /**
+ * Sets ID of the port.
+ *
+ * @param id ID of the port
+ * @return Builder object
+ */
+ public Builder id(String id) {
+ this.id = id;
+
+ return this;
+ }
+
+ /**
+ * Sets security group of the port.
+ *
+ * @param securityGroup security group of the port
+ * @return Builder object
+ */
+ public Builder securityGroup(String securityGroup) {
+ securityGroups.add(securityGroup);
+
+ return this;
+ }
+
+ /**
+ * Sets device ID of the port.
+ *
+ * @param deviceId device ID
+ * @return Builder object
+ */
+ public Builder deviceId(String deviceId) {
+ this.deviceId = deviceId;
+
+ return this;
+ }
+
+ /**
+ * Builds an OpenstackPort object.
+ *
+ * @return OpenstackPort objecet
+ */
+ public OpenstackPort build() {
+ return new OpenstackPort(status, name, adminStateUp, networkId, networkId,
+ deviceOwner, macAddress, fixedIps, id, securityGroups, deviceId);
+ }
+ }
+}
+
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
new file mode 100644
index 00000000..baae7f80
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.UDP;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@SuppressWarnings("ALL")
+@Service
+@Component(immediate = true)
+/**
+ * It populates forwarding rules for VMs created by Openstack.
+ */
+public class OpenstackSwitchingManager implements OpenstackSwitchingService {
+
+ private static Logger log = LoggerFactory
+ .getLogger(OpenstackSwitchingManager.class);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PacketService packetService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowObjectiveService flowObjectiveService;
+
+
+ public static final int DHCP_PORT = 67;
+
+ private ApplicationId appId;
+ private OpenstackArpHandler arpHandler;
+ private OpenstackDhcpHandler dhcpHandler = new OpenstackDhcpHandler();
+ private OpenstackSwitchingRulePopulator rulePopulator;
+ private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10);
+
+ private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor();
+ private InternalDeviceListener internalDeviceListener = new InternalDeviceListener();
+
+ // Map <port_id, OpenstackPort>
+ private HashMap<String, OpenstackPort> openstackPortMap;
+ // Map <network_id, OpenstackNetwork>
+ private HashMap<String, OpenstackNetwork> openstackNetworkMap;
+ // Map <vni, List <Entry <portName, host ip>>
+ private HashMap<String, List<PortInfo>> vniPortMap;
+ private HashMap<Ip4Address, Port> tunnelPortMap;
+
+
+ @Activate
+ protected void activate() {
+ appId = coreService
+ .registerApplication("org.onosproject.openstackswitching");
+ rulePopulator = new OpenstackSwitchingRulePopulator(appId, flowObjectiveService);
+ packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1));
+ deviceService.addListener(internalDeviceListener);
+
+ openstackPortMap = Maps.newHashMap();
+ openstackNetworkMap = Maps.newHashMap();
+ vniPortMap = Maps.newHashMap();
+ tunnelPortMap = Maps.newHashMap();
+
+ arpHandler = new OpenstackArpHandler(openstackPortMap);
+
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ packetService.removeProcessor(internalPacketProcessor);
+ deviceService.removeListener(internalDeviceListener);
+
+ deviceEventExcutorService.shutdown();
+
+ log.info("Stopped");
+ }
+
+ @Override
+ public void createPorts(OpenstackPort openstackPort) {
+ openstackPortMap.put(openstackPort.id(), openstackPort);
+ }
+
+ @Override
+ public void deletePorts() {
+
+ }
+
+ @Override
+ public void updatePorts() {
+
+ }
+
+ @Override
+ public void createNetwork(OpenstackNetwork openstackNetwork) {
+ openstackNetworkMap.put(openstackNetwork.id(), openstackNetwork);
+ }
+
+ private void processDeviceAdded(Device device) {
+ log.warn("device {} is added", device.id());
+ rulePopulator.populateDefaultRules(device.id());
+ }
+
+ private void processPortAdded(Device device, Port port) {
+ // TODO: Simplify the data structure to store the network info
+ // TODO: Make it stateless
+ // TODO: All the logics need to be processed inside of the rulePopulator class
+ synchronized (vniPortMap) {
+ log.warn("port {} is updated", port.toString());
+
+ updatePortMaps(device, port);
+ if (!port.annotations().value("portName").equals("vxlan")) {
+ populateFlowRulesForTrafficToSameCnode(device, port);
+ populateFlowRulesForTrafficToDifferentCnode(device, port);
+ }
+ }
+ }
+
+ private void processPortRemoved(Device device, Port port) {
+ log.warn("port {} is removed", port.toString());
+ // TODO: need to update the vniPortMap
+ }
+
+ /**
+ * Populates the flow rules for traffic to VMs in different Cnode using
+ * Nicira extention.
+ *
+ * @param device device to put rules
+ * @param port port information of the VM
+ */
+ private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) {
+ String portName = port.annotations().value("portName");
+ String channelId = device.annotations().value("channelId");
+ Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]);
+ Ip4Address fixedIp = getFixedIpAddressForPort(portName);
+ // TODO: Avoid duplicate flow rule set up for VMs in other Cnode
+ // (possibly avoided by flowrule subsystem?)
+ if (tunnelPortMap.get(hostIpAddress) == null) {
+ log.warn("There is no tunnel port information");
+ return;
+ }
+ String vni = getVniForPort(portName);
+ MacAddress vmMac = getVmMacAddressForPort(portName);
+ if (!vniPortMap.isEmpty() && vniPortMap.get(vni) != null) {
+ for (PortInfo portInfo : vniPortMap.get(vni)) {
+ if (!portInfo.portName.equals(portName) &&
+ !portInfo.hostIp.equals(hostIpAddress)) {
+ MacAddress vmMacx = getVmMacAddressForPort(portInfo.portName);
+ rulePopulator.populateForwardingRuleForOtherCnode(vni,
+ device.id(), portInfo.hostIp, portInfo.fixedIp, vmMacx,
+ tunnelPortMap.get(hostIpAddress).number(),
+ portInfo.deviceId, hostIpAddress, fixedIp, vmMac,
+ tunnelPortMap.get(portInfo.hostIp).number());
+ }
+ }
+ }
+ }
+
+ /**
+ * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
+ *
+ * @param device device to put the rules
+ * @param port port info of the VM
+ */
+ private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) {
+ Ip4Prefix cidr = getCidrForPort(port.annotations().value("portName"));
+ Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
+ if (vmIp != null) {
+ rulePopulator.populateForwardingRule(vmIp, device.id(), port, cidr);
+ }
+ }
+
+ /**
+ * Updates the port maps using the port information.
+ *
+ * @param device device info
+ * @param port port of the VM
+ */
+ private void updatePortMaps(Device device, Port port) {
+ String portName = port.annotations().value("portName");
+ String channelId = device.annotations().value("channelId");
+ Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]);
+ if (portName.startsWith("vxlan")) {
+ tunnelPortMap.put(hostIpAddress, port);
+ } else {
+ String vni = getVniForPort(portName);
+ Ip4Address fixedIp = getFixedIpAddressForPort(portName);
+ if (vniPortMap.get(vni) == null) {
+ vniPortMap.put(vni, Lists.newArrayList());
+ }
+ vniPortMap.get(vni).add(new PortInfo(device.id(), portName, fixedIp, hostIpAddress));
+ }
+ }
+
+ /**
+ * Returns CIDR information from the subnet map for the port.
+ *
+ * @param portName port name of the port of the VM
+ * @return CIDR of the VNI of the VM
+ */
+ private Ip4Prefix getCidrForPort(String portName) {
+ String networkId = null;
+ String uuid = portName.substring(3);
+ OpenstackPort port = openstackPortMap.values().stream()
+ .filter(p -> p.id().startsWith(uuid))
+ .findFirst().get();
+ if (port == null) {
+ log.warn("No port information for port {}", portName);
+ return null;
+ }
+
+ //OpenstackSubnet subnet = openstackSubnetMap.values().stream()
+ // .filter(s -> s.networkId().equals(port.networkId()))
+ // .findFirst().get();
+ //if (subnet == null) {
+ // log.warn("No subnet information for network {}", subnet.id());
+ // return null;
+ //}
+
+ //return Ip4Prefix.valueOf(subnet.cidr());
+ return null;
+ }
+
+ /**
+ * Returns the VNI of the VM of the port.
+ *
+ * @param portName VM port
+ * @return VNI
+ */
+ private String getVniForPort(String portName) {
+ String networkId = null;
+ String uuid = portName.substring(3);
+ OpenstackPort port = openstackPortMap.values().stream()
+ .filter(p -> p.id().startsWith(uuid))
+ .findFirst().get();
+ if (port == null) {
+ log.warn("No port information for port {}", portName);
+ return null;
+ }
+ OpenstackNetwork network = openstackNetworkMap.values().stream()
+ .filter(n -> n.id().equals(port.networkId()))
+ .findFirst().get();
+ if (network == null) {
+ log.warn("No VNI information for network {}", network.id());
+ return null;
+ }
+
+ return network.segmentId();
+ }
+
+ /**
+ * Returns the Fixed IP address of the VM.
+ *
+ * @param portName VM port info
+ * @return IP address of the VM
+ */
+ private Ip4Address getFixedIpAddressForPort(String portName) {
+
+ // FIXME - For now we use the information stored from neutron Rest API call.
+ // TODO - Later, the information needs to be extracted from Neutron on-demand.
+ String uuid = portName.substring(3);
+ OpenstackPort port = openstackPortMap.values().stream()
+ .filter(p -> p.id().startsWith(uuid))
+ .findFirst().get();
+
+ if (port == null) {
+ log.error("There is no port information for port name {}", portName);
+ return null;
+ }
+
+ if (port.fixedIps().isEmpty()) {
+ log.error("There is no fixed IP info in the port information");
+ return null;
+ }
+
+ return (Ip4Address) port.fixedIps().values().toArray()[0];
+ }
+
+ /**
+ * Returns the MAC address of the VM of the port.
+ *
+ * @param portName VM port
+ * @return MAC address of the VM
+ */
+ private MacAddress getVmMacAddressForPort(String portName) {
+
+ String uuid = portName.substring(3);
+ OpenstackPort port = openstackPortMap.values().stream()
+ .filter(p -> p.id().startsWith(uuid))
+ .findFirst().get();
+
+ if (port == null) {
+ log.error("There is no mac information for port name {}", portName);
+ return null;
+ }
+
+ return port.macAddress();
+ }
+
+ private class InternalPacketProcessor implements PacketProcessor {
+
+ @Override
+ public void process(PacketContext context) {
+
+ if (context.isHandled()) {
+ return;
+ }
+
+ InboundPacket pkt = context.inPacket();
+ Ethernet ethernet = pkt.parsed();
+
+ if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
+ arpHandler.processPacketIn(pkt);
+ } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
+ IPv4 ipPacket = (IPv4) ethernet.getPayload();
+
+ if (ipPacket.getProtocol() == IPv4.PROTOCOL_UDP) {
+ UDP udpPacket = (UDP) ipPacket.getPayload();
+ if (udpPacket.getDestinationPort() == DHCP_PORT) {
+ dhcpHandler.processPacketIn(pkt);
+ }
+ }
+ }
+ }
+ }
+
+ private class InternalDeviceListener implements DeviceListener {
+
+ @Override
+ public void event(DeviceEvent event) {
+ deviceEventExcutorService.execute(new InternalEventHandler(event));
+ }
+ }
+
+ private class InternalEventHandler implements Runnable {
+
+ volatile DeviceEvent deviceEvent;
+
+ InternalEventHandler(DeviceEvent deviceEvent) {
+ this.deviceEvent = deviceEvent;
+ }
+
+ @Override
+ public void run() {
+ switch (deviceEvent.type()) {
+ case DEVICE_ADDED:
+ processDeviceAdded((Device) deviceEvent.subject());
+ break;
+ case DEVICE_UPDATED:
+ Port port = (Port) deviceEvent.subject();
+ if (port.isEnabled()) {
+ processPortAdded((Device) deviceEvent.subject(), deviceEvent.port());
+ }
+ break;
+ case DEVICE_AVAILABILITY_CHANGED:
+ Device device = (Device) deviceEvent.subject();
+ if (deviceService.isAvailable(device.id())) {
+ processDeviceAdded(device);
+ }
+ break;
+ case PORT_ADDED:
+ processPortAdded((Device) deviceEvent.subject(), deviceEvent.port());
+ break;
+ case PORT_UPDATED:
+ processPortAdded((Device) deviceEvent.subject(), deviceEvent.port());
+ break;
+ case PORT_REMOVED:
+ processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private final class PortInfo {
+ DeviceId deviceId;
+ String portName;
+ Ip4Address fixedIp;
+ Ip4Address hostIp;
+
+ private PortInfo(DeviceId deviceId, String portName, Ip4Address fixedIp,
+ Ip4Address hostIp) {
+ this.deviceId = deviceId;
+ this.portName = portName;
+ this.fixedIp = fixedIp;
+ this.hostIp = hostIp;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java
new file mode 100644
index 00000000..9ead05f0
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java
@@ -0,0 +1,228 @@
+/*
+* Copyright 2015 Open Networking Laboratory
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.onosproject.openstackswitching;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * It populates switching flow rules.
+ *
+ */
+public class OpenstackSwitchingRulePopulator {
+
+ private static Logger log = LoggerFactory
+ .getLogger(OpenstackSwitchingRulePopulator.class);
+
+ private FlowObjectiveService flowObjectiveService;
+ private ApplicationId appId;
+
+ /**
+ * Creates OpenstackSwitchingRulPopulator.
+ *
+ * @param appId application id
+ * @param flowObjectiveService FlowObjectiveService reference
+ */
+ public OpenstackSwitchingRulePopulator(ApplicationId appId,
+ FlowObjectiveService flowObjectiveService) {
+ this.flowObjectiveService = flowObjectiveService;
+ this.appId = appId;
+ }
+
+ /**
+ * Populates flows rules for forwarding packets to and from VMs.
+ *
+ * @param ip v4 IP Address
+ * @param id device ID
+ * @param port port
+ * @param cidr v4 IP prefix
+ * @return true if it succeeds to populate rules, false otherwise.
+ */
+ public boolean populateForwardingRule(Ip4Address ip, DeviceId id, Port port, Ip4Prefix cidr) {
+
+
+ setFlowRuleForVMsInSameCnode(ip, id, port, cidr);
+
+ return true;
+ }
+
+ /**
+ * Populates the common flows rules for all VMs.
+ *
+ * - Send ARP packets to the controller
+ * - Send DHCP packets to the controller
+ *
+ * @param id Device ID to populates rules to
+ */
+ public void populateDefaultRules(DeviceId id) {
+
+ //setFlowRuleForDHCP(id);
+ setFlowRuleForArp(id);
+
+ log.warn("Default rule has been set");
+ }
+
+ /**
+ * Populates the forwarding rules for VMs with the same VNI but in other Code.
+ *
+ * @param vni VNI for the networks
+ * @param id device ID to populates the flow rules
+ * @param hostIp host IP address of the VM
+ * @param vmIp fixed IP address for the VM
+ * @param vmMac MAC address for the VM
+ * @param tunnelPort tunnel port number for the VM
+ * @param idx device ID for OVS of the other VM
+ * @param hostIpx host IP address of the other VM
+ * @param vmIpx fixed IP address of the other VM
+ * @param vmMacx MAC address for the other VM
+ * @param tunnelPortx x tunnel port number for other VM
+ */
+ public void populateForwardingRuleForOtherCnode(String vni, DeviceId id, Ip4Address hostIp,
+ Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort,
+ DeviceId idx, Ip4Address hostIpx,
+ Ip4Address vmIpx, MacAddress vmMacx, PortNumber tunnelPortx) {
+ setVxLanFlowRule(vni, id, hostIp, vmIp, vmMac, tunnelPort);
+ setVxLanFlowRule(vni, idx, hostIpx, vmIpx, vmMacx, tunnelPortx);
+ }
+
+ /**
+ * Populates the flow rules for DHCP packets from VMs.
+ *
+ * @param id device ID to set the rules
+ */
+ private void setFlowRuleForDHCP(DeviceId id) {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_UDP)
+ .matchUdpDst(TpPort.tpPort(OpenstackSwitchingManager.DHCP_PORT));
+ tBuilder.setOutput(PortNumber.CONTROLLER);
+
+ ForwardingObjective fo = DefaultForwardingObjective.builder()
+ .withSelector(sBuilder.build())
+ .withTreatment(tBuilder.build())
+ .withPriority(5000)
+ .withFlag(ForwardingObjective.Flag.VERSATILE)
+ .fromApp(appId)
+ .add();
+
+ flowObjectiveService.forward(id, fo);
+ }
+
+ /**
+ * Populates the flow rules for ARP packets from VMs.
+ *
+ * @param id device ID to put rules.
+ */
+ private void setFlowRuleForArp(DeviceId id) {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+ sBuilder.matchEthType(Ethernet.TYPE_ARP);
+ tBuilder.setOutput(PortNumber.CONTROLLER);
+
+ ForwardingObjective fo = DefaultForwardingObjective.builder()
+ .withSelector(sBuilder.build())
+ .withTreatment(tBuilder.build())
+ .withPriority(5000)
+ .withFlag(ForwardingObjective.Flag.VERSATILE)
+ .fromApp(appId)
+ .add();
+
+ flowObjectiveService.forward(id, fo);
+ }
+
+ /**
+ * Sets the flow rules for traffic between VMs in the same Cnode.
+ *
+ * @param ip4Address VM IP address
+ * @param id device ID to put rules
+ * @param port VM port
+ * @param cidr subnet info of the VMs
+ */
+ private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id,
+ Port port, Ip4Prefix cidr) {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(ip4Address.toIpPrefix())
+ .matchIPSrc(cidr);
+ tBuilder.setOutput(port.number());
+
+ ForwardingObjective fo = DefaultForwardingObjective.builder()
+ .withSelector(sBuilder.build())
+ .withTreatment(tBuilder.build())
+ .withPriority(5000)
+ .withFlag(ForwardingObjective.Flag.VERSATILE)
+ .fromApp(appId)
+ .add();
+
+ flowObjectiveService.forward(id, fo);
+ }
+
+ /**
+ * Sets the flow rules between traffic from VMs in different Cnode.
+ *
+ * @param vni VNI
+ * @param id device ID
+ * @param hostIp host IP of the VM
+ * @param vmIp fixed IP of the VM
+ * @param vmMac MAC address of the VM
+ * @param tunnelPort tunnel port to forward traffic to
+ */
+ private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp,
+ Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort) {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+ sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(vmIp.toIpPrefix());
+ tBuilder.setTunnelId(Long.parseLong(vni))
+ //.setTunnelDst() <- for Nicira ext
+ //.setEthDst(vmMac)
+ .setOutput(tunnelPort);
+
+ ForwardingObjective fo = DefaultForwardingObjective.builder()
+ .withSelector(sBuilder.build())
+ .withTreatment(tBuilder.build())
+ .withPriority(5000)
+ .withFlag(ForwardingObjective.Flag.VERSATILE)
+ .fromApp(appId)
+ .add();
+
+ flowObjectiveService.forward(id, fo);
+ }
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java
new file mode 100644
index 00000000..d97b39c8
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching;
+
+/**
+ * It handles port management REST API from Openstack for VMs.
+ */
+public interface OpenstackSwitchingService {
+
+ /**
+ * Store the port information created by Openstack.
+ *
+ * @param openstackPort port information
+ */
+ void createPorts(OpenstackPort openstackPort);
+
+ /**
+ * Removes flow rules corresponding to the port removed by Openstack.
+ *
+ */
+ void deletePorts();
+
+ /**
+ * Updates flow rules corresponding to the port information updated by Openstack.
+ *
+ */
+ void updatePorts();
+
+ /**
+ * Store the network information created by openstack.
+ *
+ * @param openstackNetwork network information
+ */
+ void createNetwork(OpenstackNetwork openstackNetwork);
+
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java
new file mode 100644
index 00000000..cd50f912
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * OpenStack switch interface.
+ */
+package org.onosproject.openstackswitching;
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java
new file mode 100644
index 00000000..43bd1583
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching.web;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.openstackswitching.OpenstackNetwork;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the OpenstackNetwork Codec.
+ *
+ */
+public class OpenstackNetworkCodec extends JsonCodec<OpenstackNetwork> {
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(OpenstackNetworkCodec.class);
+
+ private static final String NETWORK = "network";
+ private static final String NAME = "name";
+ private static final String TENANT_ID = "tenant_id";
+ private static final String SEGMENTATION_ID = "provider:segmentation_id";
+ private static final String NETWORK_TYPE = "provider:network_type";
+ private static final String ID = "id";
+
+ @Override
+ public OpenstackNetwork decode(ObjectNode json, CodecContext context) {
+
+ JsonNode networkInfo = json.get(NETWORK);
+
+ String name = networkInfo.path(NAME).asText();
+ String tenantId = networkInfo.path(TENANT_ID).asText();
+ String id = networkInfo.path(ID).asText();
+
+ OpenstackNetwork.Builder onb = OpenstackNetwork.builder();
+ onb.name(name)
+ .tenantId(tenantId)
+ .id(id);
+
+ if (!networkInfo.path(NETWORK_TYPE).isMissingNode()) {
+ onb.name(networkInfo.path(NETWORK_TYPE).asText());
+ onb.segmentId(networkInfo.path(SEGMENTATION_ID).asText());
+ }
+
+ return onb.build();
+ }
+
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java
new file mode 100644
index 00000000..f4c401fb
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkWebResource.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching.web;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.openstackswitching.OpenstackNetwork;
+import org.onosproject.openstackswitching.OpenstackSwitchingService;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+
+@Path("networks")
+public class OpenstackNetworkWebResource extends AbstractWebResource {
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(OpenstackNetworkWebResource.class);
+
+ private static final OpenstackNetworkCodec NETWORK_CODEC = new OpenstackNetworkCodec();
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createNetwork(InputStream input) {
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode networkNode = (ObjectNode) mapper.readTree(input);
+
+ OpenstackNetwork openstackNetwork = NETWORK_CODEC.decode(networkNode, this);
+
+ OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class);
+ switchingService.createNetwork(openstackNetwork);
+ return Response.status(Response.Status.OK).build();
+ } catch (Exception e) {
+ log.error("Creates VirtualPort failed because of exception {}",
+ e.toString());
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
+ .build();
+ }
+ }
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java
new file mode 100644
index 00000000..765b6901
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching.web;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.openstackswitching.OpenstackPort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+
+/**
+ * It encodes and decodes the OpenstackPort.
+ */
+public class OpenstackPortCodec extends JsonCodec<OpenstackPort> {
+
+ private static Logger log = LoggerFactory
+ .getLogger(OpenstackPortCodec.class);
+
+ // JSON field names
+ private static final String PORT = "port";
+ private static final String STATUS = "status";
+ private static final String NAME = "name";
+ private static final String ADDRESS_PAIR = "allowed_address_pairs";
+ private static final String ADMIN_STATUS = "admin_status";
+ private static final String NETWORK_ID = "network_id";
+ private static final String TENANT_ID = "tenant_id";
+ private static final String DEVICE_OWNER = "device_owner";
+ private static final String MAC_ADDRESS = "mac_address";
+ private static final String FIXED_IPS = "fixed_ips";
+ private static final String SUBNET_ID = "subnet_id";
+ private static final String IP_ADDRESS = "ip_address";
+ private static final String ID = "id";
+ private static final String SECURITY_GROUPS = "security_groups";
+ private static final String DEVICE_ID = "device_id";
+
+ @Override
+ public OpenstackPort decode(ObjectNode json, CodecContext context) {
+
+ HashMap<String, Ip4Address> fixedIpMap = new HashMap<>();
+ JsonNode portInfo = json.get(PORT);
+
+ String status = portInfo.path(STATUS).asText();
+ String name = portInfo.path(NAME).asText();
+ boolean adminStateUp = portInfo.path(ADMIN_STATUS).asBoolean();
+ String networkId = portInfo.path(NETWORK_ID).asText();
+ String tenantId = portInfo.path(TENANT_ID).asText();
+ String deviceOwner = portInfo.path(DEVICE_OWNER).asText();
+ String macStr = portInfo.path(MAC_ADDRESS).asText();
+ ArrayNode fixedIpList = (ArrayNode) portInfo.path(FIXED_IPS);
+ for (JsonNode fixedIpInfo: fixedIpList) {
+ String subnetId = fixedIpInfo.path(SUBNET_ID).asText();
+ String ipAddressStr = fixedIpInfo.path(IP_ADDRESS).asText();
+ if (ipAddressStr != null) {
+ Ip4Address ipAddress = Ip4Address.valueOf(ipAddressStr);
+ fixedIpMap.put(subnetId, ipAddress);
+ }
+ }
+ String id = portInfo.path(ID).asText();
+ String securityGroups = portInfo.path(SECURITY_GROUPS).asText();
+ String deviceId = portInfo.path(DEVICE_ID).asText();
+
+ OpenstackPort.Builder openstackPortBuilder = OpenstackPort.builder();
+ openstackPortBuilder.portStatus(OpenstackPort.PortStatus.valueOf(status))
+ .name(name)
+ .adminState(adminStateUp)
+ .netwrokId(networkId)
+ .tenantId(tenantId)
+ .deviceOwner(deviceOwner)
+ .macAddress(MacAddress.valueOf(macStr))
+ .fixedIps(fixedIpMap)
+ .id(id)
+ .deviceId(deviceId);
+
+ // FIX ME
+ if (!securityGroups.isEmpty()) {
+ openstackPortBuilder.securityGroup(securityGroups);
+ }
+
+ OpenstackPort openstackPort = openstackPortBuilder.build();
+
+ return openstackPort;
+ }
+
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java
new file mode 100644
index 00000000..67a9cebb
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching.web;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.openstackswitching.OpenstackPort;
+import org.onosproject.openstackswitching.OpenstackSwitchingService;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+
+@Path("ports")
+public class OpenstackPortWebResource extends AbstractWebResource {
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(OpenstackPortWebResource.class);
+
+ private static final OpenstackPortCodec PORT_CODEC = new OpenstackPortCodec();
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createPorts(InputStream input) {
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode portNode = (ObjectNode) mapper.readTree(input);
+
+ OpenstackPort openstackPort = PORT_CODEC.decode(portNode, this);
+
+ OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class);
+ switchingService.createPorts(openstackPort);
+ log.info("REST API ports is called with {}", portNode.toString());
+ return Response.status(Response.Status.OK).build();
+ } catch (Exception e) {
+ log.error("Creates VirtualPort failed because of exception {}",
+ e.toString());
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
+ .build();
+ }
+ }
+
+ @DELETE
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response deletesPorts(InputStream input) {
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode portNode = (ObjectNode) mapper.readTree(input);
+
+ OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class);
+ switchingService.deletePorts();
+ log.info("REST API ports is called with {}", portNode.toString());
+ return Response.status(Response.Status.OK).build();
+ } catch (Exception e) {
+ log.error("Delete VirtualPort failed because of exception {}",
+ e.toString());
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
+ .build();
+ }
+ }
+
+ @PUT
+ @Path("{id}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response updatePorts(InputStream input) {
+ try {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode portNode = (ObjectNode) mapper.readTree(input);
+
+ OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class);
+ switchingService.updatePorts();
+ log.info("REST API ports is called with {}", portNode.toString());
+ return Response.status(Response.Status.OK).build();
+ } catch (Exception e) {
+ log.error("Update VirtualPort failed because of exception {}",
+ e.toString());
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
+ .build();
+ }
+ }
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java
new file mode 100644
index 00000000..91e19c62
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * OpenStack switching REST API.
+ */
+package org.onosproject.openstackswitching.web;
diff --git a/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000..53b0e2e9
--- /dev/null
+++ b/framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="ONOS" version="2.5">
+ <display-name>Openstack Switching REST API v1.0</display-name>
+
+ <servlet>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+ <init-param>
+ <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
+ <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
+ </init-param>
+ <init-param>
+ <param-name>com.sun.jersey.config.property.classnames</param-name>
+ <param-value>
+ org.onosproject.openstackswitching.web.OpenstackPortWebResource,
+ org.onosproject.openstackswitching.web.OpenstackNetworkWebResource
+ </param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+</web-app>
diff --git a/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java b/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java
index 8466b95e..e0545023 100644
--- a/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java
+++ b/framework/src/onos/apps/optical/src/main/java/org/onosproject/optical/OpticalPathProvisioner.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.optical;
+import com.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -45,16 +46,16 @@ import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.OpticalCircuitIntent;
import org.onosproject.net.intent.OpticalConnectivityIntent;
import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.newresource.ResourceAllocation;
import org.onosproject.net.newresource.ResourceService;
import org.onosproject.net.resource.device.IntentSetMultimap;
-import org.onosproject.net.resource.link.LinkResourceAllocations;
-import org.onosproject.net.resource.link.LinkResourceService;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.TopologyEdge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
@@ -101,9 +102,6 @@ public class OpticalPathProvisioner {
protected IntentSetMultimap intentSetMultimap;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LinkResourceService linkResourceService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ResourceService resourceService;
private ApplicationId appId;
@@ -377,17 +375,17 @@ public class OpticalPathProvisioner {
* @param intent the intent
*/
private void releaseResources(Intent intent) {
- LinkResourceAllocations lra = linkResourceService.getAllocations(intent.id());
+ Collection<ResourceAllocation> allocations = resourceService.getResourceAllocations(intent.id());
if (intent instanceof OpticalConnectivityIntent) {
resourceService.release(intent.id());
- if (lra != null) {
- linkResourceService.releaseResources(lra);
+ if (!allocations.isEmpty()) {
+ resourceService.release(ImmutableList.copyOf(allocations));
}
} else if (intent instanceof OpticalCircuitIntent) {
resourceService.release(intent.id());
intentSetMultimap.releaseMapping(intent.id());
- if (lra != null) {
- linkResourceService.releaseResources(lra);
+ if (!allocations.isEmpty()) {
+ resourceService.release(ImmutableList.copyOf(allocations));
}
}
}
diff --git a/framework/src/onos/apps/pom.xml b/framework/src/onos/apps/pom.xml
index 98210736..005052fb 100644
--- a/framework/src/onos/apps/pom.xml
+++ b/framework/src/onos/apps/pom.xml
@@ -13,10 +13,7 @@
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
- -->
-<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/maven-v4_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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -60,6 +57,7 @@
<module>igmp</module>
<module>pim</module>
<module>mlb</module>
+ <module>openstackswitching</module>
</modules>
<properties>
diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
index b2ce0f8a..a27baaf9 100644
--- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
+++ b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
@@ -15,8 +15,6 @@
*/
package org.onosproject.sdnip;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.IPv6;
@@ -27,6 +25,8 @@ import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -43,7 +43,9 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -69,9 +71,10 @@ public class PeerConnectivityManager {
private final ApplicationId appId;
private final ApplicationId routerAppId;
- // Just putting something random here for now. Figure out exactly what
- // indexes we need when we start making use of them.
- private final Multimap<BgpConfig.BgpSpeakerConfig, PointToPointIntent> peerIntents;
+ private final Map<Key, PointToPointIntent> peerIntents;
+
+ private final InternalNetworkConfigListener configListener
+ = new InternalNetworkConfigListener();
/**
* Creates a new PeerConnectivityManager.
@@ -93,13 +96,14 @@ public class PeerConnectivityManager {
this.routerAppId = routerAppId;
this.interfaceService = interfaceService;
- peerIntents = HashMultimap.create();
+ peerIntents = new HashMap<>();
}
/**
* Starts the peer connectivity manager.
*/
public void start() {
+ configService.addListener(configListener);
setUpConnectivity();
}
@@ -107,6 +111,7 @@ public class PeerConnectivityManager {
* Stops the peer connectivity manager.
*/
public void stop() {
+ configService.removeListener(configListener);
}
/**
@@ -121,16 +126,27 @@ public class PeerConnectivityManager {
return;
}
+ Map<Key, PointToPointIntent> existingIntents = new HashMap<>(peerIntents);
+
for (BgpConfig.BgpSpeakerConfig bgpSpeaker : config.bgpSpeakers()) {
log.debug("Start to set up BGP paths for BGP speaker: {}",
bgpSpeaker);
buildSpeakerIntents(bgpSpeaker).forEach(i -> {
- peerIntents.put(bgpSpeaker, i);
- intentSynchronizer.submit(i);
+ PointToPointIntent intent = existingIntents.remove(i.key());
+ if (intent == null || !IntentUtils.equals(i, intent)) {
+ peerIntents.put(i.key(), i);
+ intentSynchronizer.submit(i);
+ }
});
-
}
+
+ // Remove any remaining intents that we used to have that we don't need
+ // anymore
+ existingIntents.values().forEach(i -> {
+ peerIntents.remove(i.key());
+ intentSynchronizer.withdraw(i);
+ });
}
private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) {
@@ -356,7 +372,7 @@ public class PeerConnectivityManager {
* @param srcIp source IP address
* @param dstIp destination IP address
* @param suffix suffix string
- * @return
+ * @return intent key
*/
private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) {
String keyString = new StringBuilder()
@@ -370,4 +386,26 @@ public class PeerConnectivityManager {
return Key.of(keyString, appId);
}
+ private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+ @Override
+ public void event(NetworkConfigEvent event) {
+ switch (event.type()) {
+ case CONFIG_REGISTERED:
+ break;
+ case CONFIG_UNREGISTERED:
+ break;
+ case CONFIG_ADDED:
+ case CONFIG_UPDATED:
+ case CONFIG_REMOVED:
+ if (event.configClass() == RoutingService.CONFIG_CLASS) {
+ setUpConnectivity();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
}
diff --git a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
index c4b2daad..0dcc969d 100644
--- a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
+++ b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
@@ -34,6 +34,7 @@ import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -60,8 +61,10 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
@@ -119,6 +122,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest {
routingConfig = createMock(RoutingConfigurationService.class);
interfaceService = createMock(InterfaceService.class);
networkConfigService = createMock(NetworkConfigService.class);
+ networkConfigService.addListener(anyObject(NetworkConfigListener.class));
+ expectLastCall().anyTimes();
bgpConfig = createMock(BgpConfig.class);
// These will set expectations on routingConfig and interfaceService
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
index f42f84b1..36563f01 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
@@ -35,7 +35,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
-import java.util.List;
+import java.util.Set;
+
import static com.google.common.base.Preconditions.checkNotNull;
public class ArpHandler {
@@ -112,7 +113,7 @@ public class ArpHandler {
private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) {
- List<Ip4Address> gatewayIpAddresses = config.getSubnetGatewayIps(deviceId);
+ Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
if (gatewayIpAddresses != null) {
Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest
.getTargetProtocolAddress());
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
index 40ee55fc..c4a91c75 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -23,14 +23,12 @@ import org.onlab.packet.IpPrefix;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
-import org.onosproject.net.MastershipRole;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -97,7 +95,7 @@ public class DefaultRoutingHandler {
log.debug("populateAllRoutingRules: populationStatus is STARTED");
for (Device sw : srManager.deviceService.getDevices()) {
- if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) {
+ if (!srManager.mastershipService.isLocalMaster(sw.id())) {
log.debug("populateAllRoutingRules: skipping device {}...we are not master",
sw.id());
continue;
@@ -146,8 +144,7 @@ public class DefaultRoutingHandler {
// Take the snapshots of the links
updatedEcmpSpgMap = new HashMap<>();
for (Device sw : srManager.deviceService.getDevices()) {
- if (srManager.mastershipService.
- getLocalRole(sw.id()) != MastershipRole.MASTER) {
+ if (!srManager.mastershipService.isLocalMaster(sw.id())) {
continue;
}
ECMPShortestPathGraph ecmpSpgUpdated =
@@ -273,8 +270,7 @@ public class DefaultRoutingHandler {
for (Device sw : srManager.deviceService.getDevices()) {
log.debug("Computing the impacted routes for device {} due to link fail",
sw.id());
- if (srManager.mastershipService.
- getLocalRole(sw.id()) != MastershipRole.MASTER) {
+ if (!srManager.mastershipService.isLocalMaster(sw.id())) {
continue;
}
ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id());
@@ -320,8 +316,7 @@ public class DefaultRoutingHandler {
for (Device sw : srManager.deviceService.getDevices()) {
log.debug("Computing the impacted routes for device {}",
sw.id());
- if (srManager.mastershipService.
- getLocalRole(sw.id()) != MastershipRole.MASTER) {
+ if (!srManager.mastershipService.isLocalMaster(sw.id())) {
log.debug("No mastership for {} and skip route optimization",
sw.id());
continue;
@@ -455,7 +450,7 @@ public class DefaultRoutingHandler {
// If both target switch and dest switch are edge routers, then set IP
// rule for both subnet and router IP.
if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) {
- List<Ip4Prefix> subnets = config.getSubnets(destSw);
+ Set<Ip4Prefix> subnets = config.getSubnets(destSw);
log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}",
targetSw, destSw, subnets);
result = rulePopulator.populateIpRuleForSubnet(targetSw,
@@ -499,14 +494,13 @@ public class DefaultRoutingHandler {
}
/**
- * Populates table miss entries for all tables, and pipeline rules for VLAN
- * and TCAM tables. XXX rename/rethink
+ * Populates filtering rules for permitting Router DstMac and VLAN.
*
* @param deviceId Switch ID to set the rules
*/
- public void populateTtpRules(DeviceId deviceId) {
- rulePopulator.populateTableVlan(deviceId);
- rulePopulator.populateTableTMac(deviceId);
+ public void populatePortAddressingRules(DeviceId deviceId) {
+ rulePopulator.populateRouterMacVlanFilters(deviceId);
+ rulePopulator.populateRouterIpPunts(deviceId);
}
/**
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
index 0bc155b8..828c51ce 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.segmentrouting;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
@@ -38,20 +39,20 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Segment Routing configuration component that reads the
* segment routing related configuration from Network Configuration Manager
* component and organizes in more accessible formats.
- *
- * TODO: Merge multiple Segment Routing configuration wrapper classes into one.
*/
public class DeviceConfiguration implements DeviceProperties {
private static final Logger log = LoggerFactory
.getLogger(DeviceConfiguration.class);
private final List<Integer> allSegmentIds = new ArrayList<>();
- private final HashMap<DeviceId, SegmentRouterInfo> deviceConfigMap = new HashMap<>();
+ private final ConcurrentHashMap<DeviceId, SegmentRouterInfo> deviceConfigMap
+ = new ConcurrentHashMap<>();
private class SegmentRouterInfo {
int nodeSid;
@@ -126,18 +127,17 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
- * Returns the segment id of a segment router.
+ * Returns the Node segment id of a segment router.
*
* @param deviceId device identifier
* @return segment id
*/
@Override
public int getSegmentId(DeviceId deviceId) {
- if (deviceConfigMap.get(deviceId) != null) {
- log.trace("getSegmentId for device{} is {}",
- deviceId,
- deviceConfigMap.get(deviceId).nodeSid);
- return deviceConfigMap.get(deviceId).nodeSid;
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid);
+ return srinfo.nodeSid;
} else {
log.warn("getSegmentId for device {} "
+ "throwing IllegalStateException "
@@ -147,10 +147,10 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
- * Returns the segment id of a segment router given its mac address.
+ * Returns the Node segment id of a segment router given its Router mac address.
*
* @param routerMac router mac address
- * @return segment id
+ * @return node segment id, or -1 if not found in config
*/
public int getSegmentId(MacAddress routerMac) {
for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
@@ -164,10 +164,10 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
- * Returns the segment id of a segment router given its router ip address.
+ * Returns the Node segment id of a segment router given its Router ip address.
*
* @param routerAddress router ip address
- * @return segment id
+ * @return node segment id, or -1 if not found in config
*/
public int getSegmentId(Ip4Address routerAddress) {
for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
@@ -188,11 +188,10 @@ public class DeviceConfiguration implements DeviceProperties {
*/
@Override
public MacAddress getDeviceMac(DeviceId deviceId) {
- if (deviceConfigMap.get(deviceId) != null) {
- log.trace("getDeviceMac for device{} is {}",
- deviceId,
- deviceConfigMap.get(deviceId).mac);
- return deviceConfigMap.get(deviceId).mac;
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac);
+ return srinfo.mac;
} else {
log.warn("getDeviceMac for device {} "
+ "throwing IllegalStateException "
@@ -208,11 +207,10 @@ public class DeviceConfiguration implements DeviceProperties {
* @return router ip address
*/
public Ip4Address getRouterIp(DeviceId deviceId) {
- if (deviceConfigMap.get(deviceId) != null) {
- log.trace("getDeviceIp for device{} is {}",
- deviceId,
- deviceConfigMap.get(deviceId).ip);
- return deviceConfigMap.get(deviceId).ip;
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip);
+ return srinfo.ip;
} else {
log.warn("getRouterIp for device {} "
+ "throwing IllegalStateException "
@@ -223,18 +221,17 @@ public class DeviceConfiguration implements DeviceProperties {
/**
* Indicates if the segment router is a edge router or
- * a transit/back bone router.
+ * a core/backbone router.
*
* @param deviceId device identifier
* @return boolean
*/
@Override
public boolean isEdgeDevice(DeviceId deviceId) {
- if (deviceConfigMap.get(deviceId) != null) {
- log.trace("isEdgeDevice for device{} is {}",
- deviceId,
- deviceConfigMap.get(deviceId).isEdge);
- return deviceConfigMap.get(deviceId).isEdge;
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge);
+ return srinfo.isEdge;
} else {
log.warn("isEdgeDevice for device {} "
+ "throwing IllegalStateException "
@@ -244,15 +241,35 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
- * Returns the segment ids of all configured segment routers.
+ * Returns the node segment ids of all configured segment routers.
*
- * @return list of segment ids
+ * @return list of node segment ids
*/
@Override
public List<Integer> getAllDeviceSegmentIds() {
return allSegmentIds;
}
+ @Override
+ public Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId) {
+ Map<Ip4Prefix, List<PortNumber>> subnetPortMap = new HashMap<>();
+
+ // Construct subnet-port mapping from port-subnet mapping
+ Map<PortNumber, Ip4Prefix> portSubnetMap =
+ this.deviceConfigMap.get(deviceId).subnets;
+ portSubnetMap.forEach((port, subnet) -> {
+ if (subnetPortMap.containsKey(subnet)) {
+ subnetPortMap.get(subnet).add(port);
+ } else {
+ ArrayList<PortNumber> ports = new ArrayList<>();
+ ports.add(port);
+ subnetPortMap.put(subnet, ports);
+ }
+ });
+
+ return subnetPortMap;
+ }
+
/**
* Returns the device identifier or data plane identifier (dpid)
* of a segment router given its segment id.
@@ -290,37 +307,68 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
- * Returns the configured subnet gateway ip addresses for a segment router.
+ * Returns the configured port ip addresses for a segment router.
+ * These addresses serve as gateway IP addresses for the subnets configured
+ * on those ports.
*
* @param deviceId device identifier
- * @return list of ip addresses
+ * @return immutable set of ip addresses configured on the ports or null if not found
*/
- public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) {
- if (deviceConfigMap.get(deviceId) != null) {
- log.trace("getSubnetGatewayIps for device{} is {}",
- deviceId,
- deviceConfigMap.get(deviceId).gatewayIps.values());
- return new ArrayList<>(deviceConfigMap.get(deviceId).gatewayIps.values());
- } else {
- return null;
+ public Set<Ip4Address> getPortIPs(DeviceId deviceId) {
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ log.trace("getSubnetGatewayIps for device{} is {}", deviceId,
+ srinfo.gatewayIps.values());
+ return ImmutableSet.copyOf(srinfo.gatewayIps.values());
+ }
+ return null;
+ }
+
+ /**
+ * Returns the configured IP addresses per port
+ * for a segment router.
+ *
+ * @param deviceId device identifier
+ * @return map of port to gateway IP addresses or null if not found
+ */
+ public Map<PortNumber, Ip4Address> getPortIPMap(DeviceId deviceId) {
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ return srinfo.gatewayIps;
}
+ return null;
}
/**
* Returns the configured subnet prefixes for a segment router.
*
* @param deviceId device identifier
- * @return list of ip prefixes
+ * @return list of ip prefixes or null if not found
*/
- public List<Ip4Prefix> getSubnets(DeviceId deviceId) {
- if (deviceConfigMap.get(deviceId) != null) {
- log.trace("getSubnets for device{} is {}",
- deviceId,
- deviceConfigMap.get(deviceId).subnets.values());
- return new ArrayList<>(deviceConfigMap.get(deviceId).subnets.values());
- } else {
- return null;
+ public Set<Ip4Prefix> getSubnets(DeviceId deviceId) {
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ log.trace("getSubnets for device{} is {}", deviceId,
+ srinfo.subnets.values());
+ return ImmutableSet.copyOf(srinfo.subnets.values());
}
+ return null;
+ }
+
+ /**
+ * Returns the configured subnet on the given port, or null if no
+ * subnet has been configured on the port.
+ *
+ * @param deviceId device identifier
+ * @param pnum port identifier
+ * @return configured subnet on port, or null
+ */
+ public Ip4Prefix getPortSubnet(DeviceId deviceId, PortNumber pnum) {
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ return srinfo.subnets.get(pnum);
+ }
+ return null;
}
/**
@@ -349,7 +397,7 @@ public class DeviceConfiguration implements DeviceProperties {
* specified ip address as one of its subnet gateway ip address.
*
* @param gatewayIpAddress router gateway ip address
- * @return router mac address
+ * @return router mac address or null if not found
*/
public MacAddress getRouterMacForAGatewayIp(Ip4Address gatewayIpAddress) {
for (Map.Entry<DeviceId, SegmentRouterInfo> entry:
@@ -377,7 +425,7 @@ public class DeviceConfiguration implements DeviceProperties {
*/
public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) {
- List<Ip4Prefix> subnets = getSubnets(deviceId);
+ Set<Ip4Prefix> subnets = getSubnets(deviceId);
if (subnets == null) {
return false;
}
@@ -399,8 +447,9 @@ public class DeviceConfiguration implements DeviceProperties {
* @return list of port numbers
*/
public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
- if (deviceConfigMap.get(deviceId) != null) {
- for (AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) {
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ for (AdjacencySid asid : srinfo.adjacencySids) {
if (asid.getAsid() == sid) {
return asid.getPorts();
}
@@ -419,12 +468,13 @@ public class DeviceConfiguration implements DeviceProperties {
* otherwise false
*/
public boolean isAdjacencySid(DeviceId deviceId, int sid) {
- if (deviceConfigMap.get(deviceId) != null) {
- if (deviceConfigMap.get(deviceId).adjacencySids.isEmpty()) {
+ SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+ if (srinfo != null) {
+ if (srinfo.adjacencySids.isEmpty()) {
return false;
} else {
for (AdjacencySid asid:
- deviceConfigMap.get(deviceId).adjacencySids) {
+ srinfo.adjacencySids) {
if (asid.getAsid() == sid) {
return true;
}
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
index f65f03e0..b3916b06 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -32,7 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
-import java.util.List;
+import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -70,7 +70,7 @@ public class IcmpHandler {
DeviceId deviceId = connectPoint.deviceId();
Ip4Address destinationAddress =
Ip4Address.valueOf(ipv4.getDestinationAddress());
- List<Ip4Address> gatewayIpAddresses = config.getSubnetGatewayIps(deviceId);
+ Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
Ip4Address routerIp = config.getRouterIp(deviceId);
IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address();
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index 7641571d..d46028e7 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -25,6 +25,7 @@ import org.onlab.packet.VlanId;
import org.onosproject.segmentrouting.grouphandler.NeighborSet;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
+import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -38,11 +39,13 @@ import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
import org.onosproject.net.flowobjective.ObjectiveContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
@@ -57,6 +60,11 @@ public class RoutingRulePopulator {
private AtomicLong rulePopulationCounter;
private SegmentRoutingManager srManager;
private DeviceConfiguration config;
+
+ private static final int HIGHEST_PRIORITY = 0xffff;
+ private static final long OFPP_MAX = 0xffffff00L;
+
+
/**
* Creates a RoutingRulePopulator object.
*
@@ -98,7 +106,7 @@ public class RoutingRulePopulator {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
- sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32));
+ sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH));
sbuilder.matchEthType(Ethernet.TYPE_IPV4);
tbuilder.deferred()
@@ -134,7 +142,7 @@ public class RoutingRulePopulator {
* @return true if all rules are set successfully, false otherwise
*/
public boolean populateIpRuleForSubnet(DeviceId deviceId,
- List<Ip4Prefix> subnets,
+ Set<Ip4Prefix> subnets,
DeviceId destSw,
Set<DeviceId> nextHops) {
@@ -350,40 +358,80 @@ public class RoutingRulePopulator {
}
/**
- * Populates VLAN flows rules. All packets are forwarded to TMAC table.
+ * Creates a filtering objective to permit all untagged packets with a
+ * dstMac corresponding to the router's MAC address. For those pipelines
+ * that need to internally assign vlans to untagged packets, this method
+ * provides per-subnet vlan-ids as metadata.
+ * <p>
+ * Note that the vlan assignment is only done by the master-instance for a switch.
+ * However we send the filtering objective from slave-instances as well, so
+ * that drivers can obtain other information (like Router MAC and IP).
*
- * @param deviceId switch ID to set the rules
+ * @param deviceId the switch dpid for the router
*/
- public void populateTableVlan(DeviceId deviceId) {
- FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
- fob.withKey(Criteria.matchInPort(PortNumber.ALL))
+ public void populateRouterMacVlanFilters(DeviceId deviceId) {
+ log.debug("Installing per-port filtering objective for untagged "
+ + "packets in device {}", deviceId);
+ for (Port port : srManager.deviceService.getPorts(deviceId)) {
+ if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
+ Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number());
+ VlanId assignedVlan = (portSubnet == null)
+ ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)
+ : srManager.getSubnetAssignedVlanId(deviceId, portSubnet);
+ FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
+ fob.withKey(Criteria.matchInPort(port.number()))
+ .addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId)))
.addCondition(Criteria.matchVlanId(VlanId.NONE));
- fob.permit().fromApp(srManager.appId);
- log.debug("populateTableVlan: Installing filtering objective for untagged packets");
- srManager.flowObjectiveService.
- filter(deviceId,
- fob.add(new SRObjectiveContext(deviceId,
- SRObjectiveContext.ObjectiveType.FILTER)));
+ // vlan assignment is valid only if this instance is master
+ if (srManager.mastershipService.isLocalMaster(deviceId)) {
+ TrafficTreatment tt = DefaultTrafficTreatment.builder()
+ .pushVlan().setVlanId(assignedVlan).build();
+ fob.setMeta(tt);
+ }
+ fob.permit().fromApp(srManager.appId);
+ srManager.flowObjectiveService.
+ filter(deviceId, fob.add(new SRObjectiveContext(deviceId,
+ SRObjectiveContext.ObjectiveType.FILTER)));
+ }
+ }
}
/**
- * Populates TMAC table rules. IP packets are forwarded to IP table. MPLS
- * packets are forwarded to MPLS table.
+ * Creates a forwarding objective to punt all IP packets, destined to the
+ * router's port IP addresses, to the controller. Note that the input
+ * port should not be matched on, as these packets can come from any input.
+ * Furthermore, these are applied only by the master instance.
*
- * @param deviceId switch ID to set the rules
+ * @param deviceId the switch dpid for the router
*/
- public void populateTableTMac(DeviceId deviceId) {
-
- FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
- fob.withKey(Criteria.matchInPort(PortNumber.ALL))
- .addCondition(Criteria.matchEthDst(config
- .getDeviceMac(deviceId)));
- fob.permit().fromApp(srManager.appId);
- log.debug("populateTableTMac: Installing filtering objective for router mac");
- srManager.flowObjectiveService.
- filter(deviceId,
- fob.add(new SRObjectiveContext(deviceId,
- SRObjectiveContext.ObjectiveType.FILTER)));
+ public void populateRouterIpPunts(DeviceId deviceId) {
+ if (!srManager.mastershipService.isLocalMaster(deviceId)) {
+ log.debug("Not installing port-IP punts - not the master for dev:{} ",
+ deviceId);
+ return;
+ }
+ ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder();
+ Set<Ip4Address> allIps = new HashSet<Ip4Address>(config.getPortIPs(deviceId));
+ allIps.add(config.getRouterIp(deviceId));
+ for (Ip4Address ipaddr : allIps) {
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ selector.matchEthType(Ethernet.TYPE_IPV4);
+ selector.matchIPDst(IpPrefix.valueOf(ipaddr,
+ IpPrefix.MAX_INET_MASK_LENGTH));
+ treatment.setOutput(PortNumber.CONTROLLER);
+ puntIp.withSelector(selector.build());
+ puntIp.withTreatment(treatment.build());
+ puntIp.withFlag(Flag.VERSATILE)
+ .withPriority(HIGHEST_PRIORITY)
+ .makePermanent()
+ .fromApp(srManager.appId);
+ log.debug("Installing forwarding objective to punt port IP addresses");
+ srManager.flowObjectiveService.
+ forward(deviceId,
+ puntIp.add(new SRObjectiveContext(deviceId,
+ SRObjectiveContext.ObjectiveType.FORWARDING)));
+ }
}
private PortNumber selectOnePort(DeviceId srcId, Set<DeviceId> destIds) {
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index eb2cf569..9d60b279 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -22,11 +22,17 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.VlanId;
import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.event.Event;
+import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigRegistry;
@@ -45,7 +51,6 @@ import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.group.GroupKey;
import org.onosproject.net.host.HostService;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.link.LinkEvent;
@@ -56,6 +61,7 @@ import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.topology.TopologyService;
+import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapBuilder;
import org.onosproject.store.service.StorageService;
@@ -64,9 +70,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
@@ -133,8 +141,13 @@ public class SegmentRoutingManager implements SegmentRoutingService {
// Per device next objective ID store with (device id + neighbor set) as key
private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore = null;
+ private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null;
private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
private EventuallyConsistentMap<String, Policy> policyStore = null;
+ // Per device, per-subnet assigned-vlans store, with (device id + subnet
+ // IPv4 prefix) as key
+ private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId>
+ subnetVidStore = null;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@@ -163,6 +176,9 @@ public class SegmentRoutingManager implements SegmentRoutingService {
private KryoNamespace.Builder kryoBuilder = null;
+ private static final short ASSIGNED_VLAN_START = 4093;
+ public static final short ASSIGNED_VLAN_NO_SUBNET = 4094;
+
@Activate
protected void activate() {
appId = coreService
@@ -170,6 +186,8 @@ public class SegmentRoutingManager implements SegmentRoutingService {
kryoBuilder = new KryoNamespace.Builder()
.register(NeighborSetNextObjectiveStoreKey.class,
+ SubnetNextObjectiveStoreKey.class,
+ SubnetAssignedVidStoreKey.class,
NeighborSet.class,
DeviceId.class,
URI.class,
@@ -180,7 +198,12 @@ public class SegmentRoutingManager implements SegmentRoutingService {
DefaultTunnel.class,
Policy.class,
TunnelPolicy.class,
- Policy.Type.class
+ Policy.Type.class,
+ VlanId.class,
+ Ip4Address.class,
+ Ip4Prefix.class,
+ IpAddress.Version.class,
+ ConnectPoint.class
);
log.debug("Creating EC map nsnextobjectivestore");
@@ -194,6 +217,16 @@ public class SegmentRoutingManager implements SegmentRoutingService {
.build();
log.trace("Current size {}", nsNextObjStore.size());
+ log.debug("Creating EC map subnetnextobjectivestore");
+ EventuallyConsistentMapBuilder<SubnetNextObjectiveStoreKey, Integer>
+ subnetNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
+
+ subnetNextObjStore = subnetNextObjMapBuilder
+ .withName("subnetnextobjectivestore")
+ .withSerializer(kryoBuilder)
+ .withTimestampProvider((k, v) -> new WallClockTimestamp())
+ .build();
+
EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
storageService.eventuallyConsistentMapBuilder();
@@ -212,6 +245,15 @@ public class SegmentRoutingManager implements SegmentRoutingService {
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
+ EventuallyConsistentMapBuilder<SubnetAssignedVidStoreKey, VlanId>
+ subnetVidStoreMapBuilder = storageService.eventuallyConsistentMapBuilder();
+
+ subnetVidStore = subnetVidStoreMapBuilder
+ .withName("subnetvidstore")
+ .withSerializer(kryoBuilder)
+ .withTimestampProvider((k, v) -> new WallClockTimestamp())
+ .build();
+
cfgService.addListener(cfgListener);
cfgService.registerConfigFactory(cfgFactory);
@@ -296,23 +338,72 @@ public class SegmentRoutingManager implements SegmentRoutingService {
}
/**
- * Returns the GroupKey object for the device and the NeighborSet given.
- * XXX is this called
+ * Returns the vlan-id assigned to the subnet configured for a device.
+ * If no vlan-id has been assigned, a new one is assigned out of a pool of ids,
+ * if and only if this controller instance is the master for the device.
+ * <p>
+ * USAGE: The assigned vlans are meant to be applied to untagged packets on those
+ * switches/pipelines that need this functionality. These vids are meant
+ * to be used internally within a switch, and thus need to be unique only
+ * on a switch level. Note that packets never go out on the wire with these
+ * vlans. Currently, vlan ids are assigned from value 4093 down.
+ * Vlan id 4094 expected to be used for all ports that are not assigned subnets.
+ * Vlan id 4095 is reserved and unused. Only a single vlan id is assigned
+ * per subnet.
+ * XXX This method should avoid any vlans configured on the ports, but
+ * currently the app works only on untagged packets and as a result
+ * ignores any vlan configuration.
*
- * @param ns NeightborSet object for the GroupKey
- * @return GroupKey object for the NeighborSet
+ * @param deviceId switch dpid
+ * @param subnet IPv4 prefix for which assigned vlan is desired
+ * @return VlanId assigned for the subnet on the device, or
+ * null if no vlan assignment was found and this instance is not
+ * the master for the device.
*/
- public GroupKey getGroupKey(NeighborSet ns) {
- for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) {
- return groupHandler.getGroupKey(ns);
+ public VlanId getSubnetAssignedVlanId(DeviceId deviceId, Ip4Prefix subnet) {
+ VlanId assignedVid = subnetVidStore.get(new SubnetAssignedVidStoreKey(
+ deviceId, subnet));
+ if (assignedVid != null) {
+ log.debug("Query for subnet:{} on device:{} returned assigned-vlan "
+ + "{}", subnet, deviceId, assignedVid);
+ return assignedVid;
+ }
+ //check mastership for the right to assign a vlan
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ log.warn("This controller instance is not the master for device {}. "
+ + "Cannot assign vlan-id for subnet {}", deviceId, subnet);
+ return null;
+ }
+ // vlan assignment is expensive but done only once
+ Set<Ip4Prefix> configuredSubnets = deviceConfiguration.getSubnets(deviceId);
+ Set<Short> assignedVlans = new HashSet<>();
+ Set<Ip4Prefix> unassignedSubnets = new HashSet<>();
+ for (Ip4Prefix sub : configuredSubnets) {
+ VlanId v = subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId,
+ sub));
+ if (v != null) {
+ assignedVlans.add(v.toShort());
+ } else {
+ unassignedSubnets.add(sub);
+ }
+ }
+ short nextAssignedVlan = ASSIGNED_VLAN_START;
+ if (!assignedVlans.isEmpty()) {
+ nextAssignedVlan = (short) (Collections.min(assignedVlans) - 1);
+ }
+ for (Ip4Prefix unsub : unassignedSubnets) {
+ subnetVidStore.put(new SubnetAssignedVidStoreKey(deviceId, unsub),
+ VlanId.vlanId(nextAssignedVlan--));
+ log.info("Assigned vlan: {} to subnet: {} on device: {}",
+ nextAssignedVlan + 1, unsub, deviceId);
}
- return null;
+ return subnetVidStore.get(new SubnetAssignedVidStoreKey(deviceId, subnet));
}
/**
- * Returns the next objective ID for the NeighborSet given. If the nextObjectiveID does not exist,
- * a new one is created and returned.
+ * Returns the next objective ID for the given NeighborSet.
+ * If the nextObjectiveID does not exist, a new one is created and returned.
*
* @param deviceId Device ID
* @param ns NegighborSet
@@ -329,6 +420,25 @@ public class SegmentRoutingManager implements SegmentRoutingService {
}
}
+ /**
+ * Returns the next objective ID for the Subnet given. If the nextObjectiveID does not exist,
+ * a new one is created and returned.
+ *
+ * @param deviceId Device ID
+ * @param prefix Subnet
+ * @return next objective ID
+ */
+ public int getSubnetNextObjectiveId(DeviceId deviceId, IpPrefix prefix) {
+ if (groupHandlerMap.get(deviceId) != null) {
+ log.trace("getSubnetNextObjectiveId query in device {}", deviceId);
+ return groupHandlerMap
+ .get(deviceId).getSubnetNextObjectiveId(prefix);
+ } else {
+ log.warn("getSubnetNextObjectiveId query in device {} not found", deviceId);
+ return -1;
+ }
+ }
+
private class InternalPacketProcessor implements PacketProcessor {
@Override
public void process(PacketContext context) {
@@ -423,6 +533,8 @@ public class SegmentRoutingManager implements SegmentRoutingService {
event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
if (deviceService.isAvailable(((Device) event.subject()).id())) {
+ log.info("Processing device event {} for available device {}",
+ event.type(), ((Device) event.subject()).id());
processDeviceAdded((Device) event.subject());
}
} else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
@@ -484,20 +596,31 @@ public class SegmentRoutingManager implements SegmentRoutingService {
private void processDeviceAdded(Device device) {
log.debug("A new device with ID {} was added", device.id());
- //Irrespective whether the local is a MASTER or not for this device,
- //create group handler instance and push default TTP flow rules.
- //Because in a multi-instance setup, instances can initiate
- //groups for any devices. Also the default TTP rules are needed
- //to be pushed before inserting any IP table entries for any device
- DefaultGroupHandler dgh = DefaultGroupHandler.
+ // Irrespective of whether the local is a MASTER or not for this device,
+ // we need to create a SR-group-handler instance. This is because in a
+ // multi-instance setup, any instance can initiate forwarding/next-objectives
+ // for any switch (even if this instance is a SLAVE or not even connected
+ // to the switch). To handle this, a default-group-handler instance is necessary
+ // per switch.
+ DefaultGroupHandler groupHandler = DefaultGroupHandler.
createGroupHandler(device.id(),
appId,
deviceConfiguration,
linkService,
flowObjectiveService,
- nsNextObjStore);
- groupHandlerMap.put(device.id(), dgh);
- defaultRoutingHandler.populateTtpRules(device.id());
+ nsNextObjStore,
+ subnetNextObjStore);
+ groupHandlerMap.put(device.id(), groupHandler);
+
+ // Also, in some cases, drivers may need extra
+ // information to process rules (eg. Router IP/MAC); and so, we send
+ // port addressing rules to the driver as well irrespective of whether
+ // this instance is the master or not.
+ defaultRoutingHandler.populatePortAddressingRules(device.id());
+
+ if (mastershipService.isLocalMaster(device.id())) {
+ groupHandler.createGroupsFromSubnetConfig();
+ }
}
private void processPortRemoved(Device device, Port port) {
@@ -531,18 +654,29 @@ public class SegmentRoutingManager implements SegmentRoutingService {
tunnelHandler, policyStore);
for (Device device : deviceService.getDevices()) {
- //Irrespective whether the local is a MASTER or not for this device,
- //create group handler instance and push default TTP flow rules.
- //Because in a multi-instance setup, instances can initiate
- //groups for any devices. Also the default TTP rules are needed
- //to be pushed before inserting any IP table entries for any device
+ // Irrespective of whether the local is a MASTER or not for this device,
+ // we need to create a SR-group-handler instance. This is because in a
+ // multi-instance setup, any instance can initiate forwarding/next-objectives
+ // for any switch (even if this instance is a SLAVE or not even connected
+ // to the switch). To handle this, a default-group-handler instance is necessary
+ // per switch.
DefaultGroupHandler groupHandler = DefaultGroupHandler
.createGroupHandler(device.id(), appId,
deviceConfiguration, linkService,
flowObjectiveService,
- nsNextObjStore);
+ nsNextObjStore,
+ subnetNextObjStore);
groupHandlerMap.put(device.id(), groupHandler);
- defaultRoutingHandler.populateTtpRules(device.id());
+
+ // Also, in some cases, drivers may need extra
+ // information to process rules (eg. Router IP/MAC); and so, we send
+ // port addressing rules to the driver as well, irrespective of whether
+ // this instance is the master or not.
+ defaultRoutingHandler.populatePortAddressingRules(device.id());
+
+ if (mastershipService.isLocalMaster(device.id())) {
+ groupHandler.createGroupsFromSubnetConfig();
+ }
}
defaultRoutingHandler.startPopulationProcess();
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java
new file mode 100644
index 00000000..84b44c97
--- /dev/null
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SubnetAssignedVidStoreKey.java
@@ -0,0 +1,66 @@
+package org.onosproject.segmentrouting;
+
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Class definition for key used to map per device subnets to assigned Vlan ids.
+ *
+ */
+public class SubnetAssignedVidStoreKey {
+ private final DeviceId deviceId;
+ private final Ip4Prefix subnet;
+
+ public SubnetAssignedVidStoreKey(DeviceId deviceId, Ip4Prefix subnet) {
+ this.deviceId = deviceId;
+ this.subnet = subnet;
+ }
+
+ /**
+ * Returns the device identification used to create this key.
+ *
+ * @return the device identifier
+ */
+ public DeviceId deviceId() {
+ return deviceId;
+ }
+
+ /**
+ * Returns the subnet information used to create this key.
+ *
+ * @return the subnet
+ */
+ public Ip4Prefix subnet() {
+ return subnet;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SubnetAssignedVidStoreKey)) {
+ return false;
+ }
+ SubnetAssignedVidStoreKey that =
+ (SubnetAssignedVidStoreKey) o;
+ return (Objects.equals(this.deviceId, that.deviceId) &&
+ Objects.equals(this.subnet, that.subnet));
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + Objects.hashCode(deviceId)
+ + Objects.hashCode(subnet);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Device: " + deviceId + " Subnet: " + subnet;
+ }
+
+}
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java
index c960adca..a5c1090f 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java
@@ -52,9 +52,12 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
LinkService linkService,
FlowObjectiveService flowObjService,
EventuallyConsistentMap<
- NeighborSetNextObjectiveStoreKey,
- Integer> nsNextObjStore) {
- super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
+ NeighborSetNextObjectiveStoreKey,
+ Integer> nsNextObjStore,
+ EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
+ Integer> subnetNextObjStore) {
+ super(deviceId, appId, config, linkService, flowObjService,
+ nsNextObjStore, subnetNextObjStore);
}
@Override
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
index 9bbde2f3..69a0d86f 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -25,10 +25,11 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.util.KryoNamespace;
@@ -74,7 +75,8 @@ public class DefaultGroupHandler {
// new HashMap<NeighborSet, Integer>();
protected EventuallyConsistentMap<
NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null;
- protected Random rand = new Random();
+ protected EventuallyConsistentMap<
+ SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null;
protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
.register(URI.class).register(HashSet.class)
@@ -89,8 +91,10 @@ public class DefaultGroupHandler {
LinkService linkService,
FlowObjectiveService flowObjService,
EventuallyConsistentMap<
- NeighborSetNextObjectiveStoreKey,
- Integer> nsNextObjStore) {
+ NeighborSetNextObjectiveStoreKey,
+ Integer> nsNextObjStore,
+ EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
+ Integer> subnetNextObjStore) {
this.deviceId = checkNotNull(deviceId);
this.appId = checkNotNull(appId);
this.deviceConfig = checkNotNull(config);
@@ -101,6 +105,7 @@ public class DefaultGroupHandler {
nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
this.flowObjectiveService = flowObjService;
this.nsNextObjStore = nsNextObjStore;
+ this.subnetNextObjStore = subnetNextObjStore;
populateNeighborMaps();
}
@@ -115,7 +120,8 @@ public class DefaultGroupHandler {
* @param config interface to retrieve the device properties
* @param linkService link service object
* @param flowObjService flow objective service object
- * @param nsNextObjStore next objective store map
+ * @param nsNextObjStore NeighborSet next objective store map
+ * @param subnetNextObjStore subnet next objective store map
* @return default group handler type
*/
public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
@@ -123,18 +129,23 @@ public class DefaultGroupHandler {
DeviceProperties config,
LinkService linkService,
FlowObjectiveService flowObjService,
- EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
- Integer> nsNextObjStore) {
+ EventuallyConsistentMap<
+ NeighborSetNextObjectiveStoreKey,
+ Integer> nsNextObjStore,
+ EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
+ Integer> subnetNextObjStore) {
if (config.isEdgeDevice(deviceId)) {
return new DefaultEdgeGroupHandler(deviceId, appId, config,
linkService,
flowObjService,
- nsNextObjStore);
+ nsNextObjStore,
+ subnetNextObjStore);
} else {
return new DefaultTransitGroupHandler(deviceId, appId, config,
linkService,
flowObjService,
- nsNextObjStore);
+ nsNextObjStore,
+ subnetNextObjStore);
}
}
@@ -323,6 +334,21 @@ public class DefaultGroupHandler {
}
/**
+ * Returns the next objective associated with the subnet.
+ * If there is no next objective for this subnet, this API
+ * would create a next objective and return.
+ *
+ * @param prefix subnet information
+ * @return int if found or -1
+ */
+ public int getSubnetNextObjectiveId(IpPrefix prefix) {
+ Integer nextId = subnetNextObjStore.
+ get(new SubnetNextObjectiveStoreKey(deviceId, prefix));
+
+ return (nextId != null) ? nextId : -1;
+ }
+
+ /**
* Checks if the next objective ID (group) for the neighbor set exists or not.
*
* @param ns neighbor set to check
@@ -486,6 +512,43 @@ public class DefaultGroupHandler {
}
}
+ public void createGroupsFromSubnetConfig() {
+ Map<Ip4Prefix, List<PortNumber>> subnetPortMap =
+ this.deviceConfig.getSubnetPortsMap(this.deviceId);
+
+ // Construct a broadcast group for each subnet
+ subnetPortMap.forEach((subnet, ports) -> {
+ SubnetNextObjectiveStoreKey key =
+ new SubnetNextObjectiveStoreKey(deviceId, subnet);
+
+ if (subnetNextObjStore.containsKey(key)) {
+ log.debug("Broadcast group for device {} and subnet {} exists",
+ deviceId, subnet);
+ return;
+ }
+
+ int nextId = flowObjectiveService.allocateNextId();
+
+ NextObjective.Builder nextObjBuilder = DefaultNextObjective
+ .builder().withId(nextId)
+ .withType(NextObjective.Type.BROADCAST).fromApp(appId);
+
+ ports.forEach(port -> {
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+ tBuilder.setOutput(port);
+ nextObjBuilder.addTreatment(tBuilder.build());
+ });
+
+ NextObjective nextObj = nextObjBuilder.add();
+ flowObjectiveService.next(deviceId, nextObj);
+ log.debug("createGroupFromSubnetConfig: Submited "
+ + "next objective {} in device {}",
+ nextId, deviceId);
+
+ subnetNextObjStore.put(key, nextId);
+ });
+ }
+
public GroupKey getGroupKey(Object obj) {
return new DefaultGroupKey(kryo.build().serialize(obj));
}
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java
index 3cb73aba..b009e869 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java
@@ -45,9 +45,12 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
LinkService linkService,
FlowObjectiveService flowObjService,
EventuallyConsistentMap<
- NeighborSetNextObjectiveStoreKey,
- Integer> nsNextObjStore) {
- super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
+ NeighborSetNextObjectiveStoreKey,
+ Integer> nsNextObjStore,
+ EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
+ Integer> subnetNextObjStore) {
+ super(deviceId, appId, config, linkService, flowObjService,
+ nsNextObjStore, subnetNextObjStore);
}
@Override
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java
index 497f5256..d28d38d5 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java
@@ -16,9 +16,12 @@
package org.onosproject.segmentrouting.grouphandler;
import java.util.List;
+import java.util.Map;
+import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
/**
* Mechanism through which group handler module retrieves
@@ -33,6 +36,7 @@ public interface DeviceProperties {
* @return segment id of a device
*/
int getSegmentId(DeviceId deviceId);
+
/**
* Returns the Mac address of a device to be used in group creation.
*
@@ -40,6 +44,7 @@ public interface DeviceProperties {
* @return mac address of a device
*/
MacAddress getDeviceMac(DeviceId deviceId);
+
/**
* Indicates whether a device is edge device or transit/core device.
*
@@ -47,6 +52,7 @@ public interface DeviceProperties {
* @return boolean
*/
boolean isEdgeDevice(DeviceId deviceId);
+
/**
* Returns all segment IDs to be considered in building auto
*
@@ -54,4 +60,16 @@ public interface DeviceProperties {
* @return list of segment IDs
*/
List<Integer> getAllDeviceSegmentIds();
+
+ /**
+ * Returns subnet-to-ports mapping of given device.
+ *
+ * For each entry of the map
+ * Key: a subnet
+ * Value: a list of ports, which are bound to the subnet
+ *
+ * @param deviceId device identifier
+ * @return a map that contains all subnet-to-ports mapping of given device
+ */
+ Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId);
}
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
index e7e87839..e47a6625 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
@@ -54,7 +54,8 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
* @param config interface to retrieve the device properties
* @param linkService link service object
* @param flowObjService flow objective service object
- * @param nsNextObjStore next objective store map
+ * @param nsNextObjStore NeighborSet next objective store map
+ * @param subnetNextObjStore subnet next objective store map
*/
public PolicyGroupHandler(DeviceId deviceId,
ApplicationId appId,
@@ -62,8 +63,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
LinkService linkService,
FlowObjectiveService flowObjService,
EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
- Integer> nsNextObjStore) {
- super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
+ Integer> nsNextObjStore,
+ EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
+ Integer> subnetNextObjStore) {
+ super(deviceId, appId, config, linkService, flowObjService,
+ nsNextObjStore, subnetNextObjStore);
}
public PolicyGroupIdentifier createPolicyGroupChain(String id,
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java
new file mode 100644
index 00000000..d6b16c7a
--- /dev/null
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/SubnetNextObjectiveStoreKey.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.grouphandler;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * Class definition of Key for Subnet to NextObjective store.
+ */
+public class SubnetNextObjectiveStoreKey {
+ private final DeviceId deviceId;
+ private final IpPrefix prefix;
+
+ public SubnetNextObjectiveStoreKey(DeviceId deviceId,
+ IpPrefix prefix) {
+ this.deviceId = deviceId;
+ this.prefix = prefix;
+ }
+
+ /**
+ * Gets device id in this SubnetNextObjectiveStoreKey.
+ *
+ * @return device id
+ */
+ public DeviceId deviceId() {
+ return this.deviceId;
+ }
+
+ /**
+ * Gets subnet information in this SubnetNextObjectiveStoreKey.
+ *
+ * @return subnet information
+ */
+ public IpPrefix prefix() {
+ return this.prefix;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SubnetNextObjectiveStoreKey)) {
+ return false;
+ }
+ SubnetNextObjectiveStoreKey that =
+ (SubnetNextObjectiveStoreKey) o;
+ return (Objects.equals(this.deviceId, that.deviceId) &&
+ Objects.equals(this.prefix, that.prefix));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(deviceId, prefix);
+ }
+
+ @Override
+ public String toString() {
+ return "Device: " + deviceId + " Subnet: " + prefix;
+ }
+}
diff --git a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java
index 204471c2..2d1aa0b8 100644
--- a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java
+++ b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestAddCommand.java
@@ -23,7 +23,7 @@ import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
-import java.util.HashSet;
+import java.util.Arrays;
import java.util.Set;
/**
@@ -44,7 +44,6 @@ public class SetTestAddCommand extends AbstractShellCommand {
String[] values = null;
Set<String> set;
- Set<String> toAdd = new HashSet<>();
Serializer serializer = Serializer.using(
@@ -68,13 +67,10 @@ public class SetTestAddCommand extends AbstractShellCommand {
}
} else if (values.length >= 1) {
// Add multiple elements to a set
- for (String value : values) {
- toAdd.add(value);
- }
- if (set.addAll(toAdd)) {
- print("%s was added to the set %s", toAdd, setName);
+ if (set.addAll(Arrays.asList(values))) {
+ print("%s was added to the set %s", Arrays.asList(values), setName);
} else {
- print("%s was already in set %s", toAdd, setName);
+ print("%s was already in set %s", Arrays.asList(values), setName);
}
}
}
diff --git a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java
index fb36a06a..74c52c16 100644
--- a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java
+++ b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestGetCommand.java
@@ -24,7 +24,7 @@ import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
-import java.util.HashSet;
+import java.util.Arrays;
import java.util.Set;
/**
@@ -49,7 +49,6 @@ public class SetTestGetCommand extends AbstractShellCommand {
String[] values = null;
Set<String> set;
- Set<String> toCheck = new HashSet<>();
String output = "";
Serializer serializer = Serializer.using(
@@ -95,13 +94,10 @@ public class SetTestGetCommand extends AbstractShellCommand {
}
} else if (values.length > 1) {
//containsAll
- for (String value : values) {
- toCheck.add(value);
- }
- if (set.containsAll(toCheck)) {
- print("Set %s contains the the subset %s", setName, toCheck);
+ if (set.containsAll(Arrays.asList(values))) {
+ print("Set %s contains the the subset %s", setName, Arrays.asList(values));
} else {
- print("Set %s did not contain the the subset %s", setName, toCheck);
+ print("Set %s did not contain the the subset %s", setName, Arrays.asList(values));
}
}
}
diff --git a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java
index d1f81e42..1fa073f3 100644
--- a/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java
+++ b/framework/src/onos/apps/test/distributed-primitives/src/main/java/org/onosproject/distributedprimitives/cli/SetTestRemoveCommand.java
@@ -24,7 +24,7 @@ import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
-import java.util.HashSet;
+import java.util.Arrays;
import java.util.Set;
/**
@@ -54,7 +54,6 @@ public class SetTestRemoveCommand extends AbstractShellCommand {
String[] values = null;
Set<String> set;
- Set<String> givenValues = new HashSet<>();
Serializer serializer = Serializer.using(
new KryoNamespace.Builder().register(KryoNamespaces.BASIC).build());
@@ -79,13 +78,10 @@ public class SetTestRemoveCommand extends AbstractShellCommand {
}
if (retain) { // Keep only the given values
- for (String value : values) {
- givenValues.add(value);
- }
- if (set.retainAll(givenValues)) {
- print("%s was pruned to contain only elements of set %s", setName, givenValues);
+ if (set.retainAll(Arrays.asList(values))) {
+ print("%s was pruned to contain only elements of set %s", setName, Arrays.asList(values));
} else {
- print("%s was not changed by retaining only elements of the set %s", setName, givenValues);
+ print("%s was not changed by retaining only elements of the set %s", setName, Arrays.asList(values));
}
} else if (values.length == 1) {
// Remove a single element from the set
@@ -94,15 +90,12 @@ public class SetTestRemoveCommand extends AbstractShellCommand {
} else {
print("[%s] was not in set %s", values[0], setName);
}
- } else if (values.length >= 1) {
+ } else if (values.length > 1) {
// Remove multiple elements from a set
- for (String value : values) {
- givenValues.add(value);
- }
- if (set.removeAll(givenValues)) {
- print("%s was removed from the set %s", givenValues, setName);
+ if (set.removeAll(Arrays.asList(values))) {
+ print("%s was removed from the set %s", Arrays.asList(values), setName);
} else {
- print("No element of %s was in set %s", givenValues, setName);
+ print("No element of %s was in set %s", Arrays.asList(values), setName);
}
}
}
diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/ConnectPointConfiguration.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/ConnectPointConfiguration.java
new file mode 100644
index 00000000..ff516d71
--- /dev/null
+++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/ConnectPointConfiguration.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.virtualbng;
+
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Configuration for a connect point.
+ */
+public class ConnectPointConfiguration {
+
+ private ConnectPoint connectPoint;
+
+ /**
+ * Creats a new connect point from a string representation.
+ *
+ * @param string connect point string
+ */
+ public ConnectPointConfiguration(String string) {
+ connectPoint = ConnectPoint.deviceConnectPoint(string);
+ }
+
+ /**
+ * Creates a new connect point from a string representation.
+ *
+ * @param string connect point string
+ * @return new connect point configuration
+ */
+ public static ConnectPointConfiguration of(String string) {
+ return new ConnectPointConfiguration(string);
+ }
+
+ /**
+ * Gets the connect point.
+ *
+ * @return connect point
+ */
+ public ConnectPoint connectPoint() {
+ return connectPoint;
+ }
+}
diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java
index ee2cbeaa..1841675f 100644
--- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java
+++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfiguration.java
@@ -17,13 +17,15 @@ package org.onosproject.virtualbng;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
-
-import java.util.Collections;
-import java.util.List;
-
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
/**
* Contains the configuration data for virtual BNG that has been read from a
@@ -36,6 +38,7 @@ public final class VbngConfiguration {
private final MacAddress publicFacingMac;
private final IpAddress xosIpAddress;
private final int xosRestPort;
+ private final Map<String, ConnectPointConfiguration> hosts;
/**
* Default constructor.
@@ -46,6 +49,7 @@ public final class VbngConfiguration {
publicFacingMac = null;
xosIpAddress = null;
xosRestPort = 0;
+ hosts = null;
}
/**
@@ -57,6 +61,7 @@ public final class VbngConfiguration {
* public IP addresses
* @param xosIpAddress the XOS server IP address
* @param xosRestPort the port of the XOS server for REST
+ * @param hosts map of hosts
*/
@JsonCreator
public VbngConfiguration(@JsonProperty("localPublicIpPrefixes")
@@ -68,12 +73,15 @@ public final class VbngConfiguration {
@JsonProperty("xosIpAddress")
IpAddress xosIpAddress,
@JsonProperty("xosRestPort")
- int xosRestPort) {
+ int xosRestPort,
+ @JsonProperty("hosts")
+ Map<String, ConnectPointConfiguration> hosts) {
localPublicIpPrefixes = prefixes;
this.nextHopIpAddress = nextHopIpAddress;
this.publicFacingMac = publicFacingMac;
this.xosIpAddress = xosIpAddress;
this.xosRestPort = xosRestPort;
+ this.hosts = hosts;
}
/**
@@ -120,4 +128,13 @@ public final class VbngConfiguration {
public int getXosRestPort() {
return xosRestPort;
}
+
+ public Map<String, ConnectPoint> getHosts() {
+ return hosts.entrySet()
+ .stream()
+ .collect(Collectors.toMap(
+ e -> e.getKey(),
+ e -> e.getValue().connectPoint()
+ ));
+ }
}
diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java
index d27d6904..eb83e06c 100644
--- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java
+++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationManager.java
@@ -16,16 +16,6 @@
package org.onosproject.virtualbng;
import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -33,9 +23,19 @@ import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* Implementation of ConfigurationService which reads virtual BNG
* configuration from a file.
@@ -63,6 +63,7 @@ public class VbngConfigurationManager implements VbngConfigurationService {
private MacAddress macOfPublicIpAddresses;
private IpAddress xosIpAddress;
private int xosRestPort;
+ private Map<String, ConnectPoint> nodeToPort;
@Activate
public void activate() {
@@ -104,6 +105,8 @@ public class VbngConfigurationManager implements VbngConfigurationService {
macOfPublicIpAddresses = config.getPublicFacingMac();
xosIpAddress = config.getXosIpAddress();
xosRestPort = config.getXosRestPort();
+ nodeToPort = config.getHosts();
+
} catch (FileNotFoundException e) {
log.warn("Configuration file not found: {}", configFileName);
@@ -132,6 +135,11 @@ public class VbngConfigurationManager implements VbngConfigurationService {
return xosRestPort;
}
+ @Override
+ public Map<String, ConnectPoint> getNodeToPort() {
+ return nodeToPort;
+ }
+
// TODO handle the case: the number of public IP addresses is not enough
// for 1:1 mapping from public IP to private IP.
@Override
diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java
index ef8698a0..68c048f4 100644
--- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java
+++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngConfigurationService.java
@@ -15,10 +15,11 @@
*/
package org.onosproject.virtualbng;
-import java.util.Map;
-
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Map;
/**
* Provides information about the virtual BNG configuration.
@@ -54,6 +55,13 @@ public interface VbngConfigurationService {
int getXosRestPort();
/**
+ * Gets the host to port map.
+ *
+ * @return host to port map
+ */
+ Map<String, ConnectPoint> getNodeToPort();
+
+ /**
* Evaluates whether an IP address is an assigned public IP address.
*
* @param ipAddress the IP address to evaluate
diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java
index 5e82b7e8..e03b25e8 100644
--- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java
+++ b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java
@@ -15,18 +15,9 @@
*/
package org.onosproject.virtualbng;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Maps;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -42,7 +33,6 @@ import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
-import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
@@ -56,6 +46,13 @@ import org.onosproject.net.intent.PointToPointIntent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* This is a virtual Broadband Network Gateway (BNG) application. It mainly
* has 3 functions:
@@ -111,9 +108,8 @@ public class VbngManager implements VbngService {
p2pIntentsToHost = new ConcurrentHashMap<>();
privateIpAddressMap = new ConcurrentHashMap<>();
- setupMap();
-
nextHopIpAddress = vbngConfigurationService.getNextHopIpAddress();
+ nodeToPort = vbngConfigurationService.getNodeToPort();
hostListener = new InternalHostListener();
hostService.addListener(hostListener);
@@ -136,10 +132,16 @@ public class VbngManager implements VbngService {
*/
private void statusRecovery() {
log.info("vBNG starts to recover from XOS record......");
- RestClient restClient =
- new RestClient(vbngConfigurationService.getXosIpAddress(),
- vbngConfigurationService.getXosRestPort());
- ObjectNode map = restClient.getRest();
+ ObjectNode map;
+ try {
+ RestClient restClient =
+ new RestClient(vbngConfigurationService.getXosIpAddress(),
+ vbngConfigurationService.getXosRestPort());
+ map = restClient.getRest();
+ } catch (Exception e) {
+ log.error("Could not contact XOS", e);
+ return;
+ }
if (map == null) {
log.info("Stop to recover vBNG status due to the vBNG map "
+ "is null!");
@@ -168,21 +170,6 @@ public class VbngManager implements VbngService {
}
/**
- * Sets up mapping from hostname to connect point.
- */
- private void setupMap() {
- nodeToPort = Maps.newHashMap();
-
- nodeToPort.put("cordcompute01.onlab.us",
- new ConnectPoint(FABRIC_DEVICE_ID,
- PortNumber.portNumber(48)));
-
- nodeToPort.put("cordcompute02.onlab.us",
- new ConnectPoint(FABRIC_DEVICE_ID,
- PortNumber.portNumber(47)));
- }
-
- /**
* Creates a new vBNG.
*
* @param privateIpAddress a private IP address
diff --git a/framework/src/onos/apps/vtn/pom.xml b/framework/src/onos/apps/vtn/pom.xml
index c2cfe2be..e91b0c9b 100644
--- a/framework/src/onos/apps/vtn/pom.xml
+++ b/framework/src/onos/apps/vtn/pom.xml
@@ -37,4 +37,21 @@
<module>vtnweb</module>
<module>app</module>
</modules>
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava-testlib</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
</project>
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/SfcService.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/SfcService.java
new file mode 100644
index 00000000..a2748f5e
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/SfcService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.sfc;
+
+import org.onosproject.vtnrsc.PortChain;
+
+/**
+ * SFC application that applies flows to the device.
+ */
+public interface SfcService {
+ /**
+ * Applies flow classification to OVS.
+ *
+ * @param portChain Port-Chain.
+ */
+ void InstallFlowClassification(PortChain portChain);
+
+
+ /**
+ * Remove flow classification from OVS.
+ *
+ * @param portChain Port-Chain.
+ */
+ void UnInstallFlowClassification(PortChain portChain);
+
+ /**
+ * Applies Service Function chain to OVS.
+ *
+ * @param portChain Port-Chain.
+ */
+ void InstallServiceFunctionChain(PortChain portChain);
+
+ /**
+ * Remove Service Function chain from OVS.
+ *
+ * @param portChain Port-Chain.
+ */
+ void UnInstallServiceFunctionChain(PortChain portChain);
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/SfcManager.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/SfcManager.java
new file mode 100644
index 00000000..1872295f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/SfcManager.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.sfc.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.vtnrsc.sfc.PortChain;
+import org.slf4j.Logger;
+
+/**
+ * Provides implementation of SFC Service.
+ */
+@Component(immediate = true)
+@Service
+public class SfcManager implements SfcService {
+
+ private final Logger log = getLogger(SfcManager.class);
+
+ @Activate
+ public void activate() {
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+
+ @Override
+ public void InstallFlowClassification(PortChain portChain) {
+ log.debug("InstallFlowClassification");
+ //TODO: Installation of flow classification into OVS.
+ }
+
+ @Override
+ public void UnInstallFlowClassification(PortChain portChain) {
+ log.debug("UnInstallFlowClassification");
+ //TODO: Un-installation flow classification from OVS
+ }
+
+ @Override
+ public void InstallServiceFunctionChain(PortChain portChain) {
+ log.debug("InstallServiceFunctionChain");
+ //TODO: Installation of Service Function chain into OVS.
+ }
+
+ @Override
+ public void UnInstallServiceFunctionChain(PortChain portChain) {
+ log.debug("UnInstallServiceFunctionChain");
+ //TODO: Un-installation of Service Function chain from OVS.
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/package-info.java
new file mode 100644
index 00000000..0dba868c
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * SFC Service manager for interacting with SFC.
+ */
+package org.onosproject.sfc.impl;
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/package-info.java
new file mode 100644
index 00000000..1dcb9929
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Service for interacting with SFC.
+ */
+package org.onosproject.sfc;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java
new file mode 100644
index 00000000..39df2cff
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import java.util.Objects;
+import org.onlab.packet.IpPrefix;
+
+import com.google.common.base.MoreObjects;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Provides Default flow classifier.
+ */
+public final class DefaultFlowClassifier implements FlowClassifier {
+
+ private final FlowClassifierId flowClassifierId;
+ private final TenantId tenantId;
+ private final String name;
+ private final String description;
+ private final String etherType;
+ private final String protocol;
+ private final int minSrcPortRange;
+ private final int maxSrcPortRange;
+ private final int minDstPortRange;
+ private final int maxDstPortRange;
+ private final IpPrefix srcIpPrefix;
+ private final IpPrefix dstIpPrefix;
+ private final VirtualPortId srcPort;
+ private final VirtualPortId dstPort;
+ private static final int NULL_PORT = 0;
+ private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "FlowClassifier id can not be null.";
+ private static final String TENANT_ID_NOT_NULL = "Tenant id can not be null.";
+
+ /**
+ * Constructor to create default flow classifier.
+ *
+ * @param flowClassifierId flow classifier Id
+ * @param tenantId Tenant ID
+ * @param name flow classifier name
+ * @param description flow classifier description
+ * @param etherType etherType
+ * @param protocol IP protocol
+ * @param minSrcPortRange Minimum Source port range
+ * @param maxSrcPortRange Maximum Source port range
+ * @param minDstPortRange Minimum destination port range
+ * @param maxDstPortRange Maximum destination port range
+ * @param srcIpPrefix Source IP prefix
+ * @param dstIpPrefix destination IP prefix
+ * @param srcPort Source VirtualPort
+ * @param dstPort destination VirtualPort
+ */
+ private DefaultFlowClassifier(FlowClassifierId flowClassifierId, TenantId tenantId, String name,
+ String description, String etherType, String protocol, int minSrcPortRange, int maxSrcPortRange,
+ int minDstPortRange, int maxDstPortRange, IpPrefix srcIpPrefix, IpPrefix dstIpPrefix,
+ VirtualPortId srcPort, VirtualPortId dstPort) {
+ this.flowClassifierId = flowClassifierId;
+ this.tenantId = tenantId;
+ this.name = name;
+ this.description = description;
+ this.etherType = etherType;
+ this.protocol = protocol;
+ this.minSrcPortRange = minSrcPortRange;
+ this.maxSrcPortRange = maxSrcPortRange;
+ this.minDstPortRange = minDstPortRange;
+ this.maxDstPortRange = maxDstPortRange;
+ this.srcIpPrefix = srcIpPrefix;
+ this.dstIpPrefix = dstIpPrefix;
+ this.srcPort = srcPort;
+ this.dstPort = dstPort;
+ }
+
+ @Override
+ public FlowClassifierId flowClassifierId() {
+ return flowClassifierId;
+ }
+
+ @Override
+ public TenantId tenantId() {
+ return tenantId;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public String description() {
+ return description;
+ }
+
+ @Override
+ public String etherType() {
+ return etherType;
+ }
+
+ @Override
+ public String protocol() {
+ return protocol;
+ }
+
+ @Override
+ public int minSrcPortRange() {
+ return minSrcPortRange;
+ }
+
+ @Override
+ public int maxSrcPortRange() {
+ return maxSrcPortRange;
+ }
+
+ @Override
+ public int minDstPortRange() {
+ return minDstPortRange;
+ }
+
+ @Override
+ public int maxDstPortRange() {
+ return maxDstPortRange;
+ }
+
+ @Override
+ public IpPrefix srcIpPrefix() {
+ return srcIpPrefix;
+ }
+
+ @Override
+ public IpPrefix dstIpPrefix() {
+ return dstIpPrefix;
+ }
+
+ @Override
+ public VirtualPortId srcPort() {
+ return srcPort;
+ }
+
+ @Override
+ public VirtualPortId dstPort() {
+ return dstPort;
+ }
+
+ /**
+ * Builder class for constructing Flow classifier.
+ */
+ public static class Builder implements FlowClassifier.Builder {
+
+ private FlowClassifierId flowClassifierId;
+ private TenantId tenantId;
+ private String name;
+ private boolean isFlowClassifierNameSet = false;
+ private String description;
+ private boolean isFlowClassifierDescriptionSet = false;
+ private String etherType;
+ private boolean isEtherTypeSet = false;
+ private String protocol;
+ private boolean isProtocolSet = false;
+ private int minSrcPortRange;
+ private boolean isMinSrcPortRangeSet = false;
+ private int maxSrcPortRange;
+ private boolean isMaxSrcPortRangeSet = false;
+ private int minDstPortRange;
+ private boolean isMinDstPortRangeSet = false;
+ private int maxDstPortRange;
+ private boolean isMaxDstPortRangeSet = false;
+ private IpPrefix srcIpPrefix;
+ private boolean isSrcIpPrefixSet = false;
+ private IpPrefix dstIpPrefix;
+ private boolean isDstIpPrefixSet = false;
+ private VirtualPortId srcPort;
+ private boolean isSrcPortSet = false;
+ private VirtualPortId dstPort;
+ private boolean isDstPortSet = false;
+
+ @Override
+ public FlowClassifier build() {
+
+ checkNotNull(flowClassifierId, FLOW_CLASSIFIER_ID_NOT_NULL);
+ checkNotNull(tenantId, TENANT_ID_NOT_NULL);
+ String name = null;
+ String description = null;
+ String etherType = null;
+ String protocol = null;
+ int minSrcPortRange = NULL_PORT;
+ int maxSrcPortRange = NULL_PORT;
+ int minDstPortRange = NULL_PORT;
+ int maxDstPortRange = NULL_PORT;
+ IpPrefix srcIpPrefix = null;
+ IpPrefix dstIpPrefix = null;
+ VirtualPortId srcPort = null;
+ VirtualPortId dstPort = null;
+
+ if (isFlowClassifierNameSet) {
+ name = this.name;
+ }
+ if (isFlowClassifierDescriptionSet) {
+ description = this.description;
+ }
+ if (isEtherTypeSet) {
+ etherType = this.etherType;
+ }
+ if (isProtocolSet) {
+ protocol = this.protocol;
+ }
+ if (isMinSrcPortRangeSet) {
+ minSrcPortRange = this.minSrcPortRange;
+ }
+ if (isMaxSrcPortRangeSet) {
+ maxSrcPortRange = this.maxSrcPortRange;
+ }
+ if (isMinDstPortRangeSet) {
+ minDstPortRange = this.minDstPortRange;
+ }
+ if (isMaxDstPortRangeSet) {
+ maxDstPortRange = this.maxDstPortRange;
+ }
+ if (isSrcIpPrefixSet) {
+ srcIpPrefix = this.srcIpPrefix;
+ }
+ if (isDstIpPrefixSet) {
+ dstIpPrefix = this.dstIpPrefix;
+ }
+ if (isSrcPortSet) {
+ srcPort = this.srcPort;
+ }
+ if (isDstPortSet) {
+ dstPort = this.dstPort;
+ }
+
+ return new DefaultFlowClassifier(flowClassifierId, tenantId, name, description, etherType, protocol,
+ minSrcPortRange, maxSrcPortRange, minDstPortRange, maxDstPortRange, srcIpPrefix, dstIpPrefix,
+ srcPort, dstPort);
+ }
+
+ @Override
+ public Builder setFlowClassifierId(FlowClassifierId flowClassifierId) {
+ this.flowClassifierId = flowClassifierId;
+ return this;
+ }
+
+ @Override
+ public Builder setTenantId(TenantId tenantId) {
+ this.tenantId = tenantId;
+ return this;
+ }
+
+ @Override
+ public Builder setName(String name) {
+ this.name = name;
+ this.isFlowClassifierNameSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setDescription(String description) {
+ this.description = description;
+ this.isFlowClassifierDescriptionSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setEtherType(String etherType) {
+ this.etherType = etherType;
+ this.isEtherTypeSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setProtocol(String protocol) {
+ this.protocol = protocol;
+ this.isProtocolSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setMinSrcPortRange(int minSrcPortRange) {
+ this.minSrcPortRange = minSrcPortRange;
+ this.isMinSrcPortRangeSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setMaxSrcPortRange(int maxSrcPortRange) {
+ this.maxSrcPortRange = maxSrcPortRange;
+ this.isMaxSrcPortRangeSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setMinDstPortRange(int minDstPortRange) {
+ this.minDstPortRange = minDstPortRange;
+ this.isMinDstPortRangeSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setMaxDstPortRange(int maxDstPortRange) {
+ this.maxDstPortRange = maxDstPortRange;
+ this.isMaxDstPortRangeSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setSrcIpPrefix(IpPrefix srcIpPrefix) {
+ this.srcIpPrefix = srcIpPrefix;
+ this.isSrcIpPrefixSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setDstIpPrefix(IpPrefix dstIpPrefix) {
+ this.dstIpPrefix = dstIpPrefix;
+ this.isDstIpPrefixSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setSrcPort(VirtualPortId srcPort) {
+ this.srcPort = srcPort;
+ this.isSrcPortSet = true;
+ return this;
+ }
+
+ @Override
+ public Builder setDstPort(VirtualPortId dstPort) {
+ this.dstPort = dstPort;
+ this.isDstPortSet = true;
+ return this;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(flowClassifierId, tenantId, name, description, etherType, protocol, minSrcPortRange,
+ maxSrcPortRange, minDstPortRange, maxDstPortRange, srcIpPrefix, dstIpPrefix, srcPort, dstPort);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultFlowClassifier) {
+ DefaultFlowClassifier other = (DefaultFlowClassifier) obj;
+ return Objects.equals(this.flowClassifierId, other.flowClassifierId)
+ && Objects.equals(this.tenantId, other.tenantId)
+ && Objects.equals(this.name, other.name)
+ && Objects.equals(this.description, other.description)
+ && Objects.equals(this.etherType, other.etherType)
+ && Objects.equals(this.protocol, other.protocol)
+ && Objects.equals(this.minSrcPortRange, other.minSrcPortRange)
+ && Objects.equals(this.maxSrcPortRange, other.maxSrcPortRange)
+ && Objects.equals(this.minDstPortRange, other.minDstPortRange)
+ && Objects.equals(this.maxDstPortRange, other.maxDstPortRange)
+ && Objects.equals(this.srcIpPrefix, other.srcIpPrefix)
+ && Objects.equals(this.dstIpPrefix, other.dstIpPrefix)
+ && Objects.equals(this.srcPort, other.srcPort)
+ && Objects.equals(this.dstPort, other.dstPort);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean exactMatch(FlowClassifier flowClassifier) {
+ return this.equals(flowClassifier)
+ && Objects.equals(this.flowClassifierId, flowClassifier.flowClassifierId())
+ && Objects.equals(this.tenantId, flowClassifier.tenantId())
+ && Objects.equals(this.name, flowClassifier.name())
+ && Objects.equals(this.description, flowClassifier.description())
+ && Objects.equals(this.etherType, flowClassifier.etherType())
+ && Objects.equals(this.protocol, flowClassifier.protocol())
+ && Objects.equals(this.minSrcPortRange, flowClassifier.minSrcPortRange())
+ && Objects.equals(this.maxSrcPortRange, flowClassifier.maxSrcPortRange())
+ && Objects.equals(this.minDstPortRange, flowClassifier.minDstPortRange())
+ && Objects.equals(this.maxDstPortRange, flowClassifier.maxDstPortRange())
+ && Objects.equals(this.srcIpPrefix, flowClassifier.srcIpPrefix())
+ && Objects.equals(this.dstIpPrefix, flowClassifier.dstIpPrefix())
+ && Objects.equals(this.srcPort, flowClassifier.srcPort())
+ && Objects.equals(this.dstPort, flowClassifier.dstPort());
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("FlowClassifierId", flowClassifierId)
+ .add("TenantId", tenantId)
+ .add("Name", name)
+ .add("Description", description)
+ .add("String", etherType)
+ .add("Protocol", protocol)
+ .add("MinSrcPortRange", minSrcPortRange)
+ .add("MaxSrcPortRange", maxSrcPortRange)
+ .add("MinDstPortRange", minDstPortRange)
+ .add("MaxDstPortRange", maxDstPortRange)
+ .add("SrcIpPrefix", srcIpPrefix)
+ .add("DstIpPrefix", dstIpPrefix)
+ .add("SrcPort", srcPort)
+ .add("DstPort", dstPort)
+ .toString();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java
new file mode 100644
index 00000000..89b94b3e
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Objects;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Implementation of port chain.
+ */
+public final class DefaultPortChain implements PortChain {
+
+ private final PortChainId portChainId;
+ private final TenantId tenantId;
+ private final String name;
+ private final String description;
+ private final List<PortPairGroupId> portPairGroupList;
+ private final List<FlowClassifierId> flowClassifierList;
+
+ /**
+ * Default constructor to create port chain.
+ *
+ * @param portChainId port chain id
+ * @param tenantId tenant id
+ * @param name name of port chain
+ * @param description description of port chain
+ * @param portPairGroupList port pair group list
+ * @param flowClassifierList flow classifier list
+ */
+ private DefaultPortChain(PortChainId portChainId, TenantId tenantId,
+ String name, String description,
+ List<PortPairGroupId> portPairGroupList,
+ List<FlowClassifierId> flowClassifierList) {
+
+ this.portChainId = portChainId;
+ this.tenantId = tenantId;
+ this.name = name;
+ this.description = description;
+ this.portPairGroupList = portPairGroupList;
+ this.flowClassifierList = flowClassifierList;
+ }
+
+ @Override
+ public PortChainId portChainId() {
+ return portChainId;
+ }
+
+ @Override
+ public TenantId tenantId() {
+ return tenantId;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public String description() {
+ return description;
+ }
+
+ @Override
+ public List<PortPairGroupId> portPairGroups() {
+ return ImmutableList.copyOf(portPairGroupList);
+ }
+
+ @Override
+ public List<FlowClassifierId> flowClassifiers() {
+ return ImmutableList.copyOf(flowClassifierList);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(portChainId, tenantId, name, description,
+ portPairGroupList, flowClassifierList);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultPortChain) {
+ DefaultPortChain that = (DefaultPortChain) obj;
+ return Objects.equals(portChainId, that.portChainId) &&
+ Objects.equals(tenantId, that.tenantId) &&
+ Objects.equals(name, that.name) &&
+ Objects.equals(description, that.description) &&
+ Objects.equals(portPairGroupList, that.portPairGroupList) &&
+ Objects.equals(flowClassifierList, that.flowClassifierList);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean exactMatch(PortChain portChain) {
+ return this.equals(portChain) &&
+ Objects.equals(this.portChainId, portChain.portChainId()) &&
+ Objects.equals(this.tenantId, portChain.tenantId());
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("id", portChainId.toString())
+ .add("tenantId", tenantId.toString())
+ .add("name", name)
+ .add("description", description)
+ .add("portPairGroupList", portPairGroupList)
+ .add("flowClassifier", flowClassifierList)
+ .toString();
+ }
+
+ /**
+ * To create an instance of the builder.
+ *
+ * @return instance of builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder class for Port chain.
+ */
+ public static final class Builder implements PortChain.Builder {
+
+ private PortChainId portChainId;
+ private TenantId tenantId;
+ private String name;
+ private String description;
+ private List<PortPairGroupId> portPairGroupList;
+ private List<FlowClassifierId> flowClassifierList;
+
+ @Override
+ public Builder setId(PortChainId portChainId) {
+ this.portChainId = portChainId;
+ return this;
+ }
+
+ @Override
+ public Builder setTenantId(TenantId tenantId) {
+ this.tenantId = tenantId;
+ return this;
+ }
+
+ @Override
+ public Builder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public Builder setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ @Override
+ public Builder setPortPairGroups(List<PortPairGroupId> portPairGroups) {
+ this.portPairGroupList = portPairGroups;
+ return this;
+ }
+
+ @Override
+ public Builder setFlowClassifiers(List<FlowClassifierId> flowClassifiers) {
+ this.flowClassifierList = flowClassifiers;
+ return this;
+ }
+
+ @Override
+ public PortChain build() {
+
+ checkNotNull(portChainId, "Port chain id cannot be null");
+ checkNotNull(tenantId, "Tenant id cannot be null");
+ checkNotNull(portPairGroupList, "Port pair groups cannot be null");
+
+ return new DefaultPortChain(portChainId, tenantId, name, description,
+ portPairGroupList, flowClassifierList);
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPair.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPair.java
new file mode 100644
index 00000000..4b3b7cf3
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPair.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * Implementation of port pair.
+ */
+public final class DefaultPortPair implements PortPair {
+
+ private final PortPairId portPairId;
+ private final TenantId tenantId;
+ private final String name;
+ private final String description;
+ private final String ingress;
+ private final String egress;
+
+ /**
+ * Default constructor to create Port Pair.
+ *
+ * @param portPairId port pair id
+ * @param tenantId tenant id
+ * @param name name of port pair
+ * @param description description of port pair
+ * @param ingress ingress port
+ * @param egress egress port
+ */
+ private DefaultPortPair(PortPairId portPairId, TenantId tenantId,
+ String name, String description,
+ String ingress, String egress) {
+
+ this.portPairId = portPairId;
+ this.tenantId = tenantId;
+ this.name = name;
+ this.description = description;
+ this.ingress = ingress;
+ this.egress = egress;
+ }
+
+ @Override
+ public PortPairId portPairId() {
+ return portPairId;
+ }
+
+ @Override
+ public TenantId tenantId() {
+ return tenantId;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public String description() {
+ return description;
+ }
+
+ @Override
+ public String ingress() {
+ return ingress;
+ }
+
+ @Override
+ public String egress() {
+ return egress;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(portPairId, tenantId, name, description,
+ ingress, egress);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultPortPair) {
+ DefaultPortPair that = (DefaultPortPair) obj;
+ return Objects.equals(portPairId, that.portPairId) &&
+ Objects.equals(tenantId, that.tenantId) &&
+ Objects.equals(name, that.name) &&
+ Objects.equals(description, that.description) &&
+ Objects.equals(ingress, that.ingress) &&
+ Objects.equals(egress, that.egress);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean exactMatch(PortPair portPair) {
+ return this.equals(portPair) &&
+ Objects.equals(this.portPairId, portPair.portPairId()) &&
+ Objects.equals(this.tenantId, portPair.tenantId());
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("id", portPairId.toString())
+ .add("tenantId", tenantId.tenantId())
+ .add("name", name)
+ .add("description", description)
+ .add("ingress", ingress)
+ .add("egress", egress)
+ .toString();
+ }
+
+ /**
+ * To create an instance of the builder.
+ *
+ * @return instance of builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder class for Port pair.
+ */
+ public static final class Builder implements PortPair.Builder {
+
+ private PortPairId portPairId;
+ private TenantId tenantId;
+ private String name;
+ private String description;
+ private String ingress;
+ private String egress;
+
+ @Override
+ public Builder setId(PortPairId portPairId) {
+ this.portPairId = portPairId;
+ return this;
+ }
+
+ @Override
+ public Builder setTenantId(TenantId tenantId) {
+ this.tenantId = tenantId;
+ return this;
+ }
+
+ @Override
+ public Builder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public Builder setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ @Override
+ public Builder setIngress(String ingress) {
+ this.ingress = ingress;
+ return this;
+ }
+
+ @Override
+ public Builder setEgress(String egress) {
+ this.egress = egress;
+ return this;
+ }
+
+ @Override
+ public PortPair build() {
+
+ checkNotNull(portPairId, "Port pair id cannot be null");
+ checkNotNull(tenantId, "Tenant id cannot be null");
+ checkNotNull(ingress, "Ingress of a port pair cannot be null");
+ checkNotNull(egress, "Egress of a port pair cannot be null");
+
+ return new DefaultPortPair(portPairId, tenantId, name, description,
+ ingress, egress);
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java
new file mode 100644
index 00000000..877cc6c9
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Objects;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Implementation of port pair group.
+ */
+public final class DefaultPortPairGroup implements PortPairGroup {
+
+ private final PortPairGroupId portPairGroupId;
+ private final TenantId tenantId;
+ private final String name;
+ private final String description;
+ private final List<PortPairId> portPairList;
+
+ /**
+ * Default constructor to create Port Pair Group.
+ *
+ * @param portPairGroupId port pair group id
+ * @param tenantId tenant id
+ * @param name name of port pair group
+ * @param description description of port pair group
+ * @param portPairList list of port pairs
+ */
+ private DefaultPortPairGroup(PortPairGroupId portPairGroupId, TenantId tenantId,
+ String name, String description,
+ List<PortPairId> portPairList) {
+
+ this.portPairGroupId = portPairGroupId;
+ this.tenantId = tenantId;
+ this.name = name;
+ this.description = description;
+ this.portPairList = portPairList;
+ }
+
+ @Override
+ public PortPairGroupId portPairGroupId() {
+ return portPairGroupId;
+ }
+
+ @Override
+ public TenantId tenantId() {
+ return tenantId;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public String description() {
+ return description;
+ }
+
+ @Override
+ public List<PortPairId> portPairs() {
+ return ImmutableList.copyOf(portPairList);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(portPairGroupId, tenantId, name, description,
+ portPairList);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultPortPairGroup) {
+ DefaultPortPairGroup that = (DefaultPortPairGroup) obj;
+ return Objects.equals(portPairGroupId, that.portPairGroupId) &&
+ Objects.equals(tenantId, that.tenantId) &&
+ Objects.equals(name, that.name) &&
+ Objects.equals(description, that.description) &&
+ Objects.equals(portPairList, that.portPairList);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean exactMatch(PortPairGroup portPairGroup) {
+ return this.equals(portPairGroup) &&
+ Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) &&
+ Objects.equals(this.tenantId, portPairGroup.tenantId());
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("id", portPairGroupId.toString())
+ .add("tenantId", tenantId.toString())
+ .add("name", name)
+ .add("description", description)
+ .add("portPairGroupList", portPairList)
+ .toString();
+ }
+
+ /**
+ * To create an instance of the builder.
+ *
+ * @return instance of builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder class for Port pair group.
+ */
+ public static final class Builder implements PortPairGroup.Builder {
+
+ private PortPairGroupId portPairGroupId;
+ private TenantId tenantId;
+ private String name;
+ private String description;
+ private List<PortPairId> portPairList;
+
+ @Override
+ public Builder setId(PortPairGroupId portPairGroupId) {
+ this.portPairGroupId = portPairGroupId;
+ return this;
+ }
+
+ @Override
+ public Builder setTenantId(TenantId tenantId) {
+ this.tenantId = tenantId;
+ return this;
+ }
+
+ @Override
+ public Builder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public Builder setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ @Override
+ public Builder setPortPairs(List<PortPairId> portPairs) {
+ this.portPairList = portPairs;
+ return this;
+ }
+
+ @Override
+ public PortPairGroup build() {
+
+ checkNotNull(portPairGroupId, "Port pair group id cannot be null");
+ checkNotNull(tenantId, "Tenant id cannot be null");
+ checkNotNull(portPairList, "Port pairs cannot be null");
+
+ return new DefaultPortPairGroup(portPairGroupId, tenantId, name, description,
+ portPairList);
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifier.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifier.java
new file mode 100644
index 00000000..7b4108dc
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifier.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Abstraction of an entity which provides flow classifier for service function chain.
+ * FlowClassifier classify the traffic based on the criteria defined in the request.
+ * The classification can be based on port range or source and destination IP address or
+ * other flow classifier elements.
+ */
+public interface FlowClassifier {
+
+ /**
+ * Returns flow classifier ID.
+ *
+ * @return flow classifier id
+ */
+ FlowClassifierId flowClassifierId();
+
+ /**
+ * Returns Tenant ID.
+ *
+ * @return tenant Id
+ */
+ TenantId tenantId();
+
+ /**
+ * Returns flow classifier name.
+ *
+ * @return flow classifier name
+ */
+ String name();
+
+ /**
+ * Returns flow classifier description.
+ *
+ * @return flow classifier description
+ */
+ String description();
+
+ /**
+ * Returns EtherType.
+ *
+ * @return EtherType
+ */
+ String etherType();
+
+ /**
+ * Returns IP Protocol.
+ *
+ * @return IP protocol
+ */
+ String protocol();
+
+ /**
+ * Returns minimum source port range.
+ *
+ * @return minimum source port range
+ */
+ int minSrcPortRange();
+
+ /**
+ * Returns maximum source port range.
+ *
+ * @return maximum source port range
+ */
+ int maxSrcPortRange();
+
+ /**
+ * Returns minimum destination port range.
+ *
+ * @return minimum destination port range
+ */
+ int minDstPortRange();
+
+ /**
+ * Returns maximum destination port range.
+ *
+ * @return maximum destination port range.
+ */
+ int maxDstPortRange();
+
+ /**
+ * Returns Source IP prefix.
+ *
+ * @return Source IP prefix
+ */
+ IpPrefix srcIpPrefix();
+
+ /**
+ * Returns Destination IP prefix.
+ *
+ * @return Destination IP prefix
+ */
+ IpPrefix dstIpPrefix();
+
+ /**
+ * Returns Source virtual port.
+ *
+ * @return Source virtual port
+ */
+ VirtualPortId srcPort();
+
+ /**
+ * Returns Destination virtual port.
+ *
+ * @return Destination virtual port
+ */
+ VirtualPortId dstPort();
+
+ /**
+ * Returns whether this Flow classifier is an exact match to the
+ * Flow classifier given in the argument.
+ *
+ * @param flowClassifier other flowClassifier to match against
+ * @return true if the flowClassifiers are an exact match, otherwise false
+ */
+ boolean exactMatch(FlowClassifier flowClassifier);
+
+ /**
+ * Builder for flow Classifier.
+ */
+ interface Builder {
+
+ /**
+ * Returns Flow Classifier.
+ *
+ * @return flow classifier.
+ */
+ FlowClassifier build();
+
+ /**
+ * Sets Flow Classifier ID.
+ *
+ * @param flowClassifierId flow classifier id.
+ * @return Builder object by setting flow classifier Id.
+ */
+ Builder setFlowClassifierId(FlowClassifierId flowClassifierId);
+
+ /**
+ * Sets Tenant ID.
+ *
+ * @param tenantId tenant id.
+ * @return Builder object by setting Tenant ID.
+ */
+ Builder setTenantId(TenantId tenantId);
+
+ /**
+ * Sets Flow classifier name.
+ *
+ * @param name flow classifier name
+ * @return builder object by setting flow classifier name
+ */
+ Builder setName(String name);
+
+ /**
+ * Sets flow classifier description.
+ *
+ * @param description flow classifier description
+ * @return flow classifier description
+ */
+ Builder setDescription(String description);
+
+ /**
+ * Sets EtherType.
+ *
+ * @param etherType EtherType
+ * @return EtherType
+ */
+ Builder setEtherType(String etherType);
+
+ /**
+ * Sets IP protocol.
+ *
+ * @param protocol IP protocol
+ * @return builder object by setting IP protocol
+ */
+ Builder setProtocol(String protocol);
+
+ /**
+ * Set minimum source port range.
+ *
+ * @param minRange minimum source port range
+ * @return builder object by setting minimum source port range
+ */
+ Builder setMinSrcPortRange(int minRange);
+
+ /**
+ * Sets maximum source port range.
+ *
+ * @param maxRange maximum source port range
+ * @return builder object by setting maximum source port range
+ */
+ Builder setMaxSrcPortRange(int maxRange);
+
+ /**
+ * Sets minimum destination port range.
+ *
+ * @param minRange minimum destination port range
+ * @return builder object by setting minimum destination port range
+ */
+ Builder setMinDstPortRange(int minRange);
+
+ /**
+ * Sets maximum destination port range.
+ *
+ * @param maxRange maximum destination port range.
+ * @return builder object by setting maximum destination port range.
+ */
+ Builder setMaxDstPortRange(int maxRange);
+
+ /**
+ * Sets Source IP prefix.
+ *
+ * @param srcIpPrefix Source IP prefix
+ * @return builder object by setting Source IP prefix
+ */
+ Builder setSrcIpPrefix(IpPrefix srcIpPrefix);
+
+ /**
+ * Sets Destination IP prefix.
+ *
+ * @param dstIpPrefix Destination IP prefix
+ * @return builder object by setting Destination IP prefix
+ */
+ Builder setDstIpPrefix(IpPrefix dstIpPrefix);
+
+ /**
+ * Sets Source virtual port.
+ *
+ * @param srcPort Source virtual port
+ * @return builder object by setting Source virtual port
+ */
+ Builder setSrcPort(VirtualPortId srcPort);
+
+ /**
+ * Sets Destination virtual port.
+ *
+ * @param dstPort Destination virtual port
+ * @return builder object by setting Destination virtual port
+ */
+ Builder setDstPort(VirtualPortId dstPort);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifierId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifierId.java
new file mode 100644
index 00000000..b789abe3
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/FlowClassifierId.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.UUID;
+import java.util.Objects;
+
+/**
+ * Flow classification identifier.
+ */
+public final class FlowClassifierId {
+
+ private final UUID flowClassifierId;
+
+ /**
+ * Constructor to create flow classifier id.
+ *
+ * @param flowClassifierId flow classifier id.
+ */
+ private FlowClassifierId(final UUID flowClassifierId) {
+ this.flowClassifierId = flowClassifierId;
+ }
+
+ /**
+ * Returns new flow classifier id.
+ *
+ * @param flowClassifierId flow classifier id
+ * @return new flow classifier id
+ */
+ public static FlowClassifierId flowClassifierId(final UUID flowClassifierId) {
+ return new FlowClassifierId(flowClassifierId);
+ }
+
+ /**
+ * Returns new flow classifier id.
+ *
+ * @param flowClassifierId flow classifier id
+ * @return new flow classifier id
+ */
+ public static FlowClassifierId flowClassifierId(final String flowClassifierId) {
+ return new FlowClassifierId(UUID.fromString(flowClassifierId));
+ }
+
+ /**
+ * Returns the value of flow classifier id.
+ *
+ * @return flow classifier id.
+ */
+ public UUID value() {
+ return flowClassifierId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.flowClassifierId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof FlowClassifierId) {
+ final FlowClassifierId other = (FlowClassifierId) obj;
+ return Objects.equals(this.flowClassifierId, other.flowClassifierId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("FlowClassifierId", flowClassifierId)
+ .toString();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java
new file mode 100644
index 00000000..d147eaaa
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import java.util.List;
+
+/**
+ * Abstraction of an entity providing Port Chain information.
+ * A Port Chain (Service Function Path) consists of
+ * a set of Neutron ports, to define the sequence of service functions
+ * a set of flow classifiers, to specify the classified traffic flows to enter the chain
+ */
+public interface PortChain {
+
+ /**
+ * Returns the ID of this port chain.
+ *
+ * @return the port chain id
+ */
+ PortChainId portChainId();
+
+ /**
+ * Returns the tenant id of this port chain.
+ *
+ * @return the tenant id
+ */
+ TenantId tenantId();
+
+ /**
+ * Returns the name of this port chain.
+ *
+ * @return name of port chain
+ */
+ String name();
+
+ /**
+ * Returns the description of this port chain.
+ *
+ * @return description of port chain
+ */
+ String description();
+
+ /**
+ * Returns the list of port pair groups associated with
+ * this port chain.
+ *
+ * @return list of port pair groups
+ */
+ List<PortPairGroupId> portPairGroups();
+
+ /**
+ * Returns the list of flow classifiers associated with
+ * this port chain.
+ *
+ * @return list of flow classifiers
+ */
+ List<FlowClassifierId> flowClassifiers();
+
+ /**
+ * Returns whether this port chain is an exact match to the port chain given
+ * in the argument.
+ * <p>
+ * Exact match means the port pair groups and flow classifiers match
+ * with the given port chain. It does not consider the port chain id, name
+ * and description.
+ * </p>
+ *
+ * @param portChain other port chain to match against
+ * @return true if the port chains are an exact match, otherwise false
+ */
+ boolean exactMatch(PortChain portChain);
+
+ /**
+ * A port chain builder..
+ */
+ interface Builder {
+
+ /**
+ * Assigns the port chain id to this object.
+ *
+ * @param portChainId the port chain id
+ * @return this the builder object
+ */
+ Builder setId(PortChainId portChainId);
+
+ /**
+ * Assigns tenant id to this object.
+ *
+ * @param tenantId tenant id of the port chain
+ * @return this the builder object
+ */
+ Builder setTenantId(TenantId tenantId);
+
+ /**
+ * Assigns the name to this object.
+ *
+ * @param name name of the port chain
+ * @return this the builder object
+ */
+ Builder setName(String name);
+
+ /**
+ * Assigns the description to this object.
+ *
+ * @param description description of the port chain
+ * @return this the builder object
+ */
+ Builder setDescription(String description);
+
+ /**
+ * Assigns the port pair groups associated with the port chain
+ * to this object.
+ *
+ * @param portPairGroups list of port pair groups
+ * @return this the builder object
+ */
+ Builder setPortPairGroups(List<PortPairGroupId> portPairGroups);
+
+ /**
+ * Assigns the flow classifiers associated with the port chain
+ * to this object.
+ *
+ * @param flowClassifiers list of flow classifiers
+ * @return this the builder object
+ */
+ Builder setFlowClassifiers(List<FlowClassifierId> flowClassifiers);
+
+ /**
+ * Builds a port chain object.
+ *
+ * @return a port chain.
+ */
+ PortChain build();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChainId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChainId.java
new file mode 100644
index 00000000..66edbdcc
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChainId.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.UUID;
+
+import com.google.common.base.Objects;
+
+/**
+ * Representation of a Port Chain ID.
+ */
+public final class PortChainId {
+
+ private final UUID portChainId;
+
+ /**
+ * Private constructor for port chain id.
+ *
+ * @param id UUID id of port chain
+ */
+ private PortChainId(UUID id) {
+ checkNotNull(id, "Port chain id can not be null");
+ this.portChainId = id;
+ }
+
+ /**
+ * Constructor to create port chain id from UUID.
+ *
+ * @param id UUID of port chain
+ * @return object of port chain id
+ */
+ public static PortChainId portChainId(UUID id) {
+ return new PortChainId(id);
+ }
+
+ /**
+ * Constructor to create port chain id from string.
+ *
+ * @param id port chain id in string
+ * @return object of port chain id
+ */
+ public static PortChainId portChainId(String id) {
+ return new PortChainId(UUID.fromString(id));
+ }
+
+ /**
+ * Returns the value of port chain id.
+ *
+ * @return port chain id
+ */
+ public UUID value() {
+ return portChainId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj.getClass() == this.getClass()) {
+ PortChainId that = (PortChainId) obj;
+ return Objects.equal(this.portChainId, that.portChainId);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.portChainId);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("portChainId", portChainId.toString())
+ .toString();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPair.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPair.java
new file mode 100644
index 00000000..f6285e61
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPair.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+
+/**
+ * Abstraction of an entity providing Port Pair information.
+ * A port pair represents a service function instance.
+ */
+public interface PortPair {
+
+ /**
+ * Returns the ID of this port Pair.
+ *
+ * @return the port pair id
+ */
+ PortPairId portPairId();
+
+ /**
+ * Returns the tenant id of this port pair.
+ *
+ * @return an tenant id
+ */
+ TenantId tenantId();
+
+ /**
+ * Returns the description of this port pair.
+ *
+ * @return description of port pair
+ */
+ String name();
+
+ /**
+ * Returns the description of this port pair.
+ *
+ * @return description of port pair
+ */
+ String description();
+
+ /**
+ * Returns the ingress port of this port pair.
+ *
+ * @return ingress of port pair
+ */
+ String ingress();
+
+ /**
+ * Returns the egress port of this port pair.
+ *
+ * @return egress of port pair
+ */
+ String egress();
+
+ /**
+ * Returns whether this port pair is an exact match to the port pair given
+ * in the argument.
+ * <p>
+ * Exact match means the Port port pairs match with the given port pair.
+ * It does not consider the port pair id, name and description.
+ * </p>
+ * @param portPair other port pair to match against
+ * @return true if the port pairs are an exact match, otherwise false
+ */
+ boolean exactMatch(PortPair portPair);
+
+ /**
+ * A port pair builder..
+ */
+ interface Builder {
+
+ /**
+ * Assigns the port pair id to this object.
+ *
+ * @param portPairId the port pair id
+ * @return this the builder object
+ */
+ Builder setId(PortPairId portPairId);
+
+ /**
+ * Assigns tenant id to this object.
+ *
+ * @param tenantId tenant id of the port pair
+ * @return this the builder object
+ */
+ Builder setTenantId(TenantId tenantId);
+
+ /**
+ * Assigns the name to this object.
+ *
+ * @param name name of the port pair
+ * @return this the builder object
+ */
+ Builder setName(String name);
+
+ /**
+ * Assigns the description to this object.
+ *
+ * @param description description of the port pair
+ * @return this the builder object
+ */
+ Builder setDescription(String description);
+
+ /**
+ * Assigns the ingress port to this object.
+ *
+ * @param port ingress port of the port pair
+ * @return this the builder object
+ */
+ Builder setIngress(String port);
+
+ /**
+ * Assigns the egress port to this object.
+ *
+ * @param port egress port of the port pair
+ * @return this the builder object
+ */
+ Builder setEgress(String port);
+
+ /**
+ * Builds a port pair object.
+ *
+ * @return a port pair.
+ */
+ PortPair build();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java
new file mode 100644
index 00000000..f647b57f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import java.util.List;
+
+/**
+ * Abstraction of an entity providing Port Pair Group information.
+ * A port pair group consists of one or more port pairs.
+ */
+public interface PortPairGroup {
+
+ /**
+ * Returns the ID of this port pair group.
+ *
+ * @return the port pair group id
+ */
+ PortPairGroupId portPairGroupId();
+
+ /**
+ * Returns the tenant id of this port pair group.
+ *
+ * @return the tenant id
+ */
+ TenantId tenantId();
+
+ /**
+ * Returns the name of this port pair group.
+ *
+ * @return name of port pair group
+ */
+ String name();
+
+ /**
+ * Returns the description of this port pair group.
+ *
+ * @return description of port pair group
+ */
+ String description();
+
+ /**
+ * Returns the list of port pairs associated with this port pair group.
+ *
+ * @return list of port pairs
+ */
+ List<PortPairId> portPairs();
+
+ /**
+ * Returns whether this port pair group is an exact match to the
+ * port pair group given in the argument.
+ * <p>
+ * Exact match means the Port pairs match with the given port pair group.
+ * It does not consider the port pair group id, name and description.
+ * </p>
+ * @param portPairGroup other port pair group to match against
+ * @return true if the port pairs are an exact match, otherwise false
+ */
+ boolean exactMatch(PortPairGroup portPairGroup);
+
+ /**
+ * A port pair group builder..
+ */
+ interface Builder {
+
+ /**
+ * Assigns the port pair group id to this object.
+ *
+ * @param portPairGroupId the port pair group id
+ * @return this the builder object
+ */
+ Builder setId(PortPairGroupId portPairGroupId);
+
+ /**
+ * Assigns tenant id to this object.
+ *
+ * @param tenantId tenant id of port pair group
+ * @return this the builder object
+ */
+ Builder setTenantId(TenantId tenantId);
+
+ /**
+ * Assigns the name to this object.
+ *
+ * @param name name of the port pair group
+ * @return this the builder object
+ */
+ Builder setName(String name);
+
+ /**
+ * Assigns the description to this object.
+ *
+ * @param description description of the port pair group
+ * @return this the builder object
+ */
+ Builder setDescription(String description);
+
+ /**
+ * Assigns the port pairs associated with the port pair group
+ * to this object.
+ *
+ * @param portPairs list of port pairs
+ * @return this the builder object
+ */
+ Builder setPortPairs(List<PortPairId> portPairs);
+
+ /**
+ * Builds a port pair group object.
+ *
+ * @return a port pair group object.
+ */
+ PortPairGroup build();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroupId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroupId.java
new file mode 100644
index 00000000..0474901c
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroupId.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.UUID;
+
+import com.google.common.base.Objects;
+
+/**
+ * Representation of a Port Pair Group ID.
+ */
+public final class PortPairGroupId {
+
+ private final UUID portPairGroupId;
+
+ /**
+ * Private constructor for port pair group id.
+ *
+ * @param id UUID id of port pair group
+ */
+ private PortPairGroupId(UUID id) {
+ checkNotNull(id, "Port pair group id can not be null");
+ this.portPairGroupId = id;
+ }
+
+ /**
+ * Constructor to create port pair group id from UUID.
+ *
+ * @param id UUID of port pair group id
+ * @return object of port pair group id
+ */
+ public static PortPairGroupId portPairGroupId(UUID id) {
+ return new PortPairGroupId(id);
+ }
+
+ /**
+ * Constructor to create port pair group id from string.
+ *
+ * @param id port pair group id in string
+ * @return object of port pair group id
+ */
+ public static PortPairGroupId portPairGroupId(String id) {
+ return new PortPairGroupId(UUID.fromString(id));
+ }
+
+ /**
+ * Returns the value of port pair group id.
+ *
+ * @return port pair group id
+ */
+ public UUID value() {
+ return portPairGroupId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj.getClass() == this.getClass()) {
+ PortPairGroupId that = (PortPairGroupId) obj;
+ return Objects.equal(this.portPairGroupId, that.portPairGroupId);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.portPairGroupId);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("portPairGroupId", portPairGroupId.toString())
+ .toString();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairId.java
new file mode 100644
index 00000000..05c31aac
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairId.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.UUID;
+
+import com.google.common.base.Objects;
+
+/**
+ * Representation of a Port Pair ID.
+ */
+public final class PortPairId {
+
+ private final UUID portPairId;
+
+ /**
+ * Private constructor for port pair id.
+ *
+ * @param id UUID id of port pair
+ */
+ private PortPairId(UUID id) {
+ checkNotNull(id, "Port chain id can not be null");
+ this.portPairId = id;
+ }
+
+ /**
+ * Constructor to create port pair id from UUID.
+ *
+ * @param id UUID of port pair id
+ * @return object of port pair id
+ */
+ public static PortPairId portPairId(UUID id) {
+ return new PortPairId(id);
+ }
+
+ /**
+ * Constructor to create port pair id from string.
+ *
+ * @param id port pair id in string
+ * @return object of port pair id
+ */
+ public static PortPairId portPairId(String id) {
+ return new PortPairId(UUID.fromString(id));
+ }
+
+ /**
+ * Returns teh value of port pair id.
+ *
+ * @return port pair id
+ */
+ public UUID value() {
+ return portPairId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj.getClass() == this.getClass()) {
+ PortPairId that = (PortPairId) obj;
+ return Objects.equal(this.portPairId, that.portPairId);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.portPairId);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("portPairId", portPairId.toString())
+ .toString();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java
new file mode 100644
index 00000000..e379be81
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.flowClassifier;
+
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
+
+/**
+ * Provides Services for Flow Classifier.
+ */
+public interface FlowClassifierService {
+
+ /**
+ * Store Flow Classifier.
+ *
+ * @param flowClassifier Flow Classifier
+ * @return true if adding Flow Classifier into store is success otherwise return false.
+ */
+ boolean createFlowClassifier(FlowClassifier flowClassifier);
+
+ /**
+ * Return the existing collection of Flow Classifier.
+ *
+ * @return Flow Classifier collections.
+ */
+ Iterable<FlowClassifier> getFlowClassifiers();
+
+ /**
+ * Check whether Flow Classifier is present based on given Flow Classifier Id.
+ *
+ * @param id Flow Classifier.
+ * @return true if Flow Classifier is present otherwise return false.
+ */
+ boolean hasFlowClassifier(FlowClassifierId id);
+
+ /**
+ * Retrieve the Flow Classifier based on given Flow Classifier id.
+ *
+ * @param id Flow Classifier Id.
+ * @return Flow Classifier if present otherwise returns null.
+ */
+ FlowClassifier getFlowClassifier(FlowClassifierId id);
+
+ /**
+ * Update Flow Classifier based on given Flow Classifier Id.
+ *
+ * @param flowClassifier Flow Classifier.
+ * @return true if update is success otherwise return false.
+ */
+ boolean updateFlowClassifier(FlowClassifier flowClassifier);
+
+ /**
+ * Remove Flow Classifier from store based on given Flow Classifier Id.
+ *
+ * @param id Flow Classifier Id.
+ * @return true if Flow Classifier removal is success otherwise return false.
+ */
+ boolean removeFlowClassifier(FlowClassifierId id);
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java
new file mode 100644
index 00000000..7238558a
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.flowClassifier.impl;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService;
+
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Provides implementation of the Flow Classifier Service.
+ */
+@Component(immediate = true)
+@Service
+public class FlowClassifierManager implements FlowClassifierService {
+
+ private final Logger log = getLogger(FlowClassifierManager.class);
+
+ private static final String FLOW_CLASSIFIER_NOT_NULL = "Flow Classifier cannot be null";
+ private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "Flow Classifier Id cannot be null";
+
+ private ConcurrentMap<FlowClassifierId, FlowClassifier> flowClassifierStore
+ = new ConcurrentHashMap<FlowClassifierId, FlowClassifier>();
+
+ @Activate
+ private void activate() {
+ log.info("Flow Classifier service activated");
+ }
+
+ @Deactivate
+ private void deactivate() {
+ log.info("Flow Classifier service deactivated");
+ }
+
+ @Override
+ public boolean createFlowClassifier(FlowClassifier flowClassifier) {
+ log.debug("createFlowClassifier");
+ checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL);
+ FlowClassifierId id = flowClassifier.flowClassifierId();
+
+ flowClassifierStore.put(id, flowClassifier);
+ if (!flowClassifierStore.containsKey(id)) {
+ log.debug("Flow Classifier creation is failed whose identifier is {}.", id.toString());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public Iterable<FlowClassifier> getFlowClassifiers() {
+ return ImmutableList.copyOf(flowClassifierStore.values());
+ }
+
+ @Override
+ public boolean hasFlowClassifier(FlowClassifierId id) {
+ checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL);
+ return flowClassifierStore.containsKey(id);
+ }
+
+ @Override
+ public FlowClassifier getFlowClassifier(FlowClassifierId id) {
+ checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL);
+ return flowClassifierStore.get(id);
+ }
+
+ @Override
+ public boolean updateFlowClassifier(FlowClassifier flowClassifier) {
+ checkNotNull(flowClassifier, FLOW_CLASSIFIER_NOT_NULL);
+ FlowClassifierId id = flowClassifier.flowClassifierId();
+ return flowClassifierStore.replace(id, flowClassifierStore.get(id), flowClassifier);
+ }
+
+ @Override
+ public boolean removeFlowClassifier(FlowClassifierId id) {
+ checkNotNull(id, FLOW_CLASSIFIER_ID_NOT_NULL);
+ flowClassifierStore.remove(id);
+ if (flowClassifierStore.containsKey(id)) {
+ log.debug("The Flow Classifier removal is failed whose identifier is {}", id.toString());
+ return false;
+ }
+ return true;
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java
new file mode 100644
index 00000000..4ea050b3
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Provides implementation of the flow Classifier service.
+ */
+package org.onosproject.vtnrsc.flowClassifier.impl;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java
new file mode 100644
index 00000000..07584170
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Service for interacting with flow Classifier of SFC.
+ */
+package org.onosproject.vtnrsc.flowClassifier;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java
new file mode 100644
index 00000000..b4ff917e
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.portchain;
+
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+
+/**
+ * Service for interacting with the inventory of port chains.
+ */
+public interface PortChainService {
+
+ /**
+ * Returns if the port chain is existed.
+ *
+ * @param portChainId port chain identifier
+ * @return true or false if one with the given identifier exists.
+ */
+ boolean exists(PortChainId portChainId);
+
+ /**
+ * Returns the number of port chains known to the system.
+ *
+ * @return number of port chains.
+ */
+ int getPortChainCount();
+
+ /**
+ * Returns an iterable collection of the currently known port chains.
+ *
+ * @return collection of port chains.
+ */
+ Iterable<PortChain> getPortChains();
+
+ /**
+ * Returns the portChain with the given identifier.
+ *
+ * @param portChainId port chain identifier
+ * @return PortChain or null if port chain with the given identifier is not
+ * known.
+ */
+ PortChain getPortChain(PortChainId portChainId);
+
+ /**
+ * Creates a PortChain in the store.
+ *
+ * @param portChain the port chain to create
+ * @return true if given port chain is created successfully.
+ */
+ boolean createPortChain(PortChain portChain);
+
+ /**
+ * Updates the portChain in the store.
+ *
+ * @param portChain the port chain to update
+ * @return true if given port chain is updated successfully.
+ */
+ boolean updatePortChain(PortChain portChain);
+
+ /**
+ * Deletes portChain by given portChainId.
+ *
+ * @param portChainId id of port chain to remove
+ * @return true if the give port chain is deleted successfully.
+ */
+ boolean removePortChain(PortChainId portChainId);
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/package-info.java
new file mode 100644
index 00000000..74642bc3
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Service for interacting with the inventory of port chains.
+ */
+package org.onosproject.vtnrsc.portchain;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java
new file mode 100644
index 00000000..77f483fc
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.portpairgroup;
+
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+
+/**
+ * Service for interacting with the inventory of port pair groups.
+ */
+public interface PortPairGroupService {
+
+ /**
+ * Returns if the port pair group is existed.
+ *
+ * @param portPairGroupId port pair group identifier
+ * @return true or false if one with the given identifier exists.
+ */
+ boolean exists(PortPairGroupId portPairGroupId);
+
+ /**
+ * Returns the number of port pair groups known to the system.
+ *
+ * @return number of port pair groups.
+ */
+ int getPortPairGroupCount();
+
+ /**
+ * Returns an iterable collection of the currently known port pair groups.
+ *
+ * @return collection of port pair groups.
+ */
+ Iterable<PortPairGroup> getPortPairGroups();
+
+ /**
+ * Returns the portPairGroup with the given identifier.
+ *
+ * @param portPairGroupId port pair group identifier
+ * @return PortPairGroup or null if port pair group with the given identifier is not
+ * known.
+ */
+ PortPairGroup getPortPairGroup(PortPairGroupId portPairGroupId);
+
+ /**
+ * Creates a PortPairGroup in the store.
+ *
+ * @param portPairGroup the port pair group to create
+ * @return true if given port pair group is created successfully.
+ */
+ boolean createPortPairGroup(PortPairGroup portPairGroup);
+
+ /**
+ * Updates the portPairGroup in the store.
+ *
+ * @param portPairGroup the port pair group to update
+ * @return true if given port pair group is updated successfully.
+ */
+ boolean updatePortPairGroup(PortPairGroup portPairGroup);
+
+ /**
+ * Deletes portPairGroup by given portPairGroupId.
+ *
+ * @param portPairGroupId id of port pair group to remove
+ * @return true if the give port pair group is deleted successfully.
+ */
+ boolean removePortPairGroup(PortPairGroupId portPairGroupId);
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/package-info.java
new file mode 100644
index 00000000..8a79fe97
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Service for interacting with the inventory of port pair groups.
+ */
+package org.onosproject.vtnrsc.portpairgroup;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java
deleted file mode 100644
index 6f3cf653..00000000
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vtnrsc.tunnel;
-
-import org.onosproject.vtnrsc.Subnet;
-import org.onosproject.vtnrsc.SubnetId;
-
-
-/**
- * Service for interacting with the inventory of subnets.
- */
-public interface TunnelConfigService {
- /**
- * Returns the subnet with the specified identifier.
- *
- * @param subnetId subnet identifier
- * @return true or false
- */
- boolean exists(SubnetId subnetId);
- /**
- * Returns a collection of the currently known subnets.
- *
- * @return iterable collection of subnets
- */
- Iterable<Subnet> getSubnets();
-
- /**
- * Returns the subnet with the specified identifier.
- *
- * @param subnetId subnet identifier
- * @return subnet or null if one with the given identifier is not known
- */
- Subnet getSubnet(SubnetId subnetId);
- /**
- * Creates new subnets.
- *
- * @param subnets the iterable collection of subnets
- * @return true if the identifier subnet has been created right
- */
- boolean createSubnets(Iterable<Subnet> subnets);
-
- /**
- * Updates existing subnets.
- *
- * @param subnets the iterable collection of subnets
- * @return true if all subnets were updated successfully
- */
- boolean updateSubnets(Iterable<Subnet> subnets);
-
- /**
- * Administratively removes the specified subnets from the store.
- *
- * @param subnetIds the iterable collection of subnets identifier
- * @return true if remove identifier subnets successfully
- */
- boolean removeSubnets(Iterable<SubnetId> subnetIds);
-
-
-}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
index c45373b9..daec7839 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
@@ -191,22 +191,20 @@ public class VirtualPortManager implements VirtualPortService {
@Override
public boolean updatePorts(Iterable<VirtualPort> vPorts) {
checkNotNull(vPorts, VIRTUALPORT_NOT_NULL);
- if (vPorts != null) {
- for (VirtualPort vPort : vPorts) {
- vPortStore.put(vPort.portId(), vPort);
- if (!vPortStore.containsKey(vPort.portId())) {
- log.debug("The virtualPort is not exist whose identifier is {}",
- vPort.portId().toString());
- return false;
- }
+ for (VirtualPort vPort : vPorts) {
+ vPortStore.put(vPort.portId(), vPort);
+ if (!vPortStore.containsKey(vPort.portId())) {
+ log.debug("The virtualPort is not exist whose identifier is {}",
+ vPort.portId().toString());
+ return false;
+ }
- vPortStore.put(vPort.portId(), vPort);
+ vPortStore.put(vPort.portId(), vPort);
- if (!vPort.equals(vPortStore.get(vPort.portId()))) {
- log.debug("The virtualPort is updated failed whose identifier is {}",
- vPort.portId().toString());
- return false;
- }
+ if (!vPort.equals(vPortStore.get(vPort.portId()))) {
+ log.debug("The virtualPort is updated failed whose identifier is {}",
+ vPort.portId().toString());
+ return false;
}
}
return true;
@@ -215,14 +213,12 @@ public class VirtualPortManager implements VirtualPortService {
@Override
public boolean removePorts(Iterable<VirtualPortId> vPortIds) {
checkNotNull(vPortIds, VIRTUALPORT_ID_NULL);
- if (vPortIds != null) {
- for (VirtualPortId vPortId : vPortIds) {
- vPortStore.remove(vPortId);
- if (vPortStore.containsKey(vPortId)) {
- log.debug("The virtualPort is removed failed whose identifier is {}",
- vPortId.toString());
- return false;
- }
+ for (VirtualPortId vPortId : vPortIds) {
+ vPortStore.remove(vPortId);
+ if (vPortStore.containsKey(vPortId)) {
+ log.debug("The virtualPort is removed failed whose identifier is {}",
+ vPortId.toString());
+ return false;
}
}
return true;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FlowClassifierCodec.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FlowClassifierCodec.java
new file mode 100644
index 00000000..fd5b1ee4
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FlowClassifierCodec.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+import java.util.UUID;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.DefaultFlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.TenantId;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Flow Classifier JSON codec.
+ */
+public final class FlowClassifierCodec extends JsonCodec<FlowClassifier> {
+
+ private static final String FLOW_CLASSIFIER_ID = "id";
+ private static final String TENANT_ID = "tenant_id";
+ private static final String NAME = "name";
+ private static final String DESCRIPTION = "description";
+ private static final String ETHER_TYPE = "etherType";
+ private static final String PROTOCOL = "protocol";
+ private static final String MIN_SRC_PORT_RANGE = "source_port_range_min";
+ private static final String MAX_SRC_PORT_RANGE = "source_port_range_max";
+ private static final String MIN_DST_PORT_RANGE = "destination_port_range_min";
+ private static final String MAX_DST_PORT_RANGE = "destination_port_range_max";
+ private static final String SRC_IP_PREFIX = "source_ip_prefix";
+ private static final String DST_IP_PREFIX = "destination_ip_prefix";
+ private static final String SRC_PORT = "logical_source_port";
+ private static final String DST_PORT = "logical_destination_port";
+ private static final String MISSING_MEMBER_MESSAGE = " member is required in Flow Classifier.";
+
+ @Override
+ public FlowClassifier decode(ObjectNode json, CodecContext context) {
+ if (json == null || !json.isObject()) {
+ return null;
+ }
+
+ FlowClassifier.Builder resultBuilder = new DefaultFlowClassifier.Builder();
+
+ String flowClassifierId = nullIsIllegal(json.get(FLOW_CLASSIFIER_ID),
+ FLOW_CLASSIFIER_ID + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setFlowClassifierId(FlowClassifierId.flowClassifierId(UUID.fromString(flowClassifierId)));
+
+ String tenantId = nullIsIllegal(json.get(TENANT_ID), TENANT_ID + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setTenantId(TenantId.tenantId(tenantId));
+
+ String flowClassiferName = nullIsIllegal(json.get(NAME), NAME + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setName(flowClassiferName);
+
+ String flowClassiferDescription = nullIsIllegal(json.get(DESCRIPTION), DESCRIPTION + MISSING_MEMBER_MESSAGE)
+ .asText();
+ resultBuilder.setDescription(flowClassiferDescription);
+
+ String etherType = nullIsIllegal(json.get(ETHER_TYPE), ETHER_TYPE + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setEtherType(etherType);
+
+ String protocol = nullIsIllegal(json.get(PROTOCOL), PROTOCOL + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setProtocol(protocol);
+
+ int minSrcPortRange = nullIsIllegal(json.get(MIN_SRC_PORT_RANGE), MIN_SRC_PORT_RANGE + MISSING_MEMBER_MESSAGE)
+ .asInt();
+ resultBuilder.setMinSrcPortRange(minSrcPortRange);
+
+ int maxSrcPortRange = nullIsIllegal(json.get(MAX_SRC_PORT_RANGE), MAX_SRC_PORT_RANGE + MISSING_MEMBER_MESSAGE)
+ .asInt();
+ resultBuilder.setMaxSrcPortRange(maxSrcPortRange);
+
+ int minDstPortRange = nullIsIllegal(json.get(MIN_DST_PORT_RANGE), MIN_DST_PORT_RANGE + MISSING_MEMBER_MESSAGE)
+ .asInt();
+ resultBuilder.setMinDstPortRange(minDstPortRange);
+
+ int maxDstPortRange = nullIsIllegal(json.get(MAX_DST_PORT_RANGE), MAX_DST_PORT_RANGE + MISSING_MEMBER_MESSAGE)
+ .asInt();
+ resultBuilder.setMaxDstPortRange(maxDstPortRange);
+
+ String srcIpPrefix = nullIsIllegal(json.get(SRC_IP_PREFIX), SRC_IP_PREFIX + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setSrcIpPrefix(IpPrefix.valueOf(srcIpPrefix));
+
+ String dstIpPrefix = nullIsIllegal(json.get(DST_IP_PREFIX), DST_IP_PREFIX + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setDstIpPrefix(IpPrefix.valueOf(dstIpPrefix));
+
+ String srcPort = nullIsIllegal(json.get(SRC_PORT), SRC_PORT + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setSrcPort(VirtualPortId.portId(srcPort));
+
+ String dstPort = nullIsIllegal(json.get(DST_PORT), DST_PORT + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setDstPort(VirtualPortId.portId(dstPort));
+
+ return resultBuilder.build();
+ }
+
+ @Override
+ public ObjectNode encode(FlowClassifier flowClassifier, CodecContext context) {
+ checkNotNull(flowClassifier, "flowClassifier cannot be null");
+ ObjectNode result = context.mapper().createObjectNode()
+ .put("FLOW_CLASSIFIER_ID", flowClassifier.flowClassifierId().toString())
+ .put("TENANT_ID", flowClassifier.tenantId().toString())
+ .put("NAME", flowClassifier.name())
+ .put("DESCRIPTION", flowClassifier.description())
+ .put("ETHER_TYPE", flowClassifier.etherType())
+ .put("PROTOCOL", flowClassifier.protocol())
+ .put("MIN_SRC_PORT_RANGE", flowClassifier.minSrcPortRange())
+ .put("MAX_SRC_PORT_RANGE", flowClassifier.maxSrcPortRange())
+ .put("MIN_DST_PORT_RANGE", flowClassifier.minDstPortRange())
+ .put("MAX_DST_PORT_RANGE", flowClassifier.maxDstPortRange())
+ .put("SRC_IP_PREFIX", flowClassifier.srcIpPrefix().toString())
+ .put("DST_IP_PREFIX", flowClassifier.dstIpPrefix().toString())
+ .put("SRC_PORT", flowClassifier.srcPort().toString())
+ .put("DST_PORT", flowClassifier.dstPort().toString());
+ return result;
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierIdTest.java
new file mode 100644
index 00000000..b2fed347
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierIdTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.flowclassifier;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.FlowClassifierId;
+
+import com.google.common.testing.EqualsTester;
+import java.util.UUID;
+
+/**
+ * Unit tests for FlowClassifierId class.
+ */
+public class FlowClassifierIdTest {
+
+ final FlowClassifierId flowClassifierId1 = FlowClassifierId
+ .flowClassifierId("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final FlowClassifierId sameAsFlowClassifierId1 = FlowClassifierId
+ .flowClassifierId("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final FlowClassifierId flowClassifierId2 = FlowClassifierId
+ .flowClassifierId("dace4513-24fc-4fae-af4b-321c5e2eb3d1");
+
+ /**
+ * Checks that the FlowClassifierId class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(FlowClassifierId.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(flowClassifierId1, sameAsFlowClassifierId1)
+ .addEqualityGroup(flowClassifierId2).testEquals();
+ }
+
+ /**
+ * Checks the construction of a FlowClassifierId object.
+ */
+ @Test
+ public void testConstruction() {
+ final String flowClassifierIdValue = "dace4513-24fc-4fae-af4b-321c5e2eb3d1";
+ final FlowClassifierId flowClassifierId = FlowClassifierId.flowClassifierId(flowClassifierIdValue);
+ assertThat(flowClassifierId, is(notNullValue()));
+ assertThat(flowClassifierId.value(), is(UUID.fromString(flowClassifierIdValue)));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultAllocationPoolTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultAllocationPoolTest.java
new file mode 100644
index 00000000..4ce4def2
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultAllocationPoolTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.subnet;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.vtnrsc.AllocationPool;
+import org.onosproject.vtnrsc.DefaultAllocationPool;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for DefaultAllocationPool class.
+ */
+public class DefaultAllocationPoolTest {
+
+ final IpAddress startIP1 = IpAddress.valueOf("192.168.1.1");
+ final IpAddress startIP2 = IpAddress.valueOf("192.168.1.2");
+ final IpAddress endIP1 = IpAddress.valueOf("192.168.1.1");
+ final IpAddress endIP2 = IpAddress.valueOf("192.168.1.2");
+
+ /**
+ * Checks that the DefaultAllocationPool class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(DefaultAllocationPool.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ AllocationPool pool1 = new DefaultAllocationPool(startIP1, endIP1);
+ AllocationPool pool2 = new DefaultAllocationPool(startIP1, endIP1);
+ AllocationPool pool3 = new DefaultAllocationPool(startIP2, endIP2);
+ new EqualsTester().addEqualityGroup(pool1, pool2)
+ .addEqualityGroup(pool3).testEquals();
+ }
+
+ /**
+ * Checks the construction of a DefaultAllocationPool object.
+ */
+ @Test
+ public void testConstruction() {
+ final AllocationPool apool = new DefaultAllocationPool(startIP1, endIP1);
+ assertThat(startIP1, is(apool.startIp()));
+ assertThat(endIP1, is(apool.endIp()));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultHostRouteTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultHostRouteTest.java
new file mode 100644
index 00000000..2f751742
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/DefaultHostRouteTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.subnet;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.vtnrsc.DefaultHostRoute;
+import org.onosproject.vtnrsc.HostRoute;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for DefaultHostRoute class.
+ */
+public class DefaultHostRouteTest {
+ final IpAddress nexthop1 = IpAddress.valueOf("192.168.1.1");
+ final IpAddress nexthop2 = IpAddress.valueOf("192.168.1.2");
+ final IpPrefix destination1 = IpPrefix.valueOf("1.1.1.1/1");
+ final IpPrefix destination2 = IpPrefix.valueOf("1.1.1.1/2");
+
+ /**
+ * Checks that the DefaultHostRoute class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(DefaultHostRoute.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ HostRoute route1 = new DefaultHostRoute(nexthop1, destination1);
+ HostRoute route2 = new DefaultHostRoute(nexthop1, destination1);
+ HostRoute route3 = new DefaultHostRoute(nexthop2, destination2);
+ new EqualsTester().addEqualityGroup(route1, route2)
+ .addEqualityGroup(route3).testEquals();
+ }
+
+ /**
+ * Checks the construction of a DefaultHostRoute object.
+ */
+ @Test
+ public void testConstruction() {
+ final HostRoute host = new DefaultHostRoute(nexthop1, destination1);
+ assertThat(nexthop1, is(host.nexthop()));
+ assertThat(destination1, is(host.destination()));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/SubnetIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/SubnetIdTest.java
new file mode 100644
index 00000000..d18dd41a
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/subnet/SubnetIdTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.subnet;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.SubnetId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for SubnetId class.
+ */
+public class SubnetIdTest {
+
+ final SubnetId subnetId1 = SubnetId.subnetId("1");
+ final SubnetId sameAsSubnetId1 = SubnetId.subnetId("1");
+ final SubnetId subnetId2 = SubnetId.subnetId("2");
+
+ /**
+ * Checks that the SubnetId class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(SubnetId.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(subnetId1, sameAsSubnetId1).addEqualityGroup(subnetId2)
+ .testEquals();
+ }
+
+ /**
+ * Checks the construction of a SubnetId object.
+ */
+ @Test
+ public void testConstruction() {
+ final String subnetIdValue = "s";
+ final SubnetId subnetId = SubnetId.subnetId(subnetIdValue);
+ assertThat(subnetId, is(notNullValue()));
+ assertThat(subnetId.subnetId(), is(subnetIdValue));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/DefaultNeutronNetworkTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/DefaultNeutronNetworkTest.java
new file mode 100644
index 00000000..742d5933
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/DefaultNeutronNetworkTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.tenantnetwork;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.DefaultTenantNetwork;
+import org.onosproject.vtnrsc.PhysicalNetwork;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for DefaultNeutronNetwork class.
+ */
+public class DefaultNeutronNetworkTest {
+
+ private String networkIdStr1 = "123";
+ private String networkIdStr2 = "234";
+ private String physicalNetworkStr = "1234";
+ private String tenantIdStr = "345";
+ private String segmentationIdStr = "1";
+ private String name = "456";
+
+ /**
+ * Checks that the DefaultNeutronNetwork class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(DefaultTenantNetwork.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquality() {
+ TenantNetworkId networkid1 = TenantNetworkId.networkId(networkIdStr1);
+ TenantNetworkId networkid2 = TenantNetworkId.networkId(networkIdStr2);
+ PhysicalNetwork physicalNetwork = PhysicalNetwork
+ .physicalNetwork(physicalNetworkStr);
+ TenantId tenantId = TenantId.tenantId(tenantIdStr);
+ SegmentationId segmentationID = SegmentationId
+ .segmentationId(segmentationIdStr);
+ TenantNetwork p1 = new DefaultTenantNetwork(networkid1, name, false,
+ TenantNetwork.State.ACTIVE,
+ false, tenantId, false,
+ TenantNetwork.Type.LOCAL,
+ physicalNetwork,
+ segmentationID);
+ TenantNetwork p2 = new DefaultTenantNetwork(networkid1, name, false,
+ TenantNetwork.State.ACTIVE,
+ false, tenantId, false,
+ TenantNetwork.Type.LOCAL,
+ physicalNetwork,
+ segmentationID);
+ TenantNetwork p3 = new DefaultTenantNetwork(networkid2, name, false,
+ TenantNetwork.State.ACTIVE,
+ false, tenantId, false,
+ TenantNetwork.Type.LOCAL,
+ physicalNetwork,
+ segmentationID);
+ new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3)
+ .testEquals();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/PhysicalNetworkTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/PhysicalNetworkTest.java
new file mode 100644
index 00000000..e101795e
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/PhysicalNetworkTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.tenantnetwork;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.PhysicalNetwork;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for PhysicalNetwork class.
+ */
+public class PhysicalNetworkTest {
+
+ final PhysicalNetwork physicalNetwork1 = PhysicalNetwork.physicalNetwork("1");
+ final PhysicalNetwork sameAsPhysicalNetwork1 = PhysicalNetwork.physicalNetwork("1");
+ final PhysicalNetwork physicalNetwork2 = PhysicalNetwork.physicalNetwork("2");
+
+ /**
+ * Checks that the PhysicalNetwork class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(PhysicalNetwork.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(physicalNetwork1, sameAsPhysicalNetwork1)
+ .addEqualityGroup(physicalNetwork2).testEquals();
+ }
+
+ /**
+ * Checks the construction of a PhysicalNetwork object.
+ */
+ @Test
+ public void testConstruction() {
+ final String physicalNetworkValue = "s";
+ final PhysicalNetwork physicalNetwork = PhysicalNetwork
+ .physicalNetwork(physicalNetworkValue);
+ assertThat(physicalNetwork, is(notNullValue()));
+ assertThat(physicalNetwork.physicalNetwork(), is(physicalNetworkValue));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/SegmentationIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/SegmentationIdTest.java
new file mode 100644
index 00000000..dea7baf6
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/SegmentationIdTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.tenantnetwork;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.SegmentationId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for SegmentationId class.
+ */
+public class SegmentationIdTest {
+
+ final SegmentationId segmentationID1 = SegmentationId.segmentationId("1");
+ final SegmentationId sameAsSegmentationID1 = SegmentationId.segmentationId("1");
+ final SegmentationId segmentationID2 = SegmentationId.segmentationId("2");
+
+ /**
+ * Checks that the SegmentationId class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(SegmentationId.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(segmentationID1, sameAsSegmentationID1)
+ .addEqualityGroup(segmentationID2).testEquals();
+ }
+
+ /**
+ * Checks the construction of a segmentationId object.
+ */
+ @Test
+ public void testConstruction() {
+ final String segmentationIdValue = "s";
+ final SegmentationId segmentationId = SegmentationId.segmentationId(segmentationIdValue);
+ assertThat(segmentationId, is(notNullValue()));
+ assertThat(segmentationId.segmentationId(), is(segmentationIdValue));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantIdTest.java
new file mode 100644
index 00000000..e9216383
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantIdTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.tenantnetwork;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.TenantId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for TenantId class.
+ */
+public class TenantIdTest {
+
+ final TenantId tenantId1 = TenantId.tenantId("1");
+ final TenantId sameAsTenantId1 = TenantId.tenantId("1");
+ final TenantId tenantId2 = TenantId.tenantId("2");
+
+ /**
+ * Checks that the TenantId class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(TenantId.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(tenantId1, sameAsTenantId1).addEqualityGroup(tenantId2)
+ .testEquals();
+ }
+
+ /**
+ * Checks the construction of a TenantId object.
+ */
+ @Test
+ public void testConstruction() {
+ final String tenantIdValue = "s";
+ final TenantId tenantId = TenantId.tenantId(tenantIdValue);
+ assertThat(tenantId, is(notNullValue()));
+ assertThat(tenantId.tenantId(), is(tenantIdValue));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkIdTest.java
new file mode 100644
index 00000000..8271b51c
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkIdTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.tenantnetwork;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.TenantNetworkId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for TenantNetworkId class.
+ */
+public class TenantNetworkIdTest {
+
+ final TenantNetworkId networkId1 = TenantNetworkId.networkId("1");
+ final TenantNetworkId sameAsnetworkId1 = TenantNetworkId.networkId("1");
+ final TenantNetworkId networkId2 = TenantNetworkId.networkId("2");
+
+ /**
+ * Checks that the TenantNetworkId class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(TenantNetworkId.class);
+ }
+
+ /**
+ * Checks the operation of equals() methods.
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(networkId1, sameAsnetworkId1)
+ .addEqualityGroup(networkId2).testEquals();
+ }
+
+ /**
+ * Checks the construction of a TenantNetworkId object.
+ */
+ @Test
+ public void testConstruction() {
+ final String networkIdValue = "s";
+ final TenantNetworkId networkId = TenantNetworkId.networkId(networkIdValue);
+ assertThat(networkId, is(notNullValue()));
+ assertThat(networkId.networkId(), is(networkIdValue));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/AllowedAddressPairTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/AllowedAddressPairTest.java
new file mode 100644
index 00000000..dabe5896
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/AllowedAddressPairTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vtnrsc.virtualport;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for AllowedAddressPair class.
+ */
+public class AllowedAddressPairTest {
+
+ final IpAddress ip1 = IpAddress.valueOf("192.168.0.1");
+ final IpAddress ip2 = IpAddress.valueOf("192.168.0.2");
+ final MacAddress mac1 = MacAddress.valueOf("fa:16:3e:76:83:88");
+ final MacAddress mac2 = MacAddress.valueOf("aa:16:3e:76:83:88");
+
+ /**
+ * Checks that the AllowedAddressPair class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(AllowedAddressPair.class);
+ }
+
+ /**
+ * Checks the operation of equals().
+ */
+ @Test
+ public void testEquals() {
+ AllowedAddressPair p1 = AllowedAddressPair
+ .allowedAddressPair(ip1, mac1);
+ AllowedAddressPair p2 = AllowedAddressPair
+ .allowedAddressPair(ip1, mac1);
+ AllowedAddressPair p3 = AllowedAddressPair
+ .allowedAddressPair(ip2, mac2);
+ new EqualsTester().addEqualityGroup(p1, p2).addEqualityGroup(p3)
+ .testEquals();
+ }
+
+ /**
+ * Checks the construction of a AllowedAddressPair object.
+ */
+ @Test
+ public void testConstruction() {
+ AllowedAddressPair allowedAddressPair = AllowedAddressPair
+ .allowedAddressPair(ip1, mac1);
+ assertThat(ip1, is(notNullValue()));
+ assertThat(ip1, is(allowedAddressPair.ip()));
+ assertThat(mac1, is(notNullValue()));
+ assertThat(mac1, is(allowedAddressPair.mac()));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/DefaultVirtualPortTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/DefaultVirtualPortTest.java
new file mode 100644
index 00000000..8a0c8004
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/DefaultVirtualPortTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vtnrsc.virtualport;
+
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultVirtualPort;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.SecurityGroup;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for DefaultVirtualPort class.
+ */
+public class DefaultVirtualPortTest {
+
+ private Set<FixedIp> fixedIps;
+ private Map<String, String> propertyMap;
+ private Set<AllowedAddressPair> allowedAddressPairs;
+ private Set<SecurityGroup> securityGroups;
+ private VirtualPortId id1;
+ private VirtualPortId id2;
+ private String macAddressStr = "fa:12:3e:56:ee:a2";
+ private String ipAddress = "10.1.1.1";
+ private String deviceStr = "of:000000000000001";
+ private String tenantIdStr = "123";
+ private String portId1 = "1241";
+ private String portId2 = "1242";
+ private String tenantNetworkId = "1234567";
+ private String subnet = "1212";
+ private String hostIdStr = "fa:e2:3e:56:ee:a2";
+
+ private void initVirtualPortId() {
+ id1 = VirtualPortId.portId(portId1);
+ id2 = VirtualPortId.portId(portId2);
+ }
+
+ private void initFixedIpSet() {
+ FixedIp fixedIp = FixedIp.fixedIp(SubnetId.subnetId(subnet),
+ IpAddress.valueOf(ipAddress));
+ fixedIps = Sets.newHashSet();
+ fixedIps.add(fixedIp);
+ }
+
+ private void initPropertyMap() {
+ String deviceOwner = "james";
+ propertyMap = Maps.newHashMap();
+ propertyMap.putIfAbsent("deviceOwner", deviceOwner);
+ }
+
+ private void initAddressPairSet() {
+ allowedAddressPairs = Sets.newHashSet();
+ AllowedAddressPair allowedAddressPair = AllowedAddressPair
+ .allowedAddressPair(IpAddress.valueOf(ipAddress),
+ MacAddress.valueOf(macAddressStr));
+ allowedAddressPairs.add(allowedAddressPair);
+ }
+
+ private void initSecurityGroupSet() {
+ securityGroups = Sets.newHashSet();
+ }
+
+ /**
+ * Checks that the DefaultVirtualPort class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(SecurityGroup.class);
+ }
+
+ /**
+ * Checks the operation of equals().
+ */
+ @Test
+ public void testEquals() {
+ initVirtualPortId();
+ initFixedIpSet();
+ initPropertyMap();
+ initAddressPairSet();
+ initSecurityGroupSet();
+ TenantNetworkId networkId = TenantNetworkId.networkId(tenantNetworkId);
+ MacAddress macAddress = MacAddress.valueOf(macAddressStr);
+ TenantId tenantId = TenantId.tenantId(tenantIdStr);
+ DeviceId deviceId = DeviceId.deviceId(deviceStr);
+ BindingHostId bindingHostId = BindingHostId.bindingHostId(hostIdStr);
+
+ VirtualPort d1 = new DefaultVirtualPort(id1, networkId, true,
+ propertyMap,
+ VirtualPort.State.ACTIVE,
+ macAddress, tenantId, deviceId,
+ fixedIps, bindingHostId,
+ allowedAddressPairs,
+ securityGroups);
+ VirtualPort d2 = new DefaultVirtualPort(id1, networkId, true,
+ propertyMap,
+ VirtualPort.State.ACTIVE,
+ macAddress, tenantId, deviceId,
+ fixedIps, bindingHostId,
+ allowedAddressPairs,
+ securityGroups);
+ VirtualPort d3 = new DefaultVirtualPort(id2, networkId, true,
+ propertyMap,
+ VirtualPort.State.ACTIVE,
+ macAddress, tenantId, deviceId,
+ fixedIps, bindingHostId,
+ allowedAddressPairs,
+ securityGroups);
+ new EqualsTester().addEqualityGroup(d1, d2).addEqualityGroup(d3)
+ .testEquals();
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/FixedIpTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/FixedIpTest.java
new file mode 100644
index 00000000..1e33da09
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/FixedIpTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vtnrsc.virtualport;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.SubnetId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for FixedIp class.
+ */
+public class FixedIpTest {
+
+ final SubnetId subnetId1 = SubnetId.subnetId("lef11-95w-4er-9c9c");
+ final SubnetId subnetId2 = SubnetId.subnetId("lefaa-95w-4er-9c9c");
+ final IpAddress ip1 = IpAddress.valueOf("192.168.0.1");
+ final IpAddress ip2 = IpAddress.valueOf("192.168.1.1");
+
+ /**
+ * Checks that the FixedIp class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(FixedIp.class);
+ }
+
+ /**
+ * Checks the operation of equals().
+ */
+ @Test
+ public void testEquals() {
+ FixedIp fixedIp1 = FixedIp.fixedIp(subnetId1, ip1);
+ FixedIp fixedIp2 = FixedIp.fixedIp(subnetId1, ip1);
+ FixedIp fixedIp3 = FixedIp.fixedIp(subnetId2, ip2);
+ new EqualsTester().addEqualityGroup(fixedIp1, fixedIp2)
+ .addEqualityGroup(fixedIp3).testEquals();
+ }
+
+ /**
+ * Checks the construction of a FixedIp object.
+ */
+ @Test
+ public void testConstruction() {
+ FixedIp fixedIp = FixedIp.fixedIp(subnetId1, ip1);
+ assertThat(ip1, is(notNullValue()));
+ assertThat(ip1, is(fixedIp.ip()));
+ assertThat(subnetId1, is(notNullValue()));
+ assertThat(subnetId1, is(fixedIp.subnetId()));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/SecurityGroupTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/SecurityGroupTest.java
new file mode 100644
index 00000000..8c04e499
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/SecurityGroupTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vtnrsc.virtualport;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.SecurityGroup;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for SecurityGroup class.
+ */
+public class SecurityGroupTest {
+
+ final SecurityGroup securityGroup1 = SecurityGroup.securityGroup("1");
+ final SecurityGroup sameAssecurityGroup = SecurityGroup.securityGroup("1");
+ final SecurityGroup securityGroup2 = SecurityGroup.securityGroup("2");
+
+ /**
+ * Checks that the SecurityGroup class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(SecurityGroup.class);
+ }
+
+ /**
+ * Checks the operation of equals().
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(securityGroup1, sameAssecurityGroup)
+ .addEqualityGroup(securityGroup2).testEquals();
+ }
+
+ /**
+ * Checks the construction of a SecurityGroup object.
+ */
+ @Test
+ public void testConstruction() {
+ final String securityGroupValue = "1";
+ final SecurityGroup securityGroup = SecurityGroup.securityGroup(securityGroupValue);
+ assertThat(securityGroup, is(notNullValue()));
+ assertThat(securityGroup.securityGroup(), is(securityGroupValue));
+
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/VirtualPortIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/VirtualPortIdTest.java
new file mode 100644
index 00000000..2d63e91c
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/virtualport/VirtualPortIdTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.vtnrsc.virtualport;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.VirtualPortId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for VirtualPortId class.
+ */
+public class VirtualPortIdTest {
+
+ final VirtualPortId virtualPortId1 = VirtualPortId.portId("1");
+ final VirtualPortId sameAsVirtualPortId1 = VirtualPortId.portId("1");
+ final VirtualPortId virtualPortId2 = VirtualPortId.portId("2");
+
+ /**
+ * Checks that the VirtualPortId class is immutable.
+ */
+ @Test
+ public void testImmutability() {
+ assertThatClassIsImmutable(VirtualPortId.class);
+ }
+
+ /**
+ * Checks the operation of equals().
+ */
+ @Test
+ public void testEquals() {
+ new EqualsTester().addEqualityGroup(virtualPortId1, sameAsVirtualPortId1)
+ .addEqualityGroup(virtualPortId2).testEquals();
+ }
+
+ /**
+ * Checks the construction of a VirtualPortId object.
+ */
+ @Test
+ public void testConstruction() {
+ final String vPortIdValue = "aaa";
+ final VirtualPortId virtualPortId = VirtualPortId.portId(vPortIdValue);
+ assertThat(virtualPortId, is(notNullValue()));
+ assertThat(virtualPortId.portId(), is(vPortIdValue));
+
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java
new file mode 100644
index 00000000..1450e4ef
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnweb.resources;
+
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+import static org.onlab.util.Tools.nullIsNotFound;
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.UUID;
+
+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.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.web.FlowClassifierCodec;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Query and program flow classifier.
+ */
+@Path("flow_classifiers")
+public class FlowClassifierWebResource extends AbstractWebResource {
+
+ final FlowClassifierService service = get(FlowClassifierService.class);
+ final ObjectNode root = mapper().createObjectNode();
+ public static final String FLOW_CLASSIFIER_NOT_FOUND = "Flow classifier not found";
+
+ /**
+ * Get all flow classifiers created. Returns list of all flow classifiers
+ * created.
+ *
+ * @return 200 OK
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getFlowClassifiers() {
+ Iterable<FlowClassifier> flowClassifiers = service.getFlowClassifiers();
+ ObjectNode result = new ObjectMapper().createObjectNode();
+ result.set("flow_classifiers", new FlowClassifierCodec().encode(flowClassifiers, this));
+ return ok(result.toString()).build();
+ }
+
+ /**
+ * Get details of a flow classifier. Returns details of a specified flow
+ * classifier id.
+ *
+ * @param id flow classifier id
+ * @return 200 OK
+ */
+ @GET
+ @Path("{flow_id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getFlowClassifier(@PathParam("flow_id") String id) {
+
+ if (!service.hasFlowClassifier(FlowClassifierId.flowClassifierId(UUID.fromString(id)))) {
+ return Response.status(NOT_FOUND).entity(FLOW_CLASSIFIER_NOT_FOUND).build();
+ }
+ FlowClassifier flowClassifier = nullIsNotFound(
+ service.getFlowClassifier(FlowClassifierId.flowClassifierId(UUID.fromString(id))),
+ FLOW_CLASSIFIER_NOT_FOUND);
+
+ ObjectNode result = new ObjectMapper().createObjectNode();
+ result.set("flow_classifier", new FlowClassifierCodec().encode(flowClassifier, this));
+ return ok(result.toString()).build();
+ }
+
+ /**
+ * Creates and stores a new flow classifier.
+ *
+ * @param flowClassifierId flow classifier identifier
+ * @param stream flow classifier from JSON
+ * @return status of the request - CREATED if the JSON is correct,
+ * BAD_REQUEST if the JSON is invalid
+ */
+ @POST
+ @Path("{flow_id}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createFlowClassifier(@PathParam("flow_id") String flowClassifierId, InputStream stream) {
+ URI location;
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+
+ FlowClassifier flowClassifier = codec(FlowClassifier.class).decode(jsonTree, this);
+ service.createFlowClassifier(flowClassifier);
+ location = new URI(flowClassifierId);
+ } catch (IOException | URISyntaxException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ return Response.created(location).build();
+ }
+
+ /**
+ * Creates and stores a new flow classifier.
+ *
+ * @param stream flow classifier from JSON
+ * @return status of the request - CREATED if the JSON is correct,
+ * BAD_REQUEST if the JSON is invalid
+ */
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createFlowClassifier(InputStream stream) {
+ URI location;
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+
+ FlowClassifier flowClassifier = codec(FlowClassifier.class).decode(jsonTree, this);
+ service.createFlowClassifier(flowClassifier);
+ location = new URI(flowClassifier.flowClassifierId().toString());
+ } catch (IOException | URISyntaxException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ return Response.created(location).build();
+ }
+
+ /**
+ * Update details of a flow classifier. Update details of a specified flow
+ * classifier id.
+ *
+ * @param id flow classifier id
+ * @param stream InputStream
+ * @return 200 OK
+ */
+ @PUT
+ @Path("{flow_id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response updateFlowClassifier(@PathParam("flow_id") String id, final InputStream stream) {
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ FlowClassifier flowClassifier = codec(FlowClassifier.class).decode(jsonTree, this);
+ Boolean result = nullIsNotFound(service.updateFlowClassifier(flowClassifier), FLOW_CLASSIFIER_NOT_FOUND);
+ if (!result) {
+ return Response.status(204).entity(FLOW_CLASSIFIER_NOT_FOUND).build();
+ }
+ return Response.status(203).entity(result.toString()).build();
+ } catch (Exception e) {
+ return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString()).build();
+ }
+ }
+
+ /**
+ * Delete details of a flow classifier. Delete details of a specified flow
+ * classifier id.
+ *
+ * @param id flow classifier id
+ * @return 200 OK
+ * @throws IOException when input doesn't match.
+ */
+ @Path("{flow_id}")
+ @DELETE
+ public Response deleteFlowClassifier(@PathParam("flow_id") String id) throws IOException {
+ try {
+ FlowClassifierId flowClassifierId = FlowClassifierId.flowClassifierId(UUID.fromString(id));
+ service.removeFlowClassifier(flowClassifierId);
+ return Response.status(201).entity("SUCCESS").build();
+ } catch (Exception e) {
+ return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString()).build();
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
index 251dcffc..0cc59a4e 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
@@ -56,7 +56,7 @@ import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.Subnet.Mode;
import org.onosproject.vtnrsc.subnet.SubnetService;
-import org.onosproject.vtnrsc.web.SubnetCodec;
+import org.onosproject.vtnweb.web.SubnetCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
index 0b877822..2dd931ea 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
@@ -51,7 +51,7 @@ import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.TenantNetwork.State;
import org.onosproject.vtnrsc.TenantNetwork.Type;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
-import org.onosproject.vtnrsc.web.TenantNetworkCodec;
+import org.onosproject.vtnweb.web.TenantNetworkCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
index 03d3a653..e47a57df 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
@@ -58,7 +58,7 @@ import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPort.State;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
-import org.onosproject.vtnrsc.web.VirtualPortCodec;
+import org.onosproject.vtnweb.web.VirtualPortCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllocationPoolsCodec.java
index 57c97c1c..4b6b662f 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllocationPoolsCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllowedAddressPairCodec.java
index 7960808f..8ffc4e91 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/AllowedAddressPairCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FixedIpCodec.java
index 96c9bb4e..559de685 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/FixedIpCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/HostRoutesCodec.java
index 69ca6b3f..815a0d02 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/HostRoutesCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/PortChainCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/PortChainCodec.java
new file mode 100644
index 00000000..28da5cd1
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/PortChainCodec.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnweb.web;
+
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.DefaultPortChain;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.PortPairGroupId;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+
+/**
+ * Port chain JSON codec.
+ */
+public final class PortChainCodec extends JsonCodec<PortChain> {
+
+ private static final String ID = "id";
+ private static final String TENANT_ID = "tenant_id";
+ private static final String NAME = "name";
+ private static final String DESCRIPTION = "description";
+ private static final String PORT_PAIR_GROUPS = "port_pair_groups";
+ private static final String FLOW_CLASSIFIERS = "flow_classifiers";
+ private static final String MISSING_MEMBER_MESSAGE =
+ " member is required in PortChain";
+
+ @Override
+ public PortChain decode(ObjectNode json, CodecContext context) {
+ if (json == null || !json.isObject()) {
+ return null;
+ }
+
+ PortChain.Builder resultBuilder = new DefaultPortChain.Builder();
+
+ String id = nullIsIllegal(json.get(ID),
+ ID + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setId(PortChainId.portChainId(id));
+
+ String tenantId = nullIsIllegal(json.get(TENANT_ID),
+ TENANT_ID + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setTenantId(TenantId.tenantId(tenantId));
+
+ String name = nullIsIllegal(json.get(NAME),
+ NAME + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setName(name);
+
+ String description = nullIsIllegal(json.get(DESCRIPTION),
+ DESCRIPTION + MISSING_MEMBER_MESSAGE).asText();
+ resultBuilder.setDescription(description);
+
+ ArrayNode arrayNode = (ArrayNode) json.path(PORT_PAIR_GROUPS);
+ if (arrayNode != null) {
+ List<PortPairGroupId> list = Lists.newArrayList();
+ arrayNode.forEach(i -> list.add(PortPairGroupId.portPairGroupId(i.asText())));
+ resultBuilder.setPortPairGroups(list);
+ }
+
+ arrayNode = (ArrayNode) json.path(FLOW_CLASSIFIERS);
+ if (arrayNode != null) {
+ List<FlowClassifierId> list = Lists.newArrayList();
+ arrayNode.forEach(i -> list.add(FlowClassifierId.flowClassifierId(UUID.fromString(i.asText()))));
+ resultBuilder.setFlowClassifiers(list);
+ }
+
+ return resultBuilder.build();
+ }
+
+ @Override
+ public ObjectNode encode(PortChain portChain, CodecContext context) {
+ checkNotNull(portChain, "port pair cannot be null");
+ ObjectNode result = context.mapper().createObjectNode()
+ .put(ID, portChain.portChainId().toString())
+ .put(TENANT_ID, portChain.tenantId().toString())
+ .put(NAME, portChain.name())
+ .put(DESCRIPTION, portChain.description())
+ .put(PORT_PAIR_GROUPS, portChain.portPairGroups().toString())
+ .put(FLOW_CLASSIFIERS, portChain.flowClassifiers().toString());
+ return result;
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SecurityGroupCodec.java
index c2ded196..18ed61ba 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SecurityGroupCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SubnetCodec.java
index 122b75a9..e3d92fea 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/SubnetCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/TenantNetworkCodec.java
index 48ba3b97..8adba034 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/TenantNetworkCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VirtualPortCodec.java
index e57d56bc..5cea5327 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VirtualPortCodec.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.onosproject.vtnrsc.web;
+package org.onosproject.vtnweb.web;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/package-info.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/package-info.java
new file mode 100644
index 00000000..3a609435
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Codecs for virtual tenant objects.
+ */
+package org.onosproject.vtnweb.web;