aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps
diff options
context:
space:
mode:
authorAshlee Young <ashlee@wildernessvoice.com>2015-12-06 07:15:03 -0800
committerAshlee Young <ashlee@wildernessvoice.com>2015-12-08 10:55:21 -0800
commit76dc892491948adae5e5e62cf94448967e8d865b (patch)
tree7a33ef05cc583946db21edad627060f280a53549 /framework/src/onos/apps
parentd333c63fdec8b064184b0a26f8d777f267577fde (diff)
Fixes bad POM file with ONOS commit 8c68536972f63069c263635c9d9f4f31d7f3e9a2
Change-Id: I7adb5a2d3738d53dbc41db7577768b0e7ced5450 Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
Diffstat (limited to 'framework/src/onos/apps')
-rw-r--r--framework/src/onos/apps/cpman/pom.xml39
-rw-r--r--framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMessageType.java43
-rw-r--r--framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java34
-rw-r--r--framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneLoad.java42
-rw-r--r--framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java47
-rw-r--r--framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMetric.java41
-rw-r--r--framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneStatsService.java59
-rw-r--r--framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/package-info.java20
-rw-r--r--framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java8
-rw-r--r--framework/src/onos/apps/faultmanagement/app/app.xml24
-rw-r--r--framework/src/onos/apps/faultmanagement/app/features.xml25
-rw-r--r--framework/src/onos/apps/faultmanagement/app/pom.xml46
-rw-r--r--framework/src/onos/apps/faultmanagement/fmmgr/pom.xml54
-rw-r--r--framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmsManager.java222
-rw-r--r--framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/package-info.java20
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/pom.xml141
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmCodec.java101
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmsWebResource.java148
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/package-info.java20
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/main/webapp/WEB-INF/web.xml42
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecContext.java73
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecTest.java140
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmJsonMatcher.java135
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmsWebResourceTest.java72
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-full.json15
-rw-r--r--framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-minimal.json12
-rw-r--r--framework/src/onos/apps/faultmanagement/pom.xml56
-rw-r--r--framework/src/onos/apps/iptopology-api/pom.xml29
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AreaId.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AsNumber.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Color.java72
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDeviceIntf.java79
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDevicePrefix.java95
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpDevice.java113
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpLink.java105
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceInterface.java100
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceIntf.java37
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DevicePrefix.java46
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceTed.java173
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DomainId.java71
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ExtendedRouteTag.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IgpFlags.java114
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/InterfaceIdentifier.java71
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDevice.java68
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDeviceIdentifier.java141
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLink.java54
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLinkIdentifier.java161
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpReachability.java73
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsIsPseudonode.java93
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsoNodeId.java79
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/LinkTed.java349
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Metric.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/OspfPseudonode.java96
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Position.java84
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixIdentifier.java98
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixTed.java138
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ProtectionType.java97
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteDistinguisher.java74
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteIdentifier.java54
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteInstance.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteTag.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteType.java96
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouterId.java78
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Signalling.java83
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Srlg.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TerminationPoint.java104
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TopologyId.java70
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultInterfaceDescription.java97
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultIpDeviceDescription.java117
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultPrefixDescription.java86
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/InterfaceDescription.java51
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceDescription.java61
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceEvent.java183
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceListener.java24
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProvider.java25
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderRegistry.java25
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderService.java78
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceService.java111
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStore.java164
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStoreDelegate.java24
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/PrefixDescription.java41
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/package-info.java20
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/DefaultIpLinkDescription.java95
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkDescription.java55
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkEvent.java68
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkListener.java24
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProvider.java25
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderRegistry.java25
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderService.java57
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkService.java108
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStore.java115
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStoreDelegate.java24
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/package-info.java20
-rw-r--r--framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/package-info.java20
-rw-r--r--framework/src/onos/apps/openstackswitching/app/features.xml1
-rw-r--r--framework/src/onos/apps/openstackswitching/app/pom.xml1
-rw-r--r--framework/src/onos/apps/pathpainter/pom.xml38
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLink.java51
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLinkMap.java30
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainter.java86
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java388
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovOverlay.java56
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/package-info.java20
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.css2
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.html4
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js119
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js260
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/css.html1
-rw-r--r--framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/js.html2
-rw-r--r--framework/src/onos/apps/pom.xml4
-rw-r--r--framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java1
-rw-r--r--framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java89
-rw-r--r--framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java1
-rw-r--r--framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java1
-rw-r--r--framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java1
-rw-r--r--framework/src/onos/apps/segmentrouting/pom.xml5
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java26
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java1
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java2
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java2
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java63
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java146
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java2
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java45
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java219
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java6
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java139
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java6
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java6
-rw-r--r--framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java77
-rw-r--r--framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java157
-rw-r--r--framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java2
-rw-r--r--framework/src/onos/apps/vtn/pom.xml6
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java (renamed from framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java)28
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java293
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java51
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java37
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java159
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java269
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java93
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java53
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java85
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java89
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java89
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java98
-rw-r--r--framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java72
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java29
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java476
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java6
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java113
-rw-r--r--framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java82
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java41
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java78
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java20
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java2
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java2
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java50
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java133
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java59
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java3
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java18
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java3
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java10
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java14
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java22
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java63
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java25
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java14
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java22
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java18
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java152
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java10
-rw-r--r--framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java22
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java27
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java45
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java51
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java39
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java56
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java9
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java247
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java234
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java7
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java41
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json15
-rw-r--r--framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json11
193 files changed, 12620 insertions, 542 deletions
diff --git a/framework/src/onos/apps/cpman/pom.xml b/framework/src/onos/apps/cpman/pom.xml
new file mode 100644
index 00000000..c01af6d8
--- /dev/null
+++ b/framework/src/onos/apps/cpman/pom.xml
@@ -0,0 +1,39 @@
+<?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>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-apps</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-app-cpman</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>Control Plane Management Application</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMessageType.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMessageType.java
new file mode 100644
index 00000000..82e414d9
--- /dev/null
+++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMessageType.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cpman;
+
+/**
+ * Abstracted Control Message Type.
+ */
+public enum ControlMessageType {
+
+ /** Mapped to PACKET-IN message of OpenFlow. */
+ INBOUND_PACKET,
+
+ /** Mapped to PACKET-OUT message of OpenFlow. */
+ OUTBOUND_PACKET,
+
+ /** Mapped to FLOW-MOD message of OpenFlow. */
+ FLOW_MOD_PACKET,
+
+ /** Mapped to FLOW-REMOVED message of OpenFlow. */
+ FLOW_REMOVED_PACKET,
+
+ /** Mapped to STATS-REQUEST message of OpenFlow. */
+ REQUEST_PACKET,
+
+ /** Mapped to STATS-REPLY message of OpenFlow. */
+ REPLY_PACKET,
+
+ /** All message types. */
+ ALL
+}
diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java
new file mode 100644
index 00000000..b5e82811
--- /dev/null
+++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java
@@ -0,0 +1,34 @@
+/*
+ * 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.cpman;
+
+/**
+ * A set of metric type used in control plane.
+ */
+public enum ControlMetricType {
+
+ /** Racket Rate of Control Message. */
+ PacketRate,
+
+ /** Byte Rate of Control Message. */
+ ByteRate,
+
+ /** Cpu Utilization. */
+ CpuInfo,
+
+ /** Memory Utilization. */
+ MemoryInfo
+}
diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneLoad.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneLoad.java
new file mode 100644
index 00000000..f55945fd
--- /dev/null
+++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneLoad.java
@@ -0,0 +1,42 @@
+/*
+ * 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.cpman;
+
+import org.onosproject.net.statistic.Load;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Data repository for control plane load information.
+ */
+public interface ControlPlaneLoad extends Load {
+
+ /**
+ * Obtain the average of the specified time duration.
+ *
+ * @param duration time duration
+ * @param unit time unit
+ * @return average control plane metric value
+ */
+ long average(int duration, TimeUnit unit);
+
+ /**
+ * Obtain the average of all time duration.
+ *
+ * @return average control plane metric value
+ */
+ long average();
+}
diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java
new file mode 100644
index 00000000..5f3dee73
--- /dev/null
+++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java
@@ -0,0 +1,47 @@
+/*
+ * 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.cpman;
+
+import com.sun.jndi.toolkit.ctx.ComponentContext;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Control plane management application.
+ */
+public class ControlPlaneManager {
+
+ private final Logger log = getLogger(getClass());
+
+ @Activate
+ public void activate(ComponentContext context) {
+
+ }
+
+ @Deactivate
+ public void deactivate() {
+
+ }
+
+ @Modified
+ public void modified(ComponentContext context) {
+
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMetric.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMetric.java
new file mode 100644
index 00000000..19f4153a
--- /dev/null
+++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMetric.java
@@ -0,0 +1,41 @@
+/*
+ * 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.cpman;
+
+/**
+ * Include various control plane metrics.
+ */
+public class ControlPlaneMetric {
+
+ private ControlMetricType metricType;
+ private long metricValue;
+
+ ControlMetricType metricType() {
+ return metricType;
+ }
+
+ void setMetricType(ControlMetricType metricType) {
+ this.metricType = metricType;
+ }
+
+ long metricValue() {
+ return metricValue;
+ }
+
+ void setMetricValue(long metricValue) {
+ this.metricValue = metricValue;
+ }
+}
diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneStatsService.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneStatsService.java
new file mode 100644
index 00000000..9fc2d7a9
--- /dev/null
+++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneStatsService.java
@@ -0,0 +1,59 @@
+/*
+ * 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.cpman;
+
+import org.onosproject.cluster.NodeId;
+import org.onosproject.net.DeviceId;
+
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Control Plane Statistics Service Interface.
+ */
+public interface ControlPlaneStatsService {
+
+ /**
+ * Add a new control plane metric value with a certain update interval.
+ *
+ * @param cpm control plane metric (e.g., control message rate, cpu, memory, etc.)
+ * @param updateInterval value update interval (time unit will be in minute)
+ */
+ void updateMetric(ControlPlaneMetric cpm, int updateInterval);
+
+ /**
+ * Obtain the control plane load of a specific device.
+ *
+ * @param nodeId node id {@link org.onosproject.cluster.NodeId}
+ * @param type control metric type
+ * @param deviceId device id {@link org.onosproject.net.DeviceId}
+ * @return control plane load
+ */
+ ControlPlaneLoad getLoad(NodeId nodeId, ControlMetricType type, Optional<DeviceId> deviceId);
+
+ /**
+ * Obtain the control plane load of a specific device with a specific time duration.
+ *
+ * @param nodeId node id {@link org.onosproject.cluster.NodeId}
+ * @param type control metric type
+ * @param duration time duration
+ * @param unit time unit
+ * @param deviceId device id {@link org.onosproject.net.Device}
+ * @return control plane load
+ */
+ ControlPlaneLoad getLoad(NodeId nodeId, ControlMetricType type, Optional<DeviceId> deviceId,
+ int duration, TimeUnit unit);
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/package-info.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/package-info.java
new file mode 100644
index 00000000..e2c1dc85
--- /dev/null
+++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/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.
+ */
+
+/**
+ * Application for control plane management.
+ */
+package org.onosproject.cpman; \ No newline at end of file
diff --git a/framework/src/onos/apps/dhcp/app/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 cd8149ea..6265fee0 100644
--- a/framework/src/onos/apps/dhcp/app/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
@@ -51,7 +51,7 @@ public class DhcpWebResource extends AbstractWebResource {
* Shows lease, renewal and rebinding times in seconds.
*
* @return 200 OK
- * @rsModel DhcpConfigGet
+ * @onos.rsModel DhcpConfigGet
*/
@GET
@Path("config")
@@ -68,7 +68,7 @@ public class DhcpWebResource extends AbstractWebResource {
* Get all MAC/IP mappings.
* Shows all MAC/IP mappings held by the DHCP server.
*
- * @rsModel DhcpConfigGetMappings
+ * @onos.rsModel DhcpConfigGetMappings
* @return 200 OK
*/
@GET
@@ -90,7 +90,7 @@ public class DhcpWebResource extends AbstractWebResource {
* Get all available IPs.
* Shows all the IPs in the free pool of the DHCP Server.
*
- * @rsModel DhcpConfigGetAvailable
+ * @onos.rsModel DhcpConfigGetAvailable
* @return 200 OK
*/
@GET
@@ -108,7 +108,7 @@ public class DhcpWebResource extends AbstractWebResource {
* Post a new static MAC/IP binding.
* Registers a static binding to the DHCP server, and displays the current set of bindings.
*
- * @rsModel DhcpConfigPut
+ * @onos.rsModel DhcpConfigPut
* @param stream JSON stream
* @return 200 OK
*/
diff --git a/framework/src/onos/apps/faultmanagement/app/app.xml b/framework/src/onos/apps/faultmanagement/app/app.xml
new file mode 100644
index 00000000..288ccc49
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/app/app.xml
@@ -0,0 +1,24 @@
+<?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.faultmanagement" origin="BTI Systems" version="${project.version}"
+ featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+ features="${project.artifactId}">
+ <description>${project.description}</description>
+
+ <artifact>mvn:${project.groupId}/onos-app-fm-mgr/${project.version}</artifact>
+ <artifact>mvn:${project.groupId}/onos-app-fm-web/${project.version}</artifact>
+</app>
diff --git a/framework/src/onos/apps/faultmanagement/app/features.xml b/framework/src/onos/apps/faultmanagement/app/features.xml
new file mode 100644
index 00000000..86aab911
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/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}">
+ <feature name="${project.artifactId}" version="${project.version}"
+ description="${project.description}">
+ <feature>onos-api</feature>
+ <feature>onos-drivers</feature>
+ <bundle>mvn:${project.groupId}/onos-app-fm-mgr/${project.version}</bundle>
+ <bundle>mvn:${project.groupId}/onos-app-fm-web/${project.version}</bundle>
+ </feature>
+</features>
diff --git a/framework/src/onos/apps/faultmanagement/app/pom.xml b/framework/src/onos/apps/faultmanagement/app/pom.xml
new file mode 100644
index 00000000..ef41cdde
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/app/pom.xml
@@ -0,0 +1,46 @@
+<?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-app-fm</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-app-fm-onosfw</artifactId>
+ <packaging>pom</packaging>
+
+ <description>ONOS framework applications</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-fm-web</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-fm-mgr</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/onos/apps/faultmanagement/fmmgr/pom.xml b/framework/src/onos/apps/faultmanagement/fmmgr/pom.xml
new file mode 100644
index 00000000..86b7cb67
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmmgr/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.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.
+ -->
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-fm</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-app-fm-mgr</artifactId>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-core-serializers</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>5.0.0</version>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmsManager.java b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmsManager.java
new file mode 100644
index 00000000..74fe7072
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmsManager.java
@@ -0,0 +1,222 @@
+/*
+ * 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.faultmanagement.impl;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+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.Modified;
+import org.apache.felix.scr.annotations.Property;
+import static org.onlab.util.Tools.nullIsNotFound;
+
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmListener;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+import org.apache.felix.scr.annotations.Service;
+import static org.onlab.util.Tools.get;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.core.CoreService;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * Implementation of the Alarm service.
+ */
+@Component(immediate = true)
+@Service
+public class AlarmsManager implements AlarmService {
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+ private final Logger log = getLogger(getClass());
+ private ApplicationId appId;
+ private IdGenerator idGenerator;
+
+
+ @Property(name = "fmDevices", value = "127.0.0.1", label = "Instance-specific configurations")
+ private String devConfigs;
+
+ private final Map<AlarmId, Alarm> alarms = new ConcurrentHashMap<>();
+
+
+ private final AtomicLong alarmIdGenerator = new AtomicLong(0);
+
+ @Override
+ public Alarm update(final Alarm replacement) {
+
+ final Alarm found = alarms.get(replacement.id());
+ if (found == null) {
+ throw new ItemNotFoundException("Alarm with id " + replacement.id() + " found");
+ }
+ final Alarm updated = new DefaultAlarm.Builder(found).
+ withAcknowledged(replacement.acknowledged()).
+ withAssignedUser(replacement.assignedUser()).build();
+ alarms.put(replacement.id(), updated);
+ return updated;
+ }
+
+ @Override
+ public int getActiveAlarmCount(final DeviceId deviceId) {
+ //TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+ private static final String NOT_SUPPORTED_YET = "Not supported yet.";
+
+ @Override
+ public Alarm getAlarm(final AlarmId alarmId) {
+ return nullIsNotFound(
+ alarms.get(alarmId),
+ "Alarm is not found");
+ }
+
+ @Override
+ public Set<Alarm> getAlarms() {
+ //TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+
+ @Override
+ public Set<Alarm> getActiveAlarms() {
+ // Enpty set if no values
+ return alarms.isEmpty() ? new HashSet<>() : new HashSet<>(alarms.values());
+
+ }
+
+ private static DefaultAlarm generateFake(final DeviceId deviceId, final AlarmId alarmId) {
+
+ return new DefaultAlarm.Builder(
+ alarmId, deviceId, "NE is not reachable", Alarm.SeverityLevel.MAJOR, System.currentTimeMillis()).
+ withTimeUpdated(System.currentTimeMillis()).
+ withServiceAffecting(true)
+ .withAcknowledged(true).
+ withManuallyClearable(true)
+ .withAssignedUser("user1").build();
+ }
+
+ @Override
+ public Set<Alarm> getAlarms(final Alarm.SeverityLevel severity) {
+ //TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+
+ @Override
+ public Set<Alarm> getAlarms(final DeviceId deviceId) {
+ //TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+
+ @Override
+ public Set<Alarm> getAlarms(final DeviceId deviceId, final AlarmEntityId source) {
+ //TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+
+ @Override
+ public Set<Alarm> getAlarmsForLink(final ConnectPoint src, final ConnectPoint dst) {
+ //TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+
+ @Override
+ public Set<Alarm> getAlarmsForFlow(final DeviceId deviceId, final long flowId) {
+ //TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+
+ private void discoverAlarmsForDevice(final DeviceId deviceId) {
+ final AlarmId alarmId = new AlarmId(alarmIdGenerator.incrementAndGet());
+
+ // TODO In a new thread invoke SNMP Provider with DeviceId and device type and when done update our of alarms
+ //
+ alarms.put(alarmId, generateFake(deviceId, alarmId));
+
+ }
+
+ private class InternalAlarmListener implements AlarmListener {
+
+ @Override
+ public void event(final AlarmEvent event) {
+ // TODO
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+ }
+
+ @Activate
+ public void activate(final ComponentContext context) {
+ log.info("Activate ...");
+ appId = coreService.registerApplication("org.onos.faultmanagement.alarms");
+ idGenerator = coreService.getIdGenerator("alarm-ids");
+ log.info("Started with appId={} idGenerator={}", appId, idGenerator);
+
+ final boolean result = modified(context);
+ log.info("modified result = {}", result);
+
+ }
+
+ @Deactivate
+ public void deactivate(final ComponentContext context) {
+ log.info("Deactivate ...");
+ // cfgService.unregisterProperties(getClass(), false);
+
+ log.info("Stopped");
+ }
+
+ @Modified
+ public boolean modified(final ComponentContext context) {
+ log.info("context={}", context);
+ if (context == null) {
+ log.info("No configuration file");
+ return false;
+ }
+ final Dictionary<?, ?> properties = context.getProperties();
+ final String ipaddresses = get(properties, "fmDevices");
+ log.info("Settings: devConfigs={}", ipaddresses);
+ if (!isNullOrEmpty(ipaddresses)) {
+ discover(ipaddresses);
+
+ }
+ return true;
+ }
+
+ private void discover(final String ipaddresses) {
+ for (String deviceEntry : ipaddresses.split(",")) {
+ final DeviceId deviceId = DeviceId.deviceId(deviceEntry);
+ if (deviceId != null) {
+ log.info("Device {} needs to have its alarms refreshed!", deviceId);
+ discoverAlarmsForDevice(deviceId);
+ }
+ }
+ }
+
+}
diff --git a/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/package-info.java b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/package-info.java
new file mode 100644
index 00000000..a3f56459
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/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.
+ */
+
+/**
+ * Fault Management application implementation.
+ */
+package org.onosproject.faultmanagement.impl;
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/pom.xml b/framework/src/onos/apps/faultmanagement/fmweb/pom.xml
new file mode 100644
index 00000000..8d759710
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/pom.xml
@@ -0,0 +1,141 @@
+<?xml version="1.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.
+-->
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-fm</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+
+ <artifactId>onos-app-fm-web</artifactId>
+ <packaging>bundle</packaging>
+ <properties>
+ <web.context>/onos/v1/fm</web.context>
+ <api.version>1.0.0</api.version>
+ <api.title>ONOS Fault Management Application REST API</api.title>
+ <api.description>
+ APIs for interacting with the Fault Management application.
+ </api.description>
+ <api.package>org.onos.faultmanagement.web</api.package>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-osgi</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.jersey</groupId>
+ <artifactId>jersey-client</artifactId>
+ <version>1.19</version>
+ <scope>test</scope>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-core-common</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-rest</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <type>jar</type>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-rest</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.jersey.jersey-test-framework</groupId>
+ <artifactId>jersey-test-framework-core</artifactId>
+ <version>1.19</version>
+ </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.commons.lang.math.*,
+ 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/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmCodec.java b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmCodec.java
new file mode 100644
index 00000000..a764c908
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmCodec.java
@@ -0,0 +1,101 @@
+/*
+ * 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.faultmanagement.web;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import org.onosproject.net.DeviceId;
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
+import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of encoder for Alarm codec.
+ */
+public final class AlarmCodec extends JsonCodec<Alarm> {
+
+ private final Logger log = getLogger(getClass());
+
+ @Override
+ public ObjectNode encode(final Alarm alarm, final CodecContext context) {
+ checkNotNull(alarm, "Alarm cannot be null");
+
+ return context.mapper().createObjectNode()
+ .put("id", alarm.id().fingerprint())
+ .put("deviceId", alarm.deviceId().toString())
+ .put("description", alarm.description())
+ .put("source",
+ alarm.source() == null ? null
+ : alarm.source().toString())
+ .put("timeRaised", alarm.timeRaised())
+ .put("timeUpdated", alarm.timeUpdated())
+ .put("timeCleared", alarm.timeCleared())
+ .put("severity", alarm.severity().toString())
+ .put("serviceAffecting", alarm.serviceAffecting())
+ .put("acknowledged", alarm.acknowledged())
+ .put("manuallyClearable", alarm.manuallyClearable())
+ .put("assignedUser", alarm.assignedUser());
+
+ }
+
+ @Override
+ public Alarm decode(final ObjectNode json, final CodecContext context) {
+ if (json == null || !json.isObject()) {
+ return null;
+ }
+
+ log.debug("id={}, full json={} ", json.get("id"), json);
+ final Long id = json.get("id").asLong();
+
+ final DeviceId deviceId = DeviceId.deviceId(json.get("deviceId").asText());
+ final String description = json.get("description").asText();
+ final Long timeRaised = json.get("timeRaised").asLong();
+ final Long timeUpdated = json.get("timeUpdated").asLong();
+
+ final JsonNode jsonTimeCleared = json.get("timeCleared");
+ final Long timeCleared = jsonTimeCleared == null || jsonTimeCleared.isNull() ? null : jsonTimeCleared.asLong();
+
+ final Alarm.SeverityLevel severity
+ = Alarm.SeverityLevel.valueOf(json.get("severity").asText().toUpperCase());
+
+ final Boolean serviceAffecting = json.get("serviceAffecting").asBoolean();
+ final Boolean acknowledged = json.get("acknowledged").asBoolean();
+ final Boolean manuallyClearable = json.get("manuallyClearable").asBoolean();
+
+ final JsonNode jsonAssignedUser = json.get("assignedUser");
+ final String assignedUser
+ = jsonAssignedUser == null || jsonAssignedUser.isNull() ? null : jsonAssignedUser.asText();
+
+ return new DefaultAlarm.Builder(
+ AlarmId.valueOf(id), deviceId, description, severity, timeRaised).forSource(AlarmEntityId.NONE).
+ withTimeUpdated(timeUpdated).
+ withTimeCleared(timeCleared).
+ withServiceAffecting(serviceAffecting).
+ withAcknowledged(acknowledged).
+ withManuallyClearable(manuallyClearable).
+ withAssignedUser(assignedUser).
+ build();
+
+ }
+}
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmsWebResource.java b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmsWebResource.java
new file mode 100644
index 00000000..56c891cd
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmsWebResource.java
@@ -0,0 +1,148 @@
+/*
+ * 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.faultmanagement.web;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.io.InputStream;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.core.Response;
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import org.onosproject.codec.CodecService;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService;
+import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Alarms on devices or ONOS.
+ */
+@Path("alarms")
+public class AlarmsWebResource extends AbstractWebResource {
+
+ public static final String ALARM_NOT_FOUND = "Alarm is not found";
+
+ private final Logger log = getLogger(getClass());
+
+ public AlarmsWebResource() {
+ get(CodecService.class).registerCodec(Alarm.class, new AlarmCodec());
+ }
+
+ /**
+ * Get all alarms. Returns a list of all alarms across all devices.
+ *
+ * @param includeCleared include recently cleared alarms in response
+ * @return JSON encoded set of alarms
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getAlarms(@DefaultValue("false") @QueryParam("includeCleared") final boolean includeCleared
+ ) {
+
+ log.info("Requesting all alarms, includeCleared={}", includeCleared);
+ final AlarmService service = get(AlarmService.class);
+
+ final Iterable<Alarm> alarms = includeCleared
+ ? service.getAlarms()
+ : service.getActiveAlarms();
+
+ final ObjectNode result = new ObjectMapper().createObjectNode();
+ result.set("alarms",
+ codec(Alarm.class).
+ encode(alarms, this));
+ return ok(result.toString()).build();
+
+ }
+
+ /**
+ * Get specified alarm. Returns details of the specified alarm.
+ *
+ * @param id ONOS allocated identifier
+ * @return JSON encoded alarm
+ */
+ @GET
+ @Path("{id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getAlarm(@PathParam("id") final String id) {
+ log.info("HTTP GET alarm for id={}", id);
+
+ final AlarmId alarmId = toAlarmId(id);
+ final Alarm alarm = get(AlarmService.class).getAlarm(alarmId);
+
+ final ObjectNode result = mapper().createObjectNode();
+ result.set("alarm", codec(Alarm.class).encode(alarm, this));
+ return ok(result.toString()).build();
+ }
+
+ /**
+ * Update book-keeping fields on the alarm. Returns an up-to-date version of the alarm. Some of its fields may have
+ * been updated since the REST client last retrieved the alarm being updated.
+ *
+ * @param alarmIdPath
+ * @param stream input JSON
+ * @return updated JSON encoded alarm
+ */
+ @PUT
+ @Path("{alarm_id}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response update(@PathParam("alarm_id") final String alarmIdPath, final InputStream stream) {
+ log.info("PUT NEW ALARM at /{}", alarmIdPath);
+
+ try {
+ final ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ log.info("jsonTree={}", jsonTree);
+
+ final Alarm alarm = codec(Alarm.class).decode(jsonTree, this);
+
+ final AlarmService service = get(AlarmService.class);
+
+ if (Long.parseLong(alarmIdPath) != alarm.id().fingerprint()) {
+ throw new IllegalArgumentException("id in path is " + Long.parseLong(alarmIdPath)
+ + " but payload uses id=" + alarm.id().fingerprint());
+
+ }
+ final Alarm updated = service.update(alarm);
+ final ObjectNode encoded = new AlarmCodec().encode(updated, this);
+ return ok(encoded.toString()).build();
+
+ } catch (IOException ioe) {
+ throw new IllegalArgumentException(ioe);
+ }
+ }
+
+ private static AlarmId toAlarmId(final String id) {
+ try {
+ return AlarmId.valueOf(Long.parseLong(id));
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException("Alarm id should be numeric", ex);
+ }
+
+ }
+
+}
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/package-info.java b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/package-info.java
new file mode 100644
index 00000000..9c291231
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/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.
+ */
+
+/**
+ * Fault management web support.
+ */
+package org.onosproject.faultmanagement.web;
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/faultmanagement/fmweb/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000..18671f01
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,42 @@
+<?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>FM2 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.faultmanagement.web.AlarmsWebResource</param-value>
+ </init-param>
+ <load-on-startup>10</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/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecContext.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecContext.java
new file mode 100644
index 00000000..89886e8a
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecContext.java
@@ -0,0 +1,73 @@
+/*
+ * 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.faultmanagement.web;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+
+/**
+ * Mock codec context for use in codec unit tests.
+ */
+public class AlarmCodecContext implements CodecContext {
+
+ private final ObjectMapper mapper = new ObjectMapper();
+ private final Map<Class<?>, JsonCodec> codecs = new ConcurrentHashMap<>();
+
+ /**
+ * Constructs a new mock codec context.
+ */
+ public AlarmCodecContext() {
+ codecs.clear();
+ registerCodec(Alarm.class, new AlarmCodec());
+
+ }
+
+ @Override
+ public ObjectMapper mapper() {
+ return mapper;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T getService(Class<T> serviceClass) {
+ // TODO
+ return null;
+ }
+
+ /**
+ * Registers the specified JSON codec for the given entity class.
+ *
+ * @param entityClass entity class
+ * @param codec JSON codec
+ * @param <T> entity type
+ */
+ public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) {
+ codecs.putIfAbsent(entityClass, codec);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> JsonCodec<T> codec(Class<T> entityClass) {
+ return codecs.get(entityClass);
+ }
+}
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecTest.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecTest.java
new file mode 100644
index 00000000..3009b99a
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.faultmanagement.web;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.IOException;
+import java.io.InputStream;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+import org.junit.Test;
+import org.onosproject.codec.JsonCodec;
+import static org.onosproject.faultmanagement.web.AlarmJsonMatcher.matchesAlarm;
+import org.onosproject.net.DeviceId;
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId;
+import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm;
+
+public class AlarmCodecTest {
+
+ private final AlarmCodecContext context = new AlarmCodecContext();
+
+ // Use this to check handling for miminal Alarm
+ private final Alarm alarmMinimumFields = new DefaultAlarm.Builder(
+ new AlarmId(44),
+ DeviceId.deviceId("of:2222000000000000"),
+ "NE unreachable",
+ Alarm.SeverityLevel.CLEARED,
+ 1).
+ build();
+
+ // Use this to check handling for fully populated Alarm
+ private final Alarm alarmWithSource = new DefaultAlarm.Builder(
+ new AlarmId(44),
+ DeviceId.deviceId("of:2222000000000000"),
+ "NE unreachable",
+ Alarm.SeverityLevel.CLEARED, 1).
+ forSource(AlarmEntityId.alarmEntityId("port:1/2/3/4")).
+ withTimeUpdated(2).
+ withTimeCleared(3L).
+ withServiceAffecting(true).
+ withAcknowledged(true).
+ withManuallyClearable(true).
+ withAssignedUser("the assigned user").build();
+
+ @Test
+ public void alarmCodecTestWithOptionalFieldMissing() {
+ //context.registerService(AlarmService.class, new AlarmServiceAdapter());
+ final JsonCodec<Alarm> codec = context.codec(Alarm.class);
+ assertThat(codec, is(notNullValue()));
+
+ final ObjectNode alarmJson = codec.encode(alarmMinimumFields, context);
+ assertThat(alarmJson, notNullValue());
+ assertThat(alarmJson, matchesAlarm(alarmMinimumFields));
+
+ }
+
+ @Test
+ public void alarmCodecTestWithOptionalField() {
+ final JsonCodec<Alarm> codec = context.codec(Alarm.class);
+ assertThat(codec, is(notNullValue()));
+
+ final ObjectNode alarmJson = codec.encode(alarmWithSource, context);
+ assertThat(alarmJson, notNullValue());
+ assertThat(alarmJson, matchesAlarm(alarmWithSource));
+
+ }
+
+ @Test
+ public void verifyMinimalAlarmIsEncoded() throws Exception {
+ final JsonCodec<Alarm> alarmCodec = context.codec(Alarm.class);
+
+ final Alarm alarm = getDecodedAlarm(alarmCodec, "alarm-minimal.json");
+ assertCommon(alarm);
+
+ assertThat(alarm.timeCleared(), nullValue());
+ assertThat(alarm.assignedUser(), nullValue());
+
+ }
+
+ @Test
+ public void verifyFullyLoadedAlarmIsEncoded() throws Exception {
+ final JsonCodec<Alarm> alarmCodec = context.codec(Alarm.class);
+
+ final Alarm alarm = getDecodedAlarm(alarmCodec, "alarm-full.json");
+ assertCommon(alarm);
+
+ assertThat(alarm.timeCleared(), is(2222L));
+ assertThat(alarm.assignedUser(), is("foo"));
+
+ }
+
+ private void assertCommon(final Alarm alarm) {
+ assertThat(alarm.id(), is(new AlarmId(10L)));
+ assertThat(alarm.description(), is("NE is not reachable"));
+ assertThat(alarm.source(), is(AlarmEntityId.NONE));
+ assertThat(alarm.timeRaised(), is(999L));
+ assertThat(alarm.timeUpdated(), is(1111L));
+ assertThat(alarm.severity(), is(Alarm.SeverityLevel.MAJOR));
+ assertThat(alarm.serviceAffecting(), is(true));
+ assertThat(alarm.acknowledged(), is(false));
+ assertThat(alarm.manuallyClearable(), is(true));
+ }
+
+ /**
+ * Reads in a rule from the given resource and decodes it.
+ *
+ * @param resourceName resource to use to read the JSON for the rule
+ * @return decoded flow rule
+ * @throws IOException if processing the resource failsdecode
+ */
+ private Alarm getDecodedAlarm(final JsonCodec<Alarm> codec, final String resourceName) throws IOException {
+ final InputStream jsonStream = AlarmCodecTest.class
+ .getResourceAsStream(resourceName);
+ final JsonNode json = context.mapper().readTree(jsonStream);
+ assertThat(json, notNullValue());
+ final Alarm result = codec.decode((ObjectNode) json, context);
+ assertThat(result, notNullValue());
+ return result;
+ }
+
+
+}
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmJsonMatcher.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmJsonMatcher.java
new file mode 100644
index 00000000..14bb45f3
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmJsonMatcher.java
@@ -0,0 +1,135 @@
+/*
+ * 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.faultmanagement.web;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Hamcrest matcher for alarms.
+ */
+public final class AlarmJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+
+ private final Alarm alarm;
+
+ private AlarmJsonMatcher(final Alarm alarm) {
+ this.alarm = alarm;
+ }
+
+ @Override
+ public boolean matchesSafely(final JsonNode jsonAlarm, final Description description) {
+ final String jsonAlarmId = jsonAlarm.get("id").asText();
+ final String alarmId = Long.toString(alarm.id().fingerprint());
+ if (!jsonAlarmId.equals(alarmId)) {
+ description.appendText("alarm id was " + jsonAlarmId);
+ return false;
+ }
+
+ final String jsonDeviceId = jsonAlarm.get("deviceId").asText();
+ final String alarmDeviceId = alarm.deviceId().toString();
+ if (!jsonDeviceId.equals(alarmDeviceId)) {
+ description.appendText("DeviceId was " + jsonDeviceId);
+ return false;
+ }
+
+
+ final String jsonDescription = jsonAlarm.get("description").asText();
+ final String alarmDesc = alarm.description();
+ if (!jsonDescription.equals(alarmDesc)) {
+ description.appendText("description was " + jsonDescription);
+ return false;
+ }
+
+ final long jsonTimeRaised = jsonAlarm.get("timeRaised").asLong();
+ final long timeRaised = alarm.timeRaised();
+ if (timeRaised != jsonTimeRaised) {
+ description.appendText("timeRaised was " + jsonTimeRaised);
+ return false;
+ }
+
+
+ final long jsonTimeUpdated = jsonAlarm.get("timeUpdated").asLong();
+ final long timeUpdated = alarm.timeUpdated();
+ if (timeUpdated != jsonTimeUpdated) {
+ description.appendText("timeUpdated was " + jsonTimeUpdated);
+ return false;
+ }
+
+ final JsonNode jsonTimeClearedNode = jsonAlarm.get("timeCleared");
+
+ if (alarm.timeCleared() != null) {
+ final Long jsonTimeCleared = jsonTimeClearedNode.longValue();
+ final Long timeCleared = alarm.timeCleared();
+
+ if (!timeCleared.equals(jsonTimeCleared)) {
+ description.appendText("Time Cleared was " + jsonTimeCleared);
+ return false;
+ }
+ } else {
+ // No clear time not specified, JSON representation must be empty
+ if (!jsonTimeClearedNode.isNull()) {
+ description.appendText("Time Cleared should be null");
+ return false;
+ }
+ }
+
+ final String jsonSeverity = jsonAlarm.get("severity").asText();
+ final String severity = alarm.severity().toString();
+ if (!severity.equals(jsonSeverity)) {
+ description.appendText("severity was " + jsonSeverity);
+ return false;
+ }
+
+ final JsonNode jsonAlarmNode = jsonAlarm.get("source");
+
+ if (alarm.source() != null) {
+ final String jsonSource = jsonAlarmNode.textValue();
+ final String source = alarm.source().toString();
+
+ if (!source.equals(jsonSource)) {
+ description.appendText("source was " + jsonSource);
+ return false;
+ }
+ } else {
+ // source not specified, JSON representation must be empty
+ if (!jsonAlarmNode.isNull()) {
+ description.appendText("source should be null");
+ return false;
+ }
+ }
+
+ // In progress
+ return true;
+ }
+
+ @Override
+ public void describeTo(final Description description) {
+ description.appendText(alarm.toString());
+ }
+
+ /**
+ * Factory to allocate a alarm matcher.
+ *
+ * @param alarm alarm object we are looking for
+ * @return matcher
+ */
+ public static AlarmJsonMatcher matchesAlarm(final Alarm alarm) {
+ return new AlarmJsonMatcher(alarm);
+ }
+}
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmsWebResourceTest.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmsWebResourceTest.java
new file mode 100644
index 00000000..0b7d9811
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmsWebResourceTest.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.faultmanagement.web;
+
+import com.sun.jersey.api.client.WebResource;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import org.junit.Ignore;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.rest.ResourceTest;
+
+/**
+ * Test of the Fault Management Web REST API for Alarms.
+ */
+public class AlarmsWebResourceTest extends ResourceTest {
+
+ @Before
+ public void setUp() {
+
+ final CodecManager codecService = new CodecManager();
+ codecService.activate();
+
+ final ServiceDirectory testDirectory
+ = new TestServiceDirectory()
+ // Currently no alarms-service implemented
+ // .add(AlarmsService.class, alarmsService)
+ .add(CodecService.class, codecService);
+ BaseResource.setServiceDirectory(testDirectory);
+ }
+
+ @Test
+ @Ignore
+ public void getAllAlarms() {
+ final WebResource rs = resource();
+ final String response = rs.path("/alarms").get(String.class);
+ // Ensure hard-coded alarms returned okay
+ assertThat(response, containsString("\"NE is not reachable\","));
+ assertThat(response, containsString("\"Equipment Missing\","));
+ }
+
+ @Test
+ @Ignore
+ public void getAlarm() {
+ final WebResource rs = resource();
+ final String response = rs.path("/alarms/1").get(String.class);
+ // Ensure hard-coded alarms returned okay
+ assertThat(response, containsString("\"NE is not reachable\","));
+ assertThat(response, not(containsString("\"Equipment Missing\",")));
+ }
+
+}
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-full.json b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-full.json
new file mode 100644
index 00000000..215fc938
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-full.json
@@ -0,0 +1,15 @@
+{
+ "id": 10,
+ "deviceId": "of:123",
+ "description": "NE is not reachable",
+ "source": "none:none",
+ "timeRaised": 999,
+ "timeUpdated": 1111,
+ "timeUpdated": 1111,
+ "timeCleared": 2222,
+ "severity": "MAJOR",
+ "serviceAffecting": true,
+ "acknowledged": false,
+ "manuallyClearable": true,
+ "assignedUser": "foo"
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-minimal.json b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-minimal.json
new file mode 100644
index 00000000..4a24db09
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-minimal.json
@@ -0,0 +1,12 @@
+{
+ "id": 10,
+ "deviceId": "of:123",
+ "description": "NE is not reachable",
+ "source": "none:none",
+ "timeRaised": 999,
+ "timeUpdated": 1111,
+ "severity": "MAJOR",
+ "serviceAffecting": true,
+ "acknowledged": false,
+ "manuallyClearable": true
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/faultmanagement/pom.xml b/framework/src/onos/apps/faultmanagement/pom.xml
new file mode 100644
index 00000000..e7bb6a1b
--- /dev/null
+++ b/framework/src/onos/apps/faultmanagement/pom.xml
@@ -0,0 +1,56 @@
+<?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/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-fm</artifactId>
+ <packaging>pom</packaging>
+
+ <description>ONOS framework applications</description>
+
+ <modules>
+ <module>fmmgr</module>
+ <module>fmweb</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/iptopology-api/pom.xml b/framework/src/onos/apps/iptopology-api/pom.xml
new file mode 100644
index 00000000..50cb4adc
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/pom.xml
@@ -0,0 +1,29 @@
+<!--
+ ~ 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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-apps</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>onos-app-iptopology-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>IP Layer Topology API</description>
+</project>
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AreaId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AreaId.java
new file mode 100644
index 00000000..79a326da
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AreaId.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Area identifier class (32 Bit Area-ID).
+ */
+public class AreaId {
+ private final int areaId;
+
+ /**
+ * Constructor to set area identifier.
+ *
+ * @param areaId area id
+ */
+ public AreaId(int areaId) {
+ this.areaId = areaId;
+ }
+
+ /**
+ * obtain area identifier.
+ *
+ * @return area identifier
+ */
+ public int areaId() {
+ return areaId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(areaId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof AreaId) {
+ AreaId other = (AreaId) obj;
+ return Objects.equals(areaId, other.areaId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("areaId", areaId)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AsNumber.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AsNumber.java
new file mode 100644
index 00000000..3159b20a
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AsNumber.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Autonomous system Number class (32 Bit ASNumber).
+ */
+public class AsNumber {
+ private final int asNum;
+
+ /**
+ * Constructor to set As number.
+ *
+ * @param asNum As number
+ */
+ public AsNumber(int asNum) {
+ this.asNum = asNum;
+ }
+
+ /**
+ * Obtain autonomous system number.
+ *
+ * @return autonomous system number
+ */
+ public int asNum() {
+ return asNum;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(asNum);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof AsNumber) {
+ AsNumber other = (AsNumber) obj;
+ return Objects.equals(asNum, other.asNum);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("asNum", asNum)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Color.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Color.java
new file mode 100644
index 00000000..cb38fa67
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Color.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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents administrative group color.
+ * bit mask - least significant bit is referred to as 'group 0',
+ * and the most significant bit is referred to as 'group 31'
+ */
+public class Color {
+ private final int color;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param color assigned by the network administrator
+ */
+ public Color(int color) {
+ this.color = color;
+ }
+
+ /**
+ * Obtains administrative group.
+ *
+ * @return administrative group
+ */
+ public int color() {
+ return color;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(color);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof Color) {
+ Color other = (Color) obj;
+ return Objects.equals(color, other.color);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("color", color)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDeviceIntf.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDeviceIntf.java
new file mode 100644
index 00000000..e40cbfc0
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDeviceIntf.java
@@ -0,0 +1,79 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onosproject.net.Element;
+
+/**
+ * Default Device interface implementation.
+ */
+public class DefaultDeviceIntf implements DeviceIntf {
+
+ private final Element element;
+ private final DeviceInterface deviceInterface;
+
+ /**
+ * Constructor to initialize device interface parameters.
+ *
+ * @param element parent network element
+ * @param deviceInterface device interface
+ */
+ public DefaultDeviceIntf(Element element, DeviceInterface deviceInterface) {
+ this.element = element;
+ this.deviceInterface = deviceInterface;
+ }
+
+ @Override
+ public Element element() {
+ return element;
+ }
+
+ @Override
+ public DeviceInterface deviceInterface() {
+ return deviceInterface;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(element, deviceInterface);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DefaultDeviceIntf) {
+ final DefaultDeviceIntf other = (DefaultDeviceIntf) obj;
+ return Objects.equals(this.element.id(), other.element.id())
+ && Objects.equals(this.deviceInterface, other.deviceInterface);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("element", element.id())
+ .add("deviceInterface", deviceInterface)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDevicePrefix.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDevicePrefix.java
new file mode 100644
index 00000000..2b1dde6f
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDevicePrefix.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.iptopology.api;
+
+import org.onosproject.net.AbstractAnnotated;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.Element;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default Device prefix implementation.
+ */
+public class DefaultDevicePrefix extends AbstractAnnotated implements DevicePrefix {
+
+ private final Element element;
+ private final PrefixIdentifier prefixIdentifier;
+ private final PrefixTed prefixTed;
+
+ /**
+ * Creates a network device prefix attributed to the specified element.
+ *
+ * @param element parent network element
+ * @param prefixIdentifier prefix identifier
+ * @param prefixTed prefid traffic engineering parameters
+ * @param annotations optional key/value annotations
+ */
+ public DefaultDevicePrefix(Element element, PrefixIdentifier prefixIdentifier,
+ PrefixTed prefixTed, Annotations... annotations) {
+ super(annotations);
+ this.element = element;
+ this.prefixIdentifier = prefixIdentifier;
+ this.prefixTed = prefixTed;
+ }
+
+ @Override
+ public Element element() {
+ return element;
+ }
+
+ @Override
+ public PrefixIdentifier prefixIdentifier() {
+ return prefixIdentifier;
+ }
+
+ @Override
+ public PrefixTed prefixTed() {
+ return prefixTed;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(element, prefixIdentifier, prefixTed);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultDevicePrefix) {
+ final DefaultDevicePrefix other = (DefaultDevicePrefix) obj;
+ return Objects.equals(this.element.id(), other.element.id()) &&
+ Objects.equals(this.prefixIdentifier, other.prefixIdentifier) &&
+ Objects.equals(this.prefixTed, other.prefixTed) &&
+ Objects.equals(this.annotations(), other.annotations());
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("element", element.id())
+ .add("prefixIdentifier", prefixIdentifier)
+ .add("prefixTed", prefixTed)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpDevice.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpDevice.java
new file mode 100644
index 00000000..a2d0165c
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpDevice.java
@@ -0,0 +1,113 @@
+/*
+ * 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.iptopology.api;
+
+import org.onosproject.net.AbstractElement;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default ip device model implementation.
+ */
+public class DefaultIpDevice extends AbstractElement implements IpDevice {
+
+ private final Type type;
+ private final IpDeviceIdentifier deviceIdentifier;
+ private final DeviceTed deviceTed;
+
+
+ /**
+ * For Serialization.
+ */
+ private DefaultIpDevice() {
+ this.type = null;
+ this.deviceIdentifier = null;
+ this.deviceTed = null;
+ }
+
+ /**
+ * Creates a network element attributed to the specified provider.
+ *
+ * @param providerId identity of the provider
+ * @param id device identifier
+ * @param type device type
+ * @param deviceIdentifier provides device identifier details
+ * @param deviceTed device traffic engineering parameters
+ * @param annotations optional key/value annotations
+ */
+ public DefaultIpDevice(ProviderId providerId, DeviceId id, Type type,
+ IpDeviceIdentifier deviceIdentifier, DeviceTed deviceTed,
+ Annotations... annotations) {
+ super(providerId, id, annotations);
+ this.type = type;
+ this.deviceIdentifier = deviceIdentifier;
+ this.deviceTed = deviceTed;
+ }
+
+ @Override
+ public DeviceId id() {
+ return (DeviceId) id;
+ }
+
+ @Override
+ public Type type() {
+ return type;
+ }
+
+ @Override
+ public IpDeviceIdentifier deviceIdentifier() {
+ return deviceIdentifier;
+ }
+
+ @Override
+ public DeviceTed deviceTed() {
+ return deviceTed; }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, deviceIdentifier, deviceTed);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DefaultIpDevice) {
+ final DefaultIpDevice other = (DefaultIpDevice) obj;
+ return Objects.equals(this.id, other.id) &&
+ Objects.equals(this.type, other.type) &&
+ Objects.equals(this.deviceIdentifier, other.deviceIdentifier) &&
+ Objects.equals(this.deviceTed, other.deviceTed);
+ }
+ return false;
+ }
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("id", id)
+ .add("deviceIdentifier", deviceIdentifier)
+ .add("deviceTed", deviceTed)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpLink.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpLink.java
new file mode 100644
index 00000000..41f06047
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpLink.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.iptopology.api;
+
+import org.onosproject.net.AbstractModel;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * This class provides Link identifier and link ted details.
+ */
+public class DefaultIpLink extends AbstractModel implements IpLink {
+
+ private final TerminationPoint src;
+ private final TerminationPoint dst;
+ private final IpLinkIdentifier linkIdentifier;
+ private final LinkTed linkTed;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param src link source termination point
+ * @param dst link destination termination point
+ * @param linkIdentifier provides link identifier details
+ * @param linkTed provides link traffic engineering details
+ * @param annotations optional key/value annotations
+ */
+ public DefaultIpLink(ProviderId providerId, TerminationPoint src, TerminationPoint dst,
+ IpLinkIdentifier linkIdentifier, LinkTed linkTed,
+ Annotations... annotations) {
+ super(providerId, annotations);
+ this.src = src;
+ this.dst = dst;
+ this.linkIdentifier = linkIdentifier;
+ this.linkTed = linkTed;
+ }
+
+ @Override
+ public TerminationPoint src() {
+ return src;
+ }
+
+ @Override
+ public TerminationPoint dst() {
+ return dst;
+ }
+
+ @Override
+ public IpLinkIdentifier linkIdentifier() {
+ return linkIdentifier;
+ }
+
+ @Override
+ public LinkTed linkTed() {
+ return linkTed;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(src, dst, linkIdentifier, linkTed);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultIpLink) {
+ final DefaultIpLink other = (DefaultIpLink) obj;
+ return Objects.equals(this.src, other.src) &&
+ Objects.equals(this.dst, other.dst) &&
+ Objects.equals(this.linkIdentifier, other.linkIdentifier) &&
+ Objects.equals(this.linkTed, other.linkTed);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("src", src)
+ .add("dst", dst)
+ .add("linkIdentifier", linkIdentifier)
+ .add("linkTed", linkTed)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceInterface.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceInterface.java
new file mode 100644
index 00000000..131aa623
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceInterface.java
@@ -0,0 +1,100 @@
+/*
+ * 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.iptopology.api;
+
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Representation of device interface.
+ */
+public class DeviceInterface {
+ private final Ip4Address ip4Address;
+ private final Ip6Address ip6Address;
+ private final InterfaceIdentifier interfaceId;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param ip4Address ipv4 interface address
+ * @param ip6Address ipv6 interface address
+ * @param interfaceId interface Identifier
+ */
+ public DeviceInterface(Ip4Address ip4Address, Ip6Address ip6Address, InterfaceIdentifier interfaceId) {
+ this.ip4Address = ip4Address;
+ this.ip6Address = ip6Address;
+ this.interfaceId = interfaceId;
+ }
+
+ /**
+ * obtains ipv4 address of an interface.
+ *
+ * @return ipv4 interface address
+ */
+ public Ip4Address ip4Address() {
+ return ip4Address;
+ }
+
+ /**
+ * obtains ipv6 interface address.
+ *
+ * @return ipv6 interface address
+ */
+ public Ip6Address ip6Address() {
+ return ip6Address;
+ }
+
+ /**
+ * obtains interface identifier.
+ *
+ * @return interface identifier
+ */
+ public InterfaceIdentifier interfaceId() {
+ return interfaceId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ip4Address, ip6Address, interfaceId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DeviceInterface) {
+ final DeviceInterface other = (DeviceInterface) obj;
+ return Objects.equals(this.ip4Address, other.ip4Address)
+ && Objects.equals(this.ip6Address, other.ip6Address)
+ && Objects.equals(this.interfaceId, other.interfaceId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("ip4Address", ip4Address)
+ .add("ip6Address", ip6Address)
+ .add("interfaceId", interfaceId)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceIntf.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceIntf.java
new file mode 100644
index 00000000..ff18d3ac
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceIntf.java
@@ -0,0 +1,37 @@
+/*
+ * 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.iptopology.api;
+
+import org.onosproject.net.Element;
+
+/**
+ * Abstraction of Device interface.
+ */
+public interface DeviceIntf {
+ /**
+ * Returns the parent network element to which this interface belongs.
+ *
+ * @return parent network element
+ */
+ Element element();
+
+ /**
+ * Returns device interface details.
+ *
+ * @return device interface details
+ */
+ DeviceInterface deviceInterface();
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DevicePrefix.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DevicePrefix.java
new file mode 100644
index 00000000..89efccd4
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DevicePrefix.java
@@ -0,0 +1,46 @@
+/*
+ * 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.iptopology.api;
+
+import org.onosproject.net.Annotated;
+import org.onosproject.net.Element;
+
+/**
+ * Abstraction of Device Prefix.
+ */
+public interface DevicePrefix extends Annotated {
+
+ /**
+ * Returns the parent network element to which this port belongs.
+ *
+ * @return parent network element
+ */
+ Element element();
+
+ /**
+ * Returns prefix identifier details.
+ *
+ * @return prefix identifier details
+ */
+ PrefixIdentifier prefixIdentifier();
+
+ /**
+ * Returns prefix Traffic engineering parameters.
+ *
+ * @return prefix Traffic engineering parameters
+ */
+ PrefixTed prefixTed();
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceTed.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceTed.java
new file mode 100644
index 00000000..4d9da55d
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceTed.java
@@ -0,0 +1,173 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+
+/**
+ * Represents Device Traffic Engineering parameters.
+ */
+public class DeviceTed {
+ private final List<Ip4Address> ipv4RouterIds;
+ private final List<Ip6Address> ipv6RouterIds;
+ private final List<TopologyId> topologyIds;
+ private final Position position;
+
+ /**
+ * Constructor to initialize the parameter fields.
+ *
+ * @param ipv4RouterIds Router ids of Ipv4
+ * @param ipv6RouterIds Router ids of Ipv6
+ * @param topologyIds list of multi-topology IDs of the node
+ * @param position of router whether it is ABR or ASBR
+ */
+ public DeviceTed(List<Ip4Address> ipv4RouterIds, List<Ip6Address> ipv6RouterIds,
+ List<TopologyId> topologyIds, Position position) {
+ this.ipv4RouterIds = ipv4RouterIds;
+ this.ipv6RouterIds = ipv6RouterIds;
+ this.topologyIds = topologyIds;
+ this.position = position;
+ }
+
+ /**
+ * Obtain list of Ipv4 Router id.
+ *
+ * @return Ipv4 Router ids
+ */
+ public List<Ip4Address> ipv4RouterIds() {
+ return ipv4RouterIds;
+ }
+
+ /**
+ * Obtain list of Ipv6 Router id.
+ *
+ * @return Ipv6 Router ids
+ */
+ public List<Ip6Address> ipv6RouterIds() {
+ return ipv6RouterIds;
+ }
+
+ /**
+ * Obtain the list of topology ID's.
+ *
+ * @return list of topology id's
+ */
+ public List<TopologyId> topologyIds() {
+ return topologyIds;
+ }
+
+
+ /**
+ * Obtain position of device in the network.
+ *
+ * @return position of device in the network
+ */
+ public Position position() {
+ return position;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ipv4RouterIds, ipv6RouterIds, topologyIds, position);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DeviceTed) {
+ int countObjSubTlv = 0;
+ int countOtherSubTlv = 0;
+ int countObjTopologyId = 0;
+ int countOtherTopologyId = 0;
+ boolean isCommonSubTlv = true;
+ boolean isCommonSubTlv6 = true;
+ boolean isCommonTopology = true;
+ DeviceTed other = (DeviceTed) obj;
+ Iterator<Ip4Address> objListIterator = other.ipv4RouterIds.iterator();
+ countOtherSubTlv = other.ipv4RouterIds.size();
+ countObjSubTlv = ipv4RouterIds.size();
+
+ Iterator<Ip6Address> objListIteratorIpv6 = other.ipv6RouterIds.iterator();
+ int countOtherSubTlv6 = other.ipv6RouterIds.size();
+ int countObjSubTlv6 = ipv6RouterIds.size();
+
+ Iterator<TopologyId> topologyId = other.topologyIds.iterator();
+ countOtherTopologyId = other.topologyIds.size();
+ countObjTopologyId = topologyIds.size();
+
+ if (countObjSubTlv != countOtherSubTlv || countOtherSubTlv6 != countObjSubTlv6
+ || countObjTopologyId != countOtherTopologyId) {
+ return false;
+ } else {
+ while (objListIterator.hasNext() && isCommonSubTlv) {
+ Ip4Address subTlv = objListIterator.next();
+ //find index of that element and then get that from the list and then compare
+ if (ipv4RouterIds.contains(subTlv) && other.ipv4RouterIds.contains(subTlv)) {
+ isCommonSubTlv = Objects.equals(ipv4RouterIds.get(ipv4RouterIds.indexOf(subTlv)),
+ other.ipv4RouterIds.get(other.ipv4RouterIds.indexOf(subTlv)));
+ } else {
+ isCommonSubTlv = false;
+ }
+ }
+ while (objListIteratorIpv6.hasNext() && isCommonSubTlv6) {
+ Ip6Address subTlv = objListIteratorIpv6.next();
+ //find index of that element and then get that from the list and then compare
+ if (ipv6RouterIds.contains(subTlv) && other.ipv6RouterIds.contains(subTlv)) {
+ isCommonSubTlv6 = Objects.equals(ipv6RouterIds.get(ipv6RouterIds.indexOf(subTlv)),
+ other.ipv6RouterIds.get(other.ipv6RouterIds.indexOf(subTlv)));
+ } else {
+ isCommonSubTlv6 = false;
+ }
+ }
+ while (topologyId.hasNext() && isCommonTopology) {
+ TopologyId subTlv = topologyId.next();
+ //find index of that element and then get that from the list and then compare
+ if (topologyIds.contains(subTlv) && other.topologyIds.contains(subTlv)) {
+ isCommonTopology = Objects.equals(topologyIds.get(topologyIds.indexOf(subTlv)),
+ other.topologyIds.get(other.topologyIds.indexOf(subTlv)));
+ } else {
+ isCommonTopology = false;
+ }
+ }
+ return isCommonSubTlv && isCommonSubTlv6 && isCommonTopology
+ && Objects.equals(position, other.position);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("ipv6RouterIds", ipv6RouterIds)
+ .add("ipv4RouterIds", ipv4RouterIds)
+ .add("topologyIds", topologyIds)
+ .add("position", position)
+ .toString();
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DomainId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DomainId.java
new file mode 100644
index 00000000..4fb10701
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DomainId.java
@@ -0,0 +1,71 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Domain Identifier(32 Bit).
+ */
+public class DomainId {
+ private final int domainIdentifier;
+
+ /**
+ * Constructor to initialize domain identifier.
+ *
+ * @param domainIdentifier domain identifier
+ */
+ public DomainId(int domainIdentifier) {
+ this.domainIdentifier = domainIdentifier;
+ }
+
+ /**
+ * Obtain domain identifier.
+ *
+ * @return domain identifier
+ */
+ public int domainIdentifier() {
+ return domainIdentifier;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(domainIdentifier);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DomainId) {
+ DomainId other = (DomainId) obj;
+ return Objects.equals(domainIdentifier, other.domainIdentifier);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("domainIdentifier", domainIdentifier)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ExtendedRouteTag.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ExtendedRouteTag.java
new file mode 100644
index 00000000..9bd87c1b
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ExtendedRouteTag.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents the extended igp administrative tags of the prefix.
+ */
+public class ExtendedRouteTag {
+ private final long extRouteTag;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param extRouteTag extended ISIS route tag
+ */
+ public ExtendedRouteTag(long extRouteTag) {
+ this.extRouteTag = extRouteTag;
+ }
+
+ /**
+ * Obtains extended igp administrative tags.
+ *
+ * @return extended igp administrative tags
+ */
+ public long extRouteTag() {
+ return extRouteTag;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(extRouteTag);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof ExtendedRouteTag) {
+ ExtendedRouteTag other = (ExtendedRouteTag) obj;
+ return Objects.equals(extRouteTag, other.extRouteTag);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("extRouteTag", extRouteTag)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IgpFlags.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IgpFlags.java
new file mode 100644
index 00000000..59084c04
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IgpFlags.java
@@ -0,0 +1,114 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * This class provides implementation IS-IS and OSPF flags assigned to the prefix.
+ */
+public class IgpFlags {
+ private final boolean isisUpDown;
+ private final boolean ospfNoUnicast;
+ private final boolean ospfLclAddr;
+ private final boolean ospfNssa;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param isisUpDown IS-IS Up/Down
+ * @param ospfNoUnicast OSPF no unicast
+ * @param ospfLclAddr OSPF local address
+ * @param ospfNssa OSPF propagate NSSA
+ */
+ public IgpFlags(boolean isisUpDown, boolean ospfNoUnicast, boolean ospfLclAddr,
+ boolean ospfNssa) {
+ this.isisUpDown = isisUpDown;
+ this.ospfNoUnicast = ospfNoUnicast;
+ this.ospfLclAddr = ospfLclAddr;
+ this.ospfNssa = ospfNssa;
+ }
+
+ /**
+ * Provides information whether IS-IS is Up/Down.
+ *
+ * @return IS-IS Up/Down bit enabled or not
+ */
+ public boolean isisUpDown() {
+ return isisUpDown;
+ }
+
+ /**
+ * Provides information whether OSPF is unicast or not.
+ *
+ * @return OSPF no unicast Bit set or not
+ */
+ public boolean ospfNoUnicast() {
+ return ospfNoUnicast;
+ }
+
+ /**
+ * Provides information on OSPF local address.
+ *
+ * @return OSPF local address Bit set or not
+ */
+ public boolean ospfLclAddr() {
+ return ospfLclAddr;
+ }
+
+ /**
+ * Provides information on OSPF propagate NSSA.
+ *
+ * @return OSPF propagate NSSA Bit set or not
+ */
+ public boolean ospfNssa() {
+ return ospfNssa;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(isisUpDown, ospfNoUnicast, ospfLclAddr,
+ ospfNssa);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IgpFlags) {
+ IgpFlags other = (IgpFlags) obj;
+ return Objects.equals(isisUpDown, other.isisUpDown)
+ && Objects.equals(ospfNoUnicast, other.ospfNoUnicast)
+ && Objects.equals(ospfLclAddr, other.ospfLclAddr)
+ && Objects.equals(ospfNssa, other.ospfNssa);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("isisUpDown", isisUpDown)
+ .add("ospfNoUnicast", ospfNoUnicast)
+ .add("ospfLclAddr", ospfLclAddr)
+ .add("ospfNssa", ospfNssa)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/InterfaceIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/InterfaceIdentifier.java
new file mode 100644
index 00000000..405e1417
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/InterfaceIdentifier.java
@@ -0,0 +1,71 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * This class provides information on Local Interface Identifier and Remote
+ * Interface Identifier of the link.
+ */
+public class InterfaceIdentifier {
+ private final Integer identifier;
+
+ /**
+ * Constructor to initialize identifier.
+ *
+ * @param identifier local/remote interface identifier
+ */
+ public InterfaceIdentifier(Integer identifier) {
+ this.identifier = identifier;
+ }
+
+ /**
+ * Provides the local/remote interface identifier of the link.
+ *
+ * @return interface identifier
+ */
+ public Integer identifier() {
+ return identifier;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(identifier);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof InterfaceIdentifier) {
+ InterfaceIdentifier other = (InterfaceIdentifier) obj;
+ return Objects.equals(identifier, other.identifier);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("identifier", identifier)
+ .toString();
+ }
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDevice.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDevice.java
new file mode 100644
index 00000000..131b7eae
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDevice.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.iptopology.api;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Element;
+
+/**
+ * Abstraction of Ip Device.
+ */
+public interface IpDevice extends Element {
+ /**
+ ** Enum type to store Device Type.
+ */
+ enum Type {
+ /**
+ * Signifies that the device is pseudo device.
+ */
+ PSEUDO,
+
+ /**
+ * Signifies that the device is non-pseudo device.
+ */
+ NONPSEUDO;
+ }
+
+ /**
+ * Obtains device id.
+ *
+ * @return device id
+ */
+ @Override
+ DeviceId id();
+
+ /**
+ * Obtains device type.
+ *
+ * @return device type
+ */
+ Type type();
+
+ /**
+ * Obtains Device identifier details.
+ *
+ * @return identifier of the device
+ */
+ IpDeviceIdentifier deviceIdentifier();
+
+ /**
+ * Obtains the traffic engineering parameters of the device.
+ *
+ * @return traffic engineering parameters of the device
+ */
+ DeviceTed deviceTed();
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDeviceIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDeviceIdentifier.java
new file mode 100644
index 00000000..472fe008
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDeviceIdentifier.java
@@ -0,0 +1,141 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents IP Device Identifiers.
+ */
+public class IpDeviceIdentifier {
+
+ private final RouteDistinguisher routeDish;
+ private final RouteInstance routeInstance;
+ private final AsNumber asNum;
+ private final DomainId domainIdentifier;
+ private final AreaId areaId;
+ private final RouteIdentifier routerIdentifier;
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param routeInstance routing protocol instance
+ * @param asNum AS number
+ * @param domainIdentifier BGP-LS domain
+ * @param areaId Area ID
+ * @param routerIdentifier IGP router ID
+ */
+ public IpDeviceIdentifier(RouteDistinguisher routeDish, RouteInstance routeInstance, AsNumber asNum,
+ DomainId domainIdentifier, AreaId areaId, RouteIdentifier routerIdentifier) {
+ this.routeDish = routeDish;
+ this.areaId = areaId;
+ this.asNum = asNum;
+ this.domainIdentifier = domainIdentifier;
+ this.routeInstance = routeInstance;
+ this.routerIdentifier = routerIdentifier;
+ }
+
+ /**
+ * Obtains Route Distinguisher of Ip Device.
+ *
+ * @return Area ID
+ */
+ public RouteDistinguisher routeDish() {
+ return routeDish;
+ }
+
+ /**
+ * Obtains Area ID if Ip Device.
+ *
+ * @return Area ID
+ */
+ public AreaId areaId() {
+ return areaId;
+ }
+
+ /**
+ * Obtains AS number of Ip Device.
+ *
+ * @return AS number
+ */
+ public AsNumber asNum() {
+ return asNum;
+ }
+
+ /**
+ * Obtains domain identifier of Ip Device.
+ *
+ * @return domain identifier
+ */
+ public DomainId domainIdentifier() {
+ return domainIdentifier;
+ }
+
+ /**
+ * Obtains Router id of Ip Device.
+ *
+ * @return Router id
+ */
+ public RouteIdentifier routerIdentifier() {
+ return routerIdentifier;
+ }
+
+ /**
+ * Obtains routing protocol instance.
+ *
+ * @return routing protocol instance
+ */
+ public RouteInstance routeInstance() {
+ return routeInstance;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(routeDish, areaId, asNum, domainIdentifier, routerIdentifier, routeInstance);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IpDeviceIdentifier) {
+ IpDeviceIdentifier other = (IpDeviceIdentifier) obj;
+ return Objects.equals(areaId, other.areaId) && Objects.equals(asNum, other.asNum)
+ && Objects.equals(domainIdentifier, other.domainIdentifier)
+ && Objects.equals(routerIdentifier, other.routerIdentifier)
+ && Objects.equals(routeInstance, other.routeInstance)
+ && Objects.equals(routeDish, other.routeDish);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("areaId", areaId)
+ .add("asNum", asNum)
+ .add("domainIdentifier", domainIdentifier)
+ .add("routerIdentifier", routerIdentifier)
+ .add("routeInstance", routeInstance)
+ .add("routeDish", routeDish)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLink.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLink.java
new file mode 100644
index 00000000..d632d2db
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLink.java
@@ -0,0 +1,54 @@
+/*
+ * 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.iptopology.api;
+
+import org.onosproject.net.Annotated;
+import org.onosproject.net.NetworkResource;
+import org.onosproject.net.Provided;
+
+/**
+ * Abstraction of a network ip link.
+ */
+public interface IpLink extends Annotated, Provided, NetworkResource {
+
+ /**
+ * Returns source termination point of link.
+ *
+ * @return source termination point of link
+ */
+ TerminationPoint src();
+
+ /**
+ * Returns destination termination point of link.
+ *
+ * @return destination termination point of link
+ */
+ TerminationPoint dst();
+
+ /**
+ * Returns link identifier details.
+ *
+ * @return link identifier details
+ */
+ IpLinkIdentifier linkIdentifier();
+
+ /**
+ * Returns the link traffic engineering parameters.
+ *
+ * @return links traffic engineering parameters
+ */
+ LinkTed linkTed();
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLinkIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLinkIdentifier.java
new file mode 100644
index 00000000..8522f945
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLinkIdentifier.java
@@ -0,0 +1,161 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+
+/**
+ * Represents Ip Link Identifier.
+ */
+public class IpLinkIdentifier {
+ private final InterfaceIdentifier localIndentifier;
+ private final InterfaceIdentifier remoteIndentifier;
+ private final Ip4Address localIpv4Addr;
+ private final Ip4Address remoteIpv4Addr;
+ private final Ip6Address localIpv6Addr;
+ private final Ip6Address remoteIpv6Addr;
+ private final TopologyId topologyId;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param localIndentifier local interface identifier of the link
+ * @param remoteIndentifier remote interface identifier of the link
+ * @param localIpv4Addr local IPv4 address of the link
+ * @param remoteIpv4Addr remote IPv4 address of the link
+ * @param localIpv6Addr local IPv6 address of the link
+ * @param remoteIpv6Addr remote IPv6 address of the link
+ * @param topologyId link topology identifier
+ */
+ public IpLinkIdentifier(InterfaceIdentifier localIndentifier, InterfaceIdentifier remoteIndentifier,
+ Ip4Address localIpv4Addr, Ip4Address remoteIpv4Addr, Ip6Address localIpv6Addr,
+ Ip6Address remoteIpv6Addr, TopologyId topologyId) {
+ this.localIndentifier = localIndentifier;
+ this.remoteIndentifier = remoteIndentifier;
+ this.localIpv4Addr = localIpv4Addr;
+ this.remoteIpv4Addr = remoteIpv4Addr;
+ this.localIpv6Addr = localIpv6Addr;
+ this.remoteIpv6Addr = remoteIpv6Addr;
+ this.topologyId = topologyId;
+ }
+
+ /**
+ * Obtains link local identifier.
+ *
+ * @return link local identifier
+ */
+ public InterfaceIdentifier localIndentifier() {
+ return localIndentifier;
+ }
+
+ /**
+ * Obtains link local identifier.
+ *
+ * @return link local identifier
+ */
+ public InterfaceIdentifier remoteIndentifier() {
+ return remoteIndentifier;
+ }
+
+ /**
+ * Obtains local IPv4 address of the link.
+ *
+ * @return local IPv4 address of the link
+ */
+ public Ip4Address localIpv4Addr() {
+ return localIpv4Addr;
+ }
+
+ /**
+ * Obtains remote IPv4 address of the link.
+ *
+ * @return remote IPv4 address of the link
+ */
+ public Ip4Address remoteIpv4Addr() {
+ return remoteIpv4Addr;
+ }
+
+ /**
+ * Obtains local IPv6 address of the link.
+ *
+ * @return local IPv6 address of the link
+ */
+ public Ip6Address localIpv6Addr() {
+ return localIpv6Addr;
+ }
+
+ /**
+ * Obtains remote IPv6 address of the link.
+ *
+ * @return remote IPv6 address of the link
+ */
+ public Ip6Address remoteIpv6Addr() {
+ return remoteIpv6Addr;
+ }
+
+ /**
+ * Obtains Topology ID of the link.
+ *
+ * @return Topology ID of the link
+ */
+ public TopologyId topologyId() {
+ return topologyId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(localIndentifier, remoteIndentifier, localIpv4Addr, remoteIpv4Addr,
+ localIpv6Addr, remoteIpv6Addr, topologyId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IpLinkIdentifier) {
+ IpLinkIdentifier other = (IpLinkIdentifier) obj;
+ return Objects.equals(topologyId, other.topologyId)
+ && Objects.equals(localIndentifier, other.localIndentifier)
+ && Objects.equals(remoteIndentifier, other.remoteIndentifier)
+ && Objects.equals(localIpv4Addr, other.localIpv4Addr)
+ && Objects.equals(remoteIpv4Addr, other.remoteIpv4Addr)
+ && Objects.equals(localIpv6Addr, other.localIpv6Addr)
+ && Objects.equals(remoteIpv6Addr, other.remoteIpv6Addr);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("localIndentifier", localIndentifier)
+ .add("remoteIndentifier", remoteIndentifier)
+ .add("localIpv4Addr", localIpv4Addr)
+ .add("remoteIpv4Addr", remoteIpv4Addr)
+ .add("localIpv6Addr", localIpv6Addr)
+ .add("remoteIpv6Addr", remoteIpv6Addr)
+ .add("topologyId", topologyId)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpReachability.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpReachability.java
new file mode 100644
index 00000000..8fdd4d31
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpReachability.java
@@ -0,0 +1,73 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Provides information of IP address prefix in the IGP topology and a router advertises
+ * this to each of its BGP nexthop.
+ */
+public class IpReachability {
+ private final IpPrefix ipPrefix;
+
+ /**
+ * Constructor to initialize IP prefix.
+ *
+ * @param ipPrefix IP address prefix
+ */
+ public IpReachability(IpPrefix ipPrefix) {
+ this.ipPrefix = ipPrefix;
+ }
+
+ /**
+ * Provides IP Address prefix reachability.
+ *
+ * @return IP Address prefix
+ */
+ public IpPrefix ipPrefix() {
+ return ipPrefix;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ipPrefix);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IpReachability) {
+ IpReachability other = (IpReachability) obj;
+ return Objects.equals(ipPrefix, other.ipPrefix);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("ipPrefix", ipPrefix)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsIsPseudonode.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsIsPseudonode.java
new file mode 100644
index 00000000..064d830b
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsIsPseudonode.java
@@ -0,0 +1,93 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents the Pseudonode information of device in ISIS domain.
+ */
+public class IsIsPseudonode implements RouteIdentifier {
+ private final IsoNodeId isoNodeId;
+ private final byte psnIdentifier;
+ private final ProtocolType type;
+
+ /**
+ * Constructor to initialize the values.
+ *
+ * @param isoNodeId ISO system-ID
+ * @param psnIdentifier Pseudonode identifier
+ * @param type Protocol ID
+ */
+ public IsIsPseudonode(IsoNodeId isoNodeId, byte psnIdentifier, ProtocolType type) {
+ this.isoNodeId = isoNodeId;
+ this.psnIdentifier = psnIdentifier;
+ this.type = type;
+ }
+
+ /**
+ * Obtains iso system id of Pseudonode of device in ISIS domain.
+ *
+ * @return ISO system Id
+ */
+ public IsoNodeId isoNodeId() {
+ return isoNodeId;
+ }
+
+ /**
+ * Obtains Pseudonode identifier.
+ *
+ * @return Pseudonode identifier
+ */
+ public byte psnIdentifier() {
+ return psnIdentifier;
+ }
+
+ @Override
+ public ProtocolType type() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(isoNodeId, psnIdentifier, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IsIsPseudonode) {
+ IsIsPseudonode other = (IsIsPseudonode) obj;
+ return Objects.equals(isoNodeId, other.isoNodeId) && Objects.equals(psnIdentifier, other.psnIdentifier)
+ && Objects.equals(type, other.type);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("isoNodeId", isoNodeId)
+ .add("psnIdentifier", psnIdentifier)
+ .add("type", type)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsoNodeId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsoNodeId.java
new file mode 100644
index 00000000..8bb3d8b9
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsoNodeId.java
@@ -0,0 +1,79 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents ISO system id of the device.
+ */
+public class IsoNodeId implements RouteIdentifier {
+ private final byte[] isoNodeId;
+ private final ProtocolType type;
+
+ /**
+ * Constructor to initialize the values.
+ *
+ * @param isoNodeId ISO system-ID
+ * @param type Protocol type
+ */
+ public IsoNodeId(byte[] isoNodeId, ProtocolType type) {
+ this.isoNodeId = isoNodeId;
+ this.type = type;
+ }
+
+ /**
+ * Obtains ISO system id of the device.
+ *
+ * @return ISO system id
+ */
+ public byte[] isoNodeId() {
+ return isoNodeId;
+ }
+
+ @Override
+ public ProtocolType type() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(isoNodeId, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IsoNodeId) {
+ IsoNodeId other = (IsoNodeId) obj;
+ return Objects.equals(isoNodeId, other.isoNodeId) && Objects.equals(type, other.type);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("isoNodeId", isoNodeId)
+ .add("type", type)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/LinkTed.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/LinkTed.java
new file mode 100644
index 00000000..3a686034
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/LinkTed.java
@@ -0,0 +1,349 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.util.Bandwidth;
+
+/**
+ * Represents Link Traffic engineering parameters.
+ */
+public class LinkTed {
+ private final Bandwidth maximumLink;
+ private final Bandwidth maxReserved;
+ private final List<Bandwidth> maxUnResBandwidth;
+ private final Metric teMetric;
+ private final Metric igpMetric;
+ private final List<Ip4Address> ipv4LocRouterId;
+ private final List<Ip6Address> ipv6LocRouterId;
+ private final List<Ip4Address> ipv4RemRouterId;
+ private final List<Ip6Address> ipv6RemRouterId;
+ private final Color color;
+ private final Signalling signalType;
+ private final List<Srlg> srlgGroup;
+ private final ProtectionType protectType;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param maximumLink maximum bandwidth can be used
+ * @param maxReserved max bandwidth that can be reserved
+ * @param maxUnResBandwidth amount of bandwidth reservable
+ * @param teMetric Traffic engineering metric
+ * @param igpMetric IGP metric
+ * @param color information on administrative group assigned to the interface
+ * @param signalType MPLS signaling protocols
+ * @param srlgGroup Shared Risk Link Group information
+ * @param protectType protection capabilities of the link
+ * @param ipv4LocRouterId IPv4 router-Id of local node
+ * @param ipv6LocRouterId IPv6 router-Id of local node
+ * @param ipv4RemRouterId IPv4 router-Id of remote node
+ * @param ipv6RemRouterId IPv6 router-Id of remote node
+ */
+ public LinkTed(Bandwidth maximumLink, Bandwidth maxReserved, List<Bandwidth> maxUnResBandwidth,
+ Metric teMetric, Metric igpMetric, Color color, Signalling signalType, List<Srlg> srlgGroup,
+ ProtectionType protectType, List<Ip4Address> ipv4LocRouterId, List<Ip6Address> ipv6LocRouterId,
+ List<Ip4Address> ipv4RemRouterId, List<Ip6Address> ipv6RemRouterId) {
+ this.maximumLink = maximumLink;
+ this.maxReserved = maxReserved;
+ this.maxUnResBandwidth = maxUnResBandwidth;
+ this.teMetric = teMetric;
+ this.igpMetric = igpMetric;
+ this.color = color;
+ this.signalType = signalType;
+ this.srlgGroup = srlgGroup;
+ this.protectType = protectType;
+ this.ipv4LocRouterId = ipv4LocRouterId;
+ this.ipv6LocRouterId = ipv6LocRouterId;
+ this.ipv4RemRouterId = ipv4RemRouterId;
+ this.ipv6RemRouterId = ipv6RemRouterId;
+ }
+
+ /**
+ * Provides maximum bandwidth can be used on the link.
+ *
+ * @return maximum bandwidth
+ */
+ public Bandwidth maximumLink() {
+ return maximumLink;
+ }
+
+ /**
+ * Amount of bandwidth reservable on the link.
+ *
+ * @return unreserved bandwidth
+ */
+ public List<Bandwidth> maxUnResBandwidth() {
+ return maxUnResBandwidth;
+ }
+
+ /**
+ * Provides max bandwidth that can be reserved on the link.
+ *
+ * @return max bandwidth reserved
+ */
+ public Bandwidth maxReserved() {
+ return maxReserved;
+ }
+
+ /**
+ * Provides Traffic engineering metric for the link.
+ *
+ * @return Traffic engineering metric
+ */
+ public Metric teMetric() {
+ return teMetric;
+ }
+
+ /**
+ * Provides IGP metric for the link.
+ *
+ * @return IGP metric
+ */
+ public Metric igpMetric() {
+ return igpMetric;
+ }
+
+ /**
+ * Provides protection capabilities of the link.
+ *
+ * @return link protection type
+ */
+ public ProtectionType protectType() {
+ return protectType;
+ }
+
+ /**
+ * Provides Shared Risk Link Group information.
+ *
+ * @return Shared Risk Link Group value
+ */
+ public List<Srlg> srlgGroup() {
+ return srlgGroup;
+ }
+
+ /**
+ * Provides which MPLS signaling protocols are enabled.
+ *
+ * @return signal type
+ */
+ public Signalling signalType() {
+ return signalType;
+ }
+
+ /**
+ * Provides information on administrative group assigned to the interface.
+ *
+ * @return 4-octect bit mask assigned by network administrator
+ */
+ public Color color() {
+ return color;
+ }
+
+ /**
+ * Provides IPv4 router-Id of local node.
+ *
+ * @return IPv4 router-Id of local node
+ */
+ public List<Ip4Address> ipv4LocRouterId() {
+ return ipv4LocRouterId;
+ }
+
+ /**
+ * Provides IPv6 router-Id of local node.
+ *
+ * @return IPv6 router-Id of local node
+ */
+ public List<Ip6Address> ipv6LocRouterId() {
+ return ipv6LocRouterId;
+ }
+
+ /**
+ * Provides IPv4 router-Id of remote node.
+ *
+ * @return IPv4 router-Id of remote node
+ */
+ public List<Ip4Address> ipv4RemRouterId() {
+ return ipv4RemRouterId;
+ }
+
+ /**
+ * Provides IPv6 router-Id of remote node.
+ *
+ * @return IPv6 router-Id of remote node
+ */
+ public List<Ip6Address> ipv6RemRouterId() {
+ return ipv6RemRouterId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(maximumLink, maxReserved, maxUnResBandwidth, teMetric, igpMetric,
+ ipv4LocRouterId, ipv6LocRouterId, ipv4RemRouterId, ipv6RemRouterId,
+ color, signalType, srlgGroup, protectType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof LinkTed) {
+ int countCommonBandwidth = 0;
+ int countOtherCommonBandwidth = 0;
+ int countOther4LocRouterId = 0;
+ int countCommon4LocRouterId = 0;
+ int countOther6RemRouterId = 0;
+ int countCommon6RemRouterId = 0;
+ int countOther4RemRouterId = 0;
+ int countCommon4RemRouterId = 0;
+ int countCommon6LocRouterId = 0;
+ int countOther6LocRouterId = 0;
+ int countCommonSrlg = 0;
+ int countOtherSrlg = 0;
+ boolean isCommonBandwidth = true;
+ boolean isCommonIp4Loc = true;
+ boolean isCommonIp4Rem = true;
+ boolean isCommonIp6Loc = true;
+ boolean isCommonIp6Rem = true;
+ boolean isCommonSrlg = true;
+ LinkTed other = (LinkTed) obj;
+ Iterator<Bandwidth> objListIterator = other.maxUnResBandwidth.iterator();
+ countOtherCommonBandwidth = other.maxUnResBandwidth.size();
+ countCommonBandwidth = maxUnResBandwidth.size();
+
+ Iterator<Ip4Address> ipv4local = other.ipv4LocRouterId.iterator();
+ countOther4LocRouterId = other.ipv4LocRouterId.size();
+ countCommon4LocRouterId = ipv4LocRouterId.size();
+
+ Iterator<Ip4Address> ipv4remote = other.ipv4RemRouterId.iterator();
+ countOther4RemRouterId = other.ipv4RemRouterId.size();
+ countCommon4RemRouterId = ipv4RemRouterId.size();
+
+ Iterator<Ip6Address> ipv6local = other.ipv6LocRouterId.iterator();
+ countOther6LocRouterId = other.ipv6LocRouterId.size();
+ countCommon6LocRouterId = ipv6LocRouterId.size();
+
+ Iterator<Ip6Address> ipv6remote = other.ipv6RemRouterId.iterator();
+ countOther6RemRouterId = other.ipv6RemRouterId.size();
+ countCommon6RemRouterId = ipv6RemRouterId.size();
+
+ Iterator<Srlg> srlg = other.srlgGroup.iterator();
+ countOtherSrlg = other.srlgGroup.size();
+ countCommonSrlg = srlgGroup.size();
+
+ if (countOtherCommonBandwidth != countCommonBandwidth
+ || countOther4LocRouterId != countCommon4LocRouterId
+ || countOther4RemRouterId != countCommon4RemRouterId
+ || countOther6LocRouterId != countCommon6LocRouterId
+ || countOther6RemRouterId != countCommon6RemRouterId
+ || countOtherSrlg != countCommonSrlg) {
+ return false;
+ } else {
+ while (objListIterator.hasNext() && isCommonBandwidth) {
+ Bandwidth subTlv = objListIterator.next();
+ if (maxUnResBandwidth.contains(subTlv) && other.maxUnResBandwidth.contains(subTlv)) {
+ isCommonBandwidth = Objects.equals(maxUnResBandwidth.get(maxUnResBandwidth.indexOf(subTlv)),
+ other.maxUnResBandwidth.get(other.maxUnResBandwidth.indexOf(subTlv)));
+ } else {
+ isCommonBandwidth = false;
+ }
+ }
+ while (ipv4local.hasNext() && isCommonIp4Loc) {
+ Ip4Address subTlv = ipv4local.next();
+ if (ipv4LocRouterId.contains(subTlv) && other.ipv4LocRouterId.contains(subTlv)) {
+ isCommonIp4Loc = Objects.equals(ipv4LocRouterId.get(ipv4LocRouterId.indexOf(subTlv)),
+ other.ipv4LocRouterId.get(other.ipv4LocRouterId.indexOf(subTlv)));
+ } else {
+ isCommonIp4Loc = false;
+ }
+ }
+ while (ipv4remote.hasNext() && isCommonIp4Rem) {
+ Ip4Address subTlv = ipv4remote.next();
+ if (ipv4RemRouterId.contains(subTlv) && other.ipv4RemRouterId.contains(subTlv)) {
+ isCommonIp4Rem = Objects.equals(ipv4RemRouterId.get(ipv4RemRouterId.indexOf(subTlv)),
+ other.ipv4RemRouterId.get(other.ipv4RemRouterId.indexOf(subTlv)));
+ } else {
+ isCommonIp4Rem = false;
+ }
+ }
+ while (ipv6remote.hasNext() && isCommonIp6Rem) {
+ Ip6Address subTlv = ipv6remote.next();
+ if (ipv6RemRouterId.contains(subTlv) && other.ipv6RemRouterId.contains(subTlv)) {
+ isCommonIp6Rem = Objects.equals(ipv6RemRouterId.get(ipv6RemRouterId.indexOf(subTlv)),
+ other.ipv6RemRouterId.get(other.ipv6RemRouterId.indexOf(subTlv)));
+ } else {
+ isCommonIp6Rem = false;
+ }
+ }
+ while (ipv6local.hasNext() && isCommonIp6Loc) {
+ Ip6Address subTlv = ipv6local.next();
+ if (ipv6LocRouterId.contains(subTlv) && other.ipv6LocRouterId.contains(subTlv)) {
+ isCommonIp6Loc = Objects.equals(ipv6LocRouterId.get(ipv6LocRouterId.indexOf(subTlv)),
+ other.ipv6LocRouterId.get(other.ipv6LocRouterId.indexOf(subTlv)));
+ } else {
+ isCommonIp6Loc = false;
+ }
+ }
+ while (srlg.hasNext() && isCommonIp6Loc) {
+ Srlg subTlv = srlg.next();
+ if (srlgGroup.contains(subTlv) && other.srlgGroup.contains(subTlv)) {
+ isCommonSrlg = Objects.equals(srlgGroup.get(srlgGroup.indexOf(subTlv)),
+ other.srlgGroup.get(other.srlgGroup.indexOf(subTlv)));
+ } else {
+ isCommonSrlg = false;
+ }
+ }
+ return isCommonBandwidth && isCommonIp4Loc && isCommonIp4Rem && isCommonIp6Rem && isCommonIp6Loc
+ && isCommonSrlg
+ && Objects.equals(igpMetric, other.igpMetric)
+ && Objects.equals(teMetric, other.teMetric)
+ && Objects.equals(maximumLink, other.maximumLink)
+ && Objects.equals(protectType, other.protectType)
+ && Objects.equals(color, other.color)
+ && Objects.equals(signalType, other.signalType);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("igpMetric", igpMetric)
+ .add("teMetric", teMetric)
+ .add("maximumLink", maximumLink)
+ .add("maxReserved", maxReserved)
+ .add("maxUnResBandwidth", maxUnResBandwidth)
+ .add("ipv4LocRouterId", ipv4LocRouterId)
+ .add("ipv4RemRouterId", ipv4RemRouterId)
+ .add("ipv6LocRouterId", ipv6LocRouterId)
+ .add("ipv6RemRouterId", ipv6RemRouterId)
+ .add("protectType", protectType)
+ .add("color", color)
+ .add("srlgGroup", srlgGroup)
+ .add("signalType", signalType)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Metric.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Metric.java
new file mode 100644
index 00000000..0af95b01
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Metric.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents Traffic engineering metrics.
+ */
+public class Metric {
+ private final Integer metric;
+
+ /**
+ * Constructor to initialize its metric.
+ *
+ * @param metric can be TE metric or IGP metric or Prefix metric
+ */
+ public Metric(Integer metric) {
+ this.metric = metric;
+ }
+
+ /**
+ * Obtains traffic engineering metric.
+ *
+ * @return traffic engineering metric
+ */
+ public Integer metric() {
+ return metric;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(metric);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof Metric) {
+ Metric other = (Metric) obj;
+ return Objects.equals(metric, other.metric);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("metric", metric)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/OspfPseudonode.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/OspfPseudonode.java
new file mode 100644
index 00000000..86d96acb
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/OspfPseudonode.java
@@ -0,0 +1,96 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Address;
+
+/**
+ * Represents Pseudonode information of OSFP device.
+ */
+public class OspfPseudonode implements RouteIdentifier {
+ private final RouterId designatedRouter;
+ private final Ip4Address drInterface;
+ private final ProtocolType type;
+
+ /**
+ * Constructor to initialize the values.
+ *
+ * @param designatedRouter Router Id of designated router
+ * @param drInterface IP address of Designated Router interface
+ * @param type Protocol ID
+ */
+ public OspfPseudonode(RouterId designatedRouter, Ip4Address drInterface, ProtocolType type) {
+ this.designatedRouter = designatedRouter;
+ this.drInterface = drInterface;
+ this.type = type;
+ }
+
+ /**
+ * Obtains designated Router Id.
+ *
+ * @return designated Router Id
+ */
+ public RouterId designatedRouter() {
+ return designatedRouter;
+ }
+
+ /**
+ * Obtains IP address of Designated Router interface.
+ *
+ * @return IP address of Designated Router interface
+ */
+ public Ip4Address drInterface() {
+ return drInterface;
+ }
+
+ @Override
+ public ProtocolType type() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(designatedRouter, drInterface, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof OspfPseudonode) {
+ OspfPseudonode other = (OspfPseudonode) obj;
+ return Objects.equals(designatedRouter, other.designatedRouter)
+ && Objects.equals(drInterface, other.drInterface)
+ && Objects.equals(type, other.type);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("designatedRouter", designatedRouter)
+ .add("drInterface", drInterface)
+ .add("type", type)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Position.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Position.java
new file mode 100644
index 00000000..f81f9fd3
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Position.java
@@ -0,0 +1,84 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents Position of device in the network.
+ */
+public class Position {
+ private final Boolean asbr;
+ private final Boolean abr;
+
+ /**
+ * Constructor to set position of device.
+ *
+ * @param asbr autonomous system boundary router
+ * @param abr area boundary router
+ */
+ public Position(Boolean asbr, Boolean abr) {
+ this.asbr = asbr;
+ this.abr = abr;
+ }
+
+ /**
+ * obtain whether the device is autonomous system boundary router or not.
+ *
+ * @return autonomous system boundary router or not
+ */
+ Boolean asbr() {
+ return asbr;
+ }
+
+ /**
+ * obtain whether the device is area boundary router or not.
+ *
+ * @return area boundary router or not
+ */
+ Boolean abr() {
+ return abr;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(abr, asbr);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof Position) {
+ Position other = (Position) obj;
+ return Objects.equals(abr, other.abr) && Objects.equals(asbr, other.asbr);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("abrBit", abr)
+ .add("asbrBit", asbr)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixIdentifier.java
new file mode 100644
index 00000000..b41b5d71
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixIdentifier.java
@@ -0,0 +1,98 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * This class provides Prefix Identifier details.
+ */
+public class PrefixIdentifier {
+ private final TopologyId topologyId;
+ private final RouteType routeType;
+ private final IpReachability ipReach;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param topologyId topology ID of prefix
+ * @param routeType OSPF Route type of the prefix
+ * @param ipReach IP address prefix reachability information
+ */
+ public PrefixIdentifier(TopologyId topologyId, RouteType routeType, IpReachability ipReach) {
+ this.topologyId = topologyId;
+ this.routeType = routeType;
+ this.ipReach = ipReach;
+ }
+
+ /**
+ * Provides topology ID of prefix.
+ *
+ * @return topology id
+ */
+ public TopologyId topologyId() {
+ return this.topologyId;
+ }
+
+ /**
+ * Provides IP address prefix reachability information.
+ *
+ * @return IP address prefix
+ */
+ public IpReachability ipReach() {
+ return this.ipReach;
+ }
+
+ /**
+ * Provides OSPF Route type of the prefix.
+ *
+ * @return Route type
+ */
+ public RouteType routeType() {
+ return this.routeType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(topologyId, routeType, ipReach);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof PrefixIdentifier) {
+ PrefixIdentifier other = (PrefixIdentifier) obj;
+ return Objects.equals(topologyId, other.topologyId) && Objects.equals(routeType, other.routeType)
+ && Objects.equals(ipReach, other.ipReach);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("routeType", routeType)
+ .add("ipReach", ipReach)
+ .add("topologyId", topologyId)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixTed.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixTed.java
new file mode 100644
index 00000000..9f1c40ad
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixTed.java
@@ -0,0 +1,138 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+
+/**
+ * This class provides implementation of prefix traffic engineering data.
+ */
+public class PrefixTed {
+ private final IgpFlags igpFlags;
+ private final RouteTag routeTag;
+ private final ExtendedRouteTag extendedRouteTag;
+ private final Metric metric;
+ private final IpAddress fwdingAddress;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param igpFlags igp flags
+ * @param routeTag ospf route tag
+ * @param extendedRouteTag isis route tag
+ * @param metric prefix metric
+ * @param fwdingAddress forwarding address
+ */
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param igpFlags IS-IS and OSPF flags assigned to the prefix
+ * @param routeTag IGP (ISIS or OSPF) tags of the prefix
+ * @param extendedRouteTag extended ISIS route tags of the prefix
+ * @param metric metric of the prefix
+ * @param fwdingAddress OSPF forwarding address
+ */
+ public PrefixTed(IgpFlags igpFlags, RouteTag routeTag, ExtendedRouteTag extendedRouteTag,
+ Metric metric, IpAddress fwdingAddress) {
+ this.igpFlags = igpFlags;
+ this.routeTag = routeTag;
+ this.extendedRouteTag = extendedRouteTag;
+ this.metric = metric;
+ this.fwdingAddress = fwdingAddress;
+ }
+
+ /**
+ * Provides IS-IS and OSPF flags assigned to the prefix.
+ *
+ * @return IGP flags
+ */
+ public IgpFlags igpFlags() {
+ return igpFlags;
+ }
+
+ /**
+ * Provides IGP (ISIS or OSPF) tags of the prefix.
+ *
+ * @return IGP route tag.
+ */
+ public RouteTag routeTag() {
+ return routeTag;
+ }
+
+ /**
+ * Provides extended ISIS route tags of the prefix.
+ *
+ * @return extended IS-IS route tag
+ */
+ public ExtendedRouteTag extendedRouteTag() {
+ return extendedRouteTag;
+ }
+
+ /**
+ * Provides metric of the prefix.
+ *
+ * @return prefix metric
+ */
+ public Metric metric() {
+ return metric;
+ }
+
+ /**
+ * Provides OSPF forwarding address.
+ *
+ * @return forwarding address
+ */
+ public IpAddress fwdingAddress() {
+ return fwdingAddress;
+ }
+
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(igpFlags, routeTag, extendedRouteTag, metric, fwdingAddress);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof PrefixTed) {
+ PrefixTed other = (PrefixTed) obj;
+ return Objects.equals(igpFlags, other.igpFlags) && Objects.equals(extendedRouteTag, other.extendedRouteTag)
+ && Objects.equals(routeTag, other.routeTag) && Objects.equals(metric, other.metric)
+ && Objects.equals(fwdingAddress, other.fwdingAddress);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("igpFlags", igpFlags)
+ .add("extendedRouteTag", extendedRouteTag)
+ .add("routeTag", routeTag)
+ .add("metric", metric)
+ .add("fwdingAddress", fwdingAddress)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ProtectionType.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ProtectionType.java
new file mode 100644
index 00000000..be7fb5a9
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ProtectionType.java
@@ -0,0 +1,97 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents protection capabilities of the link.
+ */
+public class ProtectionType {
+ private final LinkProtectionType protectionType;
+
+ /**
+ * Enum to provide Link Protection type.
+ */
+ public enum LinkProtectionType {
+ Extra_Traffic(1), Unprotected(2), Shared(4), Enhanced(0x20), Dedicated_OneIsToOne(8),
+ Dedicated_OnePlusOne(0x10), Reserved(0x40);
+ int value;
+
+ /**
+ * Constructor to assign value.
+ *
+ * @param val link protection type
+ */
+ LinkProtectionType(int val) {
+ value = val;
+ }
+
+ /**
+ * Provides Link protection type.
+ *
+ * @return protection type
+ */
+ public byte type() {
+ return (byte) value;
+ }
+ }
+
+ /**
+ * Constructor to initialize protection type.
+ *
+ * @param protectionType link protection type
+ */
+ public ProtectionType(LinkProtectionType protectionType) {
+ this.protectionType = protectionType;
+ }
+
+ /**
+ * Provides protection capabilities of the link.
+ *
+ * @return link protection type.
+ */
+ public LinkProtectionType protectionType() {
+ return protectionType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(protectionType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof ProtectionType) {
+ ProtectionType other = (ProtectionType) obj;
+ return Objects.equals(protectionType, other.protectionType);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("protectionType", protectionType)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteDistinguisher.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteDistinguisher.java
new file mode 100644
index 00000000..b6b83368
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteDistinguisher.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation of RouteDistinguisher.
+ */
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents Route Distinguisher of device in the network.
+ */
+public class RouteDistinguisher {
+ private final Long routeDistinguisher;
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param routeDistinguisher route distinguisher
+ */
+ public RouteDistinguisher(Long routeDistinguisher) {
+ this.routeDistinguisher = routeDistinguisher;
+ }
+
+ /**
+ * Obtain route distinguisher.
+ *
+ * @return route distinguisher
+ */
+ public Long routeDistinguisher() {
+ return routeDistinguisher;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(routeDistinguisher);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof RouteDistinguisher) {
+ RouteDistinguisher other = (RouteDistinguisher) obj;
+ return Objects.equals(routeDistinguisher, other.routeDistinguisher);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("routeDistinguisher", routeDistinguisher)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteIdentifier.java
new file mode 100644
index 00000000..73cda7a6
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteIdentifier.java
@@ -0,0 +1,54 @@
+/*
+ * 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.iptopology.api;
+
+/**
+ * Abstraction of Router ID to identify the router with a distinct IP address.
+ */
+public interface RouteIdentifier {
+ /**
+ * Enum to provide Protocol type.
+ */
+ public enum ProtocolType {
+ ISIS_LevelOne(1), ISIS_LevelTwo(2), OSPFv2(3), Direct(4), Static_Configuration(5), OSPFv3(6);
+ int value;
+
+ /**
+ * Sets protocol ID.
+ *
+ * @param val protocol ID
+ */
+ ProtocolType(int val) {
+ value = val;
+ }
+
+ /**
+ * Provides Protocol ID.
+ *
+ * @return Protocol ID
+ */
+ public byte getType() {
+ return (byte) value;
+ }
+ }
+
+ /**
+ * Provides Protocol ID to identify which protocol routing instance is used.
+ *
+ * @return Protocol type
+ */
+ ProtocolType type();
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteInstance.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteInstance.java
new file mode 100644
index 00000000..fbca820c
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteInstance.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents routing universe where the network element belongs.
+ */
+public class RouteInstance {
+ private final long routeInstance;
+
+ /**
+ * Constructor to initialize routeInstance.
+ *
+ * @param routeInstance routing protocol instance
+ */
+ public RouteInstance(long routeInstance) {
+ this.routeInstance = routeInstance;
+ }
+
+ /**
+ * Obtain route instance.
+ *
+ * @return route instance
+ */
+ public long routeInstance() {
+ return routeInstance;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(routeInstance);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof RouteInstance) {
+ RouteInstance other = (RouteInstance) obj;
+ return Objects.equals(routeInstance, other.routeInstance);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("routeInstance", routeInstance)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteTag.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteTag.java
new file mode 100644
index 00000000..f77cc5e6
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteTag.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents the igp administrative tags of the prefix.
+ */
+public class RouteTag {
+ private final int routeTag;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param routeTag IGP route tag
+ */
+ public RouteTag(int routeTag) {
+ this.routeTag = routeTag;
+ }
+
+ /**
+ * Obtains igp administrative tags of the prefix.
+ *
+ * @return igp administrative tags of the prefix
+ */
+ public int routeTag() {
+ return routeTag;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(routeTag);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof RouteTag) {
+ RouteTag other = (RouteTag) obj;
+ return Objects.equals(routeTag, other.routeTag);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("routeTag", routeTag)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteType.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteType.java
new file mode 100644
index 00000000..11268f6f
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteType.java
@@ -0,0 +1,96 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents Route type of the prefix in the OSPF domain.
+ */
+public class RouteType {
+ private final Type routeType;
+
+ /**
+ * Enum to provide Route type.
+ */
+ public enum Type {
+ Intra_Area(1), Inter_Area(2), External_1(3), External_2(4), NSSA_1(5), NSSA_2(6);
+ int value;
+
+ /**
+ * Constructor to assign value.
+ *
+ * @param val route type
+ */
+ Type(int val) {
+ value = val;
+ }
+
+ /**
+ * Provides route type.
+ *
+ * @return route type
+ */
+ public byte type() {
+ return (byte) value;
+ }
+ }
+
+ /**
+ * Constructor to initialize routeType.
+ *
+ * @param routeType Route type
+ */
+ public RouteType(Type routeType) {
+ this.routeType = routeType;
+ }
+
+ /**
+ * Provides Route type of the prefix.
+ *
+ * @return Route type
+ */
+ public Type routeType() {
+ return routeType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(routeType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof RouteType) {
+ RouteType other = (RouteType) obj;
+ return Objects.equals(routeType, other.routeType);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("routeType", routeType)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouterId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouterId.java
new file mode 100644
index 00000000..85714cb1
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouterId.java
@@ -0,0 +1,78 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents Router ID of the device.
+ */
+public class RouterId implements RouteIdentifier {
+ private final int routerId;
+ private final ProtocolType type;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param routerId Router ID of designated router
+ */
+ public RouterId(int routerId, ProtocolType type) {
+ this.routerId = routerId;
+ this.type = type;
+ }
+
+ /**
+ * Obtains Router Id of the device.
+ *
+ * @return Router Id of the device
+ */
+ public int routerId() {
+ return routerId;
+ }
+
+ @Override
+ public ProtocolType type() {
+ return type;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(routerId, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof RouterId) {
+ RouterId other = (RouterId) obj;
+ return Objects.equals(routerId, other.routerId) && Objects.equals(type, other.type);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("routerId", routerId)
+ .add("type", type)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Signalling.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Signalling.java
new file mode 100644
index 00000000..41593977
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Signalling.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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents signaling protocols that are enabled.
+ */
+public class Signalling {
+ private final Boolean ldp;
+ private final Boolean rsvpte;
+
+ /**
+ * Constructor to initialize the values.
+ *
+ * @param ldp Label Distribution Protocol whether enabled or not
+ * @param rsvpte RSVP TE whether enabled or not
+ */
+ public Signalling(Boolean ldp, Boolean rsvpte) {
+ this.ldp = ldp;
+ this.rsvpte = rsvpte;
+ }
+
+ /**
+ * Obtains whether LDP signalling protocol is enabled or not.
+ *
+ * @return LDP signalling protocol is enabled or not
+ */
+ public Boolean ldp() {
+ return ldp;
+ }
+
+ /**
+ * Obtains whether rsvp-te signalling protocol is enabled or not.
+ *
+ * @return rsvp-te signalling protocol is enabled or not
+ */
+ public Boolean rsvpte() {
+ return rsvpte;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ldp, rsvpte);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof Signalling) {
+ Signalling other = (Signalling) obj;
+ return Objects.equals(ldp, other.ldp) && Objects.equals(rsvpte, other.rsvpte);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("ldp", ldp)
+ .add("rsvpte", rsvpte)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Srlg.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Srlg.java
new file mode 100644
index 00000000..1f39bad2
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Srlg.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents Shared Risk Link Group information.
+ */
+public class Srlg {
+ private final int srlgGroup;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param srlgGroup list of Shared Risk Link Group value
+ */
+ public Srlg(int srlgGroup) {
+ this.srlgGroup = srlgGroup;
+ }
+
+ /**
+ * Provides Shared Risk link group.
+ *
+ * @return Shared Risk link group value
+ */
+ public int srlgGroup() {
+ return srlgGroup;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(srlgGroup);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof Srlg) {
+ Srlg other = (Srlg) obj;
+ return Objects.equals(srlgGroup, other.srlgGroup);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("srlgGroup", srlgGroup)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TerminationPoint.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TerminationPoint.java
new file mode 100644
index 00000000..9c21cb46
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TerminationPoint.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.iptopology.api;
+
+import java.util.Objects;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.ElementId;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Abstraction of a network termination point expressed as a pair of the network element identifier and device
+ * interface.
+ */
+public class TerminationPoint {
+ private final ElementId elementId;
+ private final DeviceInterface deviceInterface;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param elementId network element identifier
+ * @param deviceInterface device interface
+ */
+ public TerminationPoint(ElementId elementId, DeviceInterface deviceInterface) {
+ this.elementId = elementId;
+ this.deviceInterface = deviceInterface;
+ }
+
+ /**
+ * Returns the network element identifier.
+ *
+ * @return element identifier
+ */
+ public ElementId elementId() {
+ return elementId;
+ }
+
+ /**
+ * Returns the identifier of the infrastructure device if the termination
+ * point belongs to a network element which is indeed an ip
+ * device.
+ *
+ * @return network element identifier as a device identifier
+ * @throws java.lang.IllegalStateException if termination point is not
+ * associated with a device
+ */
+ public DeviceId deviceId() {
+ if (elementId instanceof DeviceId) {
+ return (DeviceId) elementId;
+ }
+ throw new IllegalStateException("Termination point not associated " +
+ "with an ip device");
+ }
+
+ /**
+ * Returns Device interface details.
+ *
+ * @return device interface details
+ */
+ public DeviceInterface deviceInterface() {
+ return deviceInterface;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(elementId, deviceInterface);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof TerminationPoint) {
+ final TerminationPoint other = (TerminationPoint) obj;
+ return Objects.equals(this.elementId, other.elementId)
+ && Objects.equals(this.deviceInterface, other.deviceInterface);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("elementId", elementId)
+ .add("deviceInterface", deviceInterface)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TopologyId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TopologyId.java
new file mode 100644
index 00000000..9d414e35
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TopologyId.java
@@ -0,0 +1,70 @@
+/*
+ * 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.iptopology.api;
+
+import java.util.Objects;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Represents Multi-Topology IDs for a network link, node or prefix.
+ */
+public class TopologyId {
+ private final short topologyId;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param topologyId topology id for node/link/prefix
+ */
+ public TopologyId(short topologyId) {
+ this.topologyId = topologyId;
+ }
+
+ /**
+ * Obtains the topology ID.
+ *
+ * @return topology ID
+ */
+ public short topologyId() {
+ return topologyId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(topologyId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof TopologyId) {
+ TopologyId other = (TopologyId) obj;
+ return Objects.equals(topologyId, other.topologyId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("topologyId", topologyId)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultInterfaceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultInterfaceDescription.java
new file mode 100644
index 00000000..c7e413d7
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultInterfaceDescription.java
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.iptopology.api.InterfaceIdentifier;
+import org.onosproject.net.AbstractDescription;
+import org.onosproject.net.SparseAnnotations;
+
+/**
+ * Default implementation of immutable Interface description.
+ */
+public class DefaultInterfaceDescription extends AbstractDescription
+ implements InterfaceDescription {
+
+ private final InterfaceIdentifier intfId;
+ private final Ip4Address ipv4Address;
+ private final Ip6Address ipv6Address;
+
+
+
+ /**
+ * Creates an interface description using the supplied information.
+ *
+ * @param intfId interface identifier
+ * @param ipv4Address ipv4 address of an interface
+ * @param ipv6Address ipv6 address of an interface
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultInterfaceDescription(InterfaceIdentifier intfId, Ip4Address ipv4Address,
+ Ip6Address ipv6Address, SparseAnnotations...annotations) {
+ super(annotations);
+ this.intfId = intfId;
+ this.ipv4Address = ipv4Address;
+ this.ipv6Address = ipv6Address;
+ }
+
+ /**
+ * Default constructor for serialization.
+ */
+ private DefaultInterfaceDescription() {
+ this.intfId = null;
+ this.ipv4Address = null;
+ this.ipv6Address = null;
+ }
+
+ /**
+ * Creates an interface description using the supplied information.
+ *
+ * @param base InterfaceDescription to get basic information from
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultInterfaceDescription(InterfaceDescription base,
+ SparseAnnotations annotations) {
+ this(base.intfId(), base.ipv4Address(), base.ipv6Address(), annotations);
+ }
+
+ @Override
+ public InterfaceIdentifier intfId() {
+ return intfId;
+ }
+
+ @Override
+ public Ip4Address ipv4Address() {
+ return ipv4Address;
+ }
+
+ @Override
+ public Ip6Address ipv6Address() {
+ return ipv6Address; }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("intfId", intfId)
+ .add("ipv4Address", ipv4Address)
+ .add("ipv6Address", ipv6Address)
+ .add("annotations", annotations())
+ .toString();
+ }
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultIpDeviceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultIpDeviceDescription.java
new file mode 100644
index 00000000..889e48a7
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultIpDeviceDescription.java
@@ -0,0 +1,117 @@
+/*
+ * 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.iptopology.api.device;
+
+import org.onosproject.iptopology.api.DeviceTed;
+import org.onosproject.iptopology.api.IpDeviceIdentifier;
+import org.onosproject.net.AbstractDescription;
+import org.onosproject.net.SparseAnnotations;
+
+import java.net.URI;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.iptopology.api.IpDevice.Type;
+
+/**
+ * Default implementation of immutable device description entity.
+ */
+public class DefaultIpDeviceDescription extends AbstractDescription
+ implements IpDeviceDescription {
+ private final URI uri;
+ private final Type type;
+ private final IpDeviceIdentifier deviceIdentifier;
+ private final DeviceTed deviceTed;
+
+ /**
+ * Creates an ip device description using the supplied information.
+ *
+ * @param uri device URI
+ * @param type device type
+ * @param deviceIdentifier device manufacturer
+ * @param deviceTed device Traffic Engineering parameters
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultIpDeviceDescription(URI uri, Type type, IpDeviceIdentifier deviceIdentifier,
+ DeviceTed deviceTed, SparseAnnotations... annotations) {
+ super(annotations);
+ this.uri = checkNotNull(uri, "Device URI cannot be null");
+ this.type = checkNotNull(type, "Device type cannot be null");
+ this.deviceIdentifier = deviceIdentifier;
+ this.deviceTed = deviceTed;
+ }
+
+ /**
+ * Creates an ip device description using the supplied information.
+ * @param base IpDeviceDescription to basic information
+ * @param annotations Annotations to use.
+ */
+ public DefaultIpDeviceDescription(IpDeviceDescription base, SparseAnnotations... annotations) {
+ this(base.deviceURI(), base.type(), base.deviceIdentifier(),
+ base.deviceTed(), annotations);
+ }
+
+ /**
+ * Creates an ip device description using the supplied information.
+ * @param base IpDeviceDescription to basic information (except for type)
+ * @param type device type
+ * @param annotations Annotations to use.
+ */
+ public DefaultIpDeviceDescription(IpDeviceDescription base, Type type, SparseAnnotations... annotations) {
+ this(base.deviceURI(), type, base.deviceIdentifier(),
+ base.deviceTed(), annotations);
+ }
+
+ @Override
+ public URI deviceURI() {
+ return uri;
+ }
+
+ @Override
+ public Type type() {
+ return type;
+ }
+
+ @Override
+ public IpDeviceIdentifier deviceIdentifier() {
+ return deviceIdentifier;
+ }
+
+ @Override
+ public DeviceTed deviceTed() {
+ return deviceTed;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("uri", uri)
+ .add("type", type)
+ .add("devid", deviceIdentifier)
+ .add("devTed", deviceTed)
+ .toString();
+ }
+
+ /**
+ * Default constructor for serialization.
+ */
+ private DefaultIpDeviceDescription() {
+ this.uri = null;
+ this.type = null;
+ this.deviceIdentifier = null;
+ this.deviceTed = null;
+ }
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultPrefixDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultPrefixDescription.java
new file mode 100644
index 00000000..36cc14a6
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultPrefixDescription.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.iptopology.api.PrefixIdentifier;
+import org.onosproject.iptopology.api.PrefixTed;
+import org.onosproject.net.AbstractDescription;
+import org.onosproject.net.SparseAnnotations;
+
+/**
+ * Default implementation of immutable Prefix description.
+ */
+public class DefaultPrefixDescription extends AbstractDescription
+ implements PrefixDescription {
+
+ private final PrefixIdentifier prefixIdentifier;
+ private final PrefixTed prefixTed;
+
+
+ /**
+ * Creates prefix description using the supplied information.
+ *
+ * @param prefixIdentifier prefix identifier
+ * @param prefixTed prefix traffic engineering parameters
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultPrefixDescription(PrefixIdentifier prefixIdentifier, PrefixTed prefixTed,
+ SparseAnnotations...annotations) {
+ super(annotations);
+ this.prefixIdentifier = prefixIdentifier;
+ this.prefixTed = prefixTed;
+ }
+
+ /**
+ * Default constructor for serialization.
+ */
+ private DefaultPrefixDescription() {
+ this.prefixIdentifier = null;
+ this.prefixTed = null;
+ }
+
+ /**
+ * Creates prefix description using the supplied information.
+ *
+ * @param base PrefixDescription to get basic information from
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultPrefixDescription(PrefixDescription base,
+ SparseAnnotations annotations) {
+ this(base.prefixIdentifier(), base.prefixTed(), annotations);
+ }
+
+ @Override
+ public PrefixIdentifier prefixIdentifier() {
+ return prefixIdentifier;
+ }
+
+ @Override
+ public PrefixTed prefixTed() {
+ return prefixTed;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("prefixIdentifier", prefixIdentifier)
+ .add("prefixTed", prefixTed)
+ .add("annotations", annotations())
+ .toString();
+ }
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/InterfaceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/InterfaceDescription.java
new file mode 100644
index 00000000..6e7804d9
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/InterfaceDescription.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onosproject.iptopology.api.InterfaceIdentifier;
+import org.onosproject.net.Description;
+
+
+/**
+ * Information about an interface.
+ */
+public interface InterfaceDescription extends Description {
+
+ /**
+ * Returns the IPv4 Address of an interface.
+ *
+ * @return ipv4 address
+ */
+ Ip4Address ipv4Address();
+
+ /**
+ * Returns the IPv6 Address of an interface.
+ *
+ * @return ipv6 address
+ */
+ Ip6Address ipv6Address();
+
+
+ /**
+ * Returns the interface id of the interface.
+ *
+ * @return interface identifier
+ */
+ InterfaceIdentifier intfId();
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceDescription.java
new file mode 100644
index 00000000..c0a4391d
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceDescription.java
@@ -0,0 +1,61 @@
+/*
+ * 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.iptopology.api.device;
+
+import org.onosproject.iptopology.api.DeviceTed;
+import org.onosproject.iptopology.api.IpDevice;
+import org.onosproject.iptopology.api.IpDeviceIdentifier;
+import org.onosproject.net.Description;
+
+
+import java.net.URI;
+
+/**
+ * Carrier of immutable information about an ip device.
+ */
+public interface IpDeviceDescription extends Description {
+
+ /**
+ * Protocol/provider specific URI that can be used to encode the identity
+ * information required to communicate with the ip device externally, e.g.
+ * datapath ID.
+ *
+ * @return provider specific URI for the ip device
+ */
+ URI deviceURI();
+
+ /**
+ * Returns the type of the ip device. For ex: Psuedo or actual
+ *
+ * @return type of the device
+ */
+ IpDevice.Type type();
+
+ /**
+ * Returns the device identifier details.
+ *
+ * @return identifier of the device
+ */
+ IpDeviceIdentifier deviceIdentifier();
+
+ /**
+ * Returns the traffic engineering parameters of the device.
+ *
+ * @return traffic engineering parameters of the device
+ */
+ DeviceTed deviceTed();
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceEvent.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceEvent.java
new file mode 100644
index 00000000..07f263e4
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceEvent.java
@@ -0,0 +1,183 @@
+/*
+ * 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.iptopology.api.device;
+
+import org.joda.time.LocalDateTime;
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.iptopology.api.DeviceIntf;
+import org.onosproject.iptopology.api.DevicePrefix;
+import org.onosproject.iptopology.api.IpDevice;
+
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Describes ip device event.
+ */
+public class IpDeviceEvent extends AbstractEvent<IpDeviceEvent.Type, IpDevice> {
+
+ private final DeviceIntf devInterface;
+ private final DevicePrefix devicePrefix;
+
+ /**
+ * Type of device events.
+ */
+ public enum Type {
+ /**
+ * Signifies that a new device has been detected.
+ */
+ DEVICE_ADDED,
+
+ /**
+ * Signifies that some device attributes have changed; excludes
+ * availability changes.
+ */
+ DEVICE_UPDATED,
+
+ /**
+ * Signifies that a device has been removed.
+ */
+ DEVICE_REMOVED,
+
+ /**
+ * Signifies that an interface has been added.
+ */
+ INTERFACE_ADDED,
+
+ /**
+ * Signifies that an interface has been updated.
+ */
+ INTERFACE_UPDATED,
+
+ /**
+ * Signifies that an interface has been removed.
+ */
+ INTERFACE_REMOVED,
+
+ /**
+ * Signifies that a prefix has been added.
+ */
+ PREFIX_ADDED,
+
+ /**
+ * Signifies that a prefix has been updated.
+ */
+ PREFIX_UPDATED,
+
+ /**
+ * Signifies that a prefix has been removed.
+ */
+ PREFIX_REMOVED,
+
+ }
+
+ /**
+ * Creates an event of a given type and for the specified ip device.
+ *
+ * @param type device event type
+ * @param device event device subject
+ */
+ public IpDeviceEvent(Type type, IpDevice device) {
+ this(type, device, null, null);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified device and interface.
+ *
+ * @param type device event type
+ * @param device event device subject
+ * @param devInterface optional interface subject
+ */
+ public IpDeviceEvent(Type type, IpDevice device, DeviceIntf devInterface) {
+ this(type, device, devInterface, null);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified device and interface.
+ *
+ * @param type device event type
+ * @param device event device subject
+ * @param devicePrefix optional prefix subject
+ */
+ public IpDeviceEvent(Type type, IpDevice device, DevicePrefix devicePrefix) {
+ this(type, device, null, devicePrefix);
+ }
+
+
+ /**
+ * Creates an event of a given type and for the specified device, interface and prefix.
+ *
+ * @param type device event type
+ * @param device event device subject
+ * @param devInterface optional interface subject
+ * @param devicePrefix optional prefix subject
+ */
+ public IpDeviceEvent(Type type, IpDevice device, DeviceIntf devInterface, DevicePrefix devicePrefix) {
+ super(type, device);
+ this.devInterface = devInterface;
+ this.devicePrefix = devicePrefix;
+ }
+
+
+ /**
+ * Creates an event of a given type and for the specified device, interface and time.
+ *
+ * @param type device event type
+ * @param device event device subject
+ * @param devInterface optional interface subject
+ * @param devicePrefix optional prefix subject
+ * @param time occurrence time
+ */
+
+ public IpDeviceEvent(Type type, IpDevice device, DeviceIntf devInterface, DevicePrefix devicePrefix, long time) {
+ super(type, device, time);
+ this.devInterface = devInterface;
+ this.devicePrefix = devicePrefix;
+ }
+
+
+ /**
+ * Returns the interface subject.
+ *
+ * @return interface subject or null if the event is not interface specific.
+ */
+ public DeviceIntf deviceInterface() {
+ return devInterface;
+ }
+
+ /**
+ * Returns the prefix subject.
+ *
+ * @return prefix subject or null if the event is not prefix specific.
+ */
+ public DevicePrefix prefix() {
+ return devicePrefix;
+ }
+
+ @Override
+ public String toString() {
+ if (devInterface == null || devicePrefix == null) {
+ return super.toString();
+ }
+ return toStringHelper(this)
+ .add("time", new LocalDateTime(time()))
+ .add("type", type())
+ .add("subject", subject())
+ .add("interface", devInterface)
+ .add("prefix", devicePrefix)
+ .toString();
+ }
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceListener.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceListener.java
new file mode 100644
index 00000000..cd40c405
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceListener.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of receiving ip device related events.
+ */
+public interface IpDeviceListener extends EventListener<IpDeviceEvent> {
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProvider.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProvider.java
new file mode 100644
index 00000000..67502eb6
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProvider.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import org.onosproject.net.provider.Provider;
+
+/**
+ * Abstraction of a ip device information provider.
+ */
+public interface IpDeviceProvider extends Provider {
+ // Currently there is none to set some information into the network
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderRegistry.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderRegistry.java
new file mode 100644
index 00000000..74b27415
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderRegistry.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import org.onosproject.net.provider.ProviderRegistry;
+
+/**
+ * Abstraction of a ip device provider registry.
+ */
+public interface IpDeviceProviderRegistry
+ extends ProviderRegistry<IpDeviceProvider, IpDeviceProviderService> {
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderService.java
new file mode 100644
index 00000000..f84b8b74
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderService.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.iptopology.api.device;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderService;
+
+import java.util.List;
+
+/**
+ * Service through which ip device providers can inject ip device information into
+ * the core.
+ */
+public interface IpDeviceProviderService extends ProviderService<IpDeviceProvider> {
+
+ /**
+ * Signals the core that an ip device is added or updated with IP topology information.
+ *
+ * @param deviceId device identifier
+ * @param deviceDescription information about network ip device
+ */
+ void addOrUpdateIpDevice(DeviceId deviceId, IpDeviceDescription deviceDescription);
+
+ /**
+ * Signals the core that an ip device is removed.
+ *
+ * @param deviceId identity of the ip device to be removed
+ */
+ void removeIpDevice(DeviceId deviceId);
+
+ /**
+ * Sends information about all interfaces of a device. It is up to the core to
+ * determine what has changed.
+ *
+ * @param deviceId identity of the ip device
+ * @param interfaceDescriptions list of device interfaces
+ */
+ void updateInterfaces(DeviceId deviceId, List<InterfaceDescription> interfaceDescriptions);
+
+ /**
+ * signals interfaces of a device is deleted.
+ *
+ * @param deviceId identity of the ip device
+ * @param interfaceDescriptions list of device interfaces
+ */
+ void removeInterfaces(DeviceId deviceId, List<InterfaceDescription> interfaceDescriptions);
+
+ /**
+ * Sends information about all ip prefix of a device. It is up to the core to
+ * determine what has changed.
+ *
+ * @param deviceId identity of the ip device
+ * @param prefixDescriptions list of device ip prefixes
+ */
+ void updatePrefixes(DeviceId deviceId, List<PrefixDescription> prefixDescriptions);
+
+ /**
+ * signals ip prefix of a device is deleted.
+ *
+ * @param deviceId identity of the ip device
+ * @param prefixDescriptions list of device ip prefixes
+ */
+ void removePrefixes(DeviceId deviceId, List<PrefixDescription> prefixDescriptions);
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceService.java
new file mode 100644
index 00000000..4b126eb3
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceService.java
@@ -0,0 +1,111 @@
+/*
+ * 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.iptopology.api.device;
+
+import org.onosproject.event.ListenerService;
+import org.onosproject.iptopology.api.DeviceIntf;
+import org.onosproject.iptopology.api.DevicePrefix;
+import org.onosproject.iptopology.api.InterfaceIdentifier;
+import org.onosproject.iptopology.api.IpDevice;
+import org.onosproject.net.DeviceId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+
+import java.util.List;
+
+/**
+ * Service for interacting with the inventory of ip devices.
+ */
+public interface IpDeviceService
+ extends ListenerService<IpDeviceEvent, IpDeviceListener> {
+
+ /**
+ * Returns the number of ip devices known to the system.
+ *
+ * @return number of infrastructure devices
+ */
+ int getIpDeviceCount();
+
+ /**
+ * Returns a collection of the currently known ip
+ * devices.
+ *
+ * @return collection of devices
+ */
+ Iterable<IpDevice> getIpDevices();
+
+ /**
+ * Returns a collection of the currently known ip
+ * devices by device type.
+ *
+ * @param type device type
+ * @return collection of devices
+ */
+ Iterable<IpDevice> getIpDevices(IpDevice.Type type);
+
+
+ /**
+ * Returns the ip device with the specified identifier.
+ *
+ * @param deviceId device identifier
+ * @return device or null if one with the given identifier is not known
+ */
+ IpDevice getIpDevice(DeviceId deviceId);
+
+ /**
+ * Returns the list of interfaces associated with the device.
+ *
+ * @param deviceId device identifier
+ * @return list of device interfaces
+ */
+ List<DeviceIntf> getInterfaces(DeviceId deviceId);
+
+ /**
+ * Returns the interface with the specified ipv4 address and hosted by the given device.
+ *
+ * @param deviceId device identifier
+ * @param ipv4Address ipv4 address
+ * @return device interface
+ */
+ DeviceIntf getInterface(DeviceId deviceId, Ip4Address ipv4Address);
+
+ /**
+ * Returns the interface with the specified ipv6 address and hosted by the given device.
+ *
+ * @param deviceId device identifier
+ * @param ipv6Address ipv6 address
+ * @return device interface
+ */
+ DeviceIntf getInterface(DeviceId deviceId, Ip6Address ipv6Address);
+
+ /**
+ * Returns the interface with the specified interface id and hosted by the given device.
+ *
+ * @param deviceId device identifier
+ * @param intfId interface id
+ * @return device interface
+ */
+ DeviceIntf getInterface(DeviceId deviceId, InterfaceIdentifier intfId);
+
+ /**
+ * Returns the list of ip prefix associated with the device.
+ *
+ * @param deviceId device identifier
+ * @return list of device prefixes
+ */
+ List<DevicePrefix> getPrefixes(DeviceId deviceId);
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStore.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStore.java
new file mode 100644
index 00000000..db1dd429
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStore.java
@@ -0,0 +1,164 @@
+/*
+ * 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.iptopology.api.device;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onosproject.iptopology.api.DevicePrefix;
+import org.onosproject.iptopology.api.InterfaceIdentifier;
+import org.onosproject.iptopology.api.IpDevice;
+import org.onosproject.iptopology.api.DeviceIntf;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.Store;
+
+import java.util.List;
+
+/**
+ * Manages inventory of ip devices; not intended for direct use.
+ */
+public interface IpDeviceStore extends Store<IpDeviceEvent, IpDeviceStoreDelegate> {
+
+ /**
+ * Returns the number of ip devices known to the system.
+ *
+ * @return number of ip devices
+ */
+ int getIpDeviceCount();
+
+ /**
+ * Returns an iterable collection of all ip devices known to the system.
+ *
+ * @return ip device collection
+ */
+ Iterable<IpDevice> getIpDevices();
+
+
+ /**
+ * Returns an ip device with the specified identifier.
+ *
+ * @param deviceId device identifier
+ * @return ip device
+ */
+ IpDevice getIpDevice(DeviceId deviceId);
+
+ /**
+ * Creates a new infrastructure ip device, or updates an existing one using
+ * the supplied device description.
+ *
+ * @param providerId provider identifier
+ * @param deviceId device identifier
+ * @param deviceDescription device description
+ * @return ready to send event describing what occurred; null if no change
+ */
+ IpDeviceEvent createOrUpdateIpDevice(ProviderId providerId, DeviceId deviceId,
+ IpDeviceDescription deviceDescription);
+
+ /**
+ * Administratively removes the specified ip device from the store.
+ *
+ * @param deviceId device to be removed
+ * @return null if no such ip device
+ */
+ IpDeviceEvent removeIpDevice(DeviceId deviceId);
+
+ /**
+ * Updates the interface of the specified ip device using the given
+ * list of interface descriptions. The list is assumed to be comprehensive.
+ *
+ * @param providerId provider identifier
+ * @param deviceId ip device identifier
+ * @param interfaceDescriptions list of interface descriptions
+ * @return ready to send events describing what occurred; empty list if no change
+ */
+ List<IpDeviceEvent> updateInterfaces(ProviderId providerId, DeviceId deviceId,
+ List<InterfaceDescription> interfaceDescriptions);
+
+ /**
+ * Administratively removes the specified interface from the store.
+ *
+ * @param deviceId device of the interfaces to be removed
+ * @param interfaceDescriptions list of interface descriptions
+ * @return ready to send events describing what occurred.
+ */
+ List<IpDeviceEvent> removeInterfaces(DeviceId deviceId, List<InterfaceDescription> interfaceDescriptions);
+
+ /**
+ * Returns the list of interfaces that belong to the specified device.
+ *
+ * @param deviceId device identifier
+ * @return list of device interfaces
+ */
+ List<DeviceIntf> getInterfaces(DeviceId deviceId);
+
+ /**
+ * Returns the specified device interface.
+ *
+ * @param deviceId device identifier
+ * @param ipv4Address ipv4 address of the interface
+ * @return device interface
+ */
+ DeviceIntf getInterface(DeviceId deviceId, Ip4Address ipv4Address);
+
+ /**
+ * Returns the specified device interface.
+ *
+ * @param deviceId device identifier
+ * @param ipv6Address ipv6 address of the interface
+ * @return device interface
+ */
+ DeviceIntf getInterface(DeviceId deviceId, Ip6Address ipv6Address);
+
+ /**
+ * Returns the specified device interface.
+ *
+ * @param deviceId device identifier
+ * @param intfId interface identifier of the interface
+ * @return device interface
+ */
+ DeviceIntf getInterface(DeviceId deviceId, InterfaceIdentifier intfId);
+
+ /**
+ * Updates the prefix information of the specified ip device using the given
+ * list of prefix descriptions. The list is assumed to be comprehensive.
+ *
+ * @param providerId provider identifier
+ * @param deviceId ip device identifier
+ * @param prefixDescriptions list of prefix descriptions
+ * @return ready to send events describing what occurred; empty list if no change
+ */
+ List<IpDeviceEvent> updatePrefixes(ProviderId providerId, DeviceId deviceId,
+ List<PrefixDescription> prefixDescriptions);
+
+ /**
+ * Administratively removes the specified prefix from the store.
+ *
+ * @param deviceId device of the prefix to be removed
+ * @param prefixDescriptions list of prefix descriptions
+ * @return ready to send events describing what occurred.
+ */
+ List<IpDeviceEvent> removePrefixes(DeviceId deviceId, List<PrefixDescription> prefixDescriptions);
+
+ /**
+ * Returns the list of prefixes that belong to the specified device.
+ *
+ * @param deviceId device identifier
+ * @return list of device prefixes
+ */
+ List<DevicePrefix> getPrefixes(DeviceId deviceId);
+
+}
+
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStoreDelegate.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStoreDelegate.java
new file mode 100644
index 00000000..14efe064
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStoreDelegate.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Infrastructure ip topology store delegate abstraction.
+ */
+public interface IpDeviceStoreDelegate extends StoreDelegate<IpDeviceEvent> {
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/PrefixDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/PrefixDescription.java
new file mode 100644
index 00000000..eb1ece33
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/PrefixDescription.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.device;
+
+import org.onosproject.iptopology.api.PrefixIdentifier;
+import org.onosproject.iptopology.api.PrefixTed;
+import org.onosproject.net.Description;
+
+/**
+ * Information about a prefix.
+ */
+public interface PrefixDescription extends Description {
+
+ /**
+ * Returns the prefix identifier.
+ *
+ * @return prefix identifier
+ */
+ PrefixIdentifier prefixIdentifier();
+
+ /**
+ * Returns the prefix Traffic Engineering parameters.
+ *
+ * @return prefix Traffic Engineering parameters
+ */
+ PrefixTed prefixTed();
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/package-info.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/package-info.java
new file mode 100644
index 00000000..5e4e29b1
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Ip device model &amp; related services API definitions.
+ */
+package org.onosproject.iptopology.api.device;
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/DefaultIpLinkDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/DefaultIpLinkDescription.java
new file mode 100644
index 00000000..4a3b46d2
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/DefaultIpLinkDescription.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.iptopology.api.IpLinkIdentifier;
+import org.onosproject.iptopology.api.LinkTed;
+import org.onosproject.iptopology.api.TerminationPoint;
+import org.onosproject.net.AbstractDescription;
+import org.onosproject.net.SparseAnnotations;
+
+/**
+ * Default implementation of immutable ip link description entity.
+ */
+public class DefaultIpLinkDescription extends AbstractDescription
+ implements IpLinkDescription {
+
+ private final TerminationPoint src;
+ private final TerminationPoint dst;
+ private final IpLinkIdentifier linkIdentifier;
+ private final LinkTed linkTed;
+
+ /**
+ * Creates an ip link description using the supplied information.
+ *
+ * @param src link source
+ * @param dst link destination
+ * @param linkIdentifier link identifier
+ * @param linkTed link traffic engineering parameters
+ * @param annotations optional key/value annotations
+ */
+ public DefaultIpLinkDescription(TerminationPoint src, TerminationPoint dst,
+ IpLinkIdentifier linkIdentifier, LinkTed linkTed,
+ SparseAnnotations... annotations) {
+ super(annotations);
+ this.src = src;
+ this.dst = dst;
+ this.linkIdentifier = linkIdentifier;
+ this.linkTed = linkTed;
+ }
+
+ /**
+ * Creates an ip link description using the supplied information.
+ *
+ * @param base IpLinkDescription to basic information
+ * @param annotations optional key/value annotations
+ */
+ public DefaultIpLinkDescription(IpLinkDescription base, SparseAnnotations... annotations) {
+ this(base.src(), base.dst(), base.linkIdentifier(),
+ base.linkTed(), annotations);
+ }
+
+ @Override
+ public TerminationPoint src() {
+ return src;
+ }
+
+ @Override
+ public TerminationPoint dst() {
+ return dst;
+ }
+
+ @Override
+ public IpLinkIdentifier linkIdentifier() {
+ return linkIdentifier;
+ }
+
+ @Override
+ public LinkTed linkTed() {
+ return linkTed; }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("src", src())
+ .add("dst", dst())
+ .add("linkIdentifier", linkIdentifier())
+ .add("linkTed", linkTed())
+ .toString();
+ }
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkDescription.java
new file mode 100644
index 00000000..258e7444
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkDescription.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import org.onosproject.iptopology.api.IpLinkIdentifier;
+import org.onosproject.iptopology.api.LinkTed;
+import org.onosproject.iptopology.api.TerminationPoint;
+import org.onosproject.net.Description;
+
+/**
+ * Describes an ip link.
+ */
+public interface IpLinkDescription extends Description {
+
+ /**
+ * Returns the link source.
+ *
+ * @return links source
+ */
+ TerminationPoint src();
+
+ /**
+ * Returns the link destination.
+ *
+ * @return links destination
+ */
+ TerminationPoint dst();
+
+ /**
+ * Returns the link identifier.
+ *
+ * @return links identifier informations
+ */
+ IpLinkIdentifier linkIdentifier();
+
+ /**
+ * Returns the link traffic engineering parameters.
+ *
+ * @return links traffic engineering parameters
+ */
+ LinkTed linkTed();
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkEvent.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkEvent.java
new file mode 100644
index 00000000..4050734a
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkEvent.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.iptopology.api.IpLink;
+
+/**
+ * Describes ip link event.
+ */
+public class IpLinkEvent extends AbstractEvent<IpLinkEvent.Type, IpLink> {
+
+ /**
+ * Type of link events.
+ */
+ public enum Type {
+ /**
+ * Signifies that a new ip link has been detected.
+ */
+ LINK_ADDED,
+
+ /**
+ * Signifies that an ip link has been updated or changed state.
+ */
+ LINK_UPDATED,
+
+ /**
+ * Signifies that an ip link has been removed.
+ */
+ LINK_REMOVED
+ }
+
+ /**
+ * Creates an event of a given type and for the specified ip link and the
+ * current time.
+ *
+ * @param type link event type
+ * @param link event link subject
+ */
+ public IpLinkEvent(Type type, IpLink link) {
+ super(type, link);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified ip link and time.
+ *
+ * @param type link event type
+ * @param link event link subject
+ * @param time occurrence time
+ */
+ public IpLinkEvent(Type type, IpLink link, long time) {
+ super(type, link, time);
+ }
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkListener.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkListener.java
new file mode 100644
index 00000000..5acb73aa
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkListener.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of receiving ip link related events.
+ */
+public interface IpLinkListener extends EventListener<IpLinkEvent> {
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProvider.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProvider.java
new file mode 100644
index 00000000..a58bf610
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProvider.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import org.onosproject.net.provider.Provider;
+
+/**
+ * Abstraction of an entity providing information about ip links
+ * to the core.
+ */
+public interface IpLinkProvider extends Provider {
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderRegistry.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderRegistry.java
new file mode 100644
index 00000000..e060ae68
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderRegistry.java
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import org.onosproject.net.provider.ProviderRegistry;
+
+/**
+ * Abstraction of an ip link provider registry.
+ */
+public interface IpLinkProviderRegistry
+ extends ProviderRegistry<IpLinkProvider, IpLinkProviderService> {
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderService.java
new file mode 100644
index 00000000..c2554425
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderService.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+
+import org.onosproject.iptopology.api.TerminationPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderService;
+
+/**
+ * Means for injecting ip link information into the core.
+ */
+public interface IpLinkProviderService extends ProviderService<IpLinkProvider> {
+
+ /**
+ * Signals that an ip link is added or updated with IP topology information.
+ *
+ * @param linkDescription ip link information
+ */
+ void addOrUpdateIpLink(IpLinkDescription linkDescription);
+
+ /**
+ * Signals that an ip link has disappeared.
+ *
+ * @param linkDescription ip link information
+ */
+ void removeIpLink(IpLinkDescription linkDescription);
+
+ /**
+ * Signals that ip links associated with the specified
+ * termination point have vanished.
+ *
+ * @param terminationPoint termination point
+ */
+ void removeIpLink(TerminationPoint terminationPoint);
+
+ /**
+ * Signals that ip links associated with the specified
+ * device have vanished.
+ *
+ * @param deviceId device identifier
+ */
+ void removeIpLink(DeviceId deviceId);
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkService.java
new file mode 100644
index 00000000..723e907b
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkService.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import java.util.Set;
+
+import org.onosproject.event.ListenerService;
+import org.onosproject.iptopology.api.IpLink;
+import org.onosproject.iptopology.api.TerminationPoint;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Service for interacting with the inventory of infrastructure links.
+ */
+public interface IpLinkService
+ extends ListenerService<IpLinkEvent, IpLinkListener> {
+
+ /**
+ * Returns the count of all known ip links.
+ *
+ * @return number of ip links
+ */
+ int getIpLinkCount();
+
+ /**
+ * Returns a collection of all ip links.
+ *
+ * @return all ip links
+ */
+ Iterable<IpLink> getIpLinks();
+
+
+ /**
+ * Returns set of all ip links leading to and from the
+ * specified ip device.
+ *
+ * @param deviceId device identifier
+ * @return set of ip device links
+ */
+ Set<IpLink> getIpDeviceLinks(DeviceId deviceId);
+
+ /**
+ * Returns set of all ip links leading from the specified ip device.
+ *
+ * @param deviceId device identifier
+ * @return set of ip device egress links
+ */
+ Set<IpLink> getIpDeviceEgressLinks(DeviceId deviceId);
+
+ /**
+ * Returns set of all ip links leading to the specified ip device.
+ *
+ * @param deviceId device identifier
+ * @return set of ip device ingress links
+ */
+ Set<IpLink> getIpDeviceIngressLinks(DeviceId deviceId);
+
+ /**
+ * Returns set of all ip links leading to and from the
+ * specified termination point.
+ *
+ * @param terminationPoint termination point
+ * @return set of ip links
+ */
+ Set<IpLink> getIpLinks(TerminationPoint terminationPoint);
+
+ /**
+ * Returns set of all ip links leading from the specified
+ * termination point.
+ *
+ * @param terminationPoint termination point
+ * @return set of ip device egress links
+ */
+ Set<IpLink> getEgressIpLinks(TerminationPoint terminationPoint);
+
+ /**
+ * Returns set of all ip links leading to the specified
+ * termination point.
+ *
+ * @param terminationPoint termination point
+ * @return set of ip device ingress links
+ */
+ Set<IpLink> getIngressIpLinks(TerminationPoint terminationPoint);
+
+ /**
+ * Returns the ip links between the specified source
+ * and destination termination points.
+ *
+ * @param src source termination point
+ * @param dst destination termination point
+ * @return ip link from source to destination; null if none found
+ */
+ IpLink getIpLink(TerminationPoint src, TerminationPoint dst);
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStore.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStore.java
new file mode 100644
index 00000000..8f5c60f7
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStore.java
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import org.onosproject.iptopology.api.IpLink;
+import org.onosproject.iptopology.api.TerminationPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.Store;
+
+import java.util.Set;
+
+/**
+ * Manages inventory of ip links; not intended for direct use.
+ */
+public interface IpLinkStore extends Store<IpLinkEvent, IpLinkStoreDelegate> {
+
+ /**
+ * Returns the number of ip links in the store.
+ *
+ * @return number of ip links
+ */
+ int getIpLinkCount();
+
+ /**
+ * Returns an iterable collection of all ip links in the inventory.
+ *
+ * @return collection of all ip links
+ */
+ Iterable<IpLink> getIpLinks();
+
+ /**
+ * Returns all ip links egressing from the specified device.
+ *
+ * @param deviceId device identifier
+ * @return set of ip device links
+ */
+ Set<IpLink> getIpDeviceEgressLinks(DeviceId deviceId);
+
+ /**
+ * Returns all ip links ingressing from the specified device.
+ *
+ * @param deviceId device identifier
+ * @return set of ip device links
+ */
+ Set<IpLink> getIpDeviceIngressLinks(DeviceId deviceId);
+
+ /**
+ * Returns the ip link between the two termination points.
+ *
+ * @param src source termination point
+ * @param dst destination termination point
+ * @return ip link or null if one not found between the termination points
+ */
+ IpLink getIpLink(TerminationPoint src, TerminationPoint dst);
+
+ /**
+ * Returns all ip links egressing from the specified termination point.
+ *
+ * @param src source termination point
+ * @return set of termination point ip links
+ */
+ Set<IpLink> getEgressIpLinks(TerminationPoint src);
+
+ /**
+ * Returns all ip links ingressing to the specified termination point.
+ *
+ * @param dst destination termination point
+ * @return set of termination point ip links
+ */
+ Set<IpLink> getIngressIpLinks(TerminationPoint dst);
+
+ /**
+ * Creates a new ip link, or updates an existing one, based on the given
+ * information.
+ *
+ * @param providerId provider identity
+ * @param linkDescription ip link description
+ * @return create or update ip link event, or null if no change resulted
+ */
+ IpLinkEvent createOrUpdateIpLink(ProviderId providerId,
+ IpLinkDescription linkDescription);
+
+ /**
+ * Removes ip link, based on the specified information.
+ *
+ * @param src ip link source
+ * @param dst ip link destination
+ * @return remove or update ip link event, or null if no change resulted
+ */
+ IpLinkEvent removeOrDownIpLink(TerminationPoint src, TerminationPoint dst);
+
+ /**
+ * Removes ip link based on the specified information.
+ *
+ * @param src ip link source
+ * @param dst ip link destination
+ * @return remove ip link event, or null if no change resulted
+ */
+ IpLinkEvent removeIpLink(TerminationPoint src, TerminationPoint dst);
+
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStoreDelegate.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStoreDelegate.java
new file mode 100644
index 00000000..9397a499
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStoreDelegate.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+package org.onosproject.iptopology.api.link;
+
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Ip link store delegate abstraction.
+ */
+public interface IpLinkStoreDelegate extends StoreDelegate<IpLinkEvent> {
+}
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/package-info.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/package-info.java
new file mode 100644
index 00000000..581c2367
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Ip link model &amp; related services API definitions.
+ */
+package org.onosproject.iptopology.api.link;
diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/package-info.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/package-info.java
new file mode 100644
index 00000000..e1133554
--- /dev/null
+++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/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.
+ */
+
+/**
+ * Ip Topology API.
+ */
+package org.onosproject.iptopology.api;
diff --git a/framework/src/onos/apps/openstackswitching/app/features.xml b/framework/src/onos/apps/openstackswitching/app/features.xml
index acb07b62..a13c2aaf 100644
--- a/framework/src/onos/apps/openstackswitching/app/features.xml
+++ b/framework/src/onos/apps/openstackswitching/app/features.xml
@@ -15,7 +15,6 @@
~ 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>
diff --git a/framework/src/onos/apps/openstackswitching/app/pom.xml b/framework/src/onos/apps/openstackswitching/app/pom.xml
index 5460faef..7d26f8f2 100644
--- a/framework/src/onos/apps/openstackswitching/app/pom.xml
+++ b/framework/src/onos/apps/openstackswitching/app/pom.xml
@@ -31,7 +31,6 @@
<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>
diff --git a/framework/src/onos/apps/pathpainter/pom.xml b/framework/src/onos/apps/pathpainter/pom.xml
new file mode 100644
index 00000000..c14294c8
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/pom.xml
@@ -0,0 +1,38 @@
+<?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>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-apps</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-app-pp</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>Path visualization application</description>
+
+ <properties>
+ <onos.app.name>org.onosproject.pathpainter</onos.app.name>
+ </properties>
+
+</project>
diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLink.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLink.java
new file mode 100644
index 00000000..57241705
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLink.java
@@ -0,0 +1,51 @@
+/*
+ * 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.pathpainter;
+
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.ui.topo.BiLink;
+import org.onosproject.ui.topo.LinkHighlight;
+import org.onosproject.ui.topo.LinkHighlight.Flavor;
+
+import java.util.Set;
+
+/**
+ * Bi-directional link capable of different hilights.
+ */
+public class PathLink extends BiLink {
+
+ private boolean primary = false;
+ private boolean secondary = false;
+
+ public PathLink(LinkKey key, Link link) {
+ super(key, link);
+ }
+
+ public void computeHilight(Set<Link> selectedLinks, Set<Link> allLinks) {
+ primary = selectedLinks.contains(this.one()) ||
+ (two() != null && selectedLinks.contains(two()));
+ secondary = allLinks.contains(this.one()) ||
+ (two() != null && allLinks.contains(two()));
+ }
+
+ @Override
+ public LinkHighlight highlight(Enum<?> anEnum) {
+ Flavor flavor = primary ? Flavor.PRIMARY_HIGHLIGHT :
+ (secondary ? Flavor.SECONDARY_HIGHLIGHT : Flavor.NO_HIGHLIGHT);
+ return new LinkHighlight(this.linkId(), flavor);
+ }
+}
diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLinkMap.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLinkMap.java
new file mode 100644
index 00000000..9f2ea216
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLinkMap.java
@@ -0,0 +1,30 @@
+/*
+ * 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.pathpainter;
+
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.ui.topo.BiLinkMap;
+
+/**
+ * Our concrete link map.
+ */
+public class PathLinkMap extends BiLinkMap<PathLink> {
+ @Override
+ protected PathLink create(LinkKey linkKey, Link link) {
+ return new PathLink(linkKey, link);
+ }
+}
diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainter.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainter.java
new file mode 100644
index 00000000..07ce3fe8
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainter.java
@@ -0,0 +1,86 @@
+/*
+ * 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.pathpainter;
+
+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;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.ui.UiExtension;
+import org.onosproject.ui.UiExtensionService;
+import org.onosproject.ui.UiMessageHandlerFactory;
+import org.onosproject.ui.UiTopoOverlayFactory;
+import org.onosproject.ui.UiView;
+import org.onosproject.ui.UiViewHidden;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+/**
+ * Skeletal ONOS UI Topology-Overlay application component.
+ */
+@Component(immediate = true)
+public class PathPainter {
+
+ private static final ClassLoader CL = PathPainter.class.getClassLoader();
+ private static final String VIEW_ID = "ppTopov";
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected UiExtensionService uiExtensionService;
+
+ // List of application views
+ private final List<UiView> uiViews = ImmutableList.of(
+ new UiViewHidden(VIEW_ID)
+ );
+
+ // Factory for UI message handlers
+ private final UiMessageHandlerFactory messageHandlerFactory =
+ () -> ImmutableList.of(
+ new PathPainterTopovMessageHandler()
+ );
+
+ // Factory for UI topology overlays
+ private final UiTopoOverlayFactory topoOverlayFactory =
+ () -> ImmutableList.of(
+ new PathPainterTopovOverlay()
+ );
+
+ // Application UI extension
+ protected UiExtension extension =
+ new UiExtension.Builder(CL, uiViews)
+ .resourcePath(VIEW_ID)
+ .messageHandlerFactory(messageHandlerFactory)
+ .topoOverlayFactory(topoOverlayFactory)
+ .build();
+
+ @Activate
+ protected void activate() {
+ uiExtensionService.register(extension);
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ uiExtensionService.unregister(extension);
+ log.info("Stopped");
+ }
+
+}
diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java
new file mode 100644
index 00000000..cf395e49
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java
@@ -0,0 +1,388 @@
+/*
+ * 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.pathpainter;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.ElementId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.topology.GeoDistanceLinkWeight;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyEvent;
+import org.onosproject.net.topology.TopologyListener;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiConnection;
+import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.topo.DeviceHighlight;
+import org.onosproject.ui.topo.Highlights;
+import org.onosproject.ui.topo.HostHighlight;
+import org.onosproject.ui.topo.NodeBadge;
+import org.onosproject.ui.topo.TopoJson;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Skeletal ONOS UI Topology-Overlay message handler.
+ */
+public class PathPainterTopovMessageHandler extends UiMessageHandler {
+
+ private static final String PAINTER_CLEAR = "ppTopovClear";
+ private static final String PAINTER_SET_SRC = "ppTopovSetSrc";
+ private static final String PAINTER_SET_DST = "ppTopovSetDst";
+ private static final String PAINTER_SWAP_SRC_DST = "ppTopovSwapSrcDst";
+ private static final String PAINTER_SET_MODE = "ppTopovSetMode";
+
+ private static final String PAINTER_NEXT_PATH = "ppTopovNextPath";
+ private static final String PAINTER_PREV_PATH = "ppTopovPrevPath";
+
+ private static final String ID = "id";
+ private static final String MODE = "mode";
+ private static final String TYPE = "type";
+ private static final String SWITCH = "switch";
+ private static final String ENDSTATION = "endstation";
+ public static final String DST = "Dst";
+ public static final String SRC = "Src";
+ private static LinkWeight linkData;
+
+ private final TopologyListener topologyListener = new InternalTopologyListener();
+
+ private Set<Link> allPathLinks;
+ private boolean listenersRemoved;
+
+ private enum Mode {
+ SHORTEST, DISJOINT, GEODATA, SRLG, INVALID
+ }
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private PathService pathService;
+
+ private ElementId src, dst;
+ private String srcType, dstType;
+ private Mode currentMode = Mode.SHORTEST;
+ private List<Path> paths;
+ private int pathIndex;
+
+ protected TopologyService topologyService;
+
+
+ // ===============-=-=-=-=-=-======================-=-=-=-=-=-=-================================
+
+
+ @Override
+ public void init(UiConnection connection, ServiceDirectory directory) {
+ super.init(connection, directory);
+ pathService = directory.get(PathService.class);
+ topologyService = directory.get(TopologyService.class);
+ linkData = new GeoDistanceLinkWeight(directory.get(DeviceService.class));
+ addListeners();
+ }
+
+
+ @Override
+ public void destroy() {
+ removeListeners();
+ super.destroy();
+ }
+
+ @Override
+ protected Collection<RequestHandler> createRequestHandlers() {
+ return ImmutableSet.of(
+ new ClearHandler(),
+ new SetSrcHandler(),
+ new SetDstHandler(),
+ new SwapSrcDstHandler(),
+ new NextPathHandler(),
+ new PrevPathHandler(),
+ new SetModeHandler()
+ );
+ }
+
+ // === -------------------------
+ // === Handler classes
+
+ private final class ClearHandler extends RequestHandler {
+
+ public ClearHandler() {
+ super(PAINTER_CLEAR);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ src = null;
+ dst = null;
+ sendMessage(TopoJson.highlightsMessage(new Highlights()));
+ }
+ }
+
+ private final class SetSrcHandler extends RequestHandler {
+
+ public SetSrcHandler() {
+ super(PAINTER_SET_SRC);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String id = string(payload, ID);
+ src = elementId(id);
+ srcType = string(payload, TYPE);
+ if (src.equals(dst)) {
+ dst = null;
+ }
+ sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
+ srcType,
+ src.toString(),
+ SRC)));
+ findAndSendPaths(currentMode);
+ }
+ }
+
+ private final class SetDstHandler extends RequestHandler {
+ public SetDstHandler() {
+ super(PAINTER_SET_DST);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String id = string(payload, ID);
+ dst = elementId(id);
+ dstType = string(payload, TYPE);
+ if (src.equals(dst)) {
+ src = null;
+ }
+
+ sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(),
+ dstType,
+ dst.toString(),
+ DST)));
+ findAndSendPaths(currentMode);
+ }
+ }
+
+ private final class SwapSrcDstHandler extends RequestHandler {
+ public SwapSrcDstHandler() {
+ super(PAINTER_SWAP_SRC_DST);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ ElementId temp = src;
+ src = dst;
+ dst = temp;
+ String s = srcType;
+ srcType = dstType;
+ dstType = s;
+ findAndSendPaths(currentMode);
+ }
+ }
+
+
+
+ private final class NextPathHandler extends RequestHandler {
+ public NextPathHandler() {
+ super(PAINTER_NEXT_PATH);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ pathIndex = (pathIndex >= paths.size() - 1 ? 0 : pathIndex + 1);
+ hilightAndSendPaths();
+ }
+ }
+
+ private final class PrevPathHandler extends RequestHandler {
+ public PrevPathHandler() {
+ super(PAINTER_PREV_PATH);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ pathIndex = (pathIndex <= 0 ? paths.size() - 1 : pathIndex - 1);
+ hilightAndSendPaths();
+ }
+ }
+
+ private final class SetModeHandler extends RequestHandler {
+ public SetModeHandler() {
+ super(PAINTER_SET_MODE);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String mode = string(payload, MODE);
+ switch (mode) {
+ case "shortest":
+ currentMode = Mode.SHORTEST;
+ break;
+ case "disjoint":
+ currentMode = Mode.DISJOINT;
+ break;
+ case "geodata":
+ currentMode = Mode.GEODATA;
+ break;
+ case "srlg":
+ currentMode = Mode.SRLG;
+ break;
+ default:
+ currentMode = Mode.INVALID;
+ break;
+ }
+ //TODO: add support for SRLG
+ findAndSendPaths(currentMode);
+ }
+ }
+
+ // === ------------
+
+ private ElementId elementId(String id) {
+ try {
+ return DeviceId.deviceId(id);
+ } catch (IllegalArgumentException e) {
+ return HostId.hostId(id);
+ }
+ }
+
+ private void findAndSendPaths(Mode mode) {
+ log.info("src={}; dst={}; mode={}", src, dst, currentMode);
+ if (src != null && dst != null) {
+ pathIndex = 0;
+ ImmutableSet.Builder<Link> builder = ImmutableSet.builder();
+ if (mode.equals(Mode.SHORTEST)) {
+ paths = ImmutableList.copyOf(pathService.getPaths(src, dst));
+ allPathLinks = buildPaths(builder).build();
+ } else if (mode.equals(Mode.DISJOINT)) {
+ paths = ImmutableList.copyOf(pathService.getDisjointPaths(src, dst));
+ allPathLinks = buildDisjointPaths(builder).build();
+ } else if (mode.equals(Mode.GEODATA)) {
+ paths = ImmutableList.copyOf(pathService.getPaths(src, dst, linkData));
+ allPathLinks = buildPaths(builder).build();
+ } else {
+ log.info("Unsupported MODE");
+ }
+ } else {
+ paths = ImmutableList.of();
+ allPathLinks = ImmutableSet.of();
+ }
+ hilightAndSendPaths();
+
+ }
+
+ private ImmutableSet.Builder<Link> buildPaths(ImmutableSet.Builder<Link> pathBuilder) {
+ paths.forEach(path -> path.links().forEach(pathBuilder::add));
+ return pathBuilder;
+ }
+
+ private ImmutableSet.Builder<Link> buildDisjointPaths(ImmutableSet.Builder<Link> pathBuilder) {
+ paths.forEach(path -> {
+ DisjointPath dp = (DisjointPath) path;
+ pathBuilder.addAll(dp.primary().links());
+ pathBuilder.addAll(dp.backup().links());
+ });
+ return pathBuilder;
+ }
+
+ private void hilightAndSendPaths() {
+ PathLinkMap linkMap = new PathLinkMap();
+ allPathLinks.forEach(linkMap::add);
+
+ Set<Link> selectedPathLinks;
+
+ // Prepare two working sets; one containing selected path links and
+ // the other containing all paths links.
+ if (currentMode.equals(Mode.DISJOINT)) {
+ DisjointPath dp = (DisjointPath) paths.get(pathIndex);
+ selectedPathLinks = paths.isEmpty() ?
+ ImmutableSet.of() : Sets.newHashSet(dp.primary().links());
+ selectedPathLinks.addAll(dp.backup().links());
+ } else {
+ selectedPathLinks = paths.isEmpty() ?
+ ImmutableSet.of() : ImmutableSet.copyOf(paths.get(pathIndex).links());
+ }
+ Highlights highlights = new Highlights();
+ for (PathLink plink : linkMap.biLinks()) {
+ plink.computeHilight(selectedPathLinks, allPathLinks);
+ highlights.add(plink.highlight(null));
+ }
+ if (src != null) {
+ highlights = addBadge(highlights, srcType, src.toString(), SRC);
+ }
+ if (dst != null) {
+ highlights = addBadge(highlights, dstType, dst.toString(), DST);
+ }
+ sendMessage(TopoJson.highlightsMessage(highlights));
+ }
+
+ private Highlights addBadge(Highlights highlights, String type, String elemId, String src) {
+ if (SWITCH.equals(type)) {
+ highlights = addDeviceBadge(highlights, elemId, src);
+ } else if (ENDSTATION.equals(type)) {
+ highlights = addHostBadge(highlights, elemId, src);
+ }
+ return highlights;
+ }
+
+ private Highlights addDeviceBadge(Highlights h, String elemId, String type) {
+ DeviceHighlight dh = new DeviceHighlight(elemId);
+ dh.setBadge(createBadge(type));
+ h.add(dh);
+ return h;
+ }
+
+ private Highlights addHostBadge(Highlights h, String elemId, String type) {
+ HostHighlight hh = new HostHighlight(elemId);
+ hh.setBadge(createBadge(type));
+ h.add(hh);
+ return h;
+ }
+
+ private NodeBadge createBadge(String type) {
+ return NodeBadge.text(type);
+ }
+
+ private synchronized void addListeners() {
+ listenersRemoved = false;
+ topologyService.addListener(topologyListener);
+ }
+ private synchronized void removeListeners() {
+ if (!listenersRemoved) {
+ listenersRemoved = true;
+ topologyService.removeListener(topologyListener);
+ }
+ }
+
+ // Link event listener.
+ private class InternalTopologyListener implements TopologyListener {
+ @Override
+ public void event(TopologyEvent event) {
+ findAndSendPaths(currentMode);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovOverlay.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovOverlay.java
new file mode 100644
index 00000000..78f5f905
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovOverlay.java
@@ -0,0 +1,56 @@
+/*
+ * 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.pathpainter;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.ui.UiTopoOverlay;
+import org.onosproject.ui.topo.ButtonId;
+import org.onosproject.ui.topo.PropertyPanel;
+
+/**
+ * Our topology overlay.
+ */
+public class PathPainterTopovOverlay extends UiTopoOverlay {
+
+ // NOTE: this must match the ID defined in ppTopovOverlay.js
+ private static final String OVERLAY_ID = "pp-overlay";
+
+ private static final ButtonId SRC_BUTTON = new ButtonId("src");
+ private static final ButtonId DST_BUTTON = new ButtonId("dst");
+
+ public PathPainterTopovOverlay() {
+ super(OVERLAY_ID);
+ }
+
+ @Override
+ public void deactivate() {
+ super.deactivate();
+ log.debug("PathPainterOverlay Deactivated");
+ }
+
+ @Override
+ public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
+ pp.addButton(SRC_BUTTON).addButton(DST_BUTTON);
+ }
+
+ @Override
+ public void modifyHostDetails(PropertyPanel pp, HostId hostId) {
+ pp.addButton(SRC_BUTTON).addButton(DST_BUTTON);
+ }
+
+
+}
diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/package-info.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/package-info.java
new file mode 100644
index 00000000..e625933b
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Path visualization GUI topology view overlay.
+ */
+package org.onosproject.pathpainter; \ No newline at end of file
diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.css b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.css
new file mode 100644
index 00000000..cbf460f9
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.css
@@ -0,0 +1,2 @@
+/* css for sample app topology overlay */
+
diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.html b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.html
new file mode 100644
index 00000000..9141975f
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.html
@@ -0,0 +1,4 @@
+<!-- partial HTML -->
+<div id="ov-pp-topov">
+ <p>This is a hidden view .. just a placeholder to house the javascript</p>
+</div>
diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js
new file mode 100644
index 00000000..baaaef98
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+/*
+ Sample Demo module. This contains the "business logic" for the topology
+ overlay that we are implementing.
+ */
+
+(function () {
+ 'use strict';
+
+ // injected refs
+ var $log, fs, flash, wss;
+
+ // constants
+ var srcMessage = 'ppTopovSetSrc',
+ dstMessage = 'ppTopovSetDst',
+ swapMessage = 'ppTopovSwapSrcDst',
+ modeMessage = 'ppTopovSetMode',
+ nextPathMessage = 'ppTopovNextPath',
+ clearMessage = 'ppTopovClear',
+ prevPathMessage = 'ppTopovPrevPath';
+
+ // internal state
+ var currentMode = null;
+
+
+ // === ---------------------------
+ // === Helper functions
+
+
+ // === ---------------------------
+ // === Main API functions
+
+ function clear() {
+ wss.sendEvent(clearMessage);
+ flash.flash('Source node: ' + node.id);
+ }
+
+ function setSrc(node) {
+ wss.sendEvent(srcMessage, {
+ id: node.id,
+ type: node.type
+ });
+ flash.flash('Source node: ' + node.id);
+ }
+
+ function setDst(node) {
+ wss.sendEvent(dstMessage, {
+ id: node.id,
+ type: node.type
+ });
+ flash.flash('Destination node: ' + node.id);
+ }
+
+ function swapSrcDst() {
+ wss.sendEvent(swapMessage)
+ flash.flash('Source and destination swap');
+ }
+
+ function nextPath() {
+ wss.sendEvent(nextPathMessage);
+ }
+
+ function prevPath() {
+ wss.sendEvent(prevPathMessage);
+ }
+
+
+ function setMode(mode) {
+ if (currentMode === mode) {
+ $log.debug('(in mode', mode, 'already)');
+ flash.flash('Already in ' + mode + ' mode');
+ } else {
+ currentMode = mode;
+ wss.sendEvent(modeMessage, {
+ mode: mode
+ });
+ flash.flash('Path mode: ' + mode);
+ }
+ }
+
+ // === ---------------------------
+ // === Module Factory Definition
+
+ angular.module('ovPpTopov', [])
+ .factory('PathPainterTopovService',
+ ['$log', 'FnService', 'FlashService', 'WebSocketService',
+
+ function (_$log_, _fs_, _flash_, _wss_) {
+ $log = _$log_;
+ fs = _fs_;
+ flash = _flash_;
+ wss = _wss_;
+
+ return {
+ setSrc: setSrc,
+ setDst: setDst,
+ setMode: setMode,
+ nextPath: nextPath,
+ prevPath: prevPath,
+ swapSrcDst: swapSrcDst,
+ clear: clear
+ };
+ }]);
+}());
diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js
new file mode 100644
index 00000000..f98ed2b7
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js
@@ -0,0 +1,260 @@
+// path painter topology overlay - client side
+//
+// This is the glue that binds our business logic (in ppTopovDemo.js)
+// to the overlay framework.
+
+(function () {
+ 'use strict';
+
+ // injected refs
+ var $log, tov, pps;
+
+ // internal state should be kept in the service module (not here)
+ var selection;
+
+ // our overlay definition
+ var overlay = {
+ // NOTE: this must match the ID defined in AppUiTopovOverlay
+ overlayId: 'pp-overlay',
+ glyphId: 'topo',
+ tooltip: 'Path Painter Topo Overlay',
+
+ activate: function () {
+ $log.debug("Path painter topology overlay ACTIVATED");
+ },
+ deactivate: function () {
+ pps.clear();
+ $log.debug("Path painter topology overlay DEACTIVATED");
+ },
+ // These glyphs get installed using the overlayId as a prefix.
+ // e.g. 'src' is installed as 'pp-overlay-src'
+ // They can be referenced (from this overlay) as '*src'
+ // That is, the '*' prefix stands in for 'pp-overlay-'
+ glyphs: {
+ src: {
+ vb: '0 0 110 110',
+ d: 'M28.7,59.3 M14.9,53 M8.7,39 M32.4,92.5H25l-0.2-3.6' +
+ 'c-0.5-9-5.4-23.9-12.9-33.5c-5.2-6.6-7-12.8-7-16.3c0-13.3,10.7-24,23.8-24c13.1,0,23.8,10.8,23.8,24c0,3.5-1.8,9.7-7,16.3' +
+ 'C38,65,33.1,80,32.6,88.9L32.4,92.5z M27.9,89.5h1.7l0-0.7c0.5-9.4,5.7-25.2,13.5-35.2c4.7-6,6.4-11.4,6.4-14.5' +
+ 'c0-11.6-9.3-21-20.8-21C17.3,18,7.9,27.5,7.9,39c0,3,1.7,8.4,6.4,14.5c7.9,10.1,13.1,25.8,13.5,35.2L27.9,89.5z M28.7,83.2' +
+ 'M28.6,29.8c-4.7,0-8.5,3.8-8.5,8.5c0,4.7,3.8,8.5,8.5,8.5s8.5-3.8,8.5-8.5C37.1,33.6,33.3,29.8,28.6,29.8z M89.6,47 M89.6,29.5' +
+ 'c-0.1,3.1-0.1,12.8,0,17c0.1,4.2,14.1-5.5,13.9-8.5C103.4,35.1,89.6,25.6,89.6,29.5z M51,38.1L89.5,38 M89.5,39.5l0-3L51,36.5l0,3' +
+ 'L89.5,39.5z'
+ },
+ dst: {
+ vb: '0 0 110 110',
+ d: 'M80.3,59.8 M85.8,92.5h-7.2L78.4,89c-0.4-8.8-5.2-23.6-12.3-33' +
+ 'c-4.9-6.5-6.7-12.5-6.7-16c0-13,10.2-23.7,22.7-23.7c12.5,0,22.7,10.6,22.7,23.7c0,3.5-1.8,9.5-6.7,16C91.2,65.4,86.4,80.1,86,89' +
+ 'L85.8,92.5z M81.4,89.5H83l0-0.7c0.5-9.3,5.4-24.8,12.9-34.7c4.5-5.9,6.1-11.2,6.1-14.2c0-11.4-8.9-20.7-19.8-20.7' +
+ 'c-10.9,0-19.8,9.3-19.8,20.7c0,3,1.6,8.3,6.1,14.2C76,64,80.9,79.5,81.4,88.8L81.4,89.5z M82.1,30.8c-4.5,0-8.1,3.7-8.1,8.4' +
+ 's3.6,8.4,8.1,8.4c4.5,0,8.1-3.7,8.1-8.4S86.6,30.8,82.1,30.8z M47.2,47.5 M45.2,30.8c-0.1,3.1-0.1,12.6,0,16.7' +
+ 'c0.1,4.1,13.4-5.4,13.3-8.4C58.4,36.2,45.2,26.9,45.2,30.8z M45.2,39.1L6.7,39.2 M45.2,40.6l0-3L6.7,37.7l0,3L45.2,40.6z'
+ },
+ jp: {
+ vb: '0 0 110 110',
+ d: 'M84.3,89.3L58.9,64.2l-1.4,1.4L83,90.7L84.3,89.3z M27,7.6H7.4v19.2H27V7.6z' +
+ 'M59.3,47.1H39.8v19.2h19.5V47.1z M102.1,79.5H82.6v19.2h19.5V79.5z M41.7,47.6L19,25.1l-1.2,1.2l22.7,22.5L41.7,47.6z'
+ },
+ djp: {
+ vb: '0 0 110 110',
+ d: 'M25.8,84l-9.2-57 M27.3,83.8l-9.2-57l-3,0.5l9.2,57L27.3,83.8z M83.2,37.7L26.8,15.5 M83.7,36.1L26.6,14' +
+ 'l-1,3.2l57,22.1L83.7,36.1z M34.1,95l61.4-40.6 M96.4,55.7l-1.9-2.5L33.2,93.8l1.9,2.5L96.4,55.7z M26.6,27.6H6.7V7.7h19.9V27.6z' +
+ 'M102.1,36H82.2v19.9h19.9V36z M35.3,83.5H15.3v19.9h19.9V83.5z'
+ },
+ geo: {
+ vb: '0 0 110 110',
+ d: 'M55.7,94.6c-0.1-0.3,0-1-0.1-1.4'+
+ 'c-0.7-0.5-1.3-2.2-2.1-2.6c-0.5-0.3-1.4-0.2-2-0.5c-0.3-0.1-0.6-0.3-0.9-0.4c-0.4-0.1-0.8-0.1-1.1-0.3c-1.3-0.7-1.9-3-3.5-2.9'+
+ 'c-0.7,0-1.3,0.7-1.9,0.7c-0.6,0-1.6-0.5-2.4-0.9c-0.8-0.4-1.6-0.6-2.3-1c-0.5-0.3-0.9-0.9-1.3-1.1C37.8,84,37.2,84,37,83.9'+
+ 'c-0.4-0.2-0.8-0.7-1.3-1.1c-0.5-0.4-1-0.9-1-1.4c0-0.6,0.5-1,0.5-1.6c0.2-1.7-1-2.9-1.7-3.9c-0.5-0.7-1.1-1.4-1.7-2.1'+
+ 'c0-0.5,0-0.5,0-1c-0.4-0.4-0.7-1.1-1.1-1.7c-0.4-0.6-1.1-1.2-1.2-1.9c-0.1-0.8,0.3-1.5,0-2.3c-0.5-1.3-2-0.7-1.8,1'+
+ 'c0.1,0.5,0.6,1.1,0.8,1.6c0.2,0.5,0.1,1.1,0.3,1.6c0.2,0.6,0.7,1,0.8,1.7c0.3,1,0.3,2,0.5,2.7c0.2,0.5,1,1.1,0.6,1.7'+
+ 'c-0.6,0.1-0.8-0.5-1.2-0.9c-0.2-0.2-1-0.6-1.1-1.1c-0.1-0.4,0.2-1,0.1-1.5c-0.2-1-2-1-2-2.1c0-0.7,0.8-0.7,0.8-1.4'+
+ 'c0-0.7-0.8-1.3-1-1.9c-0.2-0.5-0.2-1.4-0.3-2.2c-0.1-0.7,0-1.5-0.1-2.1c-0.1-0.5-0.8-1.2-1.2-1.4c-0.6-0.3-1-0.2-1.3-0.7'+
+ 'c-0.2-0.4-0.4-1.4-0.4-1.9c-0.1-0.9,0-1.8-0.1-2.7c0-0.9-0.1-1.8,0-2.8c0.3-0.7,0.9-1,1.2-1.7c0.2-0.5,0.3-1.1,0.5-1.6'+
+ 'c0.5-0.9,1.5-1.8,2.2-2.7c0.7-1,1.4-1.9,1.8-3.1c0.2-0.4,0.6-1.3,0.5-1.8c-0.1-0.7-1.2-1.3-1.1-2.1c0.1-0.5,0.7-0.5,0.9-1'+
+ 'c0.1-0.3,0.2-1,0.2-1.3c0-0.7-0.3-1.4-0.2-2.2c0.1-0.6,0.9-0.9,0.5-1.6c-0.4-0.7-1.2,0.4-1.7-0.1c-0.4-0.4,0.1-0.9,0.1-1.7'+
+ 'c0-0.3-0.2-0.6-0.1-0.9c0-0.3,0.6-0.9,0.4-1.1c-0.3-0.5-0.7-1.7-1.5-2.2c-0.9-0.5-1.9-0.2-3.2-0.4c-0.8-0.2-1.2-1-1.9-0.9'+
+ 'c-0.5,0-0.7,0.6-1.3,0.9c-0.6,0.3-1.4,0.2-2,0.4c-0.6,0.2-0.9,0.6-1.5,0.6c-0.5,0-0.5-0.6-1.1-0.6c-0.2,0-0.7,0.2-1.1,0.2'+
+ 'c-1,0.1-2.8,0.2-3.7-0.1c-0.9-0.2-1.5-0.5-2.5-1.1C7.4,28.2,6,27.7,6.1,27c0-0.4,1.3-0.8,1.8-1c0.8-0.3,1.3-0.7,2-0.8'+
+ 'c0.2,0,0.6,0.2,0.9,0.1c0.3,0,0.7-0.4,1.1-0.4c0.9-0.1,2.1,0.1,2-0.9c-0.7-0.6-3.4,0.4-3.5-0.9c0-0.8,1-1,1.8-1.2'+
+ 'c0.7-0.2,1.8-0.5,2.5-0.4c0.7,0,1.7,1,2.1-0.1c0.2-0.7-0.2-1.3-0.4-1.9c0.5-0.8,1.5-0.7,2.3-0.9c0.9-0.1,1.6-0.3,2.4-0.7'+
+ 'c0.7-0.4,1.5-0.6,2.4-0.7c0.9-0.1,1.7-0.5,2.5-0.6c0.6-0.1,1.2,0,1.8-0.1c0.5-0.1,1.1-0.5,1.7-0.4c0.4,0,0.7,0.4,1.1,0.4'+
+ 'c0.4,0.1,0.8,0,1.2,0.1c0.3,0.1,0.6,0.3,0.9,0.4c0.5,0.1,1-0.1,1.5,0c0.4,0.1,0.8,0.4,1.2,0.4c1,0.1,2.1-0.1,3.1,0.1'+
+ 'c0.4,0.1,0.7,0.3,1.1,0.4c0.4,0.1,0.8,0,1.1,0.1c0.5,0.1,0.9,0.7,1.5,0.7c1,0.1,2.1-0.5,3.1-0.6c0.7-0.1,1.5,0,2.3-0.1'+
+ 'c0.7-0.2,1.4-0.5,2-0.5c0.3,0,0.6,0.1,1,0.1c0.3,0,0.7-0.5,1.1-0.4c0.5,0.1,0.4,0.8,0.9,0.9c0.6-0.3,1.1,0,1.7,0'+
+ 'c0.6,0,1.1-0.3,1.8-0.2c1.2,0.2,2.8,1.5,3.7,0.8c0.2-0.2,0.2-0.5,0.4-0.9c0.3-0.6,0.8-1.3,0.7-2.2c-1.3,0-2.5,0.7-3.9,0.8'+
+ 'c-1.5-1,0.4-1.7,1.5-2.2c0.9-0.4,1.6-1.3,2.7-1.4C62,12.5,63,12.9,64,13c0.6,0.1,1.2,0,1.6,0.1c0.6,0.2,0.9,0.9,1.5,1.1'+
+ 'c0.2,0.1,0.6,0.1,0.9,0.1c0.6,0.1,1.1,0.5,1.7,0c0.4,0.1,0.5,0.6,1,0.7c0.4-0.3,0.7-0.9,1.4-1.1c0.3-0.1,0.6,0.1,0.9,0'+
+ 'c0.5-0.1,1.2-0.9,1.5-0.1c-0.1,0.5-0.8,0.6-1.2,1c-0.3,0.4-0.9,1.2-0.8,1.6c0.1,0.7,1,0.4,1,1.3c-0.1,0.5-0.7,0.3-1.1,0.5'+
+ 'c-0.4,0.2-0.5,0.6-1,0.7c-1.2,0.2-2.1-0.3-3.1-0.3c0,0.5,0.5,0.8,0.8,0.9c0.9,0.5,1.6,0.5,2.9,0.4c0.7,0,1.4,0.2,2-0.2'+
+ 'c0.4-0.3,0.3-0.9,0.6-1.2c0.4-0.4,1.2-0.8,1.7-0.7c0.3,0.1,0.7,0.4,0.7,0.7c0,0.7-0.8,0.4-0.8,1.1c0.5,0.4,2-0.4,2-1'+
+ 'c0.1-0.4-0.5-0.7-0.4-1.1c0-0.8,0.9-0.7,0.8-1.5c-0.4-0.4-0.9,0.1-1.3,0c-0.6-0.1-1.2-1-1.5-1.5c0.3-0.4,0.9-0.1,1.3-0.1'+
+ 'c0.5-0.7,1.3-1,2.5-1.1c0.4,0,1-0.2,1.2,0.2c0.1,0.7-0.9,1.1-0.7,1.9c0.9,0.2,1.1-1.1,1.8-1.6c0.3-0.2,0.8-0.4,1.2-0.6'+
+ 'c0.4-0.2,0.8-0.6,1.1-0.6c0.4,0,0.4,0.3,0.8,0.5c0.3,0.1,0.7-0.1,0.8,0.4c-0.7,1.4-3.5,0.6-4.2,2.1c0.2,1-0.4,1.9,0.1,2.6'+
+ 'c0.4,0.5,1.1,0.2,1.3,0.6c0.2,0.7-0.8,0.7-0.5,1.4c0.7,0.5,1.5-0.4,2.1-0.8c0.7-0.4,1.5-0.8,1.6-1.7c-0.3-0.7-1.6-0.2-1.8-0.9'+
+ 'c-0.1-0.4,0.4-1.3,0.5-1.5c0.7-0.8,3-2,4.6-1.9c0.3,0,0.6,0.3,1,0.3c1.1,0.1,2.4-0.5,3.2,0c0.7-0.5,1.5,0.1,2.5-0.1'+
+ 'c0.7,0.5,0.5,1.5,1.7,2c0.3,0.1,0.7,0,1.1,0.1c0.3,0.1,0.6,0.5,1,0.6c0.5,0.2,0.9,0.2,1,0.6c0.1,0.4-0.3,0.6-0.3,1'+
+ 'c0.3,0.3,0,0.6,0.2,1c0.3,0.7,1,0.6,1.6,0.9c0.5,0.2,1.5,0.9,1.5,1.4c0,0.4-1,1-1.3,1.1c-0.2,0.1-1.3,0.7-1.7,0.6'+
+ 'c-0.6-0.1-0.8-1.5-1.7-1.4c-0.4,0-0.7,0.3-0.7,0.8c0,0.9,0.9,1,1,1.8c0,1-0.5,1-1.2,1.6c-0.5-0.2-1-0.6-1.7-0.6'+
+ 'c-0.4,0.5,0.7,0.7,0.3,1.4c-1,0.2-1.8-0.3-2.7-0.6c-0.3-0.1-0.7-0.1-1-0.2c-0.4-0.2-0.5-0.9-0.8-1.3c-0.3-0.4-1-1-1.6-1'+
+ 'c-0.8,0-1.9,1.1-2.5,0.1c0.4-1.6,2.5-0.4,3.8-1c0.5-0.2,0.7-0.8,1.1-1.1c0.8-0.5,2.2-0.6,2-1.7c-0.1-0.5-0.7-0.5-1.1-0.8'+
+ 'c-0.5-0.4-0.9-1.7-1.6-1.7c-0.4,0-0.6,0.3-1,0.4c-0.8,0.1-1.7-0.4-2.5,0c-0.3,0.2-0.1,0.6-0.4,1c-0.2,0.3-0.7,0.4-1,0.8'+
+ 'c-0.2,0.4-0.2,0.9-0.5,1.2c-0.5,0.5-1.6,0.6-2.3,0.9c-0.3,0.1-0.7,0.5-1,0.5c-0.5,0-0.7-0.8-1.3-0.5c0,0.8,0.7,1.1,1.2,1.4'+
+ 'c0.5,0.4,1.1,0.8,1.3,1.4c-0.5,1.2-1.3-0.1-2.2-0.1c-0.9,0-2.2,1.9-3,0.4c0.2-0.8,1-1,1.2-1.8c-0.9,0.2-1.7,1-2.7,1.3'+
+ 'c-0.4,0.1-0.9,0.1-1.3,0.2c-0.8,0.3-1.3,0.9-2.1,1.2c-0.3,0.1-0.7,0.1-1,0.2c-0.8,0.3-1.7,0.8-2.5,1.3c-0.8,0.5-1.7,1-2.2,1.5'+
+ 'c-0.3,0.3-1,1.2-1,1.5c0,0.4,0.7,0.6,0.8,1c0,0.3-0.4,0.8-0.1,1.2c0.3,0.3,0.8,0.1,1.3,0.1c1,0.1,1.6,1,2.4,1.5'+
+ 'c0.6,0.4,1.4,0.8,2,0.9c0.9,0.1,1.8-0.3,2,0.5c0.1,0.8-0.8,1-0.9,1.5c0.5,0.7-0.3,1-0.3,1.6c0,0.5,0.5,1.2,1,1.3'+
+ 'c0.6,0.1,1.6-0.7,1.8-1.4c0.3-0.9,0.2-2,0.8-2.7c3,0.1,5.5-1.5,5.3-4.9c0-0.3-0.2-0.8-0.1-1.2c0.1-0.6,0.9-1,0.8-1.7'+
+ 'c0.8-0.3,0.8-1.8,1.7-2c0.7-0.2,1.5,0.6,2.5,0.5c0.3,0,0.7-0.3,1-0.3c0.6,0.1,1,1,1.5,1.4c0.4,0.4,0.9,0.2,1,0.7'+
+ 'c-0.1,0.8-0.6,0.8-0.6,1.6c0,0.7,0.7,1.2,1,1.2c0.5,0.1,1.1-0.2,1.6-0.4c0.8-0.5,1.6-1.8,2.3-1.7c0.6,0.1,1,2.1,1.1,2.9'+
+ 'c0.1,0.8-0.1,1.4-0.1,2.1c0.1,1.2,1.4,1.1,2.1,1.7c0.2,0.2,0.3,0.7,0.4,0.9c0.3,0.5,0.7,0.5,0.8,1c0.1,1.2-1,1.3-0.9,2.7'+
+ 'c-0.2,0.5-0.8,0.5-0.8,1.2c0.1,1.1,1.5,0.3,1.9,1.1c0.2,0.5,0,0.8-0.2,1.5c0.5,0.7,0.5,1.7-0.4,1.7c-0.5,0-0.7-0.6-1.2-0.8'+
+ 'c-0.3-0.1-0.7-0.1-1.1-0.1c-0.3-0.1-0.7-0.2-1-0.2c-0.8-0.1-1.6,0.2-2.1-0.4c0.8-1.1,1.8-2.3,2.7-3.2c0.3-0.3,0.9-0.5,0.8-1.1'+
+ 'c-0.5-0.5-1.2,0-1.7,0.4c-0.5,0.3-1.2,0.8-1.8,0.9c-1.1,0.2-2.4-0.3-3.3,0.3c-0.1,0.5,1,0.3,0.8,1.1C92.8,43,92.4,43,92,42.7'+
+ 'c-0.3-0.3-0.1-0.8-0.3-0.9c-0.3-0.3-1.5-0.4-2.1-0.3c-0.7,0.1-1.3,0.6-1.3,1.2c0.8,0.4,2.1-0.4,2.4,0.6c-0.4,0.9-1.5,1.4-1.3,2.6'+
+ 'c0.1,0.5,0.5,1.1,0.9,1.1c0.3,0.1,0.5-0.3,0.9-0.3c0.4,0,0.3,0.5,0.7,0.4c0.6-0.3,1-1.3,1.7-1.2c0.8,1.2-0.8,1.7-1.7,2.1'+
+ 'c-1,0.4-2.3,0.6-3.1,1c-0.4,0.2-1.9,1.9-2.2,0.6c-0.2-0.9,0.8-0.7,1-1.4c-1-0.2-1.9,0.5-2.8,0.9c-1.3,0.5-3.4,0.9-3.8,2.5'+
+ 'c-0.1,0.3,0.1,0.9-0.1,1.1c-0.2,0.2-1.1,0.2-1.5,0.4c-0.6,0.2-1.2,0.7-1.5,0.9C77.7,54,77.2,54,77,54.1c-0.5,0.2-0.7,1-1.3,1.5'+
+ 'c-0.2,0.2-0.8,0.4-1,0.6c-0.3,0.4-0.4,1.3-1,1.4c-0.4,0-0.7-0.3-1-0.1c0,0.9,0.3,2.2-0.1,3.1c-0.8,0.7-1.6,1.2-2.5,1.8'+
+ 'c-0.5,0.3-1,0.4-1.7,0.8c-0.5,0.3-0.9,0.9-1.4,1.2c-1.2,0.8-2.7,1.8-2.7,3.8c0,0.4,0.2,0.9,0.3,1.4c0,0.3,0,0.6,0,0.9'+
+ 'c0.1,0.7,0.6,1.7,0,2.2c-0.9-0.4-1.9-0.5-2.5-1.2c-0.2-0.7,0.3-1.3,0.3-1.9c-0.1-0.5-0.7-1.4-1.1-1.5c-0.4-0.1-0.7,0.4-1.1,0.4'+
+ 'c-0.5,0-0.9-0.8-1.5-0.9c-0.9-0.1-1.6,0.2-2.5,0.1c-1,0.6-1.2,1.6-2.4,1.5c-0.4,0-0.8-0.4-1.3-0.5c-0.5-0.1-1.3-0.3-1.8-0.3'+
+ 'c-1.1,0.1-1.9,1-2.8,1.5c-0.8,0.5-2,1.1-2.2,2.1c-0.1,0.5,0,1.3-0.2,1.8c-0.1,0.3-0.4,0.6-0.5,0.9c-0.7,1.5-1.3,3.4-0.8,5.5'+
+ 'c0.1,0.3,0.8,2.1,1.1,2.4c0.3,0.4,1.3,1,1.8,1c0.5,0,1-0.3,1.5-0.4c0.5-0.1,1.2-0.1,1.7-0.3c1.4-0.5,1.1-2.6,2.5-3.3'+
+ 'c0.6-0.3,1.3-0.4,2.4-0.4c0.3,0.3,0.5,0.9,0.4,1.4c0,0.4-0.3,0.7-0.5,1.2c-0.1,0.5-0.2,1-0.3,1.4c-0.2,0.5-0.6,0.8-0.8,1.3'+
+ 'c-0.1,0.3,0,0.7-0.1,0.9c-0.1,0.5-0.7,0.8-0.4,1.3c1.4,0.6,3-0.2,4.2,0.1c0.5,0.1,1.5,0.8,1.5,1.7c0,0.7-0.4,1.1-0.5,1.8'+
+ 'c-0.1,0.9-0.4,2-0.4,2.7c-0.1,1.2,1.5,3.2,2.7,3.2L55.7,94.6z M39.1,54.2L31.7,54v11.2h10.3v-8.7L39.1,54.2z M52.2,35.7l7.5,0.1'+
+ 'V24.6H49.5l0,8.9 M39.1,54.2l2.9,2.3l10.3-20.8l-2.7-2.1L39.1,54.2z M47.2,46.4'
+
+ }
+ },
+
+ // detail panel button definitions
+ buttons: {
+ src: {
+ gid: '*src',
+ tt: 'Set source node',
+ cb: function (data) {
+ $log.debug('Set src action invoked with data:', data);
+ pps.setSrc(selection);
+ }
+ },
+ dst: {
+ gid: '*dst',
+ tt: 'Set destination node',
+ cb: function (data) {
+ $log.debug('Set dst action invoked with data:', data);
+ pps.setDst(selection);
+ }
+ }
+ },
+
+ // Key bindings for traffic overlay buttons
+ // NOTE: fully qual. button ID is derived from overlay-id and key-name
+ // FIXME: use into [ and ] instead of 1 and 2
+ // FIXME: find better keys for shortest paths & disjoint paths modes
+ keyBindings: {
+ 1: {
+ cb: function () {
+ pps.setSrc(selection);
+ },
+ tt: 'Set source node',
+ gid: '*src'
+ },
+ 2: {
+ cb: function () {
+ pps.setDst(selection);
+ },
+ tt: 'Set destination node',
+ gid: '*dst'
+ },
+ 3: {
+ cb: function () {
+ pps.swapSrcDst();
+ },
+ tt: 'Swap source and destination nodes',
+ gid: 'refresh'
+ },
+ 4: {
+ cb: function () {
+ pps.setMode("shortest");
+ },
+ tt: 'Set shortest paths mode',
+ gid: '*jp'
+ },
+ 5: {
+ cb: function () {
+ pps.setMode("disjoint");
+ },
+ tt: 'Set disjoint paths mode',
+ gid: '*djp'
+ },
+ 6: {
+ cb: function () {
+ pps.setMode("geodata");
+ },
+ tt: 'Set geodata path weight mode',
+ gid: '*geo'
+ },
+ leftArrow: {
+ cb: function () {
+ pps.prevPath();
+ },
+ tt: 'Highlight previous path',
+ gid: 'prevIntent'
+ },
+ rightArrow: {
+ cb: function () {
+ pps.nextPath();
+ },
+ tt: 'Highlight next path',
+ gid: 'nextIntent'
+ },
+
+ _keyOrder: [
+ '1', '2', '3', '4', '5', '6', 'leftArrow', 'rightArrow'
+ ]
+ },
+
+ hooks: {
+ // hook for handling escape key
+ // Must return true to consume ESC, false otherwise.
+ escape: function () {
+ selectionCallback();
+ pps.setSrc();
+ pps.setDst();
+ },
+
+ // hooks for when the selection changes...
+ empty: function () {
+ selectionCallback();
+ },
+ single: function (data) {
+ selectionCallback(data);
+ }
+ }
+ };
+
+
+ function buttonCallback(x) {
+ $log.debug('Toolbar-button callback', x);
+ }
+
+ function selectionCallback(d) {
+ $log.debug('Selection callback', d);
+ selection = d;
+ }
+
+ // invoke code to register with the overlay service
+ angular.module('ovPpTopov')
+ .run(['$log', 'TopoOverlayService', 'PathPainterTopovService',
+
+ function (_$log_, _tov_, _pps_) {
+ $log = _$log_;
+ tov = _tov_;
+ pps = _pps_;
+ tov.register(overlay);
+ }]);
+
+}());
diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/css.html b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/css.html
new file mode 100644
index 00000000..56b32b4a
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/css.html
@@ -0,0 +1 @@
+<link rel="stylesheet" href="app/view/ppTopov/ppTopov.css"> \ No newline at end of file
diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/js.html b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/js.html
new file mode 100644
index 00000000..24124bf7
--- /dev/null
+++ b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/js.html
@@ -0,0 +1,2 @@
+<script src="app/view/ppTopov/ppTopov.js"></script>
+<script src="app/view/ppTopov/ppTopovOverlay.js"></script> \ No newline at end of file
diff --git a/framework/src/onos/apps/pom.xml b/framework/src/onos/apps/pom.xml
index 005052fb..1a279c53 100644
--- a/framework/src/onos/apps/pom.xml
+++ b/framework/src/onos/apps/pom.xml
@@ -31,6 +31,7 @@
<modules>
<module>aaa</module>
<module>acl</module>
+ <module>faultmanagement</module>
<module>fwd</module>
<module>mobility</module>
<module>proxyarp</module>
@@ -47,6 +48,7 @@
<module>cordfabric</module>
<module>xos-integration</module>
<module>pcep-api</module>
+ <module>iptopology-api</module>
<module>olt</module>
<module>cip</module>
<module>flowanalyzer</module>
@@ -58,6 +60,8 @@
<module>pim</module>
<module>mlb</module>
<module>openstackswitching</module>
+ <module>pathpainter</module>
+ <module>cpman</module>
</modules>
<properties>
diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
index 2eb5d0f3..09d4a436 100644
--- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
+++ b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
@@ -30,6 +30,7 @@ import org.onosproject.core.ApplicationId;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentUtils;
import org.onosproject.net.intent.Key;
import org.onosproject.routing.IntentSynchronizationService;
import org.slf4j.Logger;
diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java
deleted file mode 100644
index 863de12a..00000000
--- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java
+++ /dev/null
@@ -1,89 +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.sdnip;
-
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.net.intent.SinglePointToMultiPointIntent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Objects;
-
-/**
- * Utilities for dealing with intents.
- */
-public final class IntentUtils {
-
- private static final Logger log = LoggerFactory.getLogger(IntentUtils.class);
-
- private IntentUtils() {
-
- }
-
- /**
- * Checks if two intents represent the same value.
- *
- * <p>({@link Intent#equals(Object)} only checks ID equality)</p>
- *
- * <p>Both intents must be of the same type.</p>
- *
- * @param one first intent
- * @param two second intent
- * @return true if the two intents represent the same value, otherwise false
- */
- public static boolean equals(Intent one, Intent two) {
- if (one.getClass() != two.getClass()) {
- return false;
- }
-
- if (!(Objects.equals(one.appId(), two.appId()) &&
- Objects.equals(one.key(), two.key()))) {
- return false;
- }
-
- if (one instanceof SinglePointToMultiPointIntent) {
- SinglePointToMultiPointIntent intent1 = (SinglePointToMultiPointIntent) one;
- SinglePointToMultiPointIntent intent2 = (SinglePointToMultiPointIntent) two;
-
- return Objects.equals(intent1.selector(), intent2.selector()) &&
- Objects.equals(intent1.treatment(), intent2.treatment()) &&
- Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
- Objects.equals(intent1.egressPoints(), intent2.egressPoints());
- } else if (one instanceof MultiPointToSinglePointIntent) {
- MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one;
- MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two;
-
- return Objects.equals(intent1.selector(), intent2.selector()) &&
- Objects.equals(intent1.treatment(), intent2.treatment()) &&
- Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) &&
- Objects.equals(intent1.egressPoint(), intent2.egressPoint());
- } else if (one instanceof PointToPointIntent) {
- PointToPointIntent intent1 = (PointToPointIntent) one;
- PointToPointIntent intent2 = (PointToPointIntent) two;
-
- return Objects.equals(intent1.selector(), intent2.selector()) &&
- Objects.equals(intent1.treatment(), intent2.treatment()) &&
- Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
- Objects.equals(intent1.egressPoint(), intent2.egressPoint());
- } else {
- log.error("Unimplemented intent type");
- return false;
- }
- }
-}
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 fb008aad..edc2df4d 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
@@ -33,6 +33,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intent.IntentUtils;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.routing.IntentSynchronizationService;
diff --git a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
index 6dc3ce10..4736aa1d 100644
--- a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
+++ b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
@@ -45,6 +45,7 @@ import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intent.IntentUtils;
import org.onosproject.routing.RouteEntry;
import java.util.Collections;
diff --git a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java
index 7f825e81..4df7f9de 100644
--- a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java
+++ b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java
@@ -17,6 +17,7 @@ package org.onosproject.sdnip;
import org.easymock.IArgumentMatcher;
import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentUtils;
import static org.easymock.EasyMock.reportMatcher;
diff --git a/framework/src/onos/apps/segmentrouting/pom.xml b/framework/src/onos/apps/segmentrouting/pom.xml
index 83ae76db..d170a7ab 100644
--- a/framework/src/onos/apps/segmentrouting/pom.xml
+++ b/framework/src/onos/apps/segmentrouting/pom.xml
@@ -89,6 +89,11 @@
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-junit</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
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 2c6412cf..7f4bcb15 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
@@ -107,7 +107,7 @@ public class ArpHandler {
vlanId);
// ARP request for router. Send ARP reply.
- if (isArpReqForRouter(deviceId, arpRequest)) {
+ if (isArpForRouter(deviceId, arpRequest)) {
Ip4Address targetAddress = Ip4Address.valueOf(arpRequest.getTargetProtocolAddress());
sendArpResponse(arpRequest, config.getRouterMacForAGatewayIp(targetAddress), vlanId);
} else {
@@ -130,7 +130,7 @@ public class ArpHandler {
vlanId);
// ARP reply for router. Process all pending IP packets.
- if (isArpReqForRouter(deviceId, arpReply)) {
+ if (isArpForRouter(deviceId, arpReply)) {
Ip4Address hostIpAddress = Ip4Address.valueOf(arpReply.getSenderProtocolAddress());
srManager.ipHandler.forwardPackets(deviceId, hostIpAddress);
} else {
@@ -141,7 +141,8 @@ public class ArpHandler {
// ARP reply for unknown host, Flood in the subnet.
} else {
// Don't flood to non-edge ports
- if (vlanId.equals(VlanId.vlanId(srManager.ASSIGNED_VLAN_NO_SUBNET))) {
+ if (vlanId.equals(
+ VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET))) {
return;
}
removeVlanAndFlood(payload, inPort);
@@ -150,14 +151,21 @@ public class ArpHandler {
}
- private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) {
- Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
- if (gatewayIpAddresses != null) {
- Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest
- .getTargetProtocolAddress());
- if (gatewayIpAddresses.contains(targetProtocolAddress)) {
+ private boolean isArpForRouter(DeviceId deviceId, ARP arpMsg) {
+ Ip4Address targetProtocolAddress = Ip4Address.valueOf(
+ arpMsg.getTargetProtocolAddress());
+ Set<Ip4Address> gatewayIpAddresses = null;
+ try {
+ if (targetProtocolAddress.equals(config.getRouterIp(deviceId))) {
return true;
}
+ gatewayIpAddresses = config.getPortIPs(deviceId);
+ } catch (DeviceConfigNotFoundException e) {
+ log.warn(e.getMessage() + " Aborting check for router IP in processing arp");
+ }
+ if (gatewayIpAddresses != null &&
+ gatewayIpAddresses.contains(targetProtocolAddress)) {
+ return true;
}
return false;
}
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 99225874..e6451653 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
@@ -513,6 +513,7 @@ public class DefaultRoutingHandler {
public void populatePortAddressingRules(DeviceId deviceId) {
rulePopulator.populateRouterMacVlanFilters(deviceId);
rulePopulator.populateRouterIpPunts(deviceId);
+ rulePopulator.populateArpPunts(deviceId);
}
/**
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 eb3b3fd5..d1dc8ddc 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
@@ -88,10 +88,10 @@ public class IcmpHandler {
(destinationAddress.equals(routerIpAddress) ||
gatewayIpAddresses.contains(destinationAddress))) {
sendICMPResponse(ethernet, connectPoint);
- // TODO: do we need to set the flow rule again ??
// ICMP for any known host
} else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
+ // TODO: known host packet should not be coming to controller - resend flows?
srManager.ipHandler.forwardPackets(deviceId, destinationAddress);
// ICMP for an unknown host in the subnet of the router
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
index b1682e77..d6a9dcfc 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
@@ -98,7 +98,7 @@ public class IpHandler {
*/
public void addToPacketBuffer(IPv4 ipPacket) {
- // Better not buffer TPC packets due to out-of-order packet transfer
+ // Better not buffer TCP packets due to out-of-order packet transfer
if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) {
return;
}
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 a07a15d2..d4aa770c 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
@@ -147,20 +147,34 @@ public class RoutingRulePopulator {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
- sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH));
sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+ sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH));
+ TrafficSelector selector = sbuilder.build();
tbuilder.deferred()
.setEthDst(hostMac)
.setEthSrc(deviceMac)
.setOutput(outPort);
-
TrafficTreatment treatment = tbuilder.build();
- TrafficSelector selector = sbuilder.build();
+
+ // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed.
+ // for switch pipelines that need it, provide outgoing vlan as metadata
+ VlanId outvlan = null;
+ Ip4Prefix subnet = srManager.deviceConfiguration.getPortSubnet(deviceId, outPort);
+ if (subnet == null) {
+ outvlan = VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET);
+ } else {
+ outvlan = srManager.getSubnetAssignedVlanId(deviceId, subnet);
+ }
+ TrafficSelector meta = DefaultTrafficSelector.builder()
+ .matchVlanId(outvlan).build();
+ int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outPort,
+ treatment, meta);
return DefaultForwardingObjective.builder()
+ .withSelector(selector)
+ .nextStep(portNextObjId)
.fromApp(srManager.appId).makePermanent()
- .withSelector(selector).withTreatment(treatment)
.withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC);
}
@@ -454,7 +468,7 @@ public class RoutingRulePopulator {
if (srManager.mastershipService.isLocalMaster(deviceId)) {
TrafficTreatment tt = DefaultTrafficTreatment.builder()
.pushVlan().setVlanId(assignedVlan).build();
- fob.setMeta(tt);
+ fob.withMeta(tt);
}
fob.permit().fromApp(srManager.appId);
srManager.flowObjectiveService.
@@ -511,6 +525,39 @@ public class RoutingRulePopulator {
}
/**
+ * 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 the switch dpid for the router
+ */
+ public void populateArpPunts(DeviceId deviceId) {
+ if (!srManager.mastershipService.isLocalMaster(deviceId)) {
+ log.debug("Not installing port-IP punts - not the master for dev:{} ",
+ deviceId);
+ return;
+ }
+
+ ForwardingObjective.Builder puntArp = DefaultForwardingObjective.builder();
+ TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+ sbuilder.matchEthType(Ethernet.TYPE_ARP);
+ tbuilder.setOutput(PortNumber.CONTROLLER);
+ puntArp.withSelector(sbuilder.build());
+ puntArp.withTreatment(tbuilder.build());
+ puntArp.withFlag(Flag.VERSATILE)
+ .withPriority(HIGHEST_PRIORITY)
+ .makePermanent()
+ .fromApp(srManager.appId);
+ log.debug("Installing forwarding objective to punt ARPs");
+ srManager.flowObjectiveService.
+ forward(deviceId,
+ puntArp.add(new SRObjectiveContext(deviceId,
+ SRObjectiveContext.ObjectiveType.FORWARDING)));
+ }
+
+ /**
* Populates a forwarding objective to send packets that miss other high
* priority Bridging Table entries to a group that contains all ports of
* its subnet.
@@ -526,6 +573,12 @@ public class RoutingRulePopulator {
int nextId = srManager.getSubnetNextObjectiveId(deviceId, subnet);
VlanId vlanId = srManager.getSubnetAssignedVlanId(deviceId, subnet);
+ if (nextId < 0 || vlanId == null) {
+ log.error("Cannot install subnet broadcast rule in dev:{} due"
+ + "to vlanId:{} or nextId:{}", vlanId, nextId);
+ return;
+ }
+
/* Driver should treat objective with MacAddress.NONE as the
* subnet broadcast rule
*/
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 f6bf649c..62722f02 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
@@ -57,6 +57,7 @@ import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
import org.onosproject.segmentrouting.grouphandler.NeighborSet;
import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey;
+import org.onosproject.segmentrouting.grouphandler.PortNextObjectiveStoreKey;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
@@ -97,7 +98,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-@SuppressWarnings("ALL")
@Service
@Component(immediate = true)
public class SegmentRoutingManager implements SegmentRoutingService {
@@ -150,21 +150,27 @@ public class SegmentRoutingManager implements SegmentRoutingService {
private ScheduledExecutorService executorService = Executors
.newScheduledThreadPool(1);
+ @SuppressWarnings("unused")
private static ScheduledFuture<?> eventHandlerFuture = null;
+ @SuppressWarnings("rawtypes")
private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
private Map<DeviceId, DefaultGroupHandler> groupHandlerMap =
new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
// Per device next objective ID store with (device id + neighbor set) as key
private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer>
nsNextObjStore = null;
+ // Per device next objective ID store with (device id + subnet) as key
private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer>
subnetNextObjStore = null;
- private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
- private EventuallyConsistentMap<String, Policy> policyStore = null;
+ // Per device next objective ID store with (device id + port) as key
+ private EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer>
+ portNextObjStore = null;
// Per device, per-subnet assigned-vlans store, with (device id + subnet
// IPv4 prefix) as key
private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId>
subnetVidStore = null;
+ private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
+ private EventuallyConsistentMap<String, Policy> policyStore = null;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@@ -175,6 +181,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
private final InternalConfigListener cfgListener =
new InternalConfigListener(this);
+ @SuppressWarnings({ "unchecked", "rawtypes" })
private final ConfigFactory cfgFactory =
new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY,
SegmentRoutingConfig.class,
@@ -185,7 +192,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
}
};
- private final HostListener hostListener = new InternalHostListener();
+ private final InternalHostListener hostListener = new InternalHostListener();
private Object threadSchedulerLock = new Object();
private static int numOfEventsQueued = 0;
@@ -228,7 +235,6 @@ public class SegmentRoutingManager implements SegmentRoutingService {
log.debug("Creating EC map nsnextobjectivestore");
EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
-
nsNextObjStore = nsNextObjMapBuilder
.withName("nsnextobjectivestore")
.withSerializer(kryoBuilder)
@@ -239,16 +245,23 @@ public class SegmentRoutingManager implements SegmentRoutingService {
log.debug("Creating EC map subnetnextobjectivestore");
EventuallyConsistentMapBuilder<SubnetNextObjectiveStoreKey, Integer>
subnetNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
-
subnetNextObjStore = subnetNextObjMapBuilder
.withName("subnetnextobjectivestore")
.withSerializer(kryoBuilder)
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
+ log.debug("Creating EC map subnetnextobjectivestore");
+ EventuallyConsistentMapBuilder<PortNextObjectiveStoreKey, Integer>
+ portNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
+ portNextObjStore = portNextObjMapBuilder
+ .withName("portnextobjectivestore")
+ .withSerializer(kryoBuilder)
+ .withTimestampProvider((k, v) -> new WallClockTimestamp())
+ .build();
+
EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
storageService.eventuallyConsistentMapBuilder();
-
tunnelStore = tunnelMapBuilder
.withName("tunnelstore")
.withSerializer(kryoBuilder)
@@ -257,7 +270,6 @@ public class SegmentRoutingManager implements SegmentRoutingService {
EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder =
storageService.eventuallyConsistentMapBuilder();
-
policyStore = policyMapBuilder
.withName("policystore")
.withSerializer(kryoBuilder)
@@ -266,7 +278,6 @@ public class SegmentRoutingManager implements SegmentRoutingService {
EventuallyConsistentMapBuilder<SubnetAssignedVidStoreKey, VlanId>
subnetVidStoreMapBuilder = storageService.eventuallyConsistentMapBuilder();
-
subnetVidStore = subnetVidStoreMapBuilder
.withName("subnetvidstore")
.withSerializer(kryoBuilder)
@@ -425,8 +436,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
/**
* Returns the next objective ID for the given NeighborSet.
* If the nextObjective does not exist, a new one is created and
- * it's id is returned.
- * TODO move the side-effect creation of a Next Objective into a new method
+ * its id is returned.
*
* @param deviceId Device ID
* @param ns NegighborSet
@@ -441,18 +451,19 @@ public class SegmentRoutingManager implements SegmentRoutingService {
return groupHandlerMap
.get(deviceId).getNextObjectiveId(ns, meta);
} else {
- log.warn("getNextObjectiveId query in device {} not found", deviceId);
+ log.warn("getNextObjectiveId query - groupHandler for device {} "
+ + "not found", deviceId);
return -1;
}
}
/**
- * Returns the next objective ID for the Subnet given. If the nextObjectiveID does not exist,
- * a new one is created and returned.
+ * Returns the next objective ID for the given subnet prefix. It is expected
+ * that the next-objective has been pre-created from configuration.
*
* @param deviceId Device ID
* @param prefix Subnet
- * @return next objective ID
+ * @return next objective ID or -1 if it was not found
*/
public int getSubnetNextObjectiveId(DeviceId deviceId, IpPrefix prefix) {
if (groupHandlerMap.get(deviceId) != null) {
@@ -460,7 +471,33 @@ public class SegmentRoutingManager implements SegmentRoutingService {
return groupHandlerMap
.get(deviceId).getSubnetNextObjectiveId(prefix);
} else {
- log.warn("getSubnetNextObjectiveId query in device {} not found", deviceId);
+ log.warn("getSubnetNextObjectiveId query - groupHandler for "
+ + "device {} not found", deviceId);
+ return -1;
+ }
+ }
+
+ /**
+ * Returns the next objective ID for the given portNumber, given the treatment.
+ * There could be multiple different treatments to the same outport, which
+ * would result in different objectives. If the next object
+ * does not exist, a new one is created and its id is returned.
+ *
+ * @param deviceId Device ID
+ * @param portNum port number on device for which NextObjective is queried
+ * @param treatment the actions to apply on the packets (should include outport)
+ * @param meta metadata passed into the creation of a Next Objective if necessary
+ * @return next objective ID or -1 if it was not found
+ */
+ public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum,
+ TrafficTreatment treatment,
+ TrafficSelector meta) {
+ DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId);
+ if (ghdlr != null) {
+ return ghdlr.getPortNextObjectiveId(portNum, treatment, meta);
+ } else {
+ log.warn("getPortNextObjectiveId query - groupHandler for device {}"
+ + " not found", deviceId);
return -1;
}
}
@@ -475,7 +512,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
InboundPacket pkt = context.inPacket();
Ethernet ethernet = pkt.parsed();
-
+ log.trace("Rcvd pktin: {}", ethernet);
if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
arpHandler.processPacketIn(pkt);
} else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
@@ -517,6 +554,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
}
}
+ @SuppressWarnings("rawtypes")
private void scheduleEventHandlerIfNotScheduled(Event event) {
synchronized (threadSchedulerLock) {
eventQueue.add(event);
@@ -539,6 +577,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
public void run() {
try {
while (true) {
+ @SuppressWarnings("rawtypes")
Event event = null;
synchronized (threadSchedulerLock) {
if (!eventQueue.isEmpty()) {
@@ -647,7 +686,8 @@ public class SegmentRoutingManager implements SegmentRoutingService {
linkService,
flowObjectiveService,
nsNextObjStore,
- subnetNextObjStore);
+ subnetNextObjStore,
+ portNextObjStore);
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Aborting processDeviceAdded.");
return;
@@ -658,6 +698,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
// port addressing rules to the driver as well irrespective of whether
// this instance is the master or not.
defaultRoutingHandler.populatePortAddressingRules(device.id());
+ hostListener.readInitialHosts();
}
if (mastershipService.isLocalMaster(device.id())) {
DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
@@ -713,7 +754,8 @@ public class SegmentRoutingManager implements SegmentRoutingService {
linkService,
flowObjectiveService,
nsNextObjStore,
- subnetNextObjStore);
+ subnetNextObjStore,
+ portNextObjStore);
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Aborting configureNetwork.");
return;
@@ -725,6 +767,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
// port addressing rules to the driver as well, irrespective of whether
// this instance is the master or not.
defaultRoutingHandler.populatePortAddressingRules(device.id());
+ hostListener.readInitialHosts();
}
if (mastershipService.isLocalMaster(device.id())) {
DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
@@ -751,22 +794,66 @@ public class SegmentRoutingManager implements SegmentRoutingService {
}
}
+ // TODO Move bridging table population to a separate class
private class InternalHostListener implements HostListener {
+ private void readInitialHosts() {
+ hostService.getHosts().forEach(host -> {
+ MacAddress mac = host.mac();
+ VlanId vlanId = host.vlan();
+ DeviceId deviceId = host.location().deviceId();
+ PortNumber port = host.location().port();
+ Set<IpAddress> ips = host.ipAddresses();
+ log.debug("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port);
+
+ // Populate bridging table entry
+ ForwardingObjective.Builder fob =
+ getForwardingObjectiveBuilder(deviceId, mac, vlanId, port);
+ flowObjectiveService.forward(deviceId, fob.add(
+ new BridgingTableObjectiveContext(mac, vlanId)
+ ));
+
+ // Populate IP table entry
+ ips.forEach(ip -> {
+ if (ip.isIp4()) {
+ routingRulePopulator.populateIpRuleForHost(
+ deviceId, ip.getIp4Address(), mac, port);
+ }
+ });
+ });
+ }
+
private ForwardingObjective.Builder getForwardingObjectiveBuilder(
- MacAddress mac, VlanId vlanId, PortNumber port) {
+ DeviceId deviceId, MacAddress mac, VlanId vlanId,
+ PortNumber outport) {
+ // match rule
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
sbuilder.matchEthDst(mac);
sbuilder.matchVlanId(vlanId);
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
- // TODO Move popVlan from flow action to group action
tbuilder.immediate().popVlan();
- tbuilder.immediate().setOutput(port);
+ tbuilder.immediate().setOutput(outport);
+
+ // for switch pipelines that need it, provide outgoing vlan as metadata
+ VlanId outvlan = null;
+ Ip4Prefix subnet = deviceConfiguration.getPortSubnet(deviceId, outport);
+ if (subnet == null) {
+ outvlan = VlanId.vlanId(ASSIGNED_VLAN_NO_SUBNET);
+ } else {
+ outvlan = getSubnetAssignedVlanId(deviceId, subnet);
+ }
+ TrafficSelector meta = DefaultTrafficSelector.builder()
+ .matchVlanId(outvlan).build();
+
+ // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed.
+ int portNextObjId = getPortNextObjectiveId(deviceId, outport,
+ tbuilder.build(),
+ meta);
return DefaultForwardingObjective.builder()
.withFlag(ForwardingObjective.Flag.SPECIFIC)
.withSelector(sbuilder.build())
- .withTreatment(tbuilder.build())
+ .nextStep(portNextObjId)
.withPriority(100)
.fromApp(appId)
.makePermanent();
@@ -778,12 +865,13 @@ public class SegmentRoutingManager implements SegmentRoutingService {
DeviceId deviceId = event.subject().location().deviceId();
PortNumber port = event.subject().location().port();
Set<IpAddress> ips = event.subject().ipAddresses();
- log.debug("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port);
+ log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port);
- // TODO Move bridging table population to a separate class
// Populate bridging table entry
+ log.debug("Populate L2 table entry for host {} at {}:{}",
+ mac, deviceId, port);
ForwardingObjective.Builder fob =
- getForwardingObjectiveBuilder(mac, vlanId, port);
+ getForwardingObjectiveBuilder(deviceId, mac, vlanId, port);
flowObjectiveService.forward(deviceId, fob.add(
new BridgingTableObjectiveContext(mac, vlanId)
));
@@ -807,7 +895,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
// Revoke bridging table entry
ForwardingObjective.Builder fob =
- getForwardingObjectiveBuilder(mac, vlanId, port);
+ getForwardingObjectiveBuilder(deviceId, mac, vlanId, port);
flowObjectiveService.forward(deviceId, fob.remove(
new BridgingTableObjectiveContext(mac, vlanId)
));
@@ -835,7 +923,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
// Revoke previous bridging table entry
ForwardingObjective.Builder prevFob =
- getForwardingObjectiveBuilder(mac, vlanId, prevPort);
+ getForwardingObjectiveBuilder(prevDeviceId, mac, vlanId, prevPort);
flowObjectiveService.forward(prevDeviceId, prevFob.remove(
new BridgingTableObjectiveContext(mac, vlanId)
));
@@ -850,7 +938,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
// Populate new bridging table entry
ForwardingObjective.Builder newFob =
- getForwardingObjectiveBuilder(mac, vlanId, prevPort);
+ getForwardingObjectiveBuilder(newDeviceId, mac, vlanId, newPort);
flowObjectiveService.forward(newDeviceId, newFob.add(
new BridgingTableObjectiveContext(mac, vlanId)
));
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
index b86adada..5a82e712 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
@@ -158,7 +158,7 @@ public class TunnelHandler {
private int createGroupsForTunnel(Tunnel tunnel) {
- List<Integer> portNumbers;
+ Set<Integer> portNumbers;
final int groupError = -1;
DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0));
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
index 0ad00679..dbac596d 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
@@ -16,7 +16,6 @@
package org.onosproject.segmentrouting.config;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.MacAddress;
@@ -26,7 +25,6 @@ import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.segmentrouting.config.SegmentRoutingConfig.AdjacencySid;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.slf4j.Logger;
@@ -34,6 +32,7 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -60,7 +59,7 @@ public class DeviceConfiguration implements DeviceProperties {
boolean isEdge;
HashMap<PortNumber, Ip4Address> gatewayIps;
HashMap<PortNumber, Ip4Prefix> subnets;
- List<AdjacencySid> adjacencySids;
+ Map<Integer, Set<Integer>> adjacencySids;
public SegmentRouterInfo() {
this.gatewayIps = new HashMap<>();
@@ -83,11 +82,11 @@ public class DeviceConfiguration implements DeviceProperties {
cfgService.getConfig(subject, SegmentRoutingConfig.class);
SegmentRouterInfo info = new SegmentRouterInfo();
info.deviceId = subject;
- info.nodeSid = config.getSid();
- info.ip = config.getIp();
- info.mac = config.getMac();
+ info.nodeSid = config.nodeSid();
+ info.ip = config.routerIp();
+ info.mac = config.routerMac();
info.isEdge = config.isEdgeRouter();
- info.adjacencySids = config.getAdjacencySids();
+ info.adjacencySids = config.adjacencySids();
this.deviceConfigMap.put(info.deviceId, info);
this.allSegmentIds.add(info.nodeSid);
@@ -410,19 +409,13 @@ public class DeviceConfiguration implements DeviceProperties {
*
* @param deviceId device identification of the router
* @param sid adjacency Sid
- * @return list of port numbers
+ * @return set of port numbers
*/
- public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
+ public Set<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
- if (srinfo != null) {
- for (AdjacencySid asid : srinfo.adjacencySids) {
- if (asid.getAsid() == sid) {
- return asid.getPorts();
- }
- }
- }
-
- return Lists.newArrayList();
+ return srinfo != null ?
+ ImmutableSet.copyOf(srinfo.adjacencySids.get(sid)) :
+ ImmutableSet.copyOf(new HashSet<>());
}
/**
@@ -435,20 +428,6 @@ public class DeviceConfiguration implements DeviceProperties {
*/
public boolean isAdjacencySid(DeviceId deviceId, int sid) {
SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
- if (srinfo != null) {
- if (srinfo.adjacencySids.isEmpty()) {
- return false;
- } else {
- for (AdjacencySid asid:
- srinfo.adjacencySids) {
- if (asid.getAsid() == sid) {
- return true;
- }
- }
- return false;
- }
- }
-
- return false;
+ return srinfo != null && srinfo.adjacencySids.containsKey(sid);
}
} \ No newline at end of file
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java
index 6dc3f0db..f788925c 100644
--- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java
@@ -16,113 +16,210 @@
package org.onosproject.segmentrouting.config;
+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.ImmutableMap;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.Config;
-import org.onosproject.net.config.basics.BasicElementConfig;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Optional;
+import java.util.Set;
/**
* Configuration object for Segment Routing Application.
*/
public class SegmentRoutingConfig extends Config<DeviceId> {
- private static final String NAME = "name";
- private static final String IP = "routerIp";
- private static final String MAC = "routerMac";
- private static final String SID = "nodeSid";
- private static final String EDGE = "isEdgeRouter";
- private static final String ADJSID = "adjacencySids";
-
- public Optional<String> getName() {
+ public static final String NAME = "name";
+ public static final String IP = "routerIp";
+ public static final String MAC = "routerMac";
+ public static final String SID = "nodeSid";
+ public static final String EDGE = "isEdgeRouter";
+ public static final String ADJSIDS = "adjacencySids";
+ public static final String ADJSID = "adjSid";
+ public static final String PORTS = "ports";
+
+ @Override
+ public boolean isValid() {
+ return hasOnlyFields(NAME, IP, MAC, SID, EDGE, ADJSIDS, ADJSID, PORTS) &&
+ this.name() != null &&
+ this.routerIp() != null &&
+ this.routerMac() != null &&
+ this.nodeSid() != -1 &&
+ this.isEdgeRouter() != null &&
+ this.adjacencySids() != null;
+ }
+
+ /**
+ * Gets the name of the router.
+ *
+ * @return Optional name of the router. May be empty if not configured.
+ */
+ public Optional<String> name() {
String name = get(NAME, null);
return name != null ? Optional.of(name) : Optional.empty();
}
- public BasicElementConfig setName(String name) {
- return (BasicElementConfig) setOrClear(NAME, name);
+ /**
+ * Sets the name of the router.
+ *
+ * @param name name of the router.
+ * @return the config of the router.
+ */
+ public SegmentRoutingConfig setName(String name) {
+ return (SegmentRoutingConfig) setOrClear(NAME, name);
}
- public Ip4Address getIp() {
+ /**
+ * Gets the IP address of the router.
+ *
+ * @return IP address of the router. Or null if not configured.
+ */
+ public Ip4Address routerIp() {
String ip = get(IP, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
}
- public BasicElementConfig setIp(String ip) {
- return (BasicElementConfig) setOrClear(IP, ip);
+ /**
+ * Sets the IP address of the router.
+ *
+ * @param ip IP address of the router.
+ * @return the config of the router.
+ */
+ public SegmentRoutingConfig setRouterIp(String ip) {
+ return (SegmentRoutingConfig) setOrClear(IP, ip);
}
- public MacAddress getMac() {
+ /**
+ * Gets the MAC address of the router.
+ *
+ * @return MAC address of the router. Or null if not configured.
+ */
+ public MacAddress routerMac() {
String mac = get(MAC, null);
return mac != null ? MacAddress.valueOf(mac) : null;
}
- public BasicElementConfig setMac(String mac) {
- return (BasicElementConfig) setOrClear(MAC, mac);
+ /**
+ * Sets the MAC address of the router.
+ *
+ * @param mac MAC address of the router.
+ * @return the config of the router.
+ */
+ public SegmentRoutingConfig setRouterMac(String mac) {
+ return (SegmentRoutingConfig) setOrClear(MAC, mac);
}
- public int getSid() {
+ /**
+ * Gets the node SID of the router.
+ *
+ * @return node SID of the router. Or -1 if not configured.
+ */
+ public int nodeSid() {
return get(SID, -1);
}
- public BasicElementConfig setSid(int sid) {
- return (BasicElementConfig) setOrClear(SID, sid);
+ /**
+ * Sets the node SID of the router.
+ *
+ * @param sid node SID of the router.
+ * @return the config of the router.
+ */
+ public SegmentRoutingConfig setNodeSid(int sid) {
+ return (SegmentRoutingConfig) setOrClear(SID, sid);
}
- public boolean isEdgeRouter() {
- return get(EDGE, false);
+ /**
+ * Checks if the router is an edge router.
+ *
+ * @return true if the router is an edge router.
+ * false if the router is not an edge router.
+ * null if the value is not configured.
+ */
+ public Boolean isEdgeRouter() {
+ String isEdgeRouter = get(EDGE, null);
+ return isEdgeRouter != null ?
+ Boolean.valueOf(isEdgeRouter) :
+ null;
}
- public BasicElementConfig setEdgeRouter(boolean isEdgeRouter) {
- return (BasicElementConfig) setOrClear(EDGE, isEdgeRouter);
+ /**
+ * Specifies if the router is an edge router.
+ *
+ * @param isEdgeRouter true if the router is an edge router.
+ * @return the config of the router.
+ */
+ public SegmentRoutingConfig setIsEdgeRouter(boolean isEdgeRouter) {
+ return (SegmentRoutingConfig) setOrClear(EDGE, isEdgeRouter);
}
- public List<AdjacencySid> getAdjacencySids() {
- ArrayList<AdjacencySid> adjacencySids = new ArrayList<>();
-
- if (!object.has(ADJSID)) {
- return adjacencySids;
+ /**
+ * Gets the adjacency SIDs of the router.
+ *
+ * @return adjacency SIDs of the router. Or null if not configured.
+ */
+ public Map<Integer, Set<Integer>> adjacencySids() {
+ if (!object.has(ADJSIDS)) {
+ return null;
}
- ArrayNode adjacencySidNodes = (ArrayNode) object.path(ADJSID);
- adjacencySidNodes.forEach(adjacencySidNode -> {
- int asid = adjacencySidNode.path(AdjacencySid.ASID).asInt();
-
- ArrayList<Integer> ports = new ArrayList<Integer>();
- ArrayNode portsNodes = (ArrayNode) adjacencySidNode.path(AdjacencySid.PORTS);
- portsNodes.forEach(portNode -> {
- ports.add(portNode.asInt());
- });
-
- AdjacencySid adjacencySid = new AdjacencySid(asid, ports);
- adjacencySids.add(adjacencySid);
- });
+ Map<Integer, Set<Integer>> adjacencySids = new HashMap<>();
+ ArrayNode adjacencySidsNode = (ArrayNode) object.path(ADJSIDS);
+ for (JsonNode adjacencySidNode : adjacencySidsNode) {
+ int asid = adjacencySidNode.path(ADJSID).asInt(-1);
+ if (asid == -1) {
+ return null;
+ }
+
+ HashSet<Integer> ports = new HashSet<>();
+ ArrayNode portsNode = (ArrayNode) adjacencySidNode.path(PORTS);
+ for (JsonNode portNode : portsNode) {
+ int port = portNode.asInt(-1);
+ if (port == -1) {
+ return null;
+ }
+ ports.add(port);
+ }
+ adjacencySids.put(asid, ports);
+ }
- return adjacencySids;
+ return ImmutableMap.copyOf(adjacencySids);
}
- public class AdjacencySid {
- private static final String ASID = "adjSid";
- private static final String PORTS = "ports";
-
- int asid;
- List<Integer> ports;
-
- public AdjacencySid(int asid, List<Integer> ports) {
- this.asid = asid;
- this.ports = ports;
- }
+ /**
+ * Sets the adjacency SIDs of the router.
+ *
+ * @param adjacencySids adjacency SIDs of the router.
+ * @return the config of the router.
+ */
+ public SegmentRoutingConfig setAdjacencySids(Map<Integer, Set<Integer>> adjacencySids) {
+ if (adjacencySids == null) {
+ object.remove(ADJSIDS);
+ } else {
+ ArrayNode adjacencySidsNode = mapper.createArrayNode();
+
+ adjacencySids.forEach((sid, ports) -> {
+ ObjectNode adjacencySidNode = mapper.createObjectNode();
+
+ adjacencySidNode.put(ADJSID, sid);
+
+ ArrayNode portsNode = mapper.createArrayNode();
+ ports.forEach(port -> {
+ portsNode.add(port.toString());
+ });
+ adjacencySidNode.set(PORTS, portsNode);
+
+ adjacencySidsNode.add(adjacencySidNode);
+ });
- public int getAsid() {
- return asid;
+ object.set(ADJSIDS, adjacencySidsNode);
}
- public List<Integer> getPorts() {
- return ports;
- }
+ return this;
}
} \ No newline at end of file
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 6b6d960a..32c53654 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
@@ -56,9 +56,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
- Integer> subnetNextObjStore) {
+ Integer> subnetNextObjStore,
+ EventuallyConsistentMap<PortNextObjectiveStoreKey,
+ Integer> portNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService,
- nsNextObjStore, subnetNextObjStore);
+ nsNextObjStore, subnetNextObjStore, portNextObjStore);
}
@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 e792bf66..bc394b84 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
@@ -80,6 +80,8 @@ public class DefaultGroupHandler {
NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null;
protected EventuallyConsistentMap<
SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null;
+ protected EventuallyConsistentMap<
+ PortNextObjectiveStoreKey, Integer> portNextObjStore = null;
protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
.register(URI.class).register(HashSet.class)
@@ -93,11 +95,12 @@ public class DefaultGroupHandler {
DeviceProperties config,
LinkService linkService,
FlowObjectiveService flowObjService,
- EventuallyConsistentMap<
- NeighborSetNextObjectiveStoreKey,
+ EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
- Integer> subnetNextObjStore) {
+ Integer> subnetNextObjStore,
+ EventuallyConsistentMap<PortNextObjectiveStoreKey,
+ Integer> portNextObjStore) {
this.deviceId = checkNotNull(deviceId);
this.appId = checkNotNull(appId);
this.deviceConfig = checkNotNull(config);
@@ -114,6 +117,7 @@ public class DefaultGroupHandler {
this.flowObjectiveService = flowObjService;
this.nsNextObjStore = nsNextObjStore;
this.subnetNextObjStore = subnetNextObjStore;
+ this.portNextObjStore = portNextObjStore;
populateNeighborMaps();
}
@@ -133,30 +137,34 @@ public class DefaultGroupHandler {
* @throws DeviceConfigNotFoundException if the device configuration is not found
* @return default group handler type
*/
- public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
- ApplicationId appId,
- DeviceProperties config,
- LinkService linkService,
- FlowObjectiveService flowObjService,
- EventuallyConsistentMap<
- NeighborSetNextObjectiveStoreKey,
- Integer> nsNextObjStore,
- EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
- Integer> subnetNextObjStore)
- throws DeviceConfigNotFoundException {
+ public static DefaultGroupHandler createGroupHandler(
+ DeviceId deviceId,
+ ApplicationId appId,
+ DeviceProperties config,
+ LinkService linkService,
+ FlowObjectiveService flowObjService,
+ EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
+ Integer> nsNextObjStore,
+ EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
+ Integer> subnetNextObjStore,
+ EventuallyConsistentMap<PortNextObjectiveStoreKey,
+ Integer> portNextObjStore)
+ throws DeviceConfigNotFoundException {
// handle possible exception in the caller
if (config.isEdgeDevice(deviceId)) {
return new DefaultEdgeGroupHandler(deviceId, appId, config,
linkService,
flowObjService,
nsNextObjStore,
- subnetNextObjStore);
+ subnetNextObjStore,
+ portNextObjStore);
} else {
return new DefaultTransitGroupHandler(deviceId, appId, config,
linkService,
flowObjService,
nsNextObjStore,
- subnetNextObjStore);
+ subnetNextObjStore,
+ portNextObjStore);
}
}
@@ -231,25 +239,21 @@ public class DefaultGroupHandler {
Integer nextId = nsNextObjStore.
get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
- if (nextId != null) {
+ if (nextId != null && isMaster) {
NextObjective.Builder nextObjBuilder = DefaultNextObjective
.builder().withId(nextId)
.withType(NextObjective.Type.HASHED).fromApp(appId);
nextObjBuilder.addTreatment(tBuilder.build());
-
log.info("**linkUp in device {}: Adding Bucket "
- + "with Port {} to next object id {} and amIMaster:{}",
+ + "with Port {} to next object id {}",
deviceId,
newLink.src().port(),
- nextId, isMaster);
-
- if (isMaster) {
- NextObjective nextObjective = nextObjBuilder.
- addToExisting(new SRNextObjectiveContext(deviceId));
- flowObjectiveService.next(deviceId, nextObjective);
- }
- } else {
+ nextId);
+ NextObjective nextObjective = nextObjBuilder.
+ addToExisting(new SRNextObjectiveContext(deviceId));
+ flowObjectiveService.next(deviceId, nextObjective);
+ } else if (isMaster) {
log.warn("linkUp in device {}, but global store has no record "
+ "for neighbor-set {}", deviceId, ns);
}
@@ -331,8 +335,8 @@ public class DefaultGroupHandler {
}
/**
- * Returns the next objective associated with the neighborset.
- * If there is no next objective for this neighborset, this API
+ * Returns the next objective of type hashed associated with the neighborset.
+ * If there is no next objective for this neighborset, this method
* would create a next objective and return. Optionally metadata can be
* passed in for the creation of the next objective.
*
@@ -372,9 +376,10 @@ 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.
+ * Returns the next objective of type broadcast associated with the subnet,
+ * or -1 if no such objective exists. Note that this method does NOT create
+ * the next objective as a side-effect. It is expected that is objective is
+ * created at startup from network configuration.
*
* @param prefix subnet information
* @return int if found or -1
@@ -387,6 +392,38 @@ public class DefaultGroupHandler {
}
/**
+ * Returns the next objective of type simple associated with the port on the
+ * device, given the treatment. Different treatments to the same port result
+ * in different next objectives. If no such objective exists, this method
+ * creates one and returns the id. Optionally metadata can be passed in for
+ * the creation of the objective.
+ *
+ * @param portNum the port number for the simple next objective
+ * @param treatment the actions to apply on the packets (should include outport)
+ * @param meta optional metadata passed into the creation of the next objective
+ * @return int if found or created, -1 if there are errors during the
+ * creation of the next objective.
+ */
+ public int getPortNextObjectiveId(PortNumber portNum, TrafficTreatment treatment,
+ TrafficSelector meta) {
+ Integer nextId = portNextObjStore.
+ get(new PortNextObjectiveStoreKey(deviceId, portNum, treatment));
+ if (nextId == null) {
+ log.trace("getPortNextObjectiveId in device{}: Next objective id "
+ + "not found for {} and {} creating", deviceId, portNum);
+ createGroupFromPort(portNum, treatment, meta);
+ nextId = portNextObjStore.get(
+ new PortNextObjectiveStoreKey(deviceId, portNum, treatment));
+ if (nextId == null) {
+ log.warn("getPortNextObjectiveId: unable to create next obj"
+ + "for dev:{} port{}", deviceId, portNum);
+ return -1;
+ }
+ }
+ return nextId;
+ }
+
+ /**
* Checks if the next objective ID (group) for the neighbor set exists or not.
*
* @param ns neighbor set to check
@@ -561,7 +598,7 @@ public class DefaultGroupHandler {
}
}
if (meta != null) {
- nextObjBuilder.setMeta(meta);
+ nextObjBuilder.withMeta(meta);
}
NextObjective nextObj = nextObjBuilder.
add(new SRNextObjectiveContext(deviceId));
@@ -574,7 +611,10 @@ public class DefaultGroupHandler {
}
}
-
+ /**
+ * Creates broadcast groups for all ports in the same configured subnet.
+ *
+ */
public void createGroupsFromSubnetConfig() {
Map<Ip4Prefix, List<PortNumber>> subnetPortMap =
this.deviceConfig.getSubnetPortsMap(this.deviceId);
@@ -612,6 +652,37 @@ public class DefaultGroupHandler {
});
}
+
+ /**
+ * Create simple next objective for a single port. The treatments can include
+ * all outgoing actions that need to happen on the packet.
+ *
+ * @param portNum the outgoing port on the device
+ * @param treatment the actions to apply on the packets (should include outport)
+ * @param meta optional data to pass to the driver
+ */
+ public void createGroupFromPort(PortNumber portNum, TrafficTreatment treatment,
+ TrafficSelector meta) {
+ int nextId = flowObjectiveService.allocateNextId();
+ PortNextObjectiveStoreKey key = new PortNextObjectiveStoreKey(
+ deviceId, portNum, treatment);
+
+ NextObjective.Builder nextObjBuilder = DefaultNextObjective
+ .builder().withId(nextId)
+ .withType(NextObjective.Type.SIMPLE)
+ .addTreatment(treatment)
+ .fromApp(appId)
+ .withMeta(meta);
+
+ NextObjective nextObj = nextObjBuilder.add();
+ flowObjectiveService.next(deviceId, nextObj);
+ log.debug("createGroupFromPort: Submited next objective {} in device {} "
+ + "for port {}", nextId, deviceId, portNum);
+
+ portNextObjStore.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 14d77ba6..7a43e73d 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
@@ -50,9 +50,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
- Integer> subnetNextObjStore) {
+ Integer> subnetNextObjStore,
+ EventuallyConsistentMap<PortNextObjectiveStoreKey,
+ Integer> portNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService,
- nsNextObjStore, subnetNextObjStore);
+ nsNextObjStore, subnetNextObjStore, portNextObjStore);
}
@Override
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 55142078..ef143dc7 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
@@ -68,9 +68,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
- Integer> subnetNextObjStore) {
+ Integer> subnetNextObjStore,
+ EventuallyConsistentMap<PortNextObjectiveStoreKey,
+ Integer> portNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService,
- nsNextObjStore, subnetNextObjStore);
+ nsNextObjStore, subnetNextObjStore, portNextObjStore);
}
public PolicyGroupIdentifier createPolicyGroupChain(String id,
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java
new file mode 100644
index 00000000..5555565c
--- /dev/null
+++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java
@@ -0,0 +1,77 @@
+package org.onosproject.segmentrouting.grouphandler;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.TrafficTreatment;
+
+import java.util.Objects;
+
+/**
+ * Class definition of Key for Device/Port to NextObjective store. Since there
+ * can be multiple next objectives to the same physical port, we differentiate
+ * between them by including the treatment in the key.
+ */
+public class PortNextObjectiveStoreKey {
+ private final DeviceId deviceId;
+ private final PortNumber portNum;
+ private final TrafficTreatment treatment;
+
+ public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum,
+ TrafficTreatment treatment) {
+ this.deviceId = deviceId;
+ this.portNum = portNum;
+ this.treatment = treatment;
+ }
+
+ /**
+ * Gets device id in this PortNextObjectiveStoreKey.
+ *
+ * @return device id
+ */
+ public DeviceId deviceId() {
+ return deviceId;
+ }
+
+ /**
+ * Gets port information in this PortNextObjectiveStoreKey.
+ *
+ * @return port information
+ */
+ public PortNumber portNumber() {
+ return portNum;
+ }
+
+ /**
+ * Gets treatment information in this PortNextObjectiveStoreKey.
+ *
+ * @return treatment information
+ */
+ public TrafficTreatment treatment() {
+ return treatment;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof PortNextObjectiveStoreKey)) {
+ return false;
+ }
+ PortNextObjectiveStoreKey that =
+ (PortNextObjectiveStoreKey) o;
+ return (Objects.equals(this.deviceId, that.deviceId) &&
+ Objects.equals(this.portNum, that.portNum) &&
+ Objects.equals(this.treatment, that.treatment));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(deviceId, portNum, treatment);
+ }
+
+ @Override
+ public String toString() {
+ return "Device: " + deviceId + " Port: " + portNum + " Treatment: " + treatment;
+ }
+}
diff --git a/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java b/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java
new file mode 100644
index 00000000..3e5daa5b
--- /dev/null
+++ b/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for class {@link SegmentRoutingConfig}.
+ */
+public class SegmentRoutingConfigTest {
+ private SegmentRoutingConfig config;
+ private Map<Integer, Set<Integer>> adjacencySids1;
+ private Map<Integer, Set<Integer>> adjacencySids2;
+
+ @Before
+ public void setUp() throws Exception {
+ String jsonString = "{" +
+ "\"name\" : \"Leaf-R1\"," +
+ "\"nodeSid\" : 101," +
+ "\"routerIp\" : \"10.0.1.254\"," +
+ "\"routerMac\" : \"00:00:00:00:01:80\"," +
+ "\"isEdgeRouter\" : true," +
+ "\"adjacencySids\" : [" +
+ " { \"adjSid\" : 100, \"ports\" : [2, 3] }," +
+ " { \"adjSid\" : 200, \"ports\" : [4, 5] }" +
+ "]}";
+
+ adjacencySids1 = new HashMap<>();
+ Set<Integer> ports1 = new HashSet<>();
+ ports1.add(2);
+ ports1.add(3);
+ adjacencySids1.put(100, ports1);
+ Set<Integer> ports2 = new HashSet<>();
+ ports2.add(4);
+ ports2.add(5);
+ adjacencySids1.put(200, ports2);
+
+ adjacencySids2 = new HashMap<>();
+ Set<Integer> ports3 = new HashSet<>();
+ ports3.add(6);
+ adjacencySids2.put(300, ports3);
+
+ DeviceId subject = DeviceId.deviceId("of:0000000000000001");
+ String key = "org.onosproject.segmentrouting";
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonNode = mapper.readTree(jsonString);
+ ConfigApplyDelegate delegate = new MockDelegate();
+
+ config = new SegmentRoutingConfig();
+ config.init(subject, key, jsonNode, mapper, delegate);
+ }
+
+ @Test
+ public void testName() throws Exception {
+ assertTrue(config.name().isPresent());
+ assertThat(config.name().get(), is("Leaf-R1"));
+ }
+
+ @Test
+ public void testSetName() throws Exception {
+ config.setName("Spine-R1");
+ assertTrue(config.name().isPresent());
+ assertThat(config.name().get(), is("Spine-R1"));
+ }
+
+ @Test
+ public void testRouterIp() throws Exception {
+ assertThat(config.routerIp(), is(IpAddress.valueOf("10.0.1.254")));
+ }
+
+ @Test
+ public void testSetRouterIp() throws Exception {
+ config.setRouterIp("10.0.2.254");
+ assertThat(config.routerIp(), is(IpAddress.valueOf("10.0.2.254")));
+ }
+
+ @Test
+ public void testRouterMac() throws Exception {
+ assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:01:80")));
+ }
+
+ @Test
+ public void testSetRouterMac() throws Exception {
+ config.setRouterMac("00:00:00:00:02:80");
+ assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:02:80")));
+ }
+
+ @Test
+ public void testNodeSid() throws Exception {
+ assertThat(config.nodeSid(), is(101));
+ }
+
+ @Test
+ public void testSetNodeSid() throws Exception {
+ config.setNodeSid(200);
+ assertThat(config.nodeSid(), is(200));
+ }
+
+ @Test
+ public void testIsEdgeRouter() throws Exception {
+ assertThat(config.isEdgeRouter(), is(true));
+ }
+
+ @Test
+ public void testSetIsEdgeRouter() throws Exception {
+ config.setIsEdgeRouter(false);
+ assertThat(config.isEdgeRouter(), is(false));
+ }
+
+ @Test
+ public void testAdjacencySids() throws Exception {
+ assertThat(config.adjacencySids(), is(adjacencySids1));
+ }
+
+ @Test
+ public void testSetAdjacencySids() throws Exception {
+ config.setAdjacencySids(adjacencySids2);
+ assertThat(config.adjacencySids(), is(adjacencySids2));
+ }
+
+ private class MockDelegate implements ConfigApplyDelegate {
+ @Override
+ public void onApply(Config config) {
+ }
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java
index 8c160e85..cae5455d 100644
--- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java
+++ b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java
@@ -106,7 +106,7 @@ public class IntentPerfCollector {
/**
* Clears all previously accumulated data.
*/
- public void clearSamples() {
+ public synchronized void clearSamples() {
newestTime = 0;
overall = new Sample(0, nodes.length);
current = new Sample(0, nodes.length);
diff --git a/framework/src/onos/apps/vtn/pom.xml b/framework/src/onos/apps/vtn/pom.xml
index a42f91a0..e4528517 100644
--- a/framework/src/onos/apps/vtn/pom.xml
+++ b/framework/src/onos/apps/vtn/pom.xml
@@ -61,6 +61,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ <scope>test</scope>
+ <classifier>tests</classifier>
+ </dependency>
+ <dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
</dependency>
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java
index e91e6b69..0ed42fcf 100644
--- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java
@@ -15,29 +15,37 @@
*/
package org.onosproject.sfc.forwarder;
-import org.onosproject.core.ApplicationId;
import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.NshServicePathId;
import org.onosproject.vtnrsc.PortChain;
/**
* Abstraction of an entity which provides Service function forwarder.
*/
-public interface ServiceFunctionForwarder {
+public interface ServiceFunctionForwarderService {
/**
- * Install Service function chain.
+ * Install Forwarding rule.
*
- * @param portChain Port chain
+ * @param portChain port-chain
+ * @param nshSPI nsh spi
*/
- void install(PortChain portChain);
+ void installForwardingRule(PortChain portChain, NshServicePathId nshSPI);
/**
- * Programs forwarding object for Service Function.
+ * Uninstall Forwarding rule.
*
- * @param portChain port chain
- * @param appid application id
+ * @param portChain port-chain
+ * @param nshSPI nsh spi
+ */
+ void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSPI);
+
+ /**
+ * Prepare forwarding object for Service Function.
+ *
+ * @param portChain port-chain
+ * @param nshSPI nsh spi
* @param type forwarding objective operation type
*/
- void programServiceFunctionForwarder(PortChain portChain, ApplicationId appid,
- Objective.Operation type);
+ void prepareServiceFunctionForwarder(PortChain portChain, NshServicePathId nshSPI, Objective.Operation type);
}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java
new file mode 100644
index 00000000..2846ee01
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java
@@ -0,0 +1,293 @@
+/*
+ * 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.forwarder.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.behaviour.ExtensionSelectorResolver;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NshServicePathId;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+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.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.service.VtnRscService;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.portchain.PortChainService;
+import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService;
+
+import org.slf4j.Logger;
+
+/**
+ * Provides Service Function Forwarder implementation.
+ */
+public class ServiceFunctionForwarderImpl implements ServiceFunctionForwarderService {
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DriverService driverService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VirtualPortService virtualPortService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VtnRscService vtnRscService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairService portPairService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairGroupService portPairGroupService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowClassifierService flowClassifierService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortChainService portChainService;
+
+ private final Logger log = getLogger(getClass());
+ protected ApplicationId appId;
+ protected FlowObjectiveService flowObjectiveService;
+
+ private static final String DRIVER_NAME = "onosfw";
+ private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null";
+ private static final String PORT_CHAIN_ID_NOT_NULL = "Port-Chain-Id cannot be null";
+ private static final String APP_ID_NOT_NULL = "Application-Id cannot be null";
+ private static final int NULL = 0;
+
+ /**
+ * Default constructor.
+ */
+ public ServiceFunctionForwarderImpl() {
+ }
+
+ /**
+ * Explicit constructor.
+ */
+ public ServiceFunctionForwarderImpl(ApplicationId appId) {
+ this.appId = checkNotNull(appId, APP_ID_NOT_NULL);
+ ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+ this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
+ }
+
+ @Override
+ public void installForwardingRule(PortChain portChain, NshServicePathId nshSPI) {
+ checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+ prepareServiceFunctionForwarder(portChain, nshSPI, Objective.Operation.ADD);
+ }
+
+ @Override
+ public void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSPI) {
+ checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+ prepareServiceFunctionForwarder(portChain, nshSPI, Objective.Operation.REMOVE);
+ }
+
+ @Override
+ public void prepareServiceFunctionForwarder(PortChain portChain, NshServicePathId nshSPI,
+ Objective.Operation type) {
+
+ // Go through the port pair group list
+ List<PortPairGroupId> portPairGrpList = portChain.portPairGroups();
+ ListIterator<PortPairGroupId> listGrpIterator = portPairGrpList.listIterator();
+
+ // Get source port pair group
+ if (!listGrpIterator.hasNext()) {
+ return;
+ }
+ PortPairGroupId portPairGrpId = listGrpIterator.next();
+ PortPairGroup currentPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);
+
+ // Get destination port pair group
+ if (!listGrpIterator.hasNext()) {
+ return;
+ }
+ portPairGrpId = listGrpIterator.next();
+ PortPairGroup nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);
+
+ // push SFF to OVS
+ pushServiceFunctionForwarder(currentPortPairGroup, nextPortPairGroup, listGrpIterator, nshSPI, type);
+ }
+
+ /**
+ * Push service-function-forwarder to OVS.
+ *
+ * @param currentPortPairGroup current port-pair-group
+ * @param nextPortPairGroup next port-pair-group
+ * @param listGrpIterator pointer to port-pair-group list
+ */
+ public void pushServiceFunctionForwarder(PortPairGroup currentPortPairGroup, PortPairGroup nextPortPairGroup,
+ ListIterator<PortPairGroupId> listGrpIterator, NshServicePathId nshSPI, Objective.Operation type) {
+ MacAddress srcMacAddress = null;
+ MacAddress dstMacAddress = null;
+ DeviceId deviceId = null;
+ DeviceId currentDeviceId = null;
+ DeviceId nextDeviceId = null;
+ PortPairGroupId portPairGrpId = null;
+
+ // Travel from SF to SF.
+ do {
+ // Get the required information on port pairs from source port pair
+ // group
+ List<PortPairId> portPairList = currentPortPairGroup.portPairs();
+ ListIterator<PortPairId> portPLIterator = portPairList.listIterator();
+ if (!portPLIterator.hasNext()) {
+ break;
+ }
+
+ PortPairId portPairId = portPLIterator.next();
+ PortPair portPair = portPairService.getPortPair(portPairId);
+
+ currentDeviceId = vtnRscService.getSFToSFFMaping(VirtualPortId.portId(portPair.ingress()));
+ if (deviceId == null) {
+ deviceId = currentDeviceId;
+ }
+ srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();
+ dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
+
+ // pack traffic selector
+ TrafficSelector.Builder selector = packTrafficSelector(deviceId, srcMacAddress, dstMacAddress, nshSPI);
+
+ // Get the required information on port pairs from destination port
+ // pair group
+ portPairList = nextPortPairGroup.portPairs();
+ portPLIterator = portPairList.listIterator();
+ if (!portPLIterator.hasNext()) {
+ break;
+ }
+
+ portPairId = portPLIterator.next();
+ portPair = portPairService.getPortPair(portPairId);
+
+ nextDeviceId = vtnRscService.getSFToSFFMaping(VirtualPortId.portId(portPair.ingress()));
+
+ // pack traffic treatment
+ TrafficTreatment.Builder treatment = packTrafficTreatment(currentDeviceId, nextDeviceId, portPair);
+
+ // Send SFF to OVS
+ sendServiceFunctionForwarder(selector, treatment, deviceId, type);
+
+ // Replace source port pair group with destination port pair group
+ // for moving to next SFF processing.
+ currentPortPairGroup = nextPortPairGroup;
+ if (!listGrpIterator.hasNext()) {
+ break;
+ }
+ portPairGrpId = listGrpIterator.next();
+ nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId);
+ } while (true);
+ }
+
+ /**
+ * Pack Traffic selector.
+ *
+ * @param deviceId device id
+ * @param srcMacAddress source mac-address
+ * @param dstMacAddress destination mac-address
+ * @param nshSPI nsh spi
+ * @return traffic treatment
+ */
+ public TrafficSelector.Builder packTrafficSelector(DeviceId deviceId, MacAddress srcMacAddress,
+ MacAddress dstMacAddress, NshServicePathId nshSPI) {
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ selector.matchEthSrc(srcMacAddress);
+ selector.matchEthDst(dstMacAddress);
+
+ DriverHandler handler = driverService.createHandler(deviceId);
+ ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class);
+ ExtensionSelector nspSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type());
+
+ try {
+ nspSpiSelector.setPropertyValue("nshSpi", nshSPI);
+ } catch (Exception e) {
+ log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId);
+ }
+
+ selector.extension(nspSpiSelector, deviceId);
+ return selector;
+ }
+
+ /**
+ * Pack Traffic treatment.
+ *
+ * @param currentDeviceId current device id
+ * @param nextDeviceId next device id
+ * @param portPair port-pair
+ * @return traffic treatment
+ */
+ public TrafficTreatment.Builder packTrafficTreatment(DeviceId currentDeviceId, DeviceId nextDeviceId,
+ PortPair portPair) {
+ MacAddress srcMacAddress = null;
+ MacAddress dstMacAddress = null;
+
+ // Check the treatment whether destination SF is on same OVS or in
+ // different OVS.
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ if (currentDeviceId.equals(nextDeviceId)) {
+ srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress();
+ dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress();
+ treatment.setEthSrc(srcMacAddress);
+ treatment.setEthDst(dstMacAddress);
+ } else {
+ treatment.setVlanId(VlanId.vlanId(Short.parseShort((vtnRscService.getL3vni(portPair
+ .tenantId()).toString()))));
+ }
+
+ return treatment;
+ }
+
+ /**
+ * Send service function forwarder to OVS.
+ *
+ * @param selector traffic selector
+ * @param treatment traffic treatment
+ * @param deviceId device id
+ * @param type operation type
+ */
+ public void sendServiceFunctionForwarder(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment,
+ DeviceId deviceId, Objective.Operation type) {
+ ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build())
+ .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
+ if (type.equals(Objective.Operation.ADD)) {
+ log.debug("ADD");
+ flowObjectiveService.forward(deviceId, objective.add());
+ } else {
+ log.debug("REMOVE");
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java
new file mode 100644
index 00000000..02221196
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/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.forwarder.impl;
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java
new file mode 100644
index 00000000..1dbe8c8f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.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.sfc.manager;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Unique NSH SPI Id generator for NSH header.
+ */
+public final class NshSpiIdGenerators {
+
+ private static final AtomicInteger NSH_SPI_ID_GEN = new AtomicInteger();
+ private static final int MAX_NSH_SPI_ID = 0x7FFFFFFF;
+ private static int nshSpiId;
+
+ /**
+ * Default constructor.
+ */
+ private NshSpiIdGenerators() {
+ }
+
+ /**
+ * Get the next NSH SPI id.
+ *
+ * @return NSH SPI id
+ */
+ public static int create() {
+ do {
+ if (nshSpiId >= MAX_NSH_SPI_ID) {
+ if (NSH_SPI_ID_GEN.get() >= MAX_NSH_SPI_ID) {
+ NSH_SPI_ID_GEN.set(0);
+ }
+ }
+ nshSpiId = NSH_SPI_ID_GEN.incrementAndGet();
+ } while (nshSpiId > MAX_NSH_SPI_ID);
+ return nshSpiId;
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java
index ef5fc529..4af2d47c 100644
--- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java
@@ -15,6 +15,11 @@
*/
package org.onosproject.sfc.manager;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
+
/**
* SFC application that applies flows to the device.
*/
@@ -23,48 +28,64 @@ public interface SfcService {
/**
* When port-pair is created, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portPair port-pair
*/
- public void onPortPairCreated();
+ void onPortPairCreated(PortPair portPair);
/**
* When port-pair is deleted, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portPair port-pair
*/
- public void onPortPairDeleted();
+ void onPortPairDeleted(PortPair portPair);
/**
* When port-pair-group is created, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param portPairGroup port-pair-group
*/
- public void onPortPairGroupCreated();
+ void onPortPairGroupCreated(PortPairGroup portPairGroup);
/**
* When port-pair-group is deleted, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param portPairGroup port-pair-group
*/
- public void onPortPairGroupDeleted();
+ void onPortPairGroupDeleted(PortPairGroup portPairGroup);
/**
* When flow-classifier is created, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param flowClassifier flow-classifier
*/
- public void onFlowClassifierCreated();
+ void onFlowClassifierCreated(FlowClassifier flowClassifier);
/**
* When flow-classifier is deleted, check whether Forwarding Rule needs to
* be updated in OVS.
+ *
+ * @param flowClassifier flow-classifier
*/
- public void onFlowClassifierDeleted();
+ void onFlowClassifierDeleted(FlowClassifier flowClassifier);
/**
* When port-chain is created, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portChain port-chain
*/
- public void onPortChainCreated();
+ void onPortChainCreated(PortChain portChain);
/**
* When port-chain is deleted, check whether Forwarding Rule needs to be
* updated in OVS.
+ *
+ * @param portChain port-chain
*/
- public void onPortChainDeleted();
+ void onPortChainDeleted(PortChain portChain);
}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
index 12d27c87..4df07929 100644
--- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
@@ -20,9 +20,26 @@ 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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
import org.onosproject.sfc.manager.SfcService;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.event.VtnRscEvent;
+import org.onosproject.vtnrsc.event.VtnRscListener;
+import org.onosproject.vtnrsc.service.VtnRscService;
+
import org.slf4j.Logger;
/**
@@ -33,93 +50,137 @@ import org.slf4j.Logger;
public class SfcManager implements SfcService {
private final Logger log = getLogger(getClass());
+ private static final String APP_ID = "org.onosproject.app.vtn";
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VtnRscService vtnRscService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ protected ApplicationId appId;
+
+ private final VtnRscListener vtnRscListener = new InnerVtnRscListener();
@Activate
public void activate() {
+ appId = coreService.registerApplication(APP_ID);
+
+ vtnRscService.addListener(vtnRscListener);
+
+ KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+ .register(TenantId.class)
+ .register(PortPairId.class)
+ .register(PortPairGroupId.class)
+ .register(FlowClassifierId.class)
+ .register(PortChainId.class);
+
log.info("Started");
}
@Deactivate
public void deactivate() {
+ vtnRscService.removeListener(vtnRscListener);
+
log.info("Stopped");
}
+ /*
+ * Handle events.
+ */
+ private class InnerVtnRscListener implements VtnRscListener {
+ @Override
+ public void event(VtnRscEvent event) {
+
+ if (VtnRscEvent.Type.PORT_PAIR_PUT == event.type()) {
+ PortPair portPair = (PortPair) event.subject();
+ onPortPairCreated(portPair);
+ } else if (VtnRscEvent.Type.PORT_PAIR_DELETE == event.type()) {
+ PortPair portPair = (PortPair) event.subject();
+ onPortPairDeleted(portPair);
+ } else if (VtnRscEvent.Type.PORT_PAIR_UPDATE == event.type()) {
+ PortPair portPair = (PortPair) event.subject();
+ onPortPairDeleted(portPair);
+ onPortPairCreated(portPair);
+ } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
+ PortPairGroup portPairGroup = (PortPairGroup) event.subject();
+ onPortPairGroupCreated(portPairGroup);
+ } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
+ PortPairGroup portPairGroup = (PortPairGroup) event.subject();
+ onPortPairGroupDeleted(portPairGroup);
+ } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
+ PortPairGroup portPairGroup = (PortPairGroup) event.subject();
+ onPortPairGroupDeleted(portPairGroup);
+ onPortPairGroupCreated(portPairGroup);
+ } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
+ FlowClassifier flowClassifier = (FlowClassifier) event.subject();
+ onFlowClassifierCreated(flowClassifier);
+ } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
+ FlowClassifier flowClassifier = (FlowClassifier) event.subject();
+ onFlowClassifierDeleted(flowClassifier);
+ } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
+ FlowClassifier flowClassifier = (FlowClassifier) event.subject();
+ onFlowClassifierDeleted(flowClassifier);
+ onFlowClassifierCreated(flowClassifier);
+ } else if (VtnRscEvent.Type.PORT_CHAIN_PUT == event.type()) {
+ PortChain portChain = (PortChain) event.subject();
+ onPortChainCreated(portChain);
+ } else if (VtnRscEvent.Type.PORT_CHAIN_DELETE == event.type()) {
+ PortChain portChain = (PortChain) event.subject();
+ onPortChainDeleted(portChain);
+ } else if (VtnRscEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
+ PortChain portChain = (PortChain) event.subject();
+ onPortChainDeleted(portChain);
+ onPortChainCreated(portChain);
+ }
+ }
+ }
+
@Override
- public void onPortPairCreated() {
+ public void onPortPairCreated(PortPair portPair) {
log.debug("onPortPairCreated");
- // TODO: Process port-pair on creation.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair creation.
}
@Override
- public void onPortPairDeleted() {
+ public void onPortPairDeleted(PortPair portPair) {
log.debug("onPortPairDeleted");
- // TODO: Process port-pair on deletion.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair deletion.
}
@Override
- public void onPortPairGroupCreated() {
+ public void onPortPairGroupCreated(PortPairGroup portPairGroup) {
log.debug("onPortPairGroupCreated");
- // TODO: Process port-pair-group on creation.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair-group creation.
}
@Override
- public void onPortPairGroupDeleted() {
+ public void onPortPairGroupDeleted(PortPairGroup portPairGroup) {
log.debug("onPortPairGroupDeleted");
- // TODO: Process port-pair-group on deletion.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on port-pair-group deletion.
}
@Override
- public void onFlowClassifierCreated() {
+ public void onFlowClassifierCreated(FlowClassifier flowClassifier) {
log.debug("onFlowClassifierCreated");
- // TODO: Process flow-classifier on creation.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on flow-classifier creation.
}
@Override
- public void onFlowClassifierDeleted() {
+ public void onFlowClassifierDeleted(FlowClassifier flowClassifier) {
log.debug("onFlowClassifierDeleted");
- // TODO: Process flow-classifier on deletion.
- // TODO: Parameter also needs to be modified.
+ // TODO: Modify forwarding rule on flow-classifier deletion.
}
@Override
- public void onPortChainCreated() {
- log.debug("onPortChainCreated");
- // TODO: Process port-chain on creation.
- // TODO: Parameter also needs to be modified.
-
+ public void onPortChainCreated(PortChain portChain) {
+ log.debug("onPortChainCreated");
+ //TODO: Apply forwarding rule on port-chain creation.
}
@Override
- public void onPortChainDeleted() {
+ public void onPortChainDeleted(PortChain portChain) {
log.debug("onPortChainDeleted");
- // TODO: Process port-chain on deletion.
- // TODO: Parameter also needs to be modified.
- }
-
- /**
- * Install SF Forwarding rule into OVS.
- *
- * @param portChain
- * port chain
- */
- public void installForwardingRule(PortChain portChain) {
- log.debug("installForwardingRule");
- // TODO: Installation of SF Forwarding rule into OVS.
- }
-
- /**
- * Uninstall SF Forwarding rule from OVS.
- *
- * @param portChain
- * port chain
- */
- public void unInstallForwardingRule(PortChain portChain) {
- log.debug("unInstallForwardingRule");
- // TODO: Uninstallation of SF Forwarding rule from OVS.
+ //TODO: Apply forwarding rule on port-chain deletion.
}
-} \ No newline at end of file
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java
new file mode 100644
index 00000000..e4f31f98
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java
@@ -0,0 +1,269 @@
+/*
+ * 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.manager.impl;
+
+import org.junit.Test;
+
+import java.util.List;
+import java.util.LinkedList;
+
+import org.onlab.packet.IpPrefix;
+import org.onosproject.sfc.manager.SfcService;
+import org.onosproject.vtnrsc.DefaultPortChain;
+import org.onosproject.vtnrsc.DefaultPortPair;
+import org.onosproject.vtnrsc.DefaultPortPairGroup;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.DefaultFlowClassifier;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.FlowClassifier;
+
+/**
+ * Unit tests for SfcManager class.
+ */
+public class SfcManagerTest {
+ /**
+ * Checks the operation of onPortPairCreated() method.
+ */
+ @Test
+ public void testOnPortPairCreated() {
+ final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPair";
+ final String description = "PortPair";
+ final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1";
+ final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345";
+ DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder();
+ PortPair portPair = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port pair
+ portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setIngress(ingress).setEgress(egress).build();
+ sfcService.onPortPairCreated(portPair);
+ }
+
+ /**
+ * Checks the operation of onPortPairDeleted() method.
+ */
+ @Test
+ public void testOnPortPairDeleted() {
+ final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPair";
+ final String description = "PortPair";
+ final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1";
+ final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345";
+ DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder();
+ PortPair portPair = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port pair
+ portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setIngress(ingress).setEgress(egress).build();
+ sfcService.onPortPairDeleted(portPair);
+ }
+
+ /**
+ * Checks the operation of onPortPairGroupCreated() method.
+ */
+ @Test
+ public void testOnPortPairGroupCreated() {
+ final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPairGroup";
+ final String description = "PortPairGroup";
+ final List<PortPairId> portPairIdList = new LinkedList<PortPairId>();
+ DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder();
+ PortPairGroup portPairGroup = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port-pair-id list
+ PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+ portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+
+ // create port pair
+ portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId).setName(name)
+ .setDescription(description).setPortPairs(portPairIdList).build();
+ sfcService.onPortPairGroupCreated(portPairGroup);
+ }
+
+ /**
+ * Checks the operation of onPortPairGroupDeleted() method.
+ */
+ @Test
+ public void testOnPortPairGroupDeleted() {
+ final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortPairGroup";
+ final String description = "PortPairGroup";
+ final List<PortPairId> portPairIdList = new LinkedList<PortPairId>();
+ DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder();
+ PortPairGroup portPairGroup = null;
+ SfcService sfcService = new SfcManager();
+
+ // create port-pair-id list
+ PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+ portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairIdList.add(portPairId);
+
+ // create port pair
+ portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId).setName(name)
+ .setDescription(description).setPortPairs(portPairIdList).build();
+ sfcService.onPortPairGroupDeleted(portPairGroup);
+ }
+
+ /**
+ * Checks the operation of onFlowClassifierCreated() method.
+ */
+ @Test
+ public void testOnFlowClassifierCreated() {
+ final String name = "FlowClassifier";
+ final String description = "FlowClassifier";
+ final String ethType = "IPv4";
+ final String protocol = "udp";
+ final int minSrcPortRange = 1024;
+ final int maxSrcPortRange = 5000;
+ final int minDstPortRange = 1024;
+ final int maxDstPortRange = 5000;
+ final FlowClassifierId flowClassifierId = FlowClassifierId.of("71111111-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("8");
+ final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
+ final IpPrefix dstIpPrefix = IpPrefix.valueOf("100.100.100.100/0");
+ final VirtualPortId virtualSrcPort = VirtualPortId.portId("100");
+ final VirtualPortId virtualDstPort = VirtualPortId.portId("200");
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ FlowClassifier flowClassifier = null;
+ SfcService sfcService = new SfcManager();
+
+ // create flow classifier
+ flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId).setTenantId(tenantId)
+ .setName(name).setDescription(description).setEtherType(ethType).setProtocol(protocol)
+ .setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
+ .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
+ .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();
+ sfcService.onFlowClassifierCreated(flowClassifier);
+ }
+
+ /**
+ * Checks the operation of onFlowClassifierDeleted() method.
+ */
+ @Test
+ public void testOnFlowClassifierDeleted() {
+ final String name = "FlowClassifier";
+ final String description = "FlowClassifier";
+ final String ethType = "IPv4";
+ final String protocol = "udp";
+ final int minSrcPortRange = 1024;
+ final int maxSrcPortRange = 5000;
+ final int minDstPortRange = 1024;
+ final int maxDstPortRange = 5000;
+ final FlowClassifierId flowClassifierId = FlowClassifierId.of("71111111-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("8");
+ final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
+ final IpPrefix dstIpPrefix = IpPrefix.valueOf("100.100.100.100/0");
+ final VirtualPortId virtualSrcPort = VirtualPortId.portId("100");
+ final VirtualPortId virtualDstPort = VirtualPortId.portId("200");
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ FlowClassifier flowClassifier = null;
+ SfcService sfcService = new SfcManager();
+
+ // create flow classifier
+ flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId).setTenantId(tenantId)
+ .setName(name).setDescription(description).setEtherType(ethType).setProtocol(protocol)
+ .setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
+ .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
+ .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();
+ sfcService.onFlowClassifierDeleted(flowClassifier);
+ }
+
+ /**
+ * Checks the operation of onPortChainCreated() method.
+ */
+ @Test
+ public void testOnPortChainCreated() {
+ final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortChain";
+ final String description = "PortChain";
+ final List<PortPairGroupId> portPairGroupList = new LinkedList<PortPairGroupId>();
+ final List<FlowClassifierId> flowClassifierList = new LinkedList<FlowClassifierId>();
+ DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder();
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ PortChain portChain = null;
+ SfcService sfcService = new SfcManager();
+
+ // create list of Port Pair Groups.
+ PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairGroupList.add(portPairGroupId);
+ portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af");
+ portPairGroupList.add(portPairGroupId);
+
+ // create list of Flow classifiers.
+ FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ flowClassifierList.add(flowClassifierId);
+ flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af");
+ flowClassifierList.add(flowClassifierId);
+
+ // create port chain
+ portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setPortPairGroups(portPairGroupList).setFlowClassifiers(flowClassifierList).build();
+ sfcService.onPortChainCreated(portChain);
+ }
+
+ /**
+ * Checks the operation of onPortChainDeleted() method.
+ */
+ @Test
+ public void testOnPortChainDeleted() {
+ final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae");
+ final TenantId tenantId = TenantId.tenantId("1");
+ final String name = "PortChain";
+ final String description = "PortChain";
+ final List<PortPairGroupId> portPairGroupList = new LinkedList<PortPairGroupId>();
+ final List<FlowClassifierId> flowClassifierList = new LinkedList<FlowClassifierId>();
+ DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder();
+ DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
+ PortChain portChain = null;
+ SfcService sfcService = new SfcManager();
+
+ // create list of Port Pair Groups.
+ PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae");
+ portPairGroupList.add(portPairGroupId);
+ portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af");
+ portPairGroupList.add(portPairGroupId);
+
+ // create list of Flow classifiers.
+ FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae");
+ flowClassifierList.add(flowClassifierId);
+ flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af");
+ flowClassifierList.add(flowClassifierId);
+
+ // create port chain
+ portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name).setDescription(description)
+ .setPortPairGroups(portPairGroupList).setFlowClassifiers(flowClassifierList).build();
+ sfcService.onPortChainDeleted(portChain);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java
new file mode 100644
index 00000000..fe5babbd
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Provides implementation of the Flow Classifier Service.
+ */
+public class FlowClassifierManagerTestImpl implements FlowClassifierService {
+
+ private final ConcurrentMap<FlowClassifierId, FlowClassifier> flowClassifierStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(FlowClassifierId id) {
+ return flowClassifierStore.containsKey(id);
+ }
+
+ @Override
+ public int getFlowClassifierCount() {
+ return flowClassifierStore.size();
+ }
+
+ @Override
+ public Iterable<FlowClassifier> getFlowClassifiers() {
+ return ImmutableList.copyOf(flowClassifierStore.values());
+ }
+
+ @Override
+ public FlowClassifier getFlowClassifier(FlowClassifierId id) {
+ return flowClassifierStore.get(id);
+ }
+
+ @Override
+ public boolean createFlowClassifier(FlowClassifier flowClassifier) {
+ FlowClassifierId id = flowClassifier.flowClassifierId();
+
+ flowClassifierStore.put(id, flowClassifier);
+ if (!flowClassifierStore.containsKey(id)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updateFlowClassifier(FlowClassifier flowClassifier) {
+
+ if (!flowClassifierStore.containsKey(flowClassifier.flowClassifierId())) {
+ return false;
+ }
+
+ flowClassifierStore.put(flowClassifier.flowClassifierId(), flowClassifier);
+
+ if (!flowClassifier.equals(flowClassifierStore.get(flowClassifier.flowClassifierId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removeFlowClassifier(FlowClassifierId id) {
+ return true;
+ }
+
+ @Override
+ public void addListener(FlowClassifierListener listener) {
+ }
+
+ @Override
+ public void removeListener(FlowClassifierListener listener) {
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java
new file mode 100644
index 00000000..9da9ee94
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+
+/**
+ * Testing version of implementation on FlowObjectiveService.
+ */
+public class FlowObjectiveServiceTestImpl implements FlowObjectiveService {
+
+ @Override
+ public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
+
+ }
+
+ @Override
+ public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+
+ }
+
+ @Override
+ public void next(DeviceId deviceId, NextObjective nextObjective) {
+
+ }
+
+ @Override
+ public int allocateNextId() {
+ return 0;
+ }
+
+ @Override
+ public void initPolicy(String policy) {
+
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java
new file mode 100644
index 00000000..4a3ba03d
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java
@@ -0,0 +1,85 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collections;
+
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.portchain.PortChainService;
+import org.onosproject.vtnrsc.portchain.PortChainEvent;
+import org.onosproject.vtnrsc.portchain.PortChainListener;
+import org.onosproject.event.AbstractListenerManager;
+
+/**
+ * Provides implementation of the portChainService.
+ */
+public class PortChainManagerTestImpl
+ extends AbstractListenerManager<PortChainEvent, PortChainListener>
+ implements PortChainService {
+
+ private ConcurrentMap<PortChainId, PortChain> portChainStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(PortChainId portChainId) {
+ return portChainStore.containsKey(portChainId);
+ }
+
+ @Override
+ public int getPortChainCount() {
+ return portChainStore.size();
+ }
+
+ @Override
+ public Iterable<PortChain> getPortChains() {
+ return Collections.unmodifiableCollection(portChainStore.values());
+ }
+
+ @Override
+ public PortChain getPortChain(PortChainId portChainId) {
+ return portChainStore.get(portChainId);
+ }
+
+ @Override
+ public boolean createPortChain(PortChain portChain) {
+ portChainStore.put(portChain.portChainId(), portChain);
+ if (!portChainStore.containsKey(portChain.portChainId())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePortChain(PortChain portChain) {
+ if (!portChainStore.containsKey(portChain.portChainId())) {
+ return false;
+ }
+
+ portChainStore.put(portChain.portChainId(), portChain);
+
+ if (!portChain.equals(portChainStore.get(portChain.portChainId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removePortChain(PortChainId portChainId) {
+ return true;
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java
new file mode 100644
index 00000000..ba31cd60
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java
@@ -0,0 +1,89 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collections;
+
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+
+/**
+ * Provides implementation of the portPairGroupService.
+ */
+public class PortPairGroupManagerTestImpl implements PortPairGroupService {
+
+ private ConcurrentMap<PortPairGroupId, PortPairGroup> portPairGroupStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(PortPairGroupId portPairGroupId) {
+ return portPairGroupStore.containsKey(portPairGroupId);
+ }
+
+ @Override
+ public int getPortPairGroupCount() {
+ return portPairGroupStore.size();
+ }
+
+ @Override
+ public Iterable<PortPairGroup> getPortPairGroups() {
+ return Collections.unmodifiableCollection(portPairGroupStore.values());
+ }
+
+ @Override
+ public PortPairGroup getPortPairGroup(PortPairGroupId portPairGroupId) {
+ return portPairGroupStore.get(portPairGroupId);
+ }
+
+ @Override
+ public boolean createPortPairGroup(PortPairGroup portPairGroup) {
+ portPairGroupStore.put(portPairGroup.portPairGroupId(), portPairGroup);
+ if (!portPairGroupStore.containsKey(portPairGroup.portPairGroupId())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePortPairGroup(PortPairGroup portPairGroup) {
+ if (!portPairGroupStore.containsKey(portPairGroup.portPairGroupId())) {
+ return false;
+ }
+
+ portPairGroupStore.put(portPairGroup.portPairGroupId(), portPairGroup);
+
+ if (!portPairGroup.equals(portPairGroupStore.get(portPairGroup.portPairGroupId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removePortPairGroup(PortPairGroupId portPairGroupId) {
+ return true;
+ }
+
+ @Override
+ public void addListener(PortPairGroupListener listener) {
+ }
+
+ @Override
+ public void removeListener(PortPairGroupListener listener) {
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java
new file mode 100644
index 00000000..aff58823
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java
@@ -0,0 +1,89 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collections;
+
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.portpair.PortPairListener;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+
+/**
+ * Provides implementation of the portPairService.
+ */
+public class PortPairManagerTestImpl implements PortPairService {
+
+ private ConcurrentMap<PortPairId, PortPair> portPairStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(PortPairId portPairId) {
+ return portPairStore.containsKey(portPairId);
+ }
+
+ @Override
+ public int getPortPairCount() {
+ return portPairStore.size();
+ }
+
+ @Override
+ public Iterable<PortPair> getPortPairs() {
+ return Collections.unmodifiableCollection(portPairStore.values());
+ }
+
+ @Override
+ public PortPair getPortPair(PortPairId portPairId) {
+ return portPairStore.get(portPairId);
+ }
+
+ @Override
+ public boolean createPortPair(PortPair portPair) {
+ portPairStore.put(portPair.portPairId(), portPair);
+ if (!portPairStore.containsKey(portPair.portPairId())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePortPair(PortPair portPair) {
+ if (!portPairStore.containsKey(portPair.portPairId())) {
+ return false;
+ }
+
+ portPairStore.put(portPair.portPairId(), portPair);
+
+ if (!portPair.equals(portPairStore.get(portPair.portPairId()))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removePortPair(PortPairId portPairId) {
+ return true;
+ }
+
+ @Override
+ public void addListener(PortPairListener listener) {
+ }
+
+ @Override
+ public void removeListener(PortPairListener listener) {
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java
new file mode 100644
index 00000000..de056a78
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java
@@ -0,0 +1,98 @@
+/*
+ * 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.util;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+
+/**
+ * Provides implementation of the VirtualPort APIs.
+ */
+public class VirtualPortManagerTestImpl implements VirtualPortService {
+
+ protected ConcurrentMap<VirtualPortId, VirtualPort> vPortStore = new ConcurrentHashMap<>();
+
+ @Override
+ public boolean exists(VirtualPortId vPortId) {
+ return vPortStore.containsKey(vPortId);
+ }
+
+ @Override
+ public VirtualPort getPort(VirtualPortId vPortId) {
+ return vPortStore.get(vPortId);
+ }
+
+ @Override
+ public VirtualPort getPort(FixedIp fixedIP) {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts() {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts(TenantNetworkId networkId) {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public Collection<VirtualPort> getPorts(DeviceId deviceId) {
+ return null;
+ }
+
+ @Override
+ public VirtualPort getPort(TenantNetworkId networkId, IpAddress ipAddress) {
+ return null;
+ }
+
+ @Override
+ public boolean createPorts(Iterable<VirtualPort> vPorts) {
+ for (VirtualPort vPort : vPorts) {
+ vPortStore.put(vPort.portId(), vPort);
+ if (!vPortStore.containsKey(vPort.portId())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean updatePorts(Iterable<VirtualPort> vPorts) {
+ return true;
+ }
+
+ @Override
+ public boolean removePorts(Iterable<VirtualPortId> vPortIds) {
+ return true;
+ }
+}
diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java
new file mode 100644
index 00000000..4188cee6
--- /dev/null
+++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.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.sfc.util;
+
+import java.util.Iterator;
+
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.event.VtnRscListener;
+import org.onosproject.vtnrsc.service.VtnRscService;
+
+/**
+ * Provides implementation of the VtnRsc service.
+ */
+public class VtnRscManagerTestImpl implements VtnRscService {
+ @Override
+ public void addListener(VtnRscListener listener) {
+ }
+
+ @Override
+ public void removeListener(VtnRscListener listener) {
+ }
+
+ @Override
+ public SegmentationId getL3vni(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public Iterator<Device> getSFFOfTenant(TenantId tenantId) {
+ return null;
+ }
+
+ @Override
+ public MacAddress getGatewayMac(HostId hostId) {
+ return null;
+ }
+
+ @Override
+ public boolean isServiceFunction(VirtualPortId portId) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public DeviceId getSFToSFFMaping(VirtualPortId portId) {
+ return DeviceId.deviceId("www.google.com");
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java
index a104e529..d7ee3607 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java
@@ -17,6 +17,7 @@ package org.onosproject.vtn.manager;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
+import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
/**
* VTN application that applies configuration and flows to the device.
@@ -67,4 +68,32 @@ public interface VTNService {
*/
void onHostVanished(Host host);
+ /**
+ * Applies east west flows when neutron created router interface.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback);
+
+ /**
+ * Remove east west flows when neutron removed router interface.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback);
+
+ /**
+ * Applies north south flows when neutron bind floating ip.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onFloatingIpDetected(VtnRscEventFeedback l3Feedback);
+
+ /**
+ * Applies north south flows when neutron unbind floating ip.
+ *
+ * @param l3Feedback VtnrscEventFeedback
+ */
+ void onFloatingIpVanished(VtnRscEventFeedback l3Feedback);
+
}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
index be6b9364..6429314e 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
@@ -18,6 +18,7 @@ package org.onosproject.vtn.manager.impl;
import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
import static org.slf4j.LoggerFactory.getLogger;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -25,6 +26,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -39,9 +41,11 @@ import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.BridgeConfig;
@@ -74,8 +78,12 @@ import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.LogicalClockService;
import org.onosproject.store.service.StorageService;
import org.onosproject.vtn.manager.VTNService;
+import org.onosproject.vtn.table.ArpService;
import org.onosproject.vtn.table.ClassifierService;
+import org.onosproject.vtn.table.DnatService;
import org.onosproject.vtn.table.L2ForwardService;
+import org.onosproject.vtn.table.L3ForwardService;
+import org.onosproject.vtn.table.SnatService;
import org.onosproject.vtn.table.impl.ClassifierServiceImpl;
import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
import org.onosproject.vtn.util.DataPathIdGenerator;
@@ -85,6 +93,11 @@ import org.onosproject.vtnrsc.AllowedAddressPair;
import org.onosproject.vtnrsc.BindingHostId;
import org.onosproject.vtnrsc.DefaultVirtualPort;
import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.FloatingIp;
+import org.onosproject.vtnrsc.Router;
+import org.onosproject.vtnrsc.RouterGateway;
+import org.onosproject.vtnrsc.RouterId;
+import org.onosproject.vtnrsc.RouterInterface;
import org.onosproject.vtnrsc.SecurityGroup;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.SubnetId;
@@ -93,6 +106,14 @@ import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.event.VtnRscEvent;
+import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
+import org.onosproject.vtnrsc.event.VtnRscListener;
+import org.onosproject.vtnrsc.floatingip.FloatingIpService;
+import org.onosproject.vtnrsc.router.RouterService;
+import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
+import org.onosproject.vtnrsc.service.VtnRscService;
+import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
import org.slf4j.Logger;
@@ -142,12 +163,32 @@ public class VTNManager implements VTNService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected GroupService groupService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected SubnetService subnetService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected VtnRscService vtnRscService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FloatingIpService floatingIpService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RouterService routerService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RouterInterfaceService routerInterfaceService;
+
private ApplicationId appId;
private ClassifierService classifierService;
private L2ForwardService l2ForwardService;
+ private ArpService arpService;
+ private L3ForwardService l3ForwardService;
+ private SnatService snatService;
+ private DnatService dnatService;
private final HostListener hostListener = new InnerHostListener();
private final DeviceListener deviceListener = new InnerDeviceListener();
+ private final VtnRscListener l3EventListener = new VtnL3EventListener();
private static final String IFACEID = "ifaceid";
private static final String CONTROLLER_IP_KEY = "ipaddress";
@@ -156,11 +197,19 @@ public class VTNManager implements VTNService {
private static final String VIRTUALPORT = "vtn-virtual-port";
private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
+ private static final String ROUTERINF_FLAG_OF_TENANT = "routerInfFlagOfTenant";
+ private static final String HOSTS_OF_SUBNET = "hostsOfSubnet";
+ private static final String EX_PORT_OF_DEVICE = "exPortOfDevice";
private static final String DEFAULT_IP = "0.0.0.0";
+ private static final String PORT_MAC = "portMac";
+ private static final int SUBNET_NUM = 2;
private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
+ private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet;
+ private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant;
+ private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice;
@Activate
public void activate() {
@@ -206,6 +255,24 @@ public class VTNManager implements VTNService {
.withTimestampProvider((k, v) -> clockService.getTimestamp())
.build();
+ hostsOfSubnet = storageService
+ .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder()
+ .withName(HOSTS_OF_SUBNET).withSerializer(serializer)
+ .withTimestampProvider((k, v) -> clockService.getTimestamp())
+ .build();
+
+ routerInfFlagOfTenant = storageService
+ .<TenantId, Boolean>eventuallyConsistentMapBuilder()
+ .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer)
+ .withTimestampProvider((k, v) -> clockService.getTimestamp())
+ .build();
+
+ exPortOfDevice = storageService
+ .<DeviceId, Port>eventuallyConsistentMapBuilder()
+ .withName(EX_PORT_OF_DEVICE).withSerializer(serializer)
+ .withTimestampProvider((k, v) -> clockService.getTimestamp())
+ .build();
+
log.info("Started");
}
@@ -213,6 +280,7 @@ public class VTNManager implements VTNService {
public void deactivate() {
deviceService.removeListener(deviceListener);
hostService.removeListener(hostListener);
+ vtnRscService.removeListener(l3EventListener);
log.info("Stopped");
}
@@ -278,14 +346,36 @@ public class VTNManager implements VTNService {
@Override
public void onHostDetected(Host host) {
+ DeviceId deviceId = host.location().deviceId();
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ return;
+ }
+ String ifaceId = host.annotations().value(IFACEID);
+ if (ifaceId == null) {
+ log.error("The ifaceId of Host is null");
+ return;
+ }
// apply L2 openflow rules
applyHostMonitoredL2Rules(host, Objective.Operation.ADD);
+ // apply L3 openflow rules
+ applyHostMonitoredL3Rules(host, Objective.Operation.ADD);
}
@Override
public void onHostVanished(Host host) {
+ DeviceId deviceId = host.location().deviceId();
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ return;
+ }
+ String ifaceId = host.annotations().value(IFACEID);
+ if (ifaceId == null) {
+ log.error("The ifaceId of Host is null");
+ return;
+ }
// apply L2 openflow rules
applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE);
+ // apply L3 openflow rules
+ applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE);
}
private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
@@ -376,7 +466,7 @@ public class VTNManager implements VTNService {
VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
if (virtualPort == null) {
- virtualPort = vPortStore.get(virtualPortId);
+ virtualPort = VtnData.getPort(vPortStore, virtualPortId);
}
Iterable<Device> devices = deviceService.getAvailableDevices();
@@ -582,4 +672,388 @@ public class VTNManager implements VTNService {
appid);
groupService.addGroup(groupDescription);
}
+
+ private class VtnL3EventListener implements VtnRscListener {
+ @Override
+ public void event(VtnRscEvent event) {
+ VtnRscEventFeedback l3Feedback = event.subject();
+ if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
+ onRouterInterfaceDetected(l3Feedback);
+ } else
+ if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
+ onRouterInterfaceVanished(l3Feedback);
+ } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) {
+ onFloatingIpDetected(l3Feedback);
+ } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) {
+ onFloatingIpVanished(l3Feedback);
+ }
+ }
+
+ }
+
+ @Override
+ public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) {
+ Objective.Operation operation = Objective.Operation.ADD;
+ RouterInterface routerInf = l3Feedback.routerInterface();
+ Iterable<RouterInterface> interfaces = routerInterfaceService
+ .getRouterInterfaces();
+ Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
+ .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
+ .collect(Collectors.toSet());
+ if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
+ programRouterInterface(routerInf, operation);
+ } else {
+ if (interfacesSet.size() >= SUBNET_NUM) {
+ programInterfacesSet(interfacesSet, operation);
+ }
+ }
+ }
+
+ @Override
+ public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) {
+ Objective.Operation operation = Objective.Operation.REMOVE;
+ RouterInterface routerInf = l3Feedback.routerInterface();
+ Iterable<RouterInterface> interfaces = routerInterfaceService
+ .getRouterInterfaces();
+ Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
+ .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
+ .collect(Collectors.toSet());
+ if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
+ programRouterInterface(routerInf, operation);
+ if (interfacesSet.size() == 1) {
+ routerInfFlagOfTenant.remove(routerInf.tenantId());
+ interfacesSet.stream().forEach(r -> {
+ programRouterInterface(r, operation);
+ });
+ }
+ }
+ }
+
+ @Override
+ public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
+ programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT);
+ }
+
+ @Override
+ public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
+ programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE);
+ }
+
+ private void programInterfacesSet(Set<RouterInterface> interfacesSet,
+ Objective.Operation operation) {
+ int subnetVmNum = 0;
+ for (RouterInterface r : interfacesSet) {
+ // Get all the host of the subnet
+ Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId());
+ if (hosts.size() > 0) {
+ subnetVmNum++;
+ if (subnetVmNum >= SUBNET_NUM) {
+ routerInfFlagOfTenant.put(r.tenantId(), true);
+ interfacesSet.stream().forEach(f -> {
+ programRouterInterface(f, operation);
+ });
+ break;
+ }
+ }
+ }
+ }
+
+ private void programRouterInterface(RouterInterface routerInf,
+ Objective.Operation operation) {
+ SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId());
+ // Get all the host of the subnet
+ Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId());
+ hosts.values().stream().forEach(h -> {
+ applyEastWestL3Flows(h, l3vni, operation);
+ });
+ }
+
+ private void applyEastWestL3Flows(Host h, SegmentationId l3vni,
+ Objective.Operation operation) {
+ if (!mastershipService.isLocalMaster(h.location().deviceId())) {
+ log.debug("not master device:{}", h.location().deviceId());
+ return;
+ }
+ String ifaceId = h.annotations().value(IFACEID);
+ VirtualPort hPort = virtualPortService
+ .getPort(VirtualPortId.portId(ifaceId));
+ if (hPort == null) {
+ hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId));
+ }
+ IpAddress srcIp = null;
+ IpAddress srcGwIp = null;
+ MacAddress srcVmGwMac = null;
+ SubnetId srcSubnetId = null;
+ Iterator<FixedIp> srcIps = hPort.fixedIps().iterator();
+ if (srcIps.hasNext()) {
+ FixedIp fixedIp = srcIps.next();
+ srcIp = fixedIp.ip();
+ srcSubnetId = fixedIp.subnetId();
+ srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp();
+ FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp);
+ VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
+ if (gwPort == null) {
+ gwPort = VtnData.getPort(vPortStore, fixedGwIp);
+ }
+ srcVmGwMac = gwPort.macAddress();
+ }
+ TenantNetwork network = tenantNetworkService
+ .getNetwork(hPort.networkId());
+ // Classifier rules
+ classifierService
+ .programL3InPortClassifierRules(h.location().deviceId(),
+ h.location().port(), h.mac(),
+ srcVmGwMac, l3vni, operation);
+ // Arp rules
+ if (operation == Objective.Operation.ADD) {
+ classifierService.programArpClassifierRules(h.location().deviceId(),
+ srcGwIp,
+ network.segmentationId(),
+ operation);
+ DriverHandler handler = driverService.createHandler(h.location().deviceId());
+ arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
+ network.segmentationId(), srcVmGwMac,
+ operation);
+ }
+ Iterable<Device> devices = deviceService.getAvailableDevices();
+ IpAddress srcArpIp = srcIp;
+ MacAddress srcArpGwMac = srcVmGwMac;
+ Sets.newHashSet(devices).stream()
+ .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> {
+ // L3FWD rules
+ l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp,
+ network.segmentationId(),
+ srcArpGwMac, h.mac(),
+ operation);
+ });
+ }
+
+ private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback,
+ VtnRscEvent.Type type) {
+ FloatingIp floaingIp = l3Feedback.floatingIp();
+ if (floaingIp != null) {
+ VirtualPortId vmPortId = floaingIp.portId();
+ VirtualPort vmPort = virtualPortService.getPort(vmPortId);
+ VirtualPort fipPort = virtualPortService
+ .getPort(floaingIp.networkId(), floaingIp.floatingIp());
+ if (vmPort == null) {
+ vmPort = VtnData.getPort(vPortStore, vmPortId);
+ }
+ if (fipPort == null) {
+ fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(),
+ floaingIp.floatingIp());
+ }
+ Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
+ Host host = null;
+ for (Host h : hostSet) {
+ String ifaceid = h.annotations().value(IFACEID);
+ if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
+ host = h;
+ break;
+ }
+ }
+ if (host != null && vmPort != null && fipPort != null) {
+ DeviceId deviceId = host.location().deviceId();
+ Port exPort = exPortOfDevice.get(deviceId);
+ SegmentationId l3vni = vtnRscService
+ .getL3vni(vmPort.tenantId());
+ // Floating ip BIND
+ if (type == VtnRscEvent.Type.FLOATINGIP_PUT) {
+ applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
+ floaingIp, l3vni, exPort,
+ Objective.Operation.ADD);
+ } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) {
+ // Floating ip UNBIND
+ applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
+ floaingIp, l3vni, exPort,
+ Objective.Operation.REMOVE);
+ }
+ }
+ }
+ }
+
+ private void applyNorthSouthL3Flows(DeviceId deviceId, Host host,
+ VirtualPort vmPort, VirtualPort fipPort,
+ FloatingIp floatingIp,
+ SegmentationId l3Vni, Port exPort,
+ Objective.Operation operation) {
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ log.debug("not master device:{}", deviceId);
+ return;
+ }
+ List gwIpMac = getGwIpAndMac(vmPort);
+ IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
+ MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
+ FixedIp fixedGwIp = getGwFixedIp(floatingIp);
+ MacAddress fGwMac = null;
+ if (fixedGwIp != null) {
+ VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
+ if (gwPort == null) {
+ gwPort = VtnData.getPort(vPortStore, fixedGwIp);
+ }
+ fGwMac = gwPort.macAddress();
+ }
+ TenantNetwork vmNetwork = tenantNetworkService
+ .getNetwork(vmPort.networkId());
+ TenantNetwork fipNetwork = tenantNetworkService
+ .getNetwork(fipPort.networkId());
+ // L3 downlink traffic flow
+ MacAddress exPortMac = MacAddress.valueOf(exPort.annotations().value(PORT_MAC));
+ classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
+ fipNetwork.segmentationId(),
+ operation);
+ classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
+ floatingIp.floatingIp(), operation);
+ DriverHandler handler = driverService.createHandler(deviceId);
+ arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
+ fipNetwork.segmentationId(), exPortMac,
+ operation);
+ dnatService.programRules(deviceId, floatingIp.floatingIp(),
+ fGwMac, floatingIp.fixedIp(),
+ l3Vni, operation);
+ l3ForwardService
+ .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(),
+ vmNetwork.segmentationId(), dstVmGwMac,
+ vmPort.macAddress(), operation);
+
+ // L3 uplink traffic flow
+ classifierService.programL3InPortClassifierRules(deviceId,
+ host.location().port(),
+ host.mac(), dstVmGwMac,
+ l3Vni, operation);
+ snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(),
+ fGwMac, exPortMac,
+ floatingIp.floatingIp(),
+ fipNetwork.segmentationId(), operation);
+ if (operation == Objective.Operation.ADD) {
+ classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
+ vmNetwork.segmentationId(),
+ operation);
+ arpService.programArpRules(handler, deviceId, dstVmGwIp,
+ vmNetwork.segmentationId(), dstVmGwMac,
+ operation);
+ l2ForwardService.programLocalOut(deviceId,
+ fipNetwork.segmentationId(),
+ exPort.number(), fGwMac, operation);
+ }
+ }
+
+ private Port getExPort(DeviceId deviceId) {
+ List<Port> ports = deviceService.getPorts(deviceId);
+ Port exPort = null;
+ for (Port port : ports) {
+ String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
+ if (portName != null && portName.equals(EX_PORT_NAME)) {
+ exPort = port;
+ break;
+ }
+ }
+ return exPort;
+ }
+
+ private List getGwIpAndMac(VirtualPort port) {
+ List list = new ArrayList();
+ MacAddress gwMac = null;
+ SubnetId subnetId = null;
+ IpAddress gwIp = null;
+ Iterator<FixedIp> fixips = port.fixedIps().iterator();
+ if (fixips.hasNext()) {
+ FixedIp fixip = fixips.next();
+ subnetId = fixip.subnetId();
+ gwIp = subnetService.getSubnet(subnetId).gatewayIp();
+ FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp);
+ VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
+ if (gwPort == null) {
+ gwPort = VtnData.getPort(vPortStore, fixedGwIp);
+ }
+ gwMac = gwPort.macAddress();
+ }
+ list.add(gwIp);
+ list.add(gwMac);
+ return list;
+ }
+
+ private FixedIp getGwFixedIp(FloatingIp floatingIp) {
+ RouterId routerId = floatingIp.routerId();
+ Router router = routerService.getRouter(routerId);
+ RouterGateway routerGateway = router.externalGatewayInfo();
+ Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps();
+ FixedIp fixedGwIp = null;
+ if (externalFixedIps != null) {
+ Iterator<FixedIp> exFixedIps = externalFixedIps.iterator();
+ if (exFixedIps.hasNext()) {
+ fixedGwIp = exFixedIps.next();
+ }
+ }
+ return fixedGwIp;
+ }
+
+ private void applyHostMonitoredL3Rules(Host host,
+ Objective.Operation operation) {
+ String ifaceId = host.annotations().value(IFACEID);
+ DeviceId deviceId = host.location().deviceId();
+ VirtualPortId portId = VirtualPortId.portId(ifaceId);
+ VirtualPort port = virtualPortService.getPort(portId);
+ if (port == null) {
+ port = VtnData.getPort(vPortStore, portId);
+ }
+ TenantId tenantId = port.tenantId();
+ Port exPort = exPortOfDevice.get(deviceId);
+ SegmentationId l3vni = vtnRscService.getL3vni(tenantId);
+ Iterator<FixedIp> fixips = port.fixedIps().iterator();
+ SubnetId sid = null;
+ IpAddress hostIp = null;
+ if (fixips.hasNext()) {
+ FixedIp fixip = fixips.next();
+ sid = fixip.subnetId();
+ hostIp = fixip.ip();
+ }
+ final SubnetId subnetId = sid;
+ // L3 internal network access to each other
+ Iterable<RouterInterface> interfaces = routerInterfaceService
+ .getRouterInterfaces();
+ Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
+ .stream().filter(r -> r.tenantId().equals(tenantId))
+ .collect(Collectors.toSet());
+ long count = interfacesSet.stream()
+ .filter(r -> !r.subnetId().equals(subnetId)).count();
+ if (count > 0) {
+ if (operation == Objective.Operation.ADD) {
+ if (routerInfFlagOfTenant.get(tenantId) != null) {
+ applyEastWestL3Flows(host, l3vni, operation);
+ } else {
+ if (interfacesSet.size() > 1) {
+ programInterfacesSet(interfacesSet, operation);
+ }
+ }
+ } else if (operation == Objective.Operation.REMOVE) {
+ if (routerInfFlagOfTenant.get(tenantId) != null) {
+ applyEastWestL3Flows(host, l3vni, operation);
+ }
+ }
+ }
+ // L3 external and internal network access to each other
+ FloatingIp floatingIp = null;
+ Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps();
+ Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream()
+ .filter(f -> f.tenantId().equals(tenantId))
+ .collect(Collectors.toSet());
+ for (FloatingIp f : floatingIpSet) {
+ IpAddress fixedIp = f.fixedIp();
+ if (fixedIp.equals(hostIp)) {
+ floatingIp = f;
+ break;
+ }
+ }
+ if (floatingIp != null) {
+ VirtualPort fipPort = virtualPortService
+ .getPort(floatingIp.networkId(), floatingIp.floatingIp());
+ if (fipPort == null) {
+ fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(),
+ floatingIp.floatingIp());
+ }
+ applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp,
+ l3vni, exPort, operation);
+ }
+ }
}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java
index b548938b..ebb9ac3b 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java
@@ -17,10 +17,13 @@ package org.onosproject.vtn.table;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
+
import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.vtnrsc.SegmentationId;
+
/**
* ArpService interface providing the rules in ARP table which is Table(10).
*/
@@ -32,13 +35,14 @@ public interface ArpService {
* Action: set arp_operation, move arp_eth_src to arp_eth_dst, set arp_eth_src,
* move arp_ip_src to arp_ip_dst, set arp_ip_src, set output port.
*
+ * @param hander DriverHandler
* @param deviceId Device Id
* @param dstIP destination ip
* @param matchVni the vni of the source network (l2vni)
* @param dstMac destination mac
* @param type the operation type of the flow rules
*/
- void programArpRules(DeviceId deviceId, IpAddress dstIP,
+ void programArpRules(DriverHandler hander, DeviceId deviceId, IpAddress dstIP,
SegmentationId matchVni, MacAddress dstMac,
Objective.Operation type);
}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java
new file mode 100644
index 00000000..574d15a7
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java
@@ -0,0 +1,113 @@
+/*
+ * 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.vtn.table.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.EthType.EtherType;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.driver.DriverHandler;
+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.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.Objective.Operation;
+import org.onosproject.vtn.table.ArpService;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.slf4j.Logger;
+
+/**
+ * ArpTable class providing the rules in ARP table.
+ */
+public class ArpServiceImpl implements ArpService {
+ private final Logger log = getLogger(getClass());
+
+ private static final int ARP_PRIORITY = 0xffff;
+ private static final short ARP_RESPONSE = 0x2;
+ private static final EtherType ARP_TYPE = EtherType.ARP;
+
+ private final FlowObjectiveService flowObjectiveService;
+ private final ApplicationId appId;
+
+ /**
+ * Construct a ArpServiceImpl object.
+ *
+ * @param appId the application id of vtn
+ */
+ public ArpServiceImpl(ApplicationId appId) {
+ this.appId = checkNotNull(appId, "ApplicationId can not be null");
+ ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+ this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class);
+ }
+
+ @Override
+ public void programArpRules(DriverHandler hander, DeviceId deviceId,
+ IpAddress dstIP, SegmentationId srcVni,
+ MacAddress dstMac, Operation type) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(ARP_TYPE.ethType().toShort())
+ .matchArpTpa(Ip4Address.valueOf(dstIP.toString()))
+ .matchTunnelId(Long.parseLong(srcVni.segmentationId())).build();
+
+ ExtensionTreatmentResolver resolver = hander
+ .behaviour(ExtensionTreatmentResolver.class);
+ ExtensionTreatment ethSrcToDst = resolver
+ .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
+ .NICIRA_MOV_ETH_SRC_TO_DST.type());
+ ExtensionTreatment arpShaToTha = resolver
+ .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
+ .NICIRA_MOV_ARP_SHA_TO_THA.type());
+ ExtensionTreatment arpSpaToTpa = resolver
+ .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes
+ .NICIRA_MOV_ARP_SPA_TO_TPA.type());
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .extension(ethSrcToDst, deviceId)
+ .setEthSrc(dstMac).setArpOp(ARP_RESPONSE)
+ .extension(arpShaToTha, deviceId)
+ .extension(arpSpaToTpa, deviceId)
+ .setArpSha(dstMac).setArpSpa(dstIP)
+ .setOutput(PortNumber.IN_PORT).build();
+
+ ForwardingObjective.Builder objective = DefaultForwardingObjective
+ .builder().withTreatment(treatment).withSelector(selector)
+ .fromApp(appId).withFlag(Flag.SPECIFIC)
+ .withPriority(ARP_PRIORITY);
+
+ if (type.equals(Objective.Operation.ADD)) {
+ log.debug("PrivateArpRules-->ADD");
+ flowObjectiveService.forward(deviceId, objective.add());
+ } else {
+ log.debug("PrivateArpRules-->REMOVE");
+ flowObjectiveService.forward(deviceId, objective.remove());
+ }
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java
index a8562e7f..cca905c2 100644
--- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java
+++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java
@@ -17,12 +17,20 @@ package org.onosproject.vtn.util;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import org.onlab.packet.IpAddress;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -94,4 +102,78 @@ public final class VtnData {
return localTunnelPorts;
}
+ /**
+ * Get VirtualPort.
+ *
+ * @param vPortStore EventuallyConsistentMap of VirtualPort
+ * @param vPortId VirtualPortId of the VirtualPort
+ * @return VirtualPort
+ */
+ public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
+ VirtualPortId vPortId) {
+ if (vPortStore != null) {
+ return vPortStore.get(vPortId);
+ }
+ return null;
+ }
+
+ /**
+ * Get VirtualPort.
+ *
+ * @param vPortStore EventuallyConsistentMap of VirtualPort
+ * @param fixedIP FixedIp of the VirtualPort
+ * @return VirtualPort
+ */
+ public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
+ FixedIp fixedIP) {
+ if (vPortStore != null) {
+ List<VirtualPort> vPorts = new ArrayList<>();
+ vPortStore.values().stream().forEach(p -> {
+ Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
+ while (fixedIps.hasNext()) {
+ if (fixedIps.next().equals(fixedIP)) {
+ vPorts.add(p);
+ break;
+ }
+ }
+ });
+ if (vPorts.size() == 0) {
+ return null;
+ }
+ return vPorts.get(0);
+ }
+ return null;
+ }
+
+ /**
+ * Get VirtualPort.
+ *
+ * @param vPortStore EventuallyConsistentMap of VirtualPort
+ * @param networkId TenantNetworkId of the VirtualPort
+ * @param ip IpAddress of the VirtualPort
+ * @return VirtualPort
+ */
+ public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
+ TenantNetworkId networkId, IpAddress ip) {
+ if (vPortStore != null) {
+ List<VirtualPort> vPorts = new ArrayList<>();
+ vPortStore.values().stream()
+ .filter(p -> p.networkId().equals(networkId))
+ .forEach(p -> {
+ Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
+ while (fixedIps.hasNext()) {
+ if (fixedIps.next().ip().equals(ip)) {
+ vPorts.add(p);
+ break;
+ }
+ }
+ });
+ if (vPorts.size() == 0) {
+ return null;
+ }
+ return vPorts.get(0);
+ }
+ return null;
+ }
+
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java
new file mode 100644
index 00000000..a15da3ef
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java
@@ -0,0 +1,41 @@
+/*
+ * 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.classifier;
+
+import org.onosproject.net.DeviceId;
+
+/**
+ * Provides Services for Classifier.
+ */
+public interface ClassifierService {
+
+ /**
+ * Get Classifier devices for sfc.
+ *
+ * @return list of device id's for classifiers
+ */
+ Iterable<DeviceId> getClassifiers();
+
+ /**
+ * Add Classifier device for sfc.
+ */
+ void addClassifier(DeviceId deviceId);
+
+ /**
+ * Remove Classifier device for sfc.
+ */
+ void removeClassifier(DeviceId deviceId);
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java
new file mode 100644
index 00000000..a12d6221
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java
@@ -0,0 +1,78 @@
+/*
+ * 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.classifier.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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.vtnrsc.classifier.ClassifierService;
+import org.slf4j.Logger;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Provides implementation of the Classifier Service.
+ */
+@Component(immediate = true)
+@Service
+public class ClassifierManager implements ClassifierService {
+
+ private final Logger log = getLogger(ClassifierManager.class);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected StorageService storageService;
+
+ private DistributedSet<DeviceId> classifierList;
+
+ @Activate
+ protected void activate() {
+ classifierList = storageService.<DeviceId>setBuilder()
+ .withName("classifier")
+ .withSerializer(Serializer.using(KryoNamespaces.API))
+ .build();
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ log.info("Stopped");
+ }
+
+ @Override
+ public void addClassifier(DeviceId deviceId) {
+ classifierList.add(deviceId);
+ }
+
+ @Override
+ public Iterable<DeviceId> getClassifiers() {
+ return ImmutableList.copyOf(classifierList);
+ }
+
+ @Override
+ public void removeClassifier(DeviceId deviceId) {
+ classifierList.remove(deviceId);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java
new file mode 100644
index 00000000..dc72e806
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/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 Classifier service.
+ */
+package org.onosproject.vtnrsc.classifier.impl;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java
new file mode 100644
index 00000000..56976d96
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/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 Classifier of SFC.
+ */
+package org.onosproject.vtnrsc.classifier;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java
index 56236408..de8cfe53 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java
@@ -98,7 +98,7 @@ public class SubnetCreateCommand extends AbstractShellCommand {
protected void execute() {
SubnetService service = get(SubnetService.class);
if (id == null || networkId == null || tenantId == null) {
- print(null, "id,networkId,tenantId can not be null");
+ print("id,networkId,tenantId can not be null");
return;
}
Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java
index b0578a1e..c76ca5b2 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java
@@ -98,7 +98,7 @@ public class SubnetUpdateCommand extends AbstractShellCommand {
protected void execute() {
SubnetService service = get(SubnetService.class);
if (id == null || networkId == null || tenantId == null) {
- print(null, "id,networkId,tenantId can not be null");
+ print("id,networkId,tenantId can not be null");
return;
}
Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName,
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
index 3bac158b..ce3faae7 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java
@@ -51,7 +51,55 @@ public class VtnRscEvent
/**
* Signifies that router interface has remove.
*/
- ROUTER_INTERFACE_DELETE
+ ROUTER_INTERFACE_DELETE,
+ /**
+ * Signifies that port-pair has add.
+ */
+ PORT_PAIR_PUT,
+ /**
+ * Signifies that port-pair has remove.
+ */
+ PORT_PAIR_DELETE,
+ /**
+ * Signifies that port-pair has update.
+ */
+ PORT_PAIR_UPDATE,
+ /**
+ * Signifies that port-pair-group has add.
+ */
+ PORT_PAIR_GROUP_PUT,
+ /**
+ * Signifies that port-pair-group has remove.
+ */
+ PORT_PAIR_GROUP_DELETE,
+ /**
+ * Signifies that port-pair-group has update.
+ */
+ PORT_PAIR_GROUP_UPDATE,
+ /**
+ * Signifies that flow-classifier has add.
+ */
+ FLOW_CLASSIFIER_PUT,
+ /**
+ * Signifies that flow-classifier has remove.
+ */
+ FLOW_CLASSIFIER_DELETE,
+ /**
+ * Signifies that flow-classifier has update.
+ */
+ FLOW_CLASSIFIER_UPDATE,
+ /**
+ * Signifies that port-chain has add.
+ */
+ PORT_CHAIN_PUT,
+ /**
+ * Signifies that port-chain has remove.
+ */
+ PORT_CHAIN_DELETE,
+ /**
+ * Signifies that port-chain has update.
+ */
+ PORT_CHAIN_UPDATE
}
/**
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
index 63dcaeee..112c6411 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java
@@ -20,6 +20,10 @@ import java.util.Objects;
import org.onosproject.vtnrsc.FloatingIp;
import org.onosproject.vtnrsc.Router;
import org.onosproject.vtnrsc.RouterInterface;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -31,6 +35,10 @@ public class VtnRscEventFeedback {
private final FloatingIp floaingtIp;
private final Router router;
private final RouterInterface routerInterface;
+ private final PortPair portPair;
+ private final PortPairGroup portPairGroup;
+ private final FlowClassifier flowClassifier;
+ private final PortChain portChain;
/**
* Creates VtnRscEventFeedback object.
@@ -41,6 +49,10 @@ public class VtnRscEventFeedback {
this.floaingtIp = checkNotNull(floatingIp, "floaintIp cannot be null");
this.router = null;
this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
}
/**
@@ -52,6 +64,10 @@ public class VtnRscEventFeedback {
this.floaingtIp = null;
this.router = checkNotNull(router, "router cannot be null");
this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
}
/**
@@ -64,6 +80,74 @@ public class VtnRscEventFeedback {
this.router = null;
this.routerInterface = checkNotNull(routerInterface,
"routerInterface cannot be null");
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param portPair the Port-Pair
+ */
+ public VtnRscEventFeedback(PortPair portPair) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = checkNotNull(portPair,
+ "Port-Pair cannot be null");
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param portPairGroup the Port-Pair-Group
+ */
+ public VtnRscEventFeedback(PortPairGroup portPairGroup) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = checkNotNull(portPairGroup,
+ "Port-Pair-Group cannot be null");
+ this.flowClassifier = null;
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param flowClassifier the Flow-Classifier
+ */
+ public VtnRscEventFeedback(FlowClassifier flowClassifier) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = checkNotNull(flowClassifier,
+ "Flow-Classifier cannot be null");
+ this.portChain = null;
+ }
+
+ /**
+ * Creates VtnRscEventFeedback object.
+ *
+ * @param portChain the Port-Chain
+ */
+ public VtnRscEventFeedback(PortChain portChain) {
+ this.floaingtIp = null;
+ this.router = null;
+ this.routerInterface = null;
+ this.portPair = null;
+ this.portPairGroup = null;
+ this.flowClassifier = null;
+ this.portChain = checkNotNull(portChain,
+ "Port-Chain cannot be null");
}
/**
@@ -93,9 +177,46 @@ public class VtnRscEventFeedback {
return routerInterface;
}
+ /**
+ * Returns Port-Pair.
+ *
+ * @return portPair the Port-Pair
+ */
+ public PortPair portPair() {
+ return portPair;
+ }
+
+ /**
+ * Returns Port-Pair-Group.
+ *
+ * @return portPairGroup the Port-Pair-Group
+ */
+ public PortPairGroup portPairGroup() {
+ return portPairGroup;
+ }
+
+ /**
+ * Returns Flow-Classifier.
+ *
+ * @return flowClassifier the Flow-Classifier
+ */
+ public FlowClassifier flowClassifier() {
+ return flowClassifier;
+ }
+
+ /**
+ * Returns Port-Chain.
+ *
+ * @return portChain the Port-Chain
+ */
+ public PortChain portChain() {
+ return portChain;
+ }
+
@Override
public int hashCode() {
- return Objects.hash(floaingtIp, router, routerInterface);
+ return Objects.hash(floaingtIp, router, routerInterface, portPair,
+ portPairGroup, flowClassifier, portChain);
}
@Override
@@ -107,7 +228,11 @@ public class VtnRscEventFeedback {
final VtnRscEventFeedback that = (VtnRscEventFeedback) obj;
return Objects.equals(this.floaingtIp, that.floaingtIp)
&& Objects.equals(this.router, that.router)
- && Objects.equals(this.routerInterface, that.routerInterface);
+ && Objects.equals(this.routerInterface, that.routerInterface)
+ && Objects.equals(this.portPair, that.portPair)
+ && Objects.equals(this.portPairGroup, that.portPairGroup)
+ && Objects.equals(this.flowClassifier, that.flowClassifier)
+ && Objects.equals(this.portChain, that.portChain);
}
return false;
}
@@ -118,6 +243,10 @@ public class VtnRscEventFeedback {
.add("router", router)
.add("floaingtIp", floaingtIp)
.add("routerInterface", routerInterface)
+ .add("portPair", portPair)
+ .add("portPairGroup", portPairGroup)
+ .add("flowClassifier", flowClassifier)
+ .add("portChain", portChain)
.toString();
}
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
index 9f944da1..ce9bb21f 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java
@@ -202,27 +202,24 @@ public class FloatingIpManager implements FloatingIpService {
public boolean updateFloatingIps(Collection<FloatingIp> floatingIps) {
checkNotNull(floatingIps, FLOATINGIP_NOT_NULL);
boolean result = true;
- if (floatingIps != null) {
- for (FloatingIp floatingIp : floatingIps) {
- verifyFloatingIpData(floatingIp);
- if (floatingIp.portId() != null) {
- floatingIpStore.put(floatingIp.id(), floatingIp);
- if (!floatingIpStore.containsKey(floatingIp.id())) {
+ for (FloatingIp floatingIp : floatingIps) {
+ verifyFloatingIpData(floatingIp);
+ if (floatingIp.portId() != null) {
+ floatingIpStore.put(floatingIp.id(), floatingIp);
+ if (!floatingIpStore.containsKey(floatingIp.id())) {
+ log.debug("The floating Ip is updated failed whose identifier is {}",
+ floatingIp.id().toString());
+ result = false;
+ }
+ } else {
+ FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp.id());
+ if (oldFloatingIp != null) {
+ floatingIpStore.remove(floatingIp.id(), oldFloatingIp);
+ if (floatingIpStore.containsKey(floatingIp.id())) {
log.debug("The floating Ip is updated failed whose identifier is {}",
floatingIp.id().toString());
result = false;
}
- } else {
- FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp
- .id());
- if (oldFloatingIp != null) {
- floatingIpStore.remove(floatingIp.id(), oldFloatingIp);
- if (floatingIpStore.containsKey(floatingIp.id())) {
- log.debug("The floating Ip is updated failed whose identifier is {}",
- floatingIp.id().toString());
- result = false;
- }
- }
}
}
}
@@ -233,21 +230,19 @@ public class FloatingIpManager implements FloatingIpService {
public boolean removeFloatingIps(Collection<FloatingIpId> floatingIpIds) {
checkNotNull(floatingIpIds, FLOATINGIP_ID_NOT_NULL);
boolean result = true;
- if (floatingIpIds != null) {
- for (FloatingIpId floatingIpId : floatingIpIds) {
- if (!floatingIpStore.containsKey(floatingIpId)) {
- log.debug("The floatingIp is not exist whose identifier is {}",
- floatingIpId.toString());
- throw new IllegalArgumentException(
- "FloatingIP ID doesn't exist");
- }
- FloatingIp floatingIp = floatingIpStore.get(floatingIpId);
- floatingIpStore.remove(floatingIpId, floatingIp);
- if (floatingIpStore.containsKey(floatingIpId)) {
- log.debug("The floating Ip is deleted failed whose identifier is {}",
- floatingIpId.toString());
- result = false;
- }
+ for (FloatingIpId floatingIpId : floatingIpIds) {
+ if (!floatingIpStore.containsKey(floatingIpId)) {
+ log.debug("The floatingIp is not exist whose identifier is {}",
+ floatingIpId.toString());
+ throw new IllegalArgumentException(
+ "FloatingIP ID doesn't exist");
+ }
+ FloatingIp floatingIp = floatingIpStore.get(floatingIpId);
+ floatingIpStore.remove(floatingIpId, floatingIp);
+ if (floatingIpStore.containsKey(floatingIpId)) {
+ log.debug("The floating Ip is deleted failed whose identifier is {}",
+ floatingIpId.toString());
+ result = false;
}
}
return result;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java
new file mode 100644
index 00000000..d81ab48a
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.event.AbstractEvent;
+import org.onosproject.vtnrsc.FlowClassifier;
+
+/**
+ * Describes network Flow-Classifier event.
+ */
+public class FlowClassifierEvent extends AbstractEvent<FlowClassifierEvent.Type, FlowClassifier> {
+ /**
+ * Type of flow-classifier events.
+ */
+ public enum Type {
+ /**
+ * Signifies that flow-classifier has been created.
+ */
+ FLOW_CLASSIFIER_PUT,
+ /**
+ * Signifies that flow-classifier has been deleted.
+ */
+ FLOW_CLASSIFIER_DELETE,
+ /**
+ * Signifies that flow-classifier has been updated.
+ */
+ FLOW_CLASSIFIER_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Flow-Classifier.
+ *
+ * @param type Flow-Classifier event type
+ * @param flowClassifier Flow-Classifier subject
+ */
+ public FlowClassifierEvent(Type type, FlowClassifier flowClassifier) {
+ super(type, flowClassifier);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Flow-Classifier.
+ *
+ * @param type Flow-Classifier event type
+ * @param flowClassifier Flow-Classifier subject
+ * @param time occurrence time
+ */
+ public FlowClassifierEvent(Type type, FlowClassifier flowClassifier, long time) {
+ super(type, flowClassifier, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java
new file mode 100644
index 00000000..3c0409ad
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.event.EventListener;
+
+/**
+ * Entity capable of Flow-Classifier related events.
+ */
+public interface FlowClassifierListener extends EventListener<FlowClassifierEvent> {
+
+}
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
index c5911ff2..48438846 100644
--- 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
@@ -15,13 +15,14 @@
*/
package org.onosproject.vtnrsc.flowclassifier;
+import org.onosproject.event.ListenerService;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
/**
* Provides Services for Flow Classifier.
*/
-public interface FlowClassifierService {
+public interface FlowClassifierService extends ListenerService<FlowClassifierEvent, FlowClassifierListener> {
/**
* Check whether Flow Classifier is present based on given Flow Classifier
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
index 4a60cd34..18f63b30 100644
--- 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
@@ -15,6 +15,9 @@
*/
package org.onosproject.vtnrsc.flowclassifier.impl;
+import static org.slf4j.LoggerFactory.getLogger;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -22,6 +25,7 @@ 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.KryoNamespace;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.MultiValuedTimestamp;
@@ -29,12 +33,11 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
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;
/**
@@ -42,14 +45,17 @@ import com.google.common.collect.ImmutableList;
*/
@Component(immediate = true)
@Service
-public class FlowClassifierManager implements FlowClassifierService {
-
- private final Logger log = getLogger(FlowClassifierManager.class);
+public class FlowClassifierManager extends AbstractListenerManager<FlowClassifierEvent, FlowClassifierListener>
+ implements FlowClassifierService {
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 static final String LISTENER_NOT_NULL = "Listener cannot be null";
+
+ private final Logger log = getLogger(FlowClassifierManager.class);
private EventuallyConsistentMap<FlowClassifierId, FlowClassifier> flowClassifierStore;
+
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java
new file mode 100644
index 00000000..44a4e8ed
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.event.AbstractEvent;
+import org.onosproject.vtnrsc.PortChain;
+
+/**
+ * Describes network Port-Chain event.
+ */
+public class PortChainEvent extends AbstractEvent<PortChainEvent.Type, PortChain> {
+ /**
+ * Type of port-chain events.
+ */
+ public enum Type {
+ /**
+ * Signifies that port-chain has been created.
+ */
+ PORT_CHAIN_PUT,
+ /**
+ * Signifies that port-chain has been deleted.
+ */
+ PORT_CHAIN_DELETE,
+ /**
+ * Signifies that port-chain has been updated.
+ */
+ PORT_CHAIN_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Chain.
+ *
+ * @param type Port-Chain event type
+ * @param portChain Port-Chain subject
+ */
+ public PortChainEvent(Type type, PortChain portChain) {
+ super(type, portChain);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Chain.
+ *
+ * @param type Port-Chain event type
+ * @param portChain Port-Chain subject
+ * @param time occurrence time
+ */
+ public PortChainEvent(Type type, PortChain portChain, long time) {
+ super(type, portChain, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java
new file mode 100644
index 00000000..27a498b5
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.event.EventListener;
+
+/**
+ * Entity capable of Port-Chain related events.
+ */
+public interface PortChainListener extends EventListener<PortChainEvent> {
+
+}
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
index b4ff917e..5b08262b 100644
--- 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
@@ -15,13 +15,14 @@
*/
package org.onosproject.vtnrsc.portchain;
+import org.onosproject.event.ListenerService;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
/**
* Service for interacting with the inventory of port chains.
*/
-public interface PortChainService {
+public interface PortChainService extends ListenerService<PortChainEvent, PortChainListener> {
/**
* Returns if the port chain is existed.
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
index 5201a2ca..0062db48 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java
@@ -27,6 +27,7 @@ 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.KryoNamespace;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.MultiValuedTimestamp;
@@ -34,6 +35,8 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.portchain.PortChainEvent;
+import org.onosproject.vtnrsc.portchain.PortChainListener;
import org.onosproject.vtnrsc.portchain.PortChainService;
import org.slf4j.Logger;
@@ -42,13 +45,14 @@ import org.slf4j.Logger;
*/
@Component(immediate = true)
@Service
-public class PortChainManager implements PortChainService {
-
- private final Logger log = getLogger(getClass());
+public class PortChainManager extends AbstractListenerManager<PortChainEvent, PortChainListener> implements
+ PortChainService {
private static final String PORT_CHAIN_ID_NULL = "PortChain ID cannot be null";
private static final String PORT_CHAIN_NULL = "PortChain cannot be null";
+ private static final String LISTENER_NOT_NULL = "Listener cannot be null";
+ private final Logger log = getLogger(getClass());
private EventuallyConsistentMap<PortChainId, PortChain> portChainStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java
new file mode 100644
index 00000000..31ecc737
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.portpair;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.vtnrsc.PortPair;
+
+/**
+ * Describes network Port-Pair event.
+ */
+public class PortPairEvent extends AbstractEvent<PortPairEvent.Type, PortPair> {
+ /**
+ * Type of port-pair events.
+ */
+ public enum Type {
+ /**
+ * Signifies that port-pair has been created.
+ */
+ PORT_PAIR_PUT,
+ /**
+ * Signifies that port-pair has been deleted.
+ */
+ PORT_PAIR_DELETE,
+ /**
+ * Signifies that port-pair has been updated.
+ */
+ PORT_PAIR_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair.
+ *
+ * @param type Port-Pair event type
+ * @param portPair Port-Pair subject
+ */
+ public PortPairEvent(Type type, PortPair portPair) {
+ super(type, portPair);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair.
+ *
+ * @param type Port-Pair event type
+ * @param portPair Port-Pair subject
+ * @param time occurrence time
+ */
+ public PortPairEvent(Type type, PortPair portPair, long time) {
+ super(type, portPair, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java
new file mode 100644
index 00000000..3bdb9e4e
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.portpair;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of Port-Pair related events.
+ */
+public interface PortPairListener extends EventListener<PortPairEvent> {
+
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java
index f99cc2cf..e98a6a20 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java
@@ -77,4 +77,18 @@ public interface PortPairService {
* @return true if the give port pair is deleted successfully.
*/
boolean removePortPair(PortPairId portPairId);
+
+ /**
+ * Adds the specified listener to Port-Pair manager.
+ *
+ * @param listener Port-Pair listener
+ */
+ void addListener(PortPairListener listener);
+
+ /**
+ * Removes the specified listener to Port-Pair manager.
+ *
+ * @param listener Port-Pair listener
+ */
+ void removeListener(PortPairListener listener);
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java
index 93c8782a..ad6fd4bb 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
+import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -34,9 +35,12 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.portpair.PortPairListener;
import org.onosproject.vtnrsc.portpair.PortPairService;
import org.slf4j.Logger;
+import com.google.common.collect.Sets;
+
/**
* Provides implementation of the portPairService.
*/
@@ -44,11 +48,12 @@ import org.slf4j.Logger;
@Service
public class PortPairManager implements PortPairService {
- private final Logger log = getLogger(getClass());
-
private static final String PORT_PAIR_ID_NULL = "PortPair ID cannot be null";
private static final String PORT_PAIR_NULL = "PortPair cannot be null";
+ private static final String LISTENER_NOT_NULL = "Listener cannot be null";
+ private final Logger log = getLogger(getClass());
+ private final Set<PortPairListener> listeners = Sets.newCopyOnWriteArraySet();
private EventuallyConsistentMap<PortPairId, PortPair> portPairStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -73,6 +78,7 @@ public class PortPairManager implements PortPairService {
@Deactivate
public void deactivate() {
portPairStore.destroy();
+ listeners.clear();
log.info("Stopped");
}
@@ -143,4 +149,16 @@ public class PortPairManager implements PortPairService {
}
return true;
}
+
+ @Override
+ public void addListener(PortPairListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeListener(PortPairListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.remove(listener);
+ }
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java
new file mode 100644
index 00000000..88e1d7fb
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java
@@ -0,0 +1,63 @@
+/*
+ * 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.event.AbstractEvent;
+import org.onosproject.vtnrsc.PortPairGroup;
+
+/**
+ * Describes network Port-Pair-Group event.
+ */
+public class PortPairGroupEvent extends AbstractEvent<PortPairGroupEvent.Type, PortPairGroup> {
+ /**
+ * Type of port-pair-group events.
+ */
+ public enum Type {
+ /**
+ * Signifies that port-pair-group has been created.
+ */
+ PORT_PAIR_GROUP_PUT,
+ /**
+ * Signifies that port-pair-group has been deleted.
+ */
+ PORT_PAIR_GROUP_DELETE,
+ /**
+ * Signifies that port-pair-group has been updated.
+ */
+ PORT_PAIR_GROUP_UPDATE
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair-Group.
+ *
+ * @param type Port-Pair-Group event type
+ * @param portPairGroup Port-Pair-Group subject
+ */
+ public PortPairGroupEvent(Type type, PortPairGroup portPairGroup) {
+ super(type, portPairGroup);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified Port-Pair-Group.
+ *
+ * @param type Port-Pair-Group event type
+ * @param portPairGroup Port-Pair-Group subject
+ * @param time occurrence time
+ */
+ public PortPairGroupEvent(Type type, PortPairGroup portPairGroup, long time) {
+ super(type, portPairGroup, time);
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java
new file mode 100644
index 00000000..637149e3
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.event.EventListener;
+
+/**
+ * Entity capable of Port-Pair-Group related events.
+ */
+public interface PortPairGroupListener extends EventListener<PortPairGroupEvent> {
+
+}
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
index 77f483fc..efee0eb9 100644
--- 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
@@ -77,4 +77,18 @@ public interface PortPairGroupService {
* @return true if the give port pair group is deleted successfully.
*/
boolean removePortPairGroup(PortPairGroupId portPairGroupId);
+
+ /**
+ * Adds the specified listener to Port-Pair-Group manager.
+ *
+ * @param listener Port-Pair-Group listener
+ */
+ void addListener(PortPairGroupListener listener);
+
+ /**
+ * Removes the specified listener to Port-Pair-Group manager.
+ *
+ * @param listener Port-Pair-Group listener
+ */
+ void removeListener(PortPairGroupListener listener);
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java
index 55fb4e43..5f80ef64 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
+import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -34,9 +35,12 @@ import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
import org.slf4j.Logger;
+import com.google.common.collect.Sets;
+
/**
* Provides implementation of the portPairGroupService.
*/
@@ -44,11 +48,12 @@ import org.slf4j.Logger;
@Service
public class PortPairGroupManager implements PortPairGroupService {
- private final Logger log = getLogger(getClass());
-
private static final String PORT_PAIR_GROUP_ID_NULL = "PortPairGroup ID cannot be null";
private static final String PORT_PAIR_GROUP_NULL = "PortPairGroup cannot be null";
+ private static final String LISTENER_NOT_NULL = "Listener cannot be null";
+ private final Logger log = getLogger(getClass());
+ private final Set<PortPairGroupListener> listeners = Sets.newCopyOnWriteArraySet();
private EventuallyConsistentMap<PortPairGroupId, PortPairGroup> portPairGroupStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -73,6 +78,7 @@ public class PortPairGroupManager implements PortPairGroupService {
@Deactivate
public void deactivate() {
portPairGroupStore.destroy();
+ listeners.clear();
log.info("Stopped");
}
@@ -143,4 +149,16 @@ public class PortPairGroupManager implements PortPairGroupService {
}
return true;
}
+
+ @Override
+ public void addListener(PortPairGroupListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.add(listener);
+ }
+
+ @Override
+ public void removeListener(PortPairGroupListener listener) {
+ checkNotNull(listener, LISTENER_NOT_NULL);
+ listeners.remove(listener);
+ }
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java
index 21161ba5..bc9f4e68 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java
@@ -18,32 +18,20 @@ package org.onosproject.vtnrsc.service;
import java.util.Iterator;
import org.onlab.packet.MacAddress;
+import org.onosproject.event.ListenerService;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.event.VtnRscEvent;
import org.onosproject.vtnrsc.event.VtnRscListener;
/**
* Service for interacting with the inventory of Vtn resource.
*/
-public interface VtnRscService {
- /**
- * Adds the specified listener.
- *
- * @param listener VtnRsc listener
- */
- void addListener(VtnRscListener listener);
-
- /**
- * Removes the specified listener.
- *
- * @param listener VtnRsc listener
- */
- void removeListener(VtnRscListener listener);
-
+public interface VtnRscService extends ListenerService<VtnRscEvent, VtnRscListener> {
/**
* Returns the SegmentationId of tenant.
*
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
index ec9ca3ef..b21ad200 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java
@@ -32,6 +32,7 @@ import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.CoreService;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
@@ -54,6 +55,11 @@ import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.VirtualPort;
import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.event.VtnRscEvent;
import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
import org.onosproject.vtnrsc.event.VtnRscListener;
@@ -70,16 +76,27 @@ import org.onosproject.vtnrsc.service.VtnRscService;
import org.onosproject.vtnrsc.subnet.SubnetService;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.onosproject.vtnrsc.portpair.PortPairEvent;
+import org.onosproject.vtnrsc.portpair.PortPairListener;
+import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.portchain.PortChainEvent;
+import org.onosproject.vtnrsc.portchain.PortChainListener;
+import org.onosproject.vtnrsc.portchain.PortChainService;
import org.slf4j.Logger;
-import com.google.common.collect.Sets;
-
/**
* Provides implementation of the VtnRsc service.
*/
@Component(immediate = true)
@Service
-public class VtnRscManager implements VtnRscService {
+public class VtnRscManager extends AbstractListenerManager<VtnRscEvent, VtnRscListener>
+ implements VtnRscService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -88,11 +105,14 @@ public class VtnRscManager implements VtnRscService {
protected LogicalClockService clockService;
private final Logger log = getLogger(getClass());
- private final Set<VtnRscListener> listeners = Sets.newCopyOnWriteArraySet();
private HostListener hostListener = new InnerHostListener();
private FloatingIpListener floatingIpListener = new InnerFloatingIpListener();
private RouterListener routerListener = new InnerRouterListener();
private RouterInterfaceListener routerInterfaceListener = new InnerRouterInterfaceListener();
+ private PortPairListener portPairListener = new InnerPortPairListener();
+ private PortPairGroupListener portPairGroupListener = new InnerPortPairGroupListener();
+ private FlowClassifierListener flowClassifierListener = new InnerFlowClassifierListener();
+ private PortChainListener portChainListener = new InnerPortChainListener();
private EventuallyConsistentMap<TenantId, SegmentationId> l3vniMap;
private EventuallyConsistentMap<TenantId, Set<DeviceId>> classifierOvsMap;
@@ -125,6 +145,14 @@ public class VtnRscManager implements VtnRscService {
protected TenantNetworkService tenantNetworkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairService portPairService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortPairGroupService portPairGroupService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowClassifierService flowClassifierService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PortChainService portChainService;
@Activate
public void activate() {
@@ -132,6 +160,10 @@ public class VtnRscManager implements VtnRscService {
floatingIpService.addListener(floatingIpListener);
routerService.addListener(routerListener);
routerInterfaceService.addListener(routerInterfaceListener);
+ portPairService.addListener(portPairListener);
+ portPairGroupService.addListener(portPairGroupListener);
+ flowClassifierService.addListener(flowClassifierListener);
+ portChainService.addListener(portChainListener);
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
@@ -161,26 +193,18 @@ public class VtnRscManager implements VtnRscService {
floatingIpService.removeListener(floatingIpListener);
routerService.removeListener(routerListener);
routerInterfaceService.removeListener(routerInterfaceListener);
+ portPairService.removeListener(portPairListener);
+ portPairGroupService.removeListener(portPairGroupListener);
+ flowClassifierService.removeListener(flowClassifierListener);
+ portChainService.removeListener(portChainListener);
+
l3vniMap.destroy();
classifierOvsMap.destroy();
sffOvsMap.destroy();
- listeners.clear();
log.info("Stopped");
}
@Override
- public void addListener(VtnRscListener listener) {
- checkNotNull(listener, LISTENER_NOT_NULL);
- listeners.add(listener);
- }
-
- @Override
- public void removeListener(VtnRscListener listener) {
- checkNotNull(listener, LISTENER_NOT_NULL);
- listeners.add(listener);
- }
-
- @Override
public SegmentationId getL3vni(TenantId tenantId) {
checkNotNull(tenantId, "tenantId cannot be null");
SegmentationId l3vni = l3vniMap.get(tenantId);
@@ -282,6 +306,93 @@ public class VtnRscManager implements VtnRscService {
}
}
+ private class InnerPortPairListener implements PortPairListener {
+
+ @Override
+ public void event(PortPairEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ PortPair portPair = event.subject();
+ if (PortPairEvent.Type.PORT_PAIR_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(VtnRscEvent.Type.PORT_PAIR_PUT,
+ new VtnRscEventFeedback(portPair)));
+ } else if (PortPairEvent.Type.PORT_PAIR_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_DELETE,
+ new VtnRscEventFeedback(portPair)));
+ } else if (PortPairEvent.Type.PORT_PAIR_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_UPDATE,
+ new VtnRscEventFeedback(portPair)));
+ }
+ }
+ }
+
+ private class InnerPortPairGroupListener implements PortPairGroupListener {
+
+ @Override
+ public void event(PortPairGroupEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ PortPairGroup portPairGroup = event.subject();
+ if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_GROUP_PUT,
+ new VtnRscEventFeedback(portPairGroup)));
+ } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE,
+ new VtnRscEventFeedback(portPairGroup)));
+ } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE,
+ new VtnRscEventFeedback(portPairGroup)));
+ }
+ }
+ }
+
+ private class InnerFlowClassifierListener implements FlowClassifierListener {
+
+ @Override
+ public void event(FlowClassifierEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ FlowClassifier flowClassifier = event.subject();
+ if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.FLOW_CLASSIFIER_PUT,
+ new VtnRscEventFeedback(flowClassifier)));
+ } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE,
+ new VtnRscEventFeedback(flowClassifier)));
+ } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE,
+ new VtnRscEventFeedback(flowClassifier)));
+ }
+ }
+ }
+
+ private class InnerPortChainListener implements PortChainListener {
+
+ @Override
+ public void event(PortChainEvent event) {
+ checkNotNull(event, EVENT_NOT_NULL);
+ PortChain portChain = event.subject();
+ if (PortChainEvent.Type.PORT_CHAIN_PUT == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_CHAIN_PUT,
+ new VtnRscEventFeedback(portChain)));
+ } else if (PortChainEvent.Type.PORT_CHAIN_DELETE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_CHAIN_DELETE,
+ new VtnRscEventFeedback(portChain)));
+ } else if (PortChainEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
+ notifyListeners(new VtnRscEvent(
+ VtnRscEvent.Type.PORT_CHAIN_UPDATE,
+ new VtnRscEventFeedback(portChain)));
+ }
+ }
+ }
+
@Override
public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
checkNotNull(tenantId, TENANTID_NOT_NULL);
@@ -333,8 +444,7 @@ public class VtnRscManager implements VtnRscService {
@Override
public boolean isServiceFunction(VirtualPortId portId) {
- // TODO Auto-generated method stub
- return false;
+ return portPairService.exists(PortPairId.of(portId.portId()));
}
@Override
@@ -343,7 +453,7 @@ public class VtnRscManager implements VtnRscService {
VirtualPort vmPort = virtualPortService.getPort(portId);
Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
for (Host host : hostSet) {
- if (host.annotations().value(IFACEID).equals(vmPort.portId())) {
+ if (host.annotations().value(IFACEID).equals(vmPort.portId().portId())) {
return host.location().deviceId();
}
}
@@ -467,6 +577,6 @@ public class VtnRscManager implements VtnRscService {
*/
private void notifyListeners(VtnRscEvent event) {
checkNotNull(event, EVENT_NOT_NULL);
- listeners.forEach(listener -> listener.event(event));
+ post(event);
}
}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
index 0a3ea2cd..19548db8 100644
--- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
+++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
@@ -17,6 +17,7 @@ package org.onosproject.vtnrsc.virtualport;
import java.util.Collection;
+import org.onlab.packet.IpAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.TenantId;
@@ -53,6 +54,15 @@ public interface VirtualPortService {
VirtualPort getPort(FixedIp fixedIP);
/**
+ * Returns the virtualPort associated with the networkId and ip.
+ *
+ * @param networkId the TenantNetworkId identifier
+ * @param ip the ip identifier
+ * @return virtualPort.
+ */
+ VirtualPort getPort(TenantNetworkId networkId, IpAddress ip);
+
+ /**
* Returns the collection of the currently known virtualPort.
* @return collection of VirtualPort.
*/
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 daec7839..9639e086 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
@@ -72,6 +72,7 @@ public class VirtualPortManager implements VirtualPortService {
private static final String NETWORKID_NOT_NULL = "NetworkId cannot be null";
private static final String DEVICEID_NOT_NULL = "DeviceId cannot be null";
private static final String FIXEDIP_NOT_NULL = "FixedIp cannot be null";
+ private static final String IP_NOT_NULL = "Ip cannot be null";
protected Map<VirtualPortId, VirtualPort> vPortStore;
protected ApplicationId appId;
@@ -148,6 +149,27 @@ public class VirtualPortManager implements VirtualPortService {
}
@Override
+ public VirtualPort getPort(TenantNetworkId networkId, IpAddress ip) {
+ checkNotNull(networkId, NETWORKID_NOT_NULL);
+ checkNotNull(ip, IP_NOT_NULL);
+ List<VirtualPort> vPorts = new ArrayList<>();
+ vPortStore.values().stream().filter(p -> p.networkId().equals(networkId))
+ .forEach(p -> {
+ Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
+ while (fixedIps.hasNext()) {
+ if (fixedIps.next().ip().equals(ip)) {
+ vPorts.add(p);
+ break;
+ }
+ }
+ });
+ if (vPorts.size() == 0) {
+ return null;
+ }
+ return vPorts.get(0);
+ }
+
+ @Override
public Collection<VirtualPort> getPorts() {
return Collections.unmodifiableCollection(vPortStore.values());
}
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
index 08e37f96..4fd3fa48 100644
--- 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
@@ -36,12 +36,10 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
-import org.onosproject.vtnweb.web.FlowClassifierCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -64,11 +62,11 @@ public class FlowClassifierWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response getFlowClassifiers() {
Iterable<FlowClassifier> flowClassifiers = get(FlowClassifierService.class).getFlowClassifiers();
- ObjectNode result = new ObjectMapper().createObjectNode();
+ ObjectNode result = mapper().createObjectNode();
ArrayNode flowClassifierEntry = result.putArray("flow_classifiers");
if (flowClassifiers != null) {
for (final FlowClassifier flowClassifier : flowClassifiers) {
- flowClassifierEntry.add(new FlowClassifierCodec().encode(flowClassifier, this));
+ flowClassifierEntry.add(codec(FlowClassifier.class).encode(flowClassifier, this));
}
}
return ok(result.toString()).build();
@@ -85,11 +83,11 @@ public class FlowClassifierWebResource extends AbstractWebResource {
@Path("{flow_id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getFlowClassifier(@PathParam("flow_id") String id) {
- FlowClassifier flowClassifier = nullIsNotFound(
- get(FlowClassifierService.class).getFlowClassifier(FlowClassifierId.of(id)), FLOW_CLASSIFIER_NOT_FOUND);
+ FlowClassifier flowClassifier = nullIsNotFound(get(FlowClassifierService.class)
+ .getFlowClassifier(FlowClassifierId.of(id)), FLOW_CLASSIFIER_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("flow_classifier", new FlowClassifierCodec().encode(flowClassifier, this));
+ ObjectNode result = mapper().createObjectNode();
+ result.set("flow_classifier", codec(FlowClassifier.class).encode(flowClassifier, this));
return ok(result.toString()).build();
}
@@ -107,13 +105,12 @@ public class FlowClassifierWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response createFlowClassifier(InputStream stream) {
try {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode flow = jsonTree.get("flow_classifier");
- FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this);
+ FlowClassifier flowClassifier = codec(FlowClassifier.class).decode((ObjectNode) flow, this);
Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).createFlowClassifier(flowClassifier),
- FLOW_CLASSIFIER_NOT_FOUND);
+ FLOW_CLASSIFIER_NOT_FOUND);
return Response.status(OK).entity(issuccess.toString()).build();
} catch (IOException ex) {
log.error("Exception while creating flow classifier {}.", ex.toString());
@@ -139,9 +136,9 @@ public class FlowClassifierWebResource extends AbstractWebResource {
JsonNode jsonTree = mapper().readTree(stream);
JsonNode flow = jsonTree.get("flow_classifier");
- FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this);
+ FlowClassifier flowClassifier = codec(FlowClassifier.class).decode((ObjectNode) flow, this);
Boolean result = nullIsNotFound(get(FlowClassifierService.class).updateFlowClassifier(flowClassifier),
- FLOW_CLASSIFIER_NOT_FOUND);
+ FLOW_CLASSIFIER_NOT_FOUND);
return Response.status(OK).entity(result.toString()).build();
} catch (IOException e) {
log.error("Update flow classifier failed because of exception {}.", e.toString());
@@ -161,7 +158,7 @@ public class FlowClassifierWebResource extends AbstractWebResource {
log.debug("Deletes flow classifier by identifier {}.", id);
FlowClassifierId flowClassifierId = FlowClassifierId.of(id);
Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).removeFlowClassifier(flowClassifierId),
- FLOW_CLASSIFIER_NOT_FOUND);
+ FLOW_CLASSIFIER_NOT_FOUND);
}
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java
index db12bcc7..e7b908b7 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.vtnweb.resources;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.nullIsNotFound;
@@ -37,11 +36,11 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.PortChain;
import org.onosproject.vtnrsc.PortChainId;
import org.onosproject.vtnrsc.portchain.PortChainService;
-import org.onosproject.vtnweb.web.PortChainCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
@@ -52,7 +51,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class PortChainWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(PortChainWebResource.class);
- private final PortChainService service = get(PortChainService.class);
public static final String PORT_CHAIN_NOT_FOUND = "Port chain not found";
public static final String PORT_CHAIN_ID_EXIST = "Port chain exists";
public static final String PORT_CHAIN_ID_NOT_EXIST = "Port chain does not exist with identifier";
@@ -65,10 +63,15 @@ public class PortChainWebResource extends AbstractWebResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPortChains() {
- Iterable<PortChain> portChains = service.getPortChains();
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_chains", new PortChainCodec().encode(portChains, this));
- return ok(result).build();
+ Iterable<PortChain> portChains = get(PortChainService.class).getPortChains();
+ ObjectNode result = mapper().createObjectNode();
+ ArrayNode portChainEntry = result.putArray("port_chains");
+ if (portChains != null) {
+ for (final PortChain portChain : portChains) {
+ portChainEntry.add(codec(PortChain.class).encode(portChain, this));
+ }
+ }
+ return ok(result.toString()).build();
}
/**
@@ -82,14 +85,11 @@ public class PortChainWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPain(@PathParam("chain_id") String id) {
- if (!service.exists(PortChainId.of(id))) {
- return Response.status(NOT_FOUND).entity(PORT_CHAIN_NOT_FOUND).build();
- }
- PortChain portChain = nullIsNotFound(service.getPortChain(PortChainId.of(id)),
+ PortChain portChain = nullIsNotFound(get(PortChainService.class).getPortChain(PortChainId.of(id)),
PORT_CHAIN_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_chain", new PortChainCodec().encode(portChain, this));
- return ok(result).build();
+ ObjectNode result = mapper().createObjectNode();
+ result.set("port_chain", codec(PortChain.class).encode(portChain, this));
+ return ok(result.toString()).build();
}
/**
@@ -105,8 +105,10 @@ public class PortChainWebResource extends AbstractWebResource {
public Response createPortChain(InputStream stream) {
try {
ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
- PortChain portChain = codec(PortChain.class).decode(jsonTree, this);
- Boolean issuccess = nullIsNotFound(service.createPortChain(portChain), PORT_CHAIN_NOT_FOUND);
+ JsonNode port = jsonTree.get("port_chain");
+ PortChain portChain = codec(PortChain.class).decode((ObjectNode) port, this);
+ Boolean issuccess = nullIsNotFound(get(PortChainService.class).createPortChain(portChain),
+ PORT_CHAIN_NOT_FOUND);
return Response.status(OK).entity(issuccess.toString()).build();
} catch (IOException e) {
log.error("Exception while creating port chain {}.", e.toString());
@@ -129,8 +131,10 @@ public class PortChainWebResource extends AbstractWebResource {
final InputStream stream) {
try {
ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
- PortChain portChain = codec(PortChain.class).decode(jsonTree, this);
- Boolean result = nullIsNotFound(service.updatePortChain(portChain), PORT_CHAIN_NOT_FOUND);
+ JsonNode port = jsonTree.get("port_chain");
+ PortChain portChain = codec(PortChain.class).decode((ObjectNode) port, this);
+ Boolean result = nullIsNotFound(get(PortChainService.class).updatePortChain(portChain),
+ PORT_CHAIN_NOT_FOUND);
return Response.status(OK).entity(result.toString()).build();
} catch (IOException e) {
log.error("Update port chain failed because of exception {}.", e.toString());
@@ -149,7 +153,8 @@ public class PortChainWebResource extends AbstractWebResource {
log.debug("Deletes port chain by identifier {}.", id);
PortChainId portChainId = PortChainId.of(id);
- Boolean issuccess = nullIsNotFound(service.removePortChain(portChainId), PORT_CHAIN_NOT_FOUND);
+ Boolean issuccess = nullIsNotFound(get(PortChainService.class).removePortChain(portChainId),
+ PORT_CHAIN_NOT_FOUND);
if (!issuccess) {
log.debug("Port Chain identifier {} does not exist", id);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java
index 69daad37..dc5328a2 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java
@@ -16,7 +16,6 @@
package org.onosproject.vtnweb.resources;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.nullIsNotFound;
@@ -38,11 +37,12 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.PortPairGroup;
import org.onosproject.vtnrsc.PortPairGroupId;
import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
-import org.onosproject.vtnweb.web.PortPairGroupCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
@@ -53,7 +53,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class PortPairGroupWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(PortPairGroupWebResource.class);
- private final PortPairGroupService service = get(PortPairGroupService.class);
public static final String PORT_PAIR_GROUP_NOT_FOUND = "Port pair group not found";
public static final String PORT_PAIR_GROUP_ID_EXIST = "Port pair group exists";
public static final String PORT_PAIR_GROUP_ID_NOT_EXIST = "Port pair group does not exist with identifier";
@@ -66,10 +65,15 @@ public class PortPairGroupWebResource extends AbstractWebResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPairGroups() {
- Iterable<PortPairGroup> portPairGroups = service.getPortPairGroups();
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_pair_groups", new PortPairGroupCodec().encode(portPairGroups, this));
- return ok(result).build();
+ Iterable<PortPairGroup> portPairGroups = get(PortPairGroupService.class).getPortPairGroups();
+ ObjectNode result = mapper().createObjectNode();
+ ArrayNode portPairGroupEntry = result.putArray("port_pair_groups");
+ if (portPairGroups != null) {
+ for (final PortPairGroup portPairGroup : portPairGroups) {
+ portPairGroupEntry.add(codec(PortPairGroup.class).encode(portPairGroup, this));
+ }
+ }
+ return ok(result.toString()).build();
}
/**
@@ -82,17 +86,13 @@ public class PortPairGroupWebResource extends AbstractWebResource {
@Path("{group_id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPairGroup(@PathParam("group_id") String id) {
-
- if (!service.exists(PortPairGroupId.of(id))) {
- return Response.status(NOT_FOUND)
- .entity(PORT_PAIR_GROUP_NOT_FOUND).build();
- }
- PortPairGroup portPairGroup = nullIsNotFound(service.getPortPairGroup(PortPairGroupId.of(id)),
+ PortPairGroup portPairGroup = nullIsNotFound(get(PortPairGroupService.class)
+ .getPortPairGroup(PortPairGroupId.of(id)),
PORT_PAIR_GROUP_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_pair_group", new PortPairGroupCodec().encode(portPairGroup, this));
- return ok(result).build();
+ ObjectNode result = mapper().createObjectNode();
+ result.set("port_pair_group", codec(PortPairGroup.class).encode(portPairGroup, this));
+ return ok(result.toString()).build();
}
/**
@@ -108,10 +108,12 @@ public class PortPairGroupWebResource extends AbstractWebResource {
public Response createPortPairGroup(InputStream stream) {
try {
- ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ JsonNode port = jsonTree.get("port_pair_group");
- PortPairGroup portPairGroup = codec(PortPairGroup.class).decode(jsonTree, this);
- Boolean issuccess = nullIsNotFound(service.createPortPairGroup(portPairGroup),
+ PortPairGroup portPairGroup = codec(PortPairGroup.class).decode((ObjectNode) port, this);
+ Boolean issuccess = nullIsNotFound(get(PortPairGroupService.class).createPortPairGroup(portPairGroup),
PORT_PAIR_GROUP_NOT_FOUND);
return Response.status(OK).entity(issuccess.toString()).build();
} catch (IOException e) {
@@ -134,9 +136,12 @@ public class PortPairGroupWebResource extends AbstractWebResource {
public Response updatePortPairGroup(@PathParam("group_id") String id,
final InputStream stream) {
try {
- ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
- PortPairGroup portPairGroup = codec(PortPairGroup.class).decode(jsonTree, this);
- Boolean isSuccess = nullIsNotFound(service.updatePortPairGroup(portPairGroup), PORT_PAIR_GROUP_NOT_FOUND);
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ JsonNode port = jsonTree.get("port_pair_group");
+ PortPairGroup portPairGroup = codec(PortPairGroup.class).decode((ObjectNode) port, this);
+ Boolean isSuccess = nullIsNotFound(get(PortPairGroupService.class).updatePortPairGroup(portPairGroup),
+ PORT_PAIR_GROUP_NOT_FOUND);
return Response.status(OK).entity(isSuccess.toString()).build();
} catch (IOException e) {
log.error("Update port pair group failed because of exception {}.", e.toString());
@@ -154,7 +159,7 @@ public class PortPairGroupWebResource extends AbstractWebResource {
public void deletePortPairGroup(@PathParam("group_id") String id) {
log.debug("Deletes port pair group by identifier {}.", id);
PortPairGroupId portPairGroupId = PortPairGroupId.of(id);
- Boolean issuccess = nullIsNotFound(service.removePortPairGroup(portPairGroupId),
+ Boolean issuccess = nullIsNotFound(get(PortPairGroupService.class).removePortPairGroup(portPairGroupId),
PORT_PAIR_GROUP_NOT_FOUND);
if (!issuccess) {
log.debug("Port pair group identifier {} does not exist", id);
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java
index b9012898..4ed8ecd8 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java
@@ -16,7 +16,6 @@
package org.onosproject.vtnweb.resources;
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.nullIsNotFound;
@@ -38,12 +37,10 @@ import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairId;
import org.onosproject.vtnrsc.portpair.PortPairService;
-import org.onosproject.vtnweb.web.PortPairCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -54,7 +51,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
public class PortPairWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(PortPairWebResource.class);
- private final PortPairService service = get(PortPairService.class);
public static final String PORT_PAIR_NOT_FOUND = "Port pair not found";
public static final String PORT_PAIR_ID_EXIST = "Port pair exists";
public static final String PORT_PAIR_ID_NOT_EXIST = "Port pair does not exist with identifier";
@@ -67,12 +63,12 @@ public class PortPairWebResource extends AbstractWebResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPairs() {
- Iterable<PortPair> portPairs = service.getPortPairs();
- ObjectNode result = new ObjectMapper().createObjectNode();
+ Iterable<PortPair> portPairs = get(PortPairService.class).getPortPairs();
+ ObjectNode result = mapper().createObjectNode();
ArrayNode portPairEntry = result.putArray("port_pairs");
if (portPairs != null) {
for (final PortPair portPair : portPairs) {
- portPairEntry.add(new PortPairCodec().encode(portPair, this));
+ portPairEntry.add(codec(PortPair.class).encode(portPair, this));
}
}
return ok(result.toString()).build();
@@ -88,13 +84,10 @@ public class PortPairWebResource extends AbstractWebResource {
@Path("{pair_id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getPortPair(@PathParam("pair_id") String id) {
-
- if (!service.exists(PortPairId.of(id))) {
- return Response.status(NOT_FOUND).entity(PORT_PAIR_NOT_FOUND).build();
- }
- PortPair portPair = nullIsNotFound(service.getPortPair(PortPairId.of(id)), PORT_PAIR_NOT_FOUND);
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("port_pair", new PortPairCodec().encode(portPair, this));
+ PortPair portPair = nullIsNotFound(get(PortPairService.class).getPortPair(PortPairId.of(id)),
+ PORT_PAIR_NOT_FOUND);
+ ObjectNode result = mapper().createObjectNode();
+ result.set("port_pair", codec(PortPair.class).encode(portPair, this));
return ok(result.toString()).build();
}
@@ -110,11 +103,11 @@ public class PortPairWebResource extends AbstractWebResource {
@Produces(MediaType.APPLICATION_JSON)
public Response createPortPair(InputStream stream) {
try {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode port = jsonTree.get("port_pair");
- PortPair portPair = new PortPairCodec().decode((ObjectNode) port, this);
- Boolean isSuccess = nullIsNotFound(service.createPortPair(portPair), PORT_PAIR_NOT_FOUND);
+ PortPair portPair = codec(PortPair.class).decode((ObjectNode) port, this);
+ Boolean isSuccess = nullIsNotFound(get(PortPairService.class).createPortPair(portPair),
+ PORT_PAIR_NOT_FOUND);
return Response.status(OK).entity(isSuccess.toString()).build();
} catch (IOException e) {
log.error("Exception while creating port pair {}.", e.toString());
@@ -136,11 +129,11 @@ public class PortPairWebResource extends AbstractWebResource {
public Response updatePortPair(@PathParam("pair_id") String id,
final InputStream stream) {
try {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream);
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode port = jsonTree.get("port_pair");
- PortPair portPair = new PortPairCodec().decode((ObjectNode) port, this);
- Boolean isSuccess = nullIsNotFound(service.updatePortPair(portPair), PORT_PAIR_NOT_FOUND);
+ PortPair portPair = codec(PortPair.class).decode((ObjectNode) port, this);
+ Boolean isSuccess = nullIsNotFound(get(PortPairService.class).updatePortPair(portPair),
+ PORT_PAIR_NOT_FOUND);
return Response.status(OK).entity(isSuccess.toString()).build();
} catch (IOException e) {
log.error("Update port pair failed because of exception {}.", e.toString());
@@ -158,7 +151,7 @@ public class PortPairWebResource extends AbstractWebResource {
public void deletePortPair(@PathParam("pair_id") String id) {
PortPairId portPairId = PortPairId.of(id);
- Boolean isSuccess = nullIsNotFound(service.removePortPair(portPairId), PORT_PAIR_NOT_FOUND);
+ Boolean isSuccess = nullIsNotFound(get(PortPairService.class).removePortPair(portPairId), PORT_PAIR_NOT_FOUND);
if (!isSuccess) {
log.debug("Port pair identifier {} does not exist", id);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java
new file mode 100644
index 00000000..e2defe59
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.vtnweb.web;
+
+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.onosproject.codec.CodecService;
+import org.onosproject.vtnrsc.FlowClassifier;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortPair;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the JSON codec brokering service for VTN app.
+ */
+@Component(immediate = true)
+public class VtnCodecRegistrator {
+
+ private static Logger log = LoggerFactory.getLogger(VtnCodecRegistrator.class);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CodecService codecService;
+
+ @Activate
+ public void activate() {
+ codecService.registerCodec(PortPair.class, new PortPairCodec());
+ codecService.registerCodec(PortPairGroup.class, new PortPairGroupCodec());
+ codecService.registerCodec(FlowClassifier.class, new FlowClassifierCodec());
+ codecService.registerCodec(PortChain.class, new PortChainCodec());
+
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java
index be645be0..db08d7c4 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java
@@ -40,11 +40,13 @@ import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.packet.IpPrefix;
import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
import org.onosproject.vtnrsc.FlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
import com.eclipsesource.json.JsonObject;
import com.sun.jersey.api.client.ClientResponse;
@@ -192,8 +194,11 @@ public class FlowClassifierResourceTest extends VtnResourceTest {
*/
@Before
public void setUpTest() {
- ServiceDirectory testDirectory = new TestServiceDirectory().add(FlowClassifierService.class,
- flowClassifierService);
+ SfcCodecContext context = new SfcCodecContext();
+
+ ServiceDirectory testDirectory = new TestServiceDirectory()
+ .add(FlowClassifierService.class, flowClassifierService)
+ .add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java
new file mode 100644
index 00000000..3cb2c83f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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.vtnweb.resources;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.vtnrsc.FlowClassifierId;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.portchain.PortChainService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
+
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+
+/**
+ * Unit tests for port chain REST APIs.
+ */
+public class PortChainResourceTest extends VtnResourceTest {
+
+ final PortChainService portChainService = createMock(PortChainService.class);
+
+ PortChainId portChainId1 = PortChainId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae");
+ TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5");
+ private final List<PortPairGroupId> portPairGroupList1 = Lists.newArrayList();
+ private final List<FlowClassifierId> flowClassifierList1 = Lists.newArrayList();
+
+
+ final MockPortChain portChain1 = new MockPortChain(portChainId1, tenantId1, "portChain1",
+ "Mock port chain", portPairGroupList1,
+ flowClassifierList1);
+
+ /**
+ * Mock class for a port chain.
+ */
+ private static class MockPortChain 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;
+
+ public MockPortChain(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 boolean exactMatch(PortChain portChain) {
+ return this.equals(portChain) &&
+ Objects.equals(this.portChainId, portChain.portChainId()) &&
+ Objects.equals(this.tenantId, portChain.tenantId());
+ }
+ }
+
+ /**
+ * Sets up the global values for all the tests.
+ */
+ @Before
+ public void setUpTest() {
+ SfcCodecContext context = new SfcCodecContext();
+ ServiceDirectory testDirectory = new TestServiceDirectory()
+ .add(PortChainService.class, portChainService)
+ .add(CodecService.class, context.codecManager());
+ BaseResource.setServiceDirectory(testDirectory);
+
+ }
+
+ /**
+ * Cleans up.
+ */
+ @After
+ public void tearDownTest() {
+ }
+
+ /**
+ * Tests the result of the rest api GET when there are no port chains.
+ */
+ @Test
+ public void testPortChainsEmpty() {
+
+ expect(portChainService.getPortChains()).andReturn(null).anyTimes();
+ replay(portChainService);
+ final WebResource rs = resource();
+ final String response = rs.path("port_chains").get(String.class);
+ assertThat(response, is("{\"port_chains\":[]}"));
+ }
+
+ /**
+ * Tests the result of a rest api GET for port chain id.
+ */
+ @Test
+ public void testGetPortChainId() {
+
+ final Set<PortChain> portChains = new HashSet<>();
+ portChains.add(portChain1);
+
+ expect(portChainService.exists(anyObject())).andReturn(true).anyTimes();
+ expect(portChainService.getPortChain(anyObject())).andReturn(portChain1).anyTimes();
+ replay(portChainService);
+
+ final WebResource rs = resource();
+ final String response = rs.path("port_chains/1278dcd4-459f-62ed-754b-87fc5e4a6751").get(String.class);
+ final JsonObject result = JsonObject.readFrom(response);
+ assertThat(result, notNullValue());
+ }
+
+ /**
+ * Tests that a fetch of a non-existent port chain object throws an exception.
+ */
+ @Test
+ public void testBadGet() {
+ expect(portChainService.getPortChain(anyObject()))
+ .andReturn(null).anyTimes();
+ replay(portChainService);
+ WebResource rs = resource();
+ try {
+ rs.path("port_chains/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class);
+ fail("Fetch of non-existent port chain did not throw an exception");
+ } catch (UniformInterfaceException ex) {
+ assertThat(ex.getMessage(),
+ containsString("returned a response status of"));
+ }
+ }
+
+ /**
+ * Tests creating a port chain with POST.
+ */
+ @Test
+ public void testPost() {
+
+ expect(portChainService.createPortChain(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portChainService);
+
+ WebResource rs = resource();
+ InputStream jsonStream = PortChainResourceTest.class.getResourceAsStream("post-PortChain.json");
+
+ ClientResponse response = rs.path("port_chains")
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, jsonStream);
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+ }
+
+ /**
+ * Tests deleting a port chain.
+ */
+ @Test
+ public void testDelete() {
+ expect(portChainService.removePortChain(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portChainService);
+
+ WebResource rs = resource();
+
+ String location = "port_chains/1278dcd4-459f-62ed-754b-87fc5e4a6751";
+
+ ClientResponse deleteResponse = rs.path(location)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .delete(ClientResponse.class);
+ assertThat(deleteResponse.getStatus(),
+ is(HttpURLConnection.HTTP_NO_CONTENT));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java
new file mode 100644
index 00000000..c13f2141
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.vtnweb.resources;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.PortPairId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
+
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+/**
+ * Unit tests for port pair group REST APIs.
+ */
+public class PortPairGroupResourceTest extends VtnResourceTest {
+
+ final PortPairGroupService portPairGroupService = createMock(PortPairGroupService.class);
+
+ PortPairGroupId portPairGroupId1 = PortPairGroupId.of("4512d643-24fc-4fae-af4b-321c5e2eb3d1");
+ TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5");
+ private final List<PortPairId> portPairList1 = Lists.newArrayList();
+
+ final MockPortPairGroup portPairGroup1 = new MockPortPairGroup(portPairGroupId1, tenantId1, "portPairGroup1",
+ "Mock port pair group", portPairList1);
+
+ /**
+ * Mock class for a port pair group.
+ */
+ private static class MockPortPairGroup implements PortPairGroup {
+
+ private final PortPairGroupId portPairGroupId;
+ private final TenantId tenantId;
+ private final String name;
+ private final String description;
+ private final List<PortPairId> portPairList;
+
+ public MockPortPairGroup(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 boolean exactMatch(PortPairGroup portPairGroup) {
+ return this.equals(portPairGroup) &&
+ Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) &&
+ Objects.equals(this.tenantId, portPairGroup.tenantId());
+ }
+ }
+
+ /**
+ * Sets up the global values for all the tests.
+ */
+ @Before
+ public void setUpTest() {
+ SfcCodecContext context = new SfcCodecContext();
+ ServiceDirectory testDirectory = new TestServiceDirectory()
+ .add(PortPairGroupService.class, portPairGroupService)
+ .add(CodecService.class, context.codecManager());
+ BaseResource.setServiceDirectory(testDirectory);
+
+ }
+
+ /**
+ * Cleans up.
+ */
+ @After
+ public void tearDownTest() {
+ }
+
+ /**
+ * Tests the result of the rest api GET when there are no port pair groups.
+ */
+ @Test
+ public void testPortPairGroupsEmpty() {
+
+ expect(portPairGroupService.getPortPairGroups()).andReturn(null).anyTimes();
+ replay(portPairGroupService);
+ final WebResource rs = resource();
+ final String response = rs.path("port_pair_groups").get(String.class);
+ assertThat(response, is("{\"port_pair_groups\":[]}"));
+ }
+
+ /**
+ * Tests the result of a rest api GET for port pair group id.
+ */
+ @Test
+ public void testGetPortPairGroupId() {
+
+ final Set<PortPairGroup> portPairGroups = new HashSet<>();
+ portPairGroups.add(portPairGroup1);
+
+ expect(portPairGroupService.exists(anyObject())).andReturn(true).anyTimes();
+ expect(portPairGroupService.getPortPairGroup(anyObject())).andReturn(portPairGroup1).anyTimes();
+ replay(portPairGroupService);
+
+ final WebResource rs = resource();
+ final String response = rs.path("port_pair_groups/4512d643-24fc-4fae-af4b-321c5e2eb3d1").get(String.class);
+ final JsonObject result = JsonObject.readFrom(response);
+ assertThat(result, notNullValue());
+ }
+
+ /**
+ * Tests that a fetch of a non-existent port pair group object throws an exception.
+ */
+ @Test
+ public void testBadGet() {
+ expect(portPairGroupService.getPortPairGroup(anyObject()))
+ .andReturn(null).anyTimes();
+ replay(portPairGroupService);
+ WebResource rs = resource();
+ try {
+ rs.path("port_pair_groups/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class);
+ fail("Fetch of non-existent port pair group did not throw an exception");
+ } catch (UniformInterfaceException ex) {
+ assertThat(ex.getMessage(),
+ containsString("returned a response status of"));
+ }
+ }
+
+ /**
+ * Tests creating a port pair group with POST.
+ */
+ @Test
+ public void testPost() {
+
+ expect(portPairGroupService.createPortPairGroup(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portPairGroupService);
+
+ WebResource rs = resource();
+ InputStream jsonStream = PortPairGroupResourceTest.class.getResourceAsStream("post-PortPairGroup.json");
+
+ ClientResponse response = rs.path("port_pair_groups")
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .post(ClientResponse.class, jsonStream);
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+ }
+
+ /**
+ * Tests deleting a port pair group.
+ */
+ @Test
+ public void testDelete() {
+ expect(portPairGroupService.removePortPairGroup(anyObject()))
+ .andReturn(true).anyTimes();
+ replay(portPairGroupService);
+
+ WebResource rs = resource();
+
+ String location = "port_pair_groups/4512d643-24fc-4fae-af4b-321c5e2eb3d1";
+
+ ClientResponse deleteResponse = rs.path(location)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .delete(ClientResponse.class);
+ assertThat(deleteResponse.getStatus(),
+ is(HttpURLConnection.HTTP_NO_CONTENT));
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java
index 271904cc..36014ec5 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java
@@ -39,10 +39,12 @@ import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
import org.onosproject.vtnrsc.PortPair;
import org.onosproject.vtnrsc.PortPairId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.portpair.PortPairService;
+import org.onosproject.vtnweb.web.SfcCodecContext;
import com.eclipsesource.json.JsonObject;
import com.sun.jersey.api.client.ClientResponse;
@@ -129,7 +131,10 @@ public class PortPairResourceTest extends VtnResourceTest {
*/
@Before
public void setUpTest() {
- ServiceDirectory testDirectory = new TestServiceDirectory().add(PortPairService.class, portPairService);
+
+ SfcCodecContext context = new SfcCodecContext();
+ ServiceDirectory testDirectory = new TestServiceDirectory().add(PortPairService.class, portPairService)
+ .add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java
index fe9d7995..c56a4fcb 100644
--- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java
@@ -15,15 +15,10 @@
*/
package org.onosproject.vtnweb.web;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.CodecService;
import org.onosproject.codec.JsonCodec;
-import org.onosproject.vtnrsc.FlowClassifier;
-import org.onosproject.vtnrsc.PortChain;
-import org.onosproject.vtnrsc.PortPair;
-import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.codec.impl.CodecManager;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -33,17 +28,16 @@ import com.fasterxml.jackson.databind.ObjectMapper;
public class SfcCodecContext implements CodecContext {
private final ObjectMapper mapper = new ObjectMapper();
- private final Map<Class<?>, JsonCodec> codecs = new ConcurrentHashMap<>();
+ private final CodecManager codecManager = new CodecManager();
+ private final VtnCodecRegistrator manager = new VtnCodecRegistrator();
/**
* Constructs a new mock codec context.
*/
public SfcCodecContext() {
- codecs.clear();
- registerCodec(PortPair.class, new PortPairCodec());
- registerCodec(PortChain.class, new PortChainCodec());
- registerCodec(PortPairGroup.class, new PortPairGroupCodec());
- registerCodec(FlowClassifier.class, new FlowClassifierCodec());
+ codecManager.activate();
+ manager.codecService = codecManager;
+ manager.activate();
}
@Override
@@ -58,20 +52,17 @@ public class SfcCodecContext implements CodecContext {
return null;
}
+ @Override
+ public <T> JsonCodec<T> codec(Class<T> entityClass) {
+ return codecManager.getCodec(entityClass);
+ }
+
/**
- * Registers the specified JSON codec for the given entity class.
+ * Get the codec manager.
*
- * @param entityClass entity class
- * @param codec JSON codec
- * @param <T> entity type
+ * @return instance of codec manager
*/
- public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) {
- codecs.putIfAbsent(entityClass, codec);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T> JsonCodec<T> codec(Class<T> entityClass) {
- return codecs.get(entityClass);
+ public CodecService codecManager() {
+ return codecManager;
}
}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json
new file mode 100644
index 00000000..488e290f
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json
@@ -0,0 +1,15 @@
+{"port_pair": {
+ "id": "1278dcd4-459f-62ed-754b-87fc5e4a6751",
+ "name": "PC2",
+ "tenant_id": "d382007aa9904763a801f68ecf065cf5",
+ "description": "Two flows and two port-pair-groups",
+ "flow_classifiers": [
+ "456a4a34-2e9c-14ae-37fb-765feae2eb05",
+ "4a334cd4-fe9c-4fae-af4b-321c5e2eb051"
+ ],
+ "port_pair_groups": [
+ "4512d643-24fc-4fae-af4b-321c5e2eb3d1",
+ "4a634d49-76dc-4fae-af4b-321c5e23d651"
+ ]
+ }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json
new file mode 100644
index 00000000..f6a888d9
--- /dev/null
+++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json
@@ -0,0 +1,11 @@
+{"port_pair_group": {
+ "id": "4512d643-24fc-4fae-af4b-321c5e2eb3d1",
+ "name": "portPairGroup1",
+ "tenant_id": "d382007aa9904763a801f68ecf065cf5",
+ "description": "Mock port pair group",
+ "port_pairs": [
+ "875dfeda-43ed-23fe-454b-764feab2c342",
+ "78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"
+ ]
+}
+}