zoukankan      html  css  js  c++  java
  • 在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

    在文件夹xptestsrcmainyang下定义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 "	gettpsbyne neid– say what you input
    ";
       }
      }

    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有兴趣的人,可以给予帮助。

  • 相关阅读:
    MySQL创建用户并修改权限
    Jenkins触发项目构建
    dotnet-cnblogs-tool使用与坑
    Jenkins集成Jmeter接口测试(Freestyle Project)
    Jenkins发送邮件没有解析变量
    JMeter + Maven in Jenkins
    Charles&Fiddler 对手机捉包失败原因分析
    Postman 脚本
    Selenium+Chrome浏览器自动加载Flash
    idea上进行远程调试项目步骤纪录
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6736105.html
Copyright © 2011-2022 走看看