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. #pragma pack(push,1)与#pragma pack(1)的区别(转)

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式. #pragma pack (n)             作用:C编译器将按照n个字节对 ...

  2. Git-Git Book阅读笔记

    git diff [fname]    查看工作区与缓存区异同 git diff --staged [fname]    查看缓存区与上次提交之间的差异 git diff HEAD [fname] 查 ...

  3. php处理行业分类数据

    实现步骤: 1.将excel表格存储为后缀名为 .csv格式的文件: 2.将.csv格式文件导入到mysql数据库中: 3.通过条件查询将所需要的数据查出并导入另一个数据表中: 下面是一些php片段: ...

  4. easy ui datagrid 数据分页

    参照easyui官方网站提供的demo写了个datagrid数据分页的demo, 具体参数我就不一一罗列了,详细见官方网站, 这里只介绍一下具体的注意事项和常乃用到的几项, $('#test').da ...

  5. 文件操作FileStream,Log

    1.关于读写文件,犯的一个低级错误,平常代码拷贝习惯了,就像电脑用多了会提笔忘字一样,所以平常还是要多多用心才好. 这段代码的意图是在文件中写入数据,如果原文件不存在,则先新建. 事实上,当真的执行了 ...

  6. java通过CLASSPATH读取包内文件

    读取包内文件,使用的路径一定是相对的classpath路径,比如a,位于包内,此时可以创建读取a的字节流:InputStream in = ReadFile.class.getResourceAsSt ...

  7. PHP 常用函数回顾

    array_change_key_case — 返回字符串键名全为小写或大写的数组array_chunk — 将一个数组分割成多个array_combine — 创建一个数组,用一个数组的值作为其键名 ...

  8. 3.3v转5v开关电源芯片LM2731

    方案一 输入3.3(可为2.7~14v):输出5v,700ma.已经过实际验证. 其中:C1,C2为贴片陶瓷电容,Cf也为贴片陶瓷电容,L1为6.8uH 电感 输出值只和R1,R2的值有关,但手册中又 ...

  9. jquery.cookie中的操作之与换肤

    jquery.cookie.js的插件,插件的源代码如下: /** * Cookie plugin * * Copyright (c) 2006 Klaus Hartl (stilbuero.de) ...

  10. 报错"the microsoft.jet.oledb.4.0 provider is not registered on the local machine"解决方案

    报错提示:"the microsoft.jet.oledb.4.0 provider is not registered on the local machine" 错误起因:wi ...