ONOS官方示例应用解析

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();
        }
    }

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注