OpenDaylight Rest API with Java

雨燕双飞 提交于 2020-02-02 15:26:47

问题


Before posting this question I search alot to be sure how to ask.

I am trying to connect to the OpenDaylight controller with Java, I am trying to connect by consuming the rest services given by the controller. My problem is, when I send the http request I cannot get any further than the login, I am not sure if its possible. Instead of getting the topology or other answer from the controller, I am getting the html of the login form.

Also, I am not sure if I should be connecting like this.

Any help/guidance is very appreciated. :)

My code for creating the connection is:

public String getContent(String urls) throws  IOException {

    String cont="";

    CloseableHttpClient httpclient = HttpClients.createDefault();

    HttpPost httpPost = new HttpPost(urls);

    List <NameValuePair> nvps = new ArrayList <NameValuePair>();

    nvps.add(new BasicNameValuePair("j_username", "username"));

    nvps.add(new BasicNameValuePair("j_password", "password"));

    httpPost.setEntity(new UrlEncodedFormEntity(nvps));

    CloseableHttpResponse response2 = httpclient.execute(httpPost);

    try {

        System.out.println(response2.getStatusLine());

        HttpEntity entity2 = response2.getEntity();

        BufferedReader reader =new BufferedReader(new InputStreamReader(entity2.getContent()));

        String line="";

        while((line=reader.readLine())!=null){
            cont+=line+"\n";
        }


    } finally {
        response2.close();

    }           

    return cont;
}

When I run the code, this is what is printed:

HTTP/1.1 200 OK

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OpenDaylight - Login</title>
<script src="/js/bootstrap.min.js"></script>    
<script type="text/javascript">
    less = {
        env: "production"
    };
</script>
<script src="/js/less-1.3.3.min.js"></script>
</head>
<body>
<form action="j_security_check;jsessionid=LONGID" id="form" method="post">
<div class="container">
 <div class="content">
   <div class="login-form">
     <div id="logo"></div>
       <fieldset>
         <div class="control-group">
           <input type="text" name="j_username" placeholder="Username">
         </div>
         <div class="control-group">
           <input type="password" name="j_password" placeholder="Password">
         </div>
         <button class="btn btn-primary" type="submit" value="Log In" >
        <div class="icon-login"></div> Log In</button>
       </fieldset>
   </div>
 </div>
 </div> 
 </form>
 </body>
 </html>

回答1:


The problem seems to be with authentication. Username and password must be encoded to Base64. Please try the sample code below, which get the flow details in JSON format. You can to try getting topology details in the same way.

You can download the commons-codec library from here

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.codec.binary.Base64;

public class OpenDayLightUtils {

    public static void getFlowDetails() {

    String user = "admin";
    String password = "admin";
    String baseURL = "http://192.168.100.1:8080/controller/nb/v2/flowprogrammer";
    String containerName = "default";

    try {

        // Create URL = base URL + container
        URL url = new URL(baseURL + "/" + containerName);

        // Create authentication string and encode it to Base64
        String authStr = user + ":" + password;
        String encodedAuthStr = Base64.encodeBase64String(authStr.getBytes());

        // Create Http connection
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // Set connection properties
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Authorization", "Basic " + encodedAuthStr);
        connection.setRequestProperty("Accept", "application/json");

        // Get the response from connection's inputStream
        InputStream content = (InputStream) connection.getInputStream();

        BufferedReader in = new BufferedReader(new InputStreamReader(content));
        String line = "";
        while ((line = in.readLine()) != null) {
        System.out.println(line);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
}



回答2:


This link gives you the full reference to all RESTConf Api's for ODL: OpenDaylight_Controller:MD-SAL:Model_Reference

Another good place to start is here: OpenDaylight OpenFlow Plugin:User Guide

For instance, if you want to find the topology you have to send a GET request to: http://:8080/restconf/operational/network-topology:network-topology/topology/flow:1/

So, the URN name space tells you what module/bundle in the ODL controller you want to talk to.. Another example is http://:8080/restconf/operational/opendaylight-inventory:nodes/node/openflow:1, which will give you information about the openflow node 'openflow:1'..

If you want to push something, such as openflow rules, just attach the XML body to the PUT together with headers Content-Type' : 'application/xml' and 'Accept':'application/xml. This is the 'lib' I have created in python for my application. You might find some inspiration.

import sys
import json
import httplib2

#Base URLs for Config and operational
baseUrl = 'http://192.168.231.246:8080'
confUrl = baseUrl + '/restconf/config/'
operUrl = baseUrl + '/restconf/operational/'

#"Old" REST APIs that still are used
sdSalUrl = baseUrl + '/controller/nb/v2/'

#Specific REST URLs
findNodes = operUrl + '/opendaylight-inventory:nodes/'
findTopo = operUrl + '/network-topology:network-topology/'
findNodeConnector = operUrl + '/opendaylight-inventory:nodes/node/node-connector/'
findTopology = operUrl + '/network-topology:network-topology/topology/flow:1/'
findFlow = confUrl +'/opendaylight-inventory:nodes/node/openflow:1/table/0/'

h = httplib2.Http(".cache")
h.add_credentials('admin', 'admin')

#Functions for  
def get(url):
    resp, xml = h.request(
        url,
        method = "GET",
        headers = {'Content-Type' : 'application/xml'}
        )
    return xml
def put(url, body):
    resp, content = h.request(
        url, 
        method = "PUT",
        body = body,
        headers = {'Content-Type' : 'application/xml', 'Accept':'application/xml'}
        )
    return resp, content
def delete(url):
    resp, content = h.request(
        url,
        method = "DELETE"
        )
    return resp

def get_active_hosts():
    resp, content = h.request(sdSalUrl + 'hosttracker/default/hosts/active/', "GET")
    hostConfig = json.loads(content)
    hosts = hostConfig['hostConfig']
    return hosts

Oh, and by the way. One of the OVSDB devs from ODL answered something similar here earlier: networkstatic's answer



来源:https://stackoverflow.com/questions/23204630/opendaylight-rest-api-with-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!