How to Implement RPC in odl

Source: Internet
Author: User
Tags netconf

As the main open-source SDN project, opendaylight adopts the osgi framework and has been supported by many vendors. The helium version is also coming soon.

The following describes how to implement RPC in odl. odl uses Yang as the model definition file. The Yang specification was first used for netconf. Later, restconf implemented restful on the HTTP protocol, while Yang defined the model.

The implementation is divided into two steps: 1. Use Yang to define the model and implement the API jar package. 2. Implement the RPC service implementation class and register it to the session.

Two Java project directory structures.


Step 1: Define the Yang file and Its Pom. xml

Define XP test. Yang in the directory XP test \ SRC \ main \ Yang

  module xptest {    yang-version 1;    namespace      "http://startsky.com/ns/xptest";    prefix xps;    organization "xpstudio Netconf Central";    contact      "xinping <[email protected]>";    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

Define the Pom. xml of Yang, and define Pom. xml under xptest.

<?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>

The above Yang file defines two RPC.

Run MVN install to compile xptest. Yang. an RPC service xptestservice interface is generated. The two methods correspond to two RPC functions.
Step 2: Define the RPC implementation file xptestprovider and its Activator

This project is defined as xpprovider.

RPC implementation class XP testprovider

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);  }}
Implement the plug-in entry class activator, and implement the command line interface by the way. You can customize command line test commands.

/** * 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:[email protected]">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";   }  }

The Pom. xml file of the xpprovider.

<?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>

Step 3: perform the test.

Run run. bat, start odl, and run the following test case in restclient. Tools that support restclient include chrome plug-in postman and Firefox restclient. There is also a separate jar package restclient on the Internet.

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
}
}

The XML data is returned. How to add accept: Application/yang. Data + JSON in the header will return JSON data.

The failure test cases can be constructed according to the figure in the above Code.

I hope that anyone interested in odl will be able to help me.

How to Implement RPC in odl

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.