在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的工程目录结构。

在odl中如何实现rpc_第1张图片

第一步:定义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 ";

    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



  4.0.0
  
    org.opendaylight.controller.samples
    sal-samples
    1.2.0-SNAPSHOT
  
  sample-xptest
  bundle
  
    
      org.opendaylight.yangtools
      yang-binding
    
    
      org.opendaylight.yangtools
      yang-common
    
  

  
    
      
        org.opendaylight.yangtools
        yang-maven-plugin
        
          
            org.opendaylight.yangtools
            maven-sal-api-gen-plugin
            ${yangtools.version}
            jar
          
        
        
          
            
              generate-sources
            
            
              src/main/yang
              
                
                  org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
                  ${salGeneratorPath}
                
              
              true
            
          
        
      
    
  
  
    scm:git:ssh://git.opendaylight.org:29418/controller.git
    scm:git:ssh://git.opendaylight.org:29418/controller.git
    HEAD
    https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL
  

上面yang文件定义了两个rpc。

运行mvn install编译xptest.yang. 会产生一个rpc服务XptestService 接口。其中两个方法对应两个rpc 函数。

第二步:定义rpc的实现文件XpTestProvider及其Activator

该工程定义为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> cancelOrder(
      CancelOrderInput input) {
    // TODO Auto-generated method stub
    RpcResult ret=null;
    if(input.getOrderno() >10)
    {
      ret=RpcResultBuilder.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.success(builder.build()).build();
    }


    return Futures.immediateFuture(ret);
  }


  @Override
  public Future> makeOrder(MakeOrderInput input) {
    // TODO Auto-generated method stub
    RpcResult 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.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.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 Vaclav Demcak
 * *
 */
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文件。



  4.0.0
  
    org.opendaylight.controller.samples
    sal-samples
    1.2.0-SNAPSHOT
  
  sample-xptest-provider
  bundle

  
  
      ${project.groupId}
      sample-xptest
      ${project.version}
    
    
      equinoxSDK381
      org.eclipse.osgi
    
    
      org.opendaylight.controller
      config-api
    
    
      org.opendaylight.controller
      sal-binding-api
    
    
      org.opendaylight.controller
      sal-binding-config
    
    
      org.opendaylight.controller
      sal-common-util
    
    
      org.osgi
      org.osgi.core
    

    
    
      org.opendaylight.controller
      sal-binding-broker-impl
      test
    
    
      org.opendaylight.controller
      sal-binding-broker-impl
      test-jar
      test
    
    
        junit
        junit
        test
    
    
     
      org.mockito
      mockito-all
      test
    
    
      org.opendaylight.controller
      sal-binding-api
    
    
      org.opendaylight.controller.model
      model-flow-service
    
    
      org.opendaylight.yangtools
      yang-common
    
    
      org.opendaylight.controller
      sal-binding-broker-impl
      provided
    
  

  
    
      
        org.apache.felix
        maven-bundle-plugin
        
          
            org.opendaylight.controller.xptest.Activator
          
        
      
    
  

  
    scm:git:ssh://git.opendaylight.org:29418/controller.git
    scm:git:ssh://git.opendaylight.org:29418/controller.git
    HEAD
    https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL
  

运行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



  3
  112233


如果header中加accept:application/yang.data+json,将返回json数据。

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

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

你可能感兴趣的:(osgi,opendaylight,CommandProvider)