问题
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