在odl中如何实现rpc,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的工程目录结构。


第一步:定义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.1-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

该工程定义为xpprovider。

rpc实现类XpTestProvider

package org.opendaylight.controller.xptest.impl;

import java.util.concurrent.Future;

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 com.google.common.util.concurrent.Futures;

public class XpTestProvider implements XptestService {

  @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;
    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.1-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数据,如何header中加accept:application/yang.data+json,将返回json数据。

按上面代码中意图可以构造失败测试用例。

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


怎通过RPC,实现Windows客户端对Linux上的文件服务操作

安装putty或者ssh
 

php xml-rpc怎实现,数据怎传到服务器端的?

PHP中集成了XML-RPC和SOAP两种协议的访问,都是集中在xmlrpc扩展当中。另外,在PHP的PEAR中,不管是PHP 4还是PHP 5,都已经默认集成了XML-RPC扩展,而且该扩展跟xmlrpc扩展无关,能够独立实现XML-RPC的协议交互,如果没有xmlrpc扩展,建议使用PEAR::XML-RPC扩展。
Web Service介绍
Web Service就是为了异构系统的通信而产生的,它基本的思想就是使用基于XML的HTTP的远程调用提供一种标准的机制,而省去建立一种新协议的需求。目前进行Web Service通信有两种协议标准,一种是XML-RPC,另外一种是SOAP。XML-RPC比较简单,出现时间比较早,SOAP比较复杂,主要是一些需要稳定、健壮、安全并且复杂交互的时候使用。
我们这里主要是以XML-RPC来简单描述Web Service的交互过程,部分内容来自PHP手册,更详细内容,建议参考手册。
安装xmlrpc扩展
如果你的系统中没有安装xmlrpc的php扩展,那么请正确安装。
在Windows平台下,首先把PHP安装目录下的扩展php_xmlrpc.dll放到C:\Windows或者C:\Winnt目录下,(PHP4的扩展在C:\php\extensions目录中,PHP5的扩展在C:\php\ext目录中),同时在C:\Windows\php.ini或者C: \Winnt\php.ini中把extension=php_xmlrpc.dll前面的分号";"去掉,然后重启Web服务器后查看 phpinfo()有没有XML-RPC项目就能够确定是否已经正确安装xmlrpc扩展。
在Unix/Linux平台下,如果没有安装xmlrpc扩展,请在重新编译PHP,在configure的时候请加入 --with-xmlrpc 选项,然后查看phpinfo()看是否正常安装xmlrpc。
(注意:以下操作都是建立在xmlrpc扩张正常安装前提下,请务必正确安装。)
XML-RPC工作原理
XML-RPC大致就是整个过程就是使用XML来进行通信。首先构造一个RPC 服务器端用来出来从RPC客户端传递过来的使用XML封装的请求,并且把处理结果通过XML的形式返回给RPC客户端,客户端就去分析XML获取自己需要的数据。
XML-RPC的服务器端必须有现成的函数提供给客户端调用,并且客户端提交的请求中的函数和方法必须和服务器端的一致,否则将无法获取所需要的结果。
下面我进行简单的代码来描述整个过程。
XML-RPC实践
服务器端使用xmlrpc_server_create函数产生一个服务器端,然后把需要需要暴露的RPC调用接口进行注册,接受RPC客户端POST过来的XML数据,然后进行处理,处理结果通过XML的形式显示给客户端。
代码如下: rpc_server.php
<?php
/**
* 函数:提供给RPC客户端调用的函数
* 参数:
* $method 客户端需要调用的函数
* $params 客户端需要调用的函数的参数数组
* 返回:返回指定调用结果
*/
function rpc_server_func($method, $params) {
$parameter = $params[0];
if ($parameter == "get"){
$return......余下全文>>
 

相关内容