opendaylight作为sdn主要开源项目,採用osgi框架。已经得到非常多厂商的支持。氦版本号也公布在即。

以下介绍一下在odl中怎样实现rpc. odl使用yang作为model模型定义文件。yang规范最先被用于netconf,后来restconf在http协议上实现restful。而採用yang定义模型。

实现分2步:1.採用yang定义模型,实现api jar包。2 实现rpc service的实现类,注冊到session中。

2个java的project文件夹结构。

第一步:定义yang文件及其pom.xml

在文件夹xptest\src\main\yang下定义xptest.yang

  module xptest {
yang-version 1; namespace
"http://startsky.com/ns/xptest"; prefix xps; organization "xpstudio Netconf Central"; contact
"xinping <xpzh@sohu.com>"; description
"YANG version of the xptest-MIB."; revision "2014-10-3" {
description
"xptest module in progress.";
} typedef DispString {
type string {
length "0 .. 255";
}
description
"YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
reference
"RFC 2579, section 2."; } container xptester {
leaf name {
type string;
} leaf age {
type uint32;
default 99;
}
leaf homeaddress {
type string;
}
} // container toaster rpc make-order {
input {
leaf name {
type string;
}
leaf days {
type uint32;
default 1;
}
}
output {
leaf name {
type string;
}
leaf orderno {
type uint32;
}
}
} // make-order rpc cancel-order {
input {
leaf orderno {
type uint32;
}
}
output {
leaf name {
type string;
}
leaf order-status {
type enumeration {
enum "success" {
value 1;
}
enum "fail" {
value 2;
}
}
}
}
} // cancel-order } // module xptest

定义yang的pom.xml,在xptest下定义pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.opendaylight.controller.samples</groupId>
    <artifactId>sal-samples</artifactId>
    <version>1.2.0-SNAPSHOT</version>
  </parent>
<artifactId>sample-xptest</artifactId>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-binding</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-sal-api-gen-plugin</artifactId>
<version>${yangtools.version}</version>
<type>jar</type>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>generate-sources</goal>
</goals>
<configuration>
<yangFilesRootDir>src/main/yang</yangFilesRootDir>
<codeGenerators>
<generator>
<codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
<outputBaseDir>${salGeneratorPath}</outputBaseDir>
</generator>
</codeGenerators>
<inspectDependencies>true</inspectDependencies>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
<tag>HEAD</tag>
<url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
</scm>
</project>

上面yang文件定义了两个rpc。

执行mvn install编译xptest.yang. 会产生一个rpc服务XptestService 接口。当中两个方法相应两个rpc 函数。

第二步:定义rpc的实现文件XpTestProvider及其Activator

该project定义为xpprovider。

rpc实现类XpTestProvider

package org.opendaylight.controller.xptest.impl;

import java.io.File;
import java.util.concurrent.Future; //import org.opendaylight.controller.xptest.Activator;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.CancelOrderInput;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.CancelOrderOutput;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.CancelOrderOutput.OrderStatus;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.CancelOrderOutputBuilder;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.MakeOrderInput;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.MakeOrderOutput;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.MakeOrderOutputBuilder;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.XptestService;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.google.common.util.concurrent.Futures; public class XpTestProvider implements XptestService {
  private final static Logger LOG = LoggerFactory.getLogger(XpTestProvider.class);
  @Override
  public Future<RpcResult<CancelOrderOutput>> cancelOrder(
      CancelOrderInput input) {
    // TODO Auto-generated method stub
    RpcResult<CancelOrderOutput> ret=null;
    if(input.getOrderno() >10)
    {
      ret=RpcResultBuilder.<CancelOrderOutput>failed().withError( ErrorType.APPLICATION, "resource-denied",
                  "days > 10,failed!!" ).build();
    }else {
      CancelOrderOutputBuilder builder=new CancelOrderOutputBuilder();
      builder.setName("name"+input.getOrderno());
      builder.setOrderStatus(OrderStatus.Success);
      ret=RpcResultBuilder.<CancelOrderOutput>success(builder.build()).build();
    }     return Futures.immediateFuture(ret);
  }   @Override
  public Future<RpcResult<MakeOrderOutput>> makeOrder(MakeOrderInput input) {
    // TODO Auto-generated method stub
    RpcResult<MakeOrderOutput> ret=null;
    LOG.info( "user.dir "+System.getProperty("user.dir"));
    File directory = new File("");//设定为当前目录
    try{
      LOG.info("std: "+directory.getCanonicalPath());//获取标准的路径
      LOG.info("abs: "+directory.getAbsolutePath());//获取绝对路径
    }catch(Exception e)
    {     }
    if(input.getDays()>10)
    {
      ret=RpcResultBuilder.<MakeOrderOutput>failed().withError( ErrorType.APPLICATION, "resource-denied",
                  "days > 10,failed!!" ).build();
    }else {
      MakeOrderOutputBuilder builder=new MakeOrderOutputBuilder();
      builder.setName(input.getName());
      builder.setOrderno((long) 112233);
      ret=RpcResultBuilder.<MakeOrderOutput>success(builder.build()).build();
    }     return Futures.immediateFuture(ret);
  } }

