onos-app-calendar
一个RESTful的web应用,提供添加链路时延、带宽限制的Intent。用到了ConnectivityIntent
。完成功能的逻辑
/**
* 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协议。
@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();
}
}