Sa1ka's Shelter

ONOS官方示例应用解析

Word count: 1.1kReading time: 5 min
2019/12/06 Share

onos-app-calendar

一个RESTful的web应用,提供添加链路时延、带宽限制的Intent。用到了ConnectivityIntent。完成功能的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
* Create an Intent for a bidirectional path with constraints.
*
* @param key optional intent key
* @param src the path source (DPID or hostID)
* @param dst the path destination (DPID or hostID)
* @param srcPort the source port (-1 if src/dest is a host)
* @param dstPort the destination port (-1 if src/dest is a host)
* @param bandwidth the bandwidth (mbps) requirement for the path
* @param latency the latency (micro sec) requirement for the path
* @return the appropriate intent
*/
private Intent createIntent(Key key,
String src,
String dst,
String srcPort,
String dstPort,
Long bandwidth,
Long latency) {

TrafficSelector selector = buildTrafficSelector();
TrafficTreatment treatment = builder().build();

final Constraint constraintBandwidth =
new BandwidthConstraint(Bandwidth.mbps(bandwidth));
final Constraint constraintLatency =
new LatencyConstraint(Duration.of(latency, ChronoUnit.MICROS));
final List<Constraint> constraints = new LinkedList<>();

constraints.add(constraintBandwidth);
constraints.add(constraintLatency);

if (srcPort.equals("-1")) {
HostId srcPoint = HostId.hostId(src);
HostId dstPoint = HostId.hostId(dst);
return HostToHostIntent.builder()
.appId(appId())
.key(key)
.one(srcPoint)
.two(dstPoint)
.selector(selector)
.treatment(treatment)
.constraints(constraints)
.build();

} else {
ConnectPoint srcPoint = new ConnectPoint(deviceId(src), portNumber(srcPort));
ConnectPoint dstPoint = new ConnectPoint(deviceId(dst), portNumber(dstPort));
return TwoWayP2PIntent.builder()
.appId(appId())
.key(key)
.one(srcPoint)
.two(dstPoint)
.selector(selector)
.treatment(treatment)
.constraints(constraints)
.build();
}
}


/**
* Synchronously submits an intent to the Intent Service.
*
* @param intent intent to submit
* @return true if operation succeed, false otherwise
*/
private boolean submitIntent(Intent intent)
throws InterruptedException {
IntentService service = get(IntentService.class);

CountDownLatch latch = new CountDownLatch(1);
InternalIntentListener listener = new InternalIntentListener(intent, service, latch);
service.addListener(listener);
service.submit(intent);
log.info("Submitted Calendar App intent and waiting: {}", intent);
if (latch.await(TIMEOUT, TimeUnit.SECONDS) &&
listener.getState() == INSTALLED) {
return true;
}
return false;
}

onos-app-carrierethernet

根据pom.xml文件的内容,我们可以知道这个应用是用于运营以太网服务(Carrier Ethernet),具体介绍在Carrier Ethernet,由城域以太网论坛(MEF)建立。CE包含五个模块:保护、QoS、扩展、业务管理、TDM。个人理解是,希望以太网上的流量,能够在SDN环境下加入一定的识别特征,这样才能方便城域网中的网络设备根据这些特征进行服务的定制。这个项目相对来说比较复杂,而且更新也非常的频繁,先挖个坑在这里,以后有时间的话可以认真阅读一下其实现。

onos-app-database-perf

一个用来测试ONOS集群存储数据性能的应用,在activate中包含有对于StorageService的使用,包括创建并发式Map的方法,注册序列化器KryoNamespace等,之后创建多个线程测试具体的性能指标。

onos-app-ecord-co

一个CORD的实现应用,CORD(Central Office Re-architected as a DataCenter),意为在家庭、公司等网络边界的基础网络设备,实现一个数据中心的服务功能。CORD目前有三种类型:ECORD、RCORD和MCORD,具体的详情可以查看CORD。这个应用给出了一个ECORD的实现方案。这个应用比较全面地展示了ONOS的抽象子系统概念,我们可以从项目的结构看出来。

CentralOffice.java文件是组件的主文件,主要工作是注册应用,并且创建了一个名为BigSwitchDeviceProvider的对象,那么接下来我们去找找实现。BigSwitchDeviceProvider继承于DeviceProvider。从前面两次的loadConfig操作中我们可以看出来这个应用支持修改config文件,并且提供有RPC和RESTful两种修改模式,然而目前我对于ConfigService还没有太深的了解,因此这里填个坑等到以后再来了解。在activate方法中基本就是向deviceProvider中注册了一个设备,接下来使用LLDP协议发现网络拓扑。为了完成LLDP的工作,程序中使用到了onlab-misc中的ONOSLLDP工具类,方便使用LLDP协议。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@Activate
public void activate(ComponentContext context) {
cfgService.registerProperties(getClass()); // 在ComponentConfigService上进行注册
loadRpcConfig(context);
loadRestConfig(context);

// setup service to, and register with, providers
try {
remoteServiceContext = rpcService.get(URI.create(remoteUri));
} catch (UnsupportedOperationException e) {
log.warn("Unsupported URI: {}", remoteUri);
}
providerId = new ProviderId(schemeProp, idProp);
executor = newSingleThreadScheduledExecutor(groupedThreads("onos/bigswitch", "discovery-%d"));
registerToDeviceProvider();
prepareProbe();
registerToLinkServices();

// start listening to config changes
NetworkConfigListener cfglistener = new InternalConfigListener();
cfgRegistry.addListener(cfglistener);
cfgRegistry.registerConfigFactory(xcConfigFactory);
log.info("Started");
}

@Deactivate
public void deactivate() {
packetService.removeProcessor(packetProcessor);


// advertise all Links as vanished
knownLinks.invalidateAll();

cfgRegistry.unregisterConfigFactory(xcConfigFactory);
cfgService.unregisterProperties(getClass(), false);
unregisterFromLinkServices();
executor.shutdownNow();
unregisterFromDeviceProvider();
// Won't hurt but necessary?
deviceProviderService = null;
providerId = null;
log.info("Stopped");
}

@Modified
public void modified(ComponentContext context) {
log.info("Reloading config...");
// Needs re-registration to DeviceProvider
if (loadRpcConfig(context)) {
// unregister from Device and Link Providers with old parameters
unregisterFromLinkServices();
unregisterFromDeviceProvider();
// register to Device and Link Providers with new parameters
try {
remoteServiceContext = rpcService.get(URI.create(remoteUri));
providerId = new ProviderId(schemeProp, idProp);
registerToDeviceProvider();
registerToLinkServices();
} catch (UnsupportedOperationException e) {
log.warn("Unsupported URI: {}", remoteUri);
}
log.info("Re-registered with Device and Link Providers");
}

// Needs to advertise cross-connect links
if (loadRestConfig(context)) {
advertiseCrossConnectLinksOnAllPorts();
}
}

CATALOG
  1. 1. onos-app-calendar
  2. 2. onos-app-carrierethernet
  3. 3. onos-app-database-perf
  4. 4. onos-app-ecord-co