实现插件入口类Activator,顺便实现命令行接口,能够自己定义命令行測试命令。

/**
* Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.controller.xptest;
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.xptest.impl.XpTestProvider;
import org.opendaylight.yang.gen.v1.http.startsky.com.ns.xptest.rev141003.XptestService;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* Forwarding Rules Manager Activator
*
* Activator {@link ForwardingRulesManager}.
* It registers all listeners (DataChangeEvent, ReconcilNotification)
* in the Session Initialization phase.
*
* @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
* *
*/
public class Activator extends AbstractBindingAwareProvider
implements CommandProvider { private final static Logger LOG = LoggerFactory.getLogger(Activator.class); @Override
public void onSessionInitiated(ProviderContext session) {
LOG.info("FRMActivator initialization.");
try {
// final DataBroker dataBroker = session.getSALService(DataBroker.class);
// this.manager = new ForwardingRulesManagerImpl(dataBroker, session);
// this.manager.start();
XpTestProvider rpcins=new XpTestProvider();
session.addRpcImplementation(XptestService.class,rpcins);
LOG.info("FRMActivator initialization successfull.");
}
catch (Exception e) {
LOG.error("Unexpected error by FRM initialization!", e);
this.stopImpl(null);
}
} @Override
protected void startImpl(BundleContext context) {
// TODO Auto-generated method stub
super.startImpl(context);
context.registerService(CommandProvider.class.getName(),
this, null);
} @Override
protected void stopImpl(final BundleContext context) {
/* if (manager != null) {
try {
manager.close();
} catch (Exception e) {
LOG.error("Unexpected error by stopping FRMActivator", e);
}
manager = null;
}*/
LOG.info("FRMActivator stopped.");
}
public void _gettpsbyne(CommandInterpreter ci) {
ci.println("gettpsbyne:" + ci.nextArgument());
} @Override
public String getHelp() {
return "\tgettpsbyne neid– say what you input\n";
}
}

xpprovider的pom.xml文件。

<?xml version="1.0" encoding="UTF-8"?

>
<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.opendaylight.controller.samples</groupId>
    <artifactId>sal-samples</artifactId>
    <version>1.2.0-SNAPSHOT</version>
  </parent>
<artifactId>sample-xptest-provider</artifactId>
<packaging>bundle</packaging> <dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sample-xptest</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.osgi</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-api</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-api</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-config</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-common-util</artifactId>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency> <!-- dependencies to use AbstractDataBrokerTest -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-broker-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-broker-impl</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
<scope>test</scope>
</dependency>
<!-- used to mock up classes -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-api</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.controller.model</groupId>
<artifactId>model-flow-service</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-common</artifactId>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-broker-impl</artifactId>
<scope>provided</scope>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-Activator>org.opendaylight.controller.xptest.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
</plugins>
</build> <scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
<tag>HEAD</tag>
<url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
</scm>
</project>

执行mvn install 编译,之后把这两个jar包复制到odl的plugins文件夹下,最好执行odl准备。

第三步:进行測试。

执行run.bat,启动odl,在restclient中执行以下測试用例。

能够做restclient的工具有chrome插件postman,firefox的restclient,网上还有个单独jar包restclient.

HTTP Method => POST

URL => http://localhost:8080/restconf/operations/xptest:make-order

Header => Content-Type: application/yang.data+json  

Body =>  

{

  "input" :

  {

     "xptest:name" : "3","xptest:days":3

  }

}

能够看到返回xml数据, response header

  1. Status Code: 200 OK
  2. Content-Type: application/xml
  3. Date: Wed, 08 Oct 2014 12:43:29 GMT
  4. Server: Apache-Coyote/1.1
  5. Transfer-Encoding: chunked

response body

<?

xml version="1.0" encoding="UTF-8" standalone="no"?>
<output xmlns="http://startsky.com/ns/xptest">
<name>3</name>
<orderno>112233</orderno>
</output>

假设header中加accept:application/yang.data+json,将返回json数据。

按上面代码中意图能够构造失败測试用例。

希望本文对odl有兴趣的人,可以给予帮助。

