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

  • 相关阅读:
    OS + Multipass
    服务器间文件实时双向同步(rsync+inotify)
    全链路追踪 & 性能监控工具 SkyWalking 实战
    TCP Dup ACK linux kernel 3.2
    Ns3.35 errata Compilation on Python 3.10 systems
    LeetCode 108. Convert Sorted Array to Binary Search Tree
    LeetCode 98. Validate Binary Search Tree
    LeetCode 701. Insert into a Binary Search Tree
    LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
    LeetCode 783. Minimum Distance Between BST Nodes
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6736105.html
Copyright © 2020-2023  润新知