在odl中怎样实现rpc
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
- Status Code: 200 OK
- Content-Type: application/xml
- Date: Wed, 08 Oct 2014 12:43:29 GMT
- Server: Apache-Coyote/1.1
- 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的更多相关文章
- php中流行的rpc框架详解
什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call) 那什么是远程调用? 我的官方群点击此处. 通常我们调用一个php中的方法,比如这样一个函数方 ...
- Linux中配置Aria2 RPC Server
启动Aria2 RPC Server 直接在终端中执行aria2c --enable-rpc --rpc-allow-origin-all可直接开启RPC服务. 这种方法并不能进行个性化的参数设置,需 ...
- golang中的net/rpc包
本文先介绍RPC,然后go原生对RPC的使用,之后是介绍go语言中有哪些RPC框架以及一些其他常见的框架,最后是探究go语言中rpc的源码. (1)首先介绍下什么RPC? (2)RPC可以做什么? ( ...
- Linux中LPC、RPC、IPC的区别
其实这玩意儿就是纸老虎,将英文缩写翻译为中文就明白一半了. IPC:(Inter Process Communication )跨进程通信 这个概念泛指进程之间任何形式的通信行为,是个可以拿来到处套的 ...
- Yarn中ResourceManager的RPC协议
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemNjXzAwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- golang中的RPC开发-2
RPC简介 远程过程调用(Remote Procedure Call,RPC)是一个计算机通信协议 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程 如果 ...
- Lithium中关键特性更新
Lithium中关键特性更新 1. Lithium特性更新概述 Lithium相对于Helium更新特性共27项,其中原有特性提升或增强13项,新增特性14项,如下表所示 特性类型 相对于Helium ...
- Netty实现高性能RPC服务器优化篇之消息序列化
在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...
- RPC 的概念模型与实现解析
今天分布式应用.云计算.微服务大行其道,作为其技术基石之一的 RPC 你了解多少?一篇 RPC 的技术总结文章,数了下 5k+ 字,略长,可能也不适合休闲的碎片化时间阅读,可以先收藏抽空再细读:) 全 ...
随机推荐
- Mybatis <where>标签
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHER ...
- Hadoop生态圈介绍及入门(转)
本帖最后由 howtodown 于 2015-4-2 23:15 编辑 问题导读 1.Hadoop生态圈介绍了哪些组件,分别都是什么? 2.大数据与Hadoop是什么关系? 本章主要内容: 理解大数据 ...
- jQuery基本选择 元素
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- CI框架下nginx重写规则
因为: server { listen ; server_name 222.73.130.124; location / { index index.html index.htm index.php; ...
- jq的form验证
jQuery(document).ready(function(){ $('#cform img.contact-loader').hide(); $('#cform').submit(functio ...
- mongodb - Replication Set搭建过程
1.创建目录 mkdir -p /mongodb/data/r1 mkdir -p /mongodb/data/r2 mkdir -p /mongodb/data/r3 mkdir -p /mongo ...
- 重写spring cloud config 本地bootstrap
在spring-cloud中使用了config-server之后,需要在client端加入bootstrap作为配置文件,其中通常包含如下: spring.application.name=ms-as ...
- Vim进阶指南
常用按键说明 按键 解释 移动光标 n+(Space) 向右移动n个字符 n+(Enter) 向下移动n行 nG 移动到第n行 gg 移动到第一行 G 移动到最后一行 0或Home键(Mac使用fn+ ...
- 分页技术框架(Pager-taglib)学习一(页面分页)
一.Pager-taglib简介 1.Pager-taglib,支持多种风格的分页显示.实际上她是一个Jsp标签库,为在JSP上显示分页信息而设计的一套标签,通过这些标签的不同的组合,会形成多 ...
- HDU 1867 A + B for you again(KMP算法的应用)
A + B for you again Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...