在odl中怎样实现rpc的更多相关文章

  1. php中流行的rpc框架详解

    什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call) 那什么是远程调用? 我的官方群点击此处. 通常我们调用一个php中的方法,比如这样一个函数方 ...

  2. Linux中配置Aria2 RPC Server

    启动Aria2 RPC Server 直接在终端中执行aria2c --enable-rpc --rpc-allow-origin-all可直接开启RPC服务. 这种方法并不能进行个性化的参数设置,需 ...

  3. golang中的net/rpc包

    本文先介绍RPC,然后go原生对RPC的使用,之后是介绍go语言中有哪些RPC框架以及一些其他常见的框架,最后是探究go语言中rpc的源码. (1)首先介绍下什么RPC? (2)RPC可以做什么? ( ...

  4. Linux中LPC、RPC、IPC的区别

    其实这玩意儿就是纸老虎,将英文缩写翻译为中文就明白一半了. IPC:(Inter Process Communication )跨进程通信 这个概念泛指进程之间任何形式的通信行为,是个可以拿来到处套的 ...

  5. Yarn中ResourceManager的RPC协议

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemNjXzAwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  6. golang中的RPC开发-2

    RPC简介 远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程 如果 ...

  7. Lithium中关键特性更新

    Lithium中关键特性更新 1. Lithium特性更新概述 Lithium相对于Helium更新特性共27项,其中原有特性提升或增强13项,新增特性14项,如下表所示 特性类型 相对于Helium ...

  8. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  9. RPC 的概念模型与实现解析

    今天分布式应用.云计算.微服务大行其道,作为其技术基石之一的 RPC 你了解多少?一篇 RPC 的技术总结文章,数了下 5k+ 字,略长,可能也不适合休闲的碎片化时间阅读,可以先收藏抽空再细读:) 全 ...

随机推荐

  1. Android Exception 9(requestFeature() must be called before adding content)

    08-05 17:36:12.799: W/System.err(10378): java.lang.reflect.InvocationTargetException08-05 17:36:12.7 ...

  2. CentOS 安装jdk1.7 32位

    CentOS 安装jdk1.7 32位 1.下载jdk-7u21-linux-i586.rpm ? 1 wget http://uni-smr.ac.ru/archive/dev/java/bulk/ ...

  3. nutch中bin/crawl和bin/nutch crawl的用法(转)

    针对上一篇文章中出现的问题:Command crawl is deprecated, please use bin/crawl instead错误信息,今天在官网上查阅了一下,进行了总结. 官网lin ...

  4. 网站缓存技术(Redis、Memcached、Ehcache)

    Redis 是什么? 通常而言目前的数据库分类有几种,包括 SQL/NSQL,,关系数据库,键值数据库等等等. 分类的标准也不一,Redis本质上也是一种键值数据库的,但它在保持键值数据库简单快捷特点 ...

  5. 15个极好的Linux find命令示例

    基于访问/修改/更改时间查找文件 你可以找到基于以下三个文件的时间属性的文件. 访问时间的文件.文件访问时,访问时间得到更新. 的文件的修改时间.文件内容修改时,修改时间得到更新. 更改文件的时间.更 ...

  6. Rabbitmq消息队列(六) 主题交换机

    1.简介 前面学习了有选择性的接收消息,但是却没有办法基于多个标准来接收消息.为了实现这个目的,接下来我们学习如何使用另一种更复杂的交换机 —— 主题交换机. 2.主题交换机 发送到主题交换机(top ...

  7. 【转载】使用Exp和Expdp导出数据的性能对比与优化

    转自:http://blog.itpub.net/117319/viewspace-1410931/ 序:这方面的文章虽然很多人写过,但是结合实际进行详细的对比分析的不多,这里,结合所在公司的行业,进 ...

  8. C#反射取数组单个元素的类型

    去bing上查了一下,果然有和我一样蛋疼的朋友,他们在论坛研究了半天,最后还是暴力解决: public Type GetArrayElementType(Type t) { string tName ...

  9. Atitit.异常的设计原理与 策略处理 java 最佳实践 p93

    Atitit.异常的设计原理与 策略处理 java 最佳实践 p93 1 异常方面的使用准则,答案是:: 2 1.1 普通项目优先使用异常取代返回值,如果开发类库方面的项目,最好异常机制与返回值都提供 ...

  10. Atitit.软件开发的最终的设计 dsl化,ast化(建立ast, 解析执行ast)

    Atitit.软件开发的最终的设计 dsl化,ast化(建立ast, 解析执行ast) 1. 使用js,html 撰写dsl1 1.1. 架构图1 1.2. html2 1.3. Js2 1.4. C ...