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. hibernate的配置, 增删改查

    路径:查找路径 实际上都是查找编译后的对应的路径,在bin文件夹中总 增删改必须开启事务才行 hibernate加载文件的两种方式 configure 1.引包 antlr-2.7.6.jar bac ...

  2. 使用httpModules做一些事

    httpmodules是http管道处理程序 可以重写接口进行一些在请求到达api接口前做全局处理 这是一个过滤关键词的例子 using System; using System.Collection ...

  3. Task WaitAll的用法

    var tasklst = new List<Task>(); ; i < urls.Count; i++) { tasklst.Add(Task.Factory.StartNew& ...

  4. python --存储对象

    转自:http://www.cnblogs.com/vamei/archive/2012/09/15/2684781.html 在之前对Python对象的介绍中 (面向对象的基本概念,面向对象的进一步 ...

  5. Navicat Premium 快捷键

    1.ctrl+q 打开查询窗口2.ctrl+/ 注释sql语句3.ctrl+shift +/ 解除注释4.ctrl+r 运行查询窗口的sql语句5.ctrl+shift+r 只运行选中的sql语句6. ...

  6. IoC容器Autofac学习笔记

    一.一个没有使用IoC的例子 IoC的全称是Inversion of Control,中文叫控制反转.要理解控制反转,可以看看非控制反转的一个例子. public class MPGMovieList ...

  7. unity Editor下自启动

    [InitializeOnLoad] 加上这个特性,并且在静态构造函数里写上内容.即可在Unity启动的时候自启动这个Editor脚本

  8. atitti.atiNav 手机导航组件的设计

    atitti.atiNav 手机导航组件的设计 1.1. 三大按键导航功能,back,menu ,home1 1.2. header页头组件,为移动页面顶部的导航条设计.1 1.3. 页头主题设计1 ...

  9. atitit.userService 用户系统设计 v5 q330

    atitit.userService 用户系统设计 v5 q330 1. 新特性1 2. Admin  login1 3. 用户注册登录2 3.1. <!-- 会员注册使用 -->  商家 ...

  10. Atitit。 沉思录 与it软件开发管理中的总结 读后感

    Atitit. 沉思录 与it软件开发管理中的总结 读后感 1. <沉思录>,古罗马唯一一位哲学家皇帝马可·奥勒留所著 2 2. 沉思录与it软件开发管理中的总结 2 2.1. 要有自己的 ...