Cleaned up Integration Tests
[controller.git] / opendaylight / northbound / integrationtest / src / test / java / org / opendaylight / controller / northbound / integrationtest / NorthboundIT.java
1 package org.opendaylight.controller.northbound.integrationtest;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5 import org.osgi.framework.ServiceReference;
6 import org.osgi.framework.Bundle;
7 import javax.inject.Inject;
8
9 import org.junit.Assert;
10 import org.junit.Test;
11 import org.junit.Before;
12 import org.junit.runner.RunWith;
13 import org.ops4j.pax.exam.junit.PaxExam;
14 import org.osgi.framework.BundleContext;
15 import static org.junit.Assert.*;
16 import org.ops4j.pax.exam.junit.Configuration;
17 import static org.ops4j.pax.exam.CoreOptions.*;
18 import org.ops4j.pax.exam.Option;
19 import org.ops4j.pax.exam.util.PathUtils;
20 import java.io.BufferedReader;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.io.OutputStreamWriter;
24 import java.net.HttpURLConnection;
25 import java.net.URL;
26 import java.nio.charset.Charset;
27 import java.util.Arrays;
28
29 import org.apache.commons.codec.binary.Base64;
30
31 import org.codehaus.jettison.json.JSONArray;
32 import org.codehaus.jettison.json.JSONException;
33 import org.codehaus.jettison.json.JSONObject;
34 import org.codehaus.jettison.json.JSONTokener;
35
36 import org.opendaylight.controller.hosttracker.IfIptoHost;
37 import org.opendaylight.controller.sal.core.ConstructionException;
38 import org.opendaylight.controller.sal.core.Node;
39 import org.opendaylight.controller.sal.core.NodeConnector;
40 import org.opendaylight.controller.sal.core.UpdateType;
41 import org.opendaylight.controller.switchmanager.IInventoryListener;
42 import org.opendaylight.controller.usermanager.IUserManager;
43
44
45 @RunWith(PaxExam.class)
46 public class NorthboundIT {
47     private Logger log = LoggerFactory
48             .getLogger(NorthboundIT.class);
49     // get the OSGI bundle context
50     @Inject
51     private BundleContext bc;
52     private IUserManager users = null;
53     private IInventoryListener invtoryListener = null;
54
55     private String stateToString(int state) {
56         switch (state) {
57         case Bundle.ACTIVE:
58             return "ACTIVE";
59         case Bundle.INSTALLED:
60             return "INSTALLED";
61         case Bundle.RESOLVED:
62             return "RESOLVED";
63         case Bundle.UNINSTALLED:
64             return "UNINSTALLED";
65         default:
66             return "Not CONVERTED";
67         }
68     }
69
70     @Before
71     public void areWeReady() {
72         assertNotNull(bc);
73         boolean debugit = false;
74         Bundle b[] = bc.getBundles();
75         for (int i = 0; i < b.length; i++) {
76             int state = b[i].getState();
77             if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
78                 log.debug("Bundle:" + b[i].getSymbolicName() + " state:"
79                         + stateToString(state));
80                 debugit = true;
81             }
82         }
83         if (debugit) {
84             log.debug("Do some debugging because some bundle is "
85                     + "unresolved");
86         }
87         // Assert if true, if false we are good to go!
88         assertFalse(debugit);
89
90         ServiceReference r = bc.getServiceReference(IUserManager.class
91                 .getName());
92         if (r != null) {
93             this.users = (IUserManager) bc.getService(r);
94         }
95         // If UserManager is null, cannot login to run tests.
96         assertNotNull(this.users);
97
98         r = bc.getServiceReference(IfIptoHost.class.getName());
99         if (r != null) {
100             this.invtoryListener = (IInventoryListener) bc.getService(r);
101         }
102
103         // If inventoryListener is null, cannot run hosttracker tests.
104         assertNotNull(this.invtoryListener);
105
106     }
107
108     // static variable to pass response code from getJsonResult()
109     private static Integer httpResponseCode = null;
110
111     private String getJsonResult(String restUrl) {
112         return getJsonResult(restUrl, "GET", null);
113     }
114
115     private String getJsonResult(String restUrl, String method) {
116         return getJsonResult(restUrl, method, null);
117     }
118
119     private String getJsonResult(String restUrl, String method, String body) {
120         // initialize response code to indicate error
121         httpResponseCode = 400;
122
123         try {
124             URL url = new URL(restUrl);
125             this.users.getAuthorizationList();
126             this.users.authenticate("admin", "admin");
127             String authString = "admin:admin";
128             byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
129             String authStringEnc = new String(authEncBytes);
130
131             HttpURLConnection connection = (HttpURLConnection) url
132                     .openConnection();
133             connection.setRequestMethod(method);
134             connection.setRequestProperty("Authorization", "Basic "
135                     + authStringEnc);
136             connection.setRequestProperty("Content-Type", "application/json");
137             connection.setRequestProperty("Accept", "application/json");
138
139             if (body != null) {
140                 connection.setDoOutput(true);
141                 OutputStreamWriter wr = new OutputStreamWriter(
142                         connection.getOutputStream());
143                 wr.write(body);
144                 wr.flush();
145             }
146             connection.connect();
147             connection.getContentType();
148
149             // Response code for success should be 2xx
150             httpResponseCode = connection.getResponseCode();
151             if (httpResponseCode > 299)
152                 return httpResponseCode.toString();
153
154             InputStream is = connection.getInputStream();
155             BufferedReader rd = new BufferedReader(new InputStreamReader(is,
156                     Charset.forName("UTF-8")));
157             StringBuilder sb = new StringBuilder();
158             int cp;
159             while ((cp = rd.read()) != -1) {
160                 sb.append((char) cp);
161             }
162             is.close();
163             connection.disconnect();
164             return sb.toString();
165         } catch (Exception e) {
166             return null;
167         }
168     }
169
170     @Test
171     public void testStatistics() {
172         String actionTypes[] = { "drop", "loopback", "flood", "floodAll",
173                 "controller", "swPath", "hwPath", "output", "setDlSrc",
174                 "setDlDst", "setDlType", "setVlanId", "setVlanPcp",
175                 "setVlanCfi", "popVlan", "pushVlan", "setNwSrc", "setNwDst",
176                 "setNwTos", "setTpSrc", "setTpDst" };
177         System.out.println("Starting Statistics JAXB client.");
178
179         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
180         try {
181             String result = getJsonResult(baseURL + "flowstats");
182             JSONTokener jt = new JSONTokener(result);
183             JSONObject json = new JSONObject(jt);
184             JSONObject flowStatistics = getJsonInstance(json, "flowStatistics",
185                     0xCAFE);
186             JSONObject node = flowStatistics.getJSONObject("node");
187             // test that node was returned properly
188             Assert.assertTrue(node.getInt("@id") == 0xCAFE);
189             Assert.assertTrue(node.getString("@type").equals("STUB"));
190
191             // test that flow statistics results are correct
192             JSONArray flowStats = flowStatistics.getJSONArray("flowStat");
193             for (int i = 0; i < flowStats.length(); i++) {
194
195                 JSONObject flowStat = flowStats.getJSONObject(i);
196                 testFlowStat(flowStat, actionTypes[i]);
197
198             }
199
200             // for /controller/nb/v2/statistics/default/portstats
201             result = getJsonResult(baseURL + "portstats");
202             jt = new JSONTokener(result);
203             json = new JSONObject(jt);
204             JSONObject portStatistics = getJsonInstance(json, "portStatistics",
205                     0xCAFE);
206             JSONObject node2 = portStatistics.getJSONObject("node");
207             // test that node was returned properly
208             Assert.assertTrue(node2.getInt("@id") == 0xCAFE);
209             Assert.assertTrue(node2.getString("@type").equals("STUB"));
210
211             // test that port statistic results are correct
212             JSONObject portStat = portStatistics.getJSONObject("portStat");
213             Assert.assertTrue(portStat.getInt("receivePackets") == 250);
214             Assert.assertTrue(portStat.getInt("transmitPackets") == 500);
215             Assert.assertTrue(portStat.getInt("receiveBytes") == 1000);
216             Assert.assertTrue(portStat.getInt("transmitBytes") == 5000);
217             Assert.assertTrue(portStat.getInt("receiveDrops") == 2);
218             Assert.assertTrue(portStat.getInt("transmitDrops") == 50);
219             Assert.assertTrue(portStat.getInt("receiveErrors") == 3);
220             Assert.assertTrue(portStat.getInt("transmitErrors") == 10);
221             Assert.assertTrue(portStat.getInt("receiveFrameError") == 5);
222             Assert.assertTrue(portStat.getInt("receiveOverRunError") == 6);
223             Assert.assertTrue(portStat.getInt("receiveCrcError") == 1);
224             Assert.assertTrue(portStat.getInt("collisionCount") == 4);
225
226             // test for getting one specific node's stats
227             result = getJsonResult(baseURL + "flowstats/STUB/51966");
228             jt = new JSONTokener(result);
229             json = new JSONObject(jt);
230             node = json.getJSONObject("node");
231             // test that node was returned properly
232             Assert.assertTrue(node.getInt("@id") == 0xCAFE);
233             Assert.assertTrue(node.getString("@type").equals("STUB"));
234
235             // test that flow statistics results are correct
236             flowStats = json.getJSONArray("flowStat");
237             for (int i = 0; i < flowStats.length(); i++) {
238                 JSONObject flowStat = flowStats.getJSONObject(i);
239                 testFlowStat(flowStat, actionTypes[i]);
240             }
241
242             result = getJsonResult(baseURL + "portstats/STUB/51966");
243             jt = new JSONTokener(result);
244             json = new JSONObject(jt);
245             node2 = json.getJSONObject("node");
246             // test that node was returned properly
247             Assert.assertTrue(node2.getInt("@id") == 0xCAFE);
248             Assert.assertTrue(node2.getString("@type").equals("STUB"));
249
250             // test that port statistic results are correct
251             portStat = json.getJSONObject("portStat");
252             Assert.assertTrue(portStat.getInt("receivePackets") == 250);
253             Assert.assertTrue(portStat.getInt("transmitPackets") == 500);
254             Assert.assertTrue(portStat.getInt("receiveBytes") == 1000);
255             Assert.assertTrue(portStat.getInt("transmitBytes") == 5000);
256             Assert.assertTrue(portStat.getInt("receiveDrops") == 2);
257             Assert.assertTrue(portStat.getInt("transmitDrops") == 50);
258             Assert.assertTrue(portStat.getInt("receiveErrors") == 3);
259             Assert.assertTrue(portStat.getInt("transmitErrors") == 10);
260             Assert.assertTrue(portStat.getInt("receiveFrameError") == 5);
261             Assert.assertTrue(portStat.getInt("receiveOverRunError") == 6);
262             Assert.assertTrue(portStat.getInt("receiveCrcError") == 1);
263             Assert.assertTrue(portStat.getInt("collisionCount") == 4);
264
265         } catch (Exception e) {
266             // Got an unexpected exception
267             Assert.assertTrue(false);
268
269         }
270     }
271
272     private void testFlowStat(JSONObject flowStat, String actionType) {
273         try {
274             Assert.assertTrue(flowStat.getInt("tableId") == 1);
275             Assert.assertTrue(flowStat.getInt("durationSeconds") == 40);
276             Assert.assertTrue(flowStat.getInt("durationNanoseconds") == 400);
277             Assert.assertTrue(flowStat.getInt("packetCount") == 200);
278             Assert.assertTrue(flowStat.getInt("byteCount") == 100);
279
280             // test that flow information is correct
281             JSONObject flow = flowStat.getJSONObject("flow");
282             Assert.assertTrue(flow.getInt("priority") == 3500);
283             Assert.assertTrue(flow.getInt("idleTimeout") == 1000);
284             Assert.assertTrue(flow.getInt("hardTimeout") == 2000);
285             Assert.assertTrue(flow.getInt("id") == 12345);
286
287             JSONObject match = (flow.getJSONObject("match")
288                     .getJSONObject("matchField"));
289             Assert.assertTrue(match.getString("type").equals("NW_DST"));
290             Assert.assertTrue(match.getString("value").equals("1.1.1.1"));
291
292             JSONObject act = flow.getJSONObject("actions");
293             Assert.assertTrue(act.getString("@type").equals(actionType));
294
295             if (act.getString("@type").equals("output")) {
296                 JSONObject port = act.getJSONObject("port");
297                 JSONObject port_node = port.getJSONObject("node");
298                 Assert.assertTrue(port.getInt("@id") == 51966);
299                 Assert.assertTrue(port.getString("@type").equals("STUB"));
300                 Assert.assertTrue(port_node.getInt("@id") == 51966);
301                 Assert.assertTrue(port_node.getString("@type").equals("STUB"));
302             }
303
304             if (act.getString("@type").equals("setDlSrc")) {
305                 byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2,
306                         (byte) 1 };
307                 String src = act.getString("address");
308                 byte srcBytes[] = new byte[5];
309                 srcBytes[0] = Byte.parseByte(src.substring(0, 2));
310                 srcBytes[1] = Byte.parseByte(src.substring(2, 4));
311                 srcBytes[2] = Byte.parseByte(src.substring(4, 6));
312                 srcBytes[3] = Byte.parseByte(src.substring(6, 8));
313                 srcBytes[4] = Byte.parseByte(src.substring(8, 10));
314                 Assert.assertTrue(Arrays.equals(srcBytes, srcMatch));
315             }
316
317             if (act.getString("@type").equals("setDlDst")) {
318                 byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4,
319                         (byte) 5 };
320                 String dst = act.getString("address");
321                 byte dstBytes[] = new byte[5];
322                 dstBytes[0] = Byte.parseByte(dst.substring(0, 2));
323                 dstBytes[1] = Byte.parseByte(dst.substring(2, 4));
324                 dstBytes[2] = Byte.parseByte(dst.substring(4, 6));
325                 dstBytes[3] = Byte.parseByte(dst.substring(6, 8));
326                 dstBytes[4] = Byte.parseByte(dst.substring(8, 10));
327                 Assert.assertTrue(Arrays.equals(dstBytes, dstMatch));
328             }
329             if (act.getString("@type").equals("setDlType"))
330                 Assert.assertTrue(act.getInt("dlType") == 10);
331             if (act.getString("@type").equals("setVlanId"))
332                 Assert.assertTrue(act.getInt("vlanId") == 2);
333             if (act.getString("@type").equals("setVlanPcp"))
334                 Assert.assertTrue(act.getInt("pcp") == 3);
335             if (act.getString("@type").equals("setVlanCfi"))
336                 Assert.assertTrue(act.getInt("cfi") == 1);
337
338             if (act.getString("@type").equals("setNwSrc"))
339                 Assert.assertTrue(act.getString("address").equals("2.2.2.2"));
340             if (act.getString("@type").equals("setNwDst"))
341                 Assert.assertTrue(act.getString("address").equals("1.1.1.1"));
342
343             if (act.getString("@type").equals("pushVlan")) {
344                 int head = act.getInt("VlanHeader");
345                 // parsing vlan header
346                 int id = head & 0xfff;
347                 int cfi = (head >> 12) & 0x1;
348                 int pcp = (head >> 13) & 0x7;
349                 int tag = (head >> 16) & 0xffff;
350                 Assert.assertTrue(id == 1234);
351                 Assert.assertTrue(cfi == 1);
352                 Assert.assertTrue(pcp == 1);
353                 Assert.assertTrue(tag == 0x8100);
354             }
355             if (act.getString("@type").equals("setNwTos"))
356                 Assert.assertTrue(act.getInt("tos") == 16);
357             if (act.getString("@type").equals("setTpSrc"))
358                 Assert.assertTrue(act.getInt("port") == 4201);
359             if (act.getString("@type").equals("setTpDst"))
360                 Assert.assertTrue(act.getInt("port") == 8080);
361         } catch (Exception e) {
362             Assert.assertTrue(false);
363         }
364     }
365
366     @Test
367     public void testFlowProgrammer() {
368         try {
369             String baseURL = "http://127.0.0.1:8080/controller/nb/v2/flow/default/";
370             // Attempt to get a flow that doesn't exit. Should return 404
371             // status.
372             String result = getJsonResult(baseURL + "STUB/51966/test1", "GET");
373             Assert.assertTrue(result.equals("404"));
374
375             // test add flow1
376             String fc = "{\"dynamic\":\"false\", \"name\":\"test1\", \"node\":{\"@id\":\"51966\",\"@type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
377             result = getJsonResult(baseURL + "STUB/51966/test1", "POST", fc);
378             Assert.assertTrue(httpResponseCode == 201);
379
380             // test get returns flow that was added.
381             result = getJsonResult(baseURL + "STUB/51966/test1", "GET");
382             // check that result came out fine.
383             Assert.assertTrue(httpResponseCode == 200);
384             JSONTokener jt = new JSONTokener(result);
385             JSONObject json = new JSONObject(jt);
386             Assert.assertTrue(json.getString("name").equals("test1"));
387             Assert.assertTrue(json.getString("actions").equals("DROP"));
388             Assert.assertTrue(json.getString("installInHw").equals("true"));
389             JSONObject node = json.getJSONObject("node");
390             Assert.assertTrue(node.getString("@type").equals("STUB"));
391             Assert.assertTrue(node.getString("@id").equals("51966"));
392             // test adding same flow again fails due to repeat name..return 409
393             // code
394             result = getJsonResult(baseURL + "STUB/51966/test1", "POST", fc);
395             Assert.assertTrue(result.equals("409"));
396
397             fc = "{\"dynamic\":\"false\", \"name\":\"test2\", \"node\":{\"@id\":\"51966\",\"@type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
398             result = getJsonResult(baseURL + "STUB/51966/test2", "POST", fc);
399             // test should return 500 for error due to same flow being added.
400             Assert.assertTrue(result.equals("500"));
401
402             // add second flow that's different
403             fc = "{\"dynamic\":\"false\", \"name\":\"test2\", \"nwSrc\":\"1.1.1.1\", \"node\":{\"@id\":\"51966\",\"@type\":\"STUB\"}, \"actions\":[\"DROP\"]}";
404             result = getJsonResult(baseURL + "STUB/51966/test2", "POST", fc);
405             Assert.assertTrue(httpResponseCode == 201);
406             
407             // check that request returns both flows given node.
408             result = getJsonResult(baseURL + "STUB/51966/", "GET");
409             jt = new JSONTokener(result);
410             json = new JSONObject(jt);
411             Assert.assertTrue(json.get("flowConfig") instanceof JSONArray);
412             JSONArray ja = json.getJSONArray("flowConfig");
413             Integer count = ja.length();
414             Assert.assertTrue(count == 2);
415
416             // check that request returns both flows given just container.
417             result = getJsonResult(baseURL);
418             jt = new JSONTokener(result);
419             json = new JSONObject(jt);
420             Assert.assertTrue(json.get("flowConfig") instanceof JSONArray);
421             ja = json.getJSONArray("flowConfig");
422             count = ja.length();
423             Assert.assertTrue(count == 2);
424
425             // delete a flow, check that it's no longer in list.
426             result = getJsonResult(baseURL + "STUB/51966/test2", "DELETE");
427             Assert.assertTrue(httpResponseCode == 200);
428
429             result = getJsonResult(baseURL + "STUB/51966/test2", "GET");
430             Assert.assertTrue(result.equals("404"));
431
432         } catch (Exception e) {
433             Assert.assertTrue(false);
434         }
435
436     }
437
438     // method to extract a JSONObject with specified node ID from a JSONObject
439     // that may contain an array of JSONObjects
440     // This is specifically written for statistics manager northbound REST
441     // interface
442     // array_name should be either "flowStatistics" or "portStatistics"
443     private JSONObject getJsonInstance(JSONObject json, String array_name,
444             Integer nodeId) throws JSONException {
445         JSONObject result = null;
446         if (json.get(array_name) instanceof JSONArray) {
447             JSONArray json_array = json.getJSONArray(array_name);
448             for (int i = 0; i < json_array.length(); i++) {
449                 result = json_array.getJSONObject(i);
450                 Integer nid = result.getJSONObject("node").getInt("@id");
451                 if (nid.equals(nodeId))
452                     break;
453             }
454         } else {
455             result = json.getJSONObject(array_name);
456             Integer nid = result.getJSONObject("node").getInt("@id");
457             if (!nid.equals(nodeId))
458                 result = null;
459         }
460         return result;
461     }
462
463     // a class to construct query parameter for HTTP request
464     private class QueryParameter {
465         StringBuilder queryString = null;
466
467         // constructor
468         QueryParameter(String key, String value) {
469             queryString = new StringBuilder();
470             queryString.append("?").append(key).append("=").append(value);
471         }
472
473         // method to add more query parameter
474         QueryParameter add(String key, String value) {
475             this.queryString.append("&").append(key).append("=").append(value);
476             return this;
477         }
478
479         // method to get the query parameter string
480         String getString() {
481             return this.queryString.toString();
482         }
483
484     }
485
486     @Test
487     public void testHostTracker() {
488
489         System.out.println("Starting HostTracker JAXB client.");
490
491         // setup 2 host models for @POST method
492         // 1st host
493         String networkAddress_1 = "192.168.0.8";
494         String dataLayerAddress_1 = "11:22:33:44:55:66";
495         String nodeType_1 = "STUB";
496         Integer nodeId_1 = 3366;
497         String nodeConnectorType_1 = "STUB";
498         Integer nodeConnectorId_1 = 12;
499         String vlan_1 = "4";
500
501         // 2nd host
502         String networkAddress_2 = "10.1.1.1";
503         String dataLayerAddress_2 = "1A:2B:3C:4D:5E:6F";
504         String nodeType_2 = "STUB";
505         Integer nodeId_2 = 4477;
506         String nodeConnectorType_2 = "STUB";
507         Integer nodeConnectorId_2 = 34;
508         String vlan_2 = "0";
509
510         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/host/default";
511
512         // test POST method: addHost()
513         try {
514             String queryParameter = new QueryParameter("dataLayerAddress",
515                     dataLayerAddress_1).add("nodeType", nodeType_1)
516                     .add("nodeId", nodeId_1.toString())
517                     .add("nodeConnectorType", nodeConnectorType_1)
518                     .add("nodeConnectorId", nodeConnectorId_1.toString())
519                     .add("vlan", vlan_1).getString();
520
521             String result = getJsonResult(baseURL + "/" + networkAddress_1
522                     + queryParameter, "POST");
523             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 201);
524
525             // vlan is not passed through query parameter but should be
526             // defaulted to "0"
527             queryParameter = new QueryParameter("dataLayerAddress",
528                     dataLayerAddress_2).add("nodeType", nodeType_2)
529                     .add("nodeId", nodeId_2.toString())
530                     .add("nodeConnectorType", nodeConnectorType_2)
531                     .add("nodeConnectorId", nodeConnectorId_2.toString())
532                     .getString();
533
534             result = getJsonResult(baseURL + "/" + networkAddress_2
535                     + queryParameter, "POST");
536             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 201);
537         } catch (Exception e) {
538             // Got an unexpected exception
539             Assert.assertTrue(false);
540         }
541
542         // define variables for decoding returned strings
543         String networkAddress;
544         JSONObject host_jo, dl_jo, nc_jo, node_jo;
545
546         // the two hosts should be in inactive host DB
547         // test GET method: getInactiveHosts()
548         try {
549             String result = getJsonResult(baseURL + "/inactive", "GET");
550             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
551
552             JSONTokener jt = new JSONTokener(result);
553             JSONObject json = new JSONObject(jt);
554             // there should be at least two hosts in the DB
555             Assert.assertTrue(json.get("host") instanceof JSONArray);
556             JSONArray ja = json.getJSONArray("host");
557             Integer count = ja.length();
558             Assert.assertTrue(count == 2);
559
560             for (int i = 0; i < count; i++) {
561                 host_jo = ja.getJSONObject(i);
562                 dl_jo = host_jo.getJSONObject("dataLayerAddress");
563                 nc_jo = host_jo.getJSONObject("nodeConnector");
564                 node_jo = nc_jo.getJSONObject("node");
565
566                 networkAddress = host_jo.getString("networkAddress");
567                 if (networkAddress.equalsIgnoreCase(networkAddress_1)) {
568                     Assert.assertTrue(dl_jo.getString("macAddress")
569                             .equalsIgnoreCase(dataLayerAddress_1));
570                     Assert.assertTrue(nc_jo.getString("@type")
571                             .equalsIgnoreCase(nodeConnectorType_1));
572                     Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1);
573                     Assert.assertTrue(node_jo.getString("@type")
574                             .equalsIgnoreCase(nodeType_1));
575                     Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_1);
576                     Assert.assertTrue(host_jo.getString("vlan")
577                             .equalsIgnoreCase(vlan_1));
578                 } else if (networkAddress.equalsIgnoreCase(networkAddress_2)) {
579                     Assert.assertTrue(dl_jo.getString("macAddress")
580                             .equalsIgnoreCase(dataLayerAddress_2));
581                     Assert.assertTrue(nc_jo.getString("@type")
582                             .equalsIgnoreCase(nodeConnectorType_2));
583                     Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_2);
584                     Assert.assertTrue(node_jo.getString("@type")
585                             .equalsIgnoreCase(nodeType_2));
586                     Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_2);
587                     Assert.assertTrue(host_jo.getString("vlan")
588                             .equalsIgnoreCase(vlan_2));
589                 } else {
590                     Assert.assertTrue(false);
591                 }
592             }
593         } catch (Exception e) {
594             // Got an unexpected exception
595             Assert.assertTrue(false);
596         }
597
598         // test GET method: getActiveHosts() - no host expected
599         try {
600             String result = getJsonResult(baseURL, "GET");
601             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
602
603             JSONTokener jt = new JSONTokener(result);
604             JSONObject json = new JSONObject(jt);
605             Assert.assertFalse(hostInJson(json, networkAddress_1));
606             Assert.assertFalse(hostInJson(json, networkAddress_2));
607         } catch (Exception e) {
608             // Got an unexpected exception
609             Assert.assertTrue(false);
610         }
611
612         // put the 1st host into active host DB
613         Node nd;
614         NodeConnector ndc;
615         try {
616             nd = new Node(nodeType_1, nodeId_1);
617             ndc = new NodeConnector(nodeConnectorType_1, nodeConnectorId_1, nd);
618             this.invtoryListener.notifyNodeConnector(ndc, UpdateType.ADDED,
619                     null);
620         } catch (ConstructionException e) {
621             ndc = null;
622             nd = null;
623         }
624
625         // verify the host shows up in active host DB
626         try {
627             String result = getJsonResult(baseURL, "GET");
628             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
629
630             JSONTokener jt = new JSONTokener(result);
631             JSONObject json = new JSONObject(jt);
632
633             Assert.assertTrue(hostInJson(json, networkAddress_1));
634         } catch (Exception e) {
635             // Got an unexpected exception
636             Assert.assertTrue(false);
637         }
638
639         // test GET method for getHostDetails()
640         try {
641             String result = getJsonResult(baseURL + "/" + networkAddress_1,
642                     "GET");
643             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
644
645             JSONTokener jt = new JSONTokener(result);
646             JSONObject json = new JSONObject(jt);
647
648             Assert.assertFalse(json.length() == 0);
649
650             dl_jo = json.getJSONObject("dataLayerAddress");
651             nc_jo = json.getJSONObject("nodeConnector");
652             node_jo = nc_jo.getJSONObject("node");
653
654             Assert.assertTrue(json.getString("networkAddress")
655                     .equalsIgnoreCase(networkAddress_1));
656             Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(
657                     dataLayerAddress_1));
658             Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(
659                     nodeConnectorType_1));
660             Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1);
661             Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(
662                     nodeType_1));
663             Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_1);
664             Assert.assertTrue(json.getString("vlan").equalsIgnoreCase(vlan_1));
665         } catch (Exception e) {
666             // Got an unexpected exception
667             Assert.assertTrue(false);
668         }
669
670         // test DELETE method for deleteFlow()
671         try {
672             String result = getJsonResult(baseURL + "/" + networkAddress_1,
673                     "DELETE");
674             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
675
676         } catch (Exception e) {
677             // Got an unexpected exception
678             Assert.assertTrue(false);
679         }
680
681         // verify host_1 removed from active host DB
682         // test GET method: getActiveHosts() - no host expected
683         try {
684             String result = getJsonResult(baseURL, "GET");
685             Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
686
687             JSONTokener jt = new JSONTokener(result);
688             JSONObject json = new JSONObject(jt);
689
690             Assert.assertFalse(hostInJson(json, networkAddress_1));
691         } catch (Exception e) {
692             // Got an unexpected exception
693             Assert.assertTrue(false);
694         }
695     }
696
697     private Boolean hostInJson(JSONObject json, String hostIp)
698             throws JSONException {
699         // input JSONObject may be empty
700         if (json.length() == 0) {
701             return false;
702         }
703         if (json.get("host") instanceof JSONArray) {
704             JSONArray ja = json.getJSONArray("host");
705             for (int i = 0; i < ja.length(); i++) {
706                 String na = ja.getJSONObject(i).getString("networkAddress");
707                 if (na.equalsIgnoreCase(hostIp))
708                     return true;
709             }
710             return false;
711         } else {
712             String na = json.getJSONObject("host").getString("networkAddress");
713             return (na.equalsIgnoreCase(hostIp)) ? true : false;
714         }
715     }
716
717     // Configure the OSGi container
718     @Configuration
719     public Option[] config() {
720         return options(
721                 //
722                 systemProperty("logback.configurationFile").value(
723                         "file:" + PathUtils.getBaseDir()
724                                 + "/src/test/resources/logback.xml"),
725                 // To start OSGi console for inspection remotely
726                 systemProperty("osgi.console").value("2401"),
727                 systemProperty("org.eclipse.gemini.web.tomcat.config.path")
728                         .value(PathUtils.getBaseDir()
729                                 + "/src/test/resources/tomcat-server.xml"),
730
731                 // setting default level. Jersey bundles will need to be started
732                 // earlier.
733                 systemProperty("osgi.bundles.defaultStartLevel").value("4"),
734
735                 // Set the systemPackages (used by clustering)
736                 systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
737                 mavenBundle("javax.servlet", "servlet-api", "2.5"),
738
739                 mavenBundle("org.slf4j", "jcl-over-slf4j", "1.7.2"),
740                 mavenBundle("org.slf4j", "slf4j-api", "1.7.2"),
741                 mavenBundle("org.slf4j", "log4j-over-slf4j", "1.7.2"),
742                 mavenBundle("ch.qos.logback", "logback-core", "1.0.9"),
743                 mavenBundle("ch.qos.logback", "logback-classic", "1.0.9"),
744                 mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
745                 mavenBundle("org.apache.felix",
746                         "org.apache.felix.dependencymanager", "3.1.0"),
747
748                 // the plugin stub to get data for the tests
749                 mavenBundle("org.opendaylight.controller",
750                         "protocol_plugins.stub", "0.4.0-SNAPSHOT"),
751
752                 // List all the opendaylight modules
753                 mavenBundle("org.opendaylight.controller", "security",
754                         "0.4.0-SNAPSHOT").noStart(),
755                 mavenBundle("org.opendaylight.controller", "sal",
756                         "0.5.0-SNAPSHOT"),
757                 mavenBundle("org.opendaylight.controller",
758                         "sal.implementation", "0.4.0-SNAPSHOT"),
759                 mavenBundle("org.opendaylight.controller", "statisticsmanager",
760                         "0.4.0-SNAPSHOT"),
761                 mavenBundle("org.opendaylight.controller",
762                         "statisticsmanager.implementation", "0.4.0-SNAPSHOT"),
763                 mavenBundle("org.opendaylight.controller", "containermanager",
764                         "0.4.0-SNAPSHOT"),
765                 mavenBundle("org.opendaylight.controller",
766                         "containermanager.implementation", "0.4.0-SNAPSHOT"),
767                 mavenBundle("org.opendaylight.controller",
768                         "forwardingrulesmanager", "0.4.0-SNAPSHOT"),
769                 mavenBundle("org.opendaylight.controller",
770                         "forwardingrulesmanager.implementation",
771                         "0.4.0-SNAPSHOT"),
772                 mavenBundle("org.opendaylight.controller", "arphandler",
773                         "0.4.0-SNAPSHOT"),
774                 mavenBundle("org.opendaylight.controller",
775                         "clustering.services", "0.4.0-SNAPSHOT"),
776                 mavenBundle("org.opendaylight.controller",
777                         "clustering.services-implementation", "0.4.0-SNAPSHOT"),
778                 mavenBundle("org.opendaylight.controller", "switchmanager",
779                         "0.4.0-SNAPSHOT"),
780                 mavenBundle("org.opendaylight.controller",
781                         "switchmanager.implementation", "0.4.0-SNAPSHOT"),
782                 mavenBundle("org.opendaylight.controller", "configuration",
783                         "0.4.0-SNAPSHOT"),
784                 mavenBundle("org.opendaylight.controller",
785                         "configuration.implementation", "0.4.0-SNAPSHOT"),
786                 mavenBundle("org.opendaylight.controller", "hosttracker",
787                         "0.4.0-SNAPSHOT"),
788                 mavenBundle("org.opendaylight.controller",
789                         "hosttracker.implementation", "0.4.0-SNAPSHOT"),
790                 mavenBundle("org.opendaylight.controller", "arphandler",
791                         "0.4.0-SNAPSHOT"),
792                 mavenBundle("org.opendaylight.controller",
793                         "routing.dijkstra_implementation", "0.4.0-SNAPSHOT"),
794                 mavenBundle("org.opendaylight.controller", "topologymanager",
795                         "0.4.0-SNAPSHOT"),
796
797                 mavenBundle("org.opendaylight.controller", "usermanager",
798                         "0.4.0-SNAPSHOT"),
799                 mavenBundle("org.opendaylight.controller", "logging.bridge",
800                         "0.4.0-SNAPSHOT"),
801                 mavenBundle("org.opendaylight.controller", "clustering.test",
802                         "0.4.0-SNAPSHOT"),
803
804                 mavenBundle("org.opendaylight.controller",
805                         "forwarding.staticrouting", "0.4.0-SNAPSHOT"),
806
807                 // Northbound bundles
808                 mavenBundle("org.opendaylight.controller",
809                         "commons.northbound", "0.4.0-SNAPSHOT"),
810                 mavenBundle("org.opendaylight.controller",
811                         "forwarding.staticrouting.northbound", "0.4.0-SNAPSHOT"),
812                 mavenBundle("org.opendaylight.controller",
813                         "statistics.northbound", "0.4.0-SNAPSHOT"),
814                 mavenBundle("org.opendaylight.controller",
815                         "topology.northbound", "0.4.0-SNAPSHOT"),
816                 mavenBundle("org.opendaylight.controller",
817                         "hosttracker.northbound", "0.4.0-SNAPSHOT"),
818                 mavenBundle("org.opendaylight.controller",
819                         "switchmanager.northbound", "0.4.0-SNAPSHOT"),
820                 mavenBundle("org.opendaylight.controller",
821                         "flowprogrammer.northbound", "0.4.0-SNAPSHOT"),
822                 mavenBundle("org.opendaylight.controller",
823                         "subnets.northbound", "0.4.0-SNAPSHOT"),
824
825                 mavenBundle("org.codehaus.jackson", "jackson-mapper-asl",
826                         "1.9.8"),
827                 mavenBundle("org.codehaus.jackson", "jackson-core-asl", "1.9.8"),
828                 mavenBundle("org.codehaus.jackson", "jackson-jaxrs", "1.9.8"),
829                 mavenBundle("org.codehaus.jettison", "jettison", "1.3.3"),
830
831                 mavenBundle("commons-io", "commons-io", "2.3"),
832
833                 mavenBundle("commons-fileupload", "commons-fileupload", "1.2.2"),
834
835                 mavenBundle("equinoxSDK381", "javax.servlet",
836                         "3.0.0.v201112011016"),
837                 mavenBundle("equinoxSDK381", "javax.servlet.jsp",
838                         "2.2.0.v201112011158"),
839                 mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds",
840                         "1.4.0.v20120522-1841"),
841                 mavenBundle("orbit", "javax.xml.rpc", "1.1.0.v201005080400"),
842                 mavenBundle("equinoxSDK381", "org.eclipse.equinox.util",
843                         "1.0.400.v20120522-2049"),
844                 mavenBundle("equinoxSDK381", "org.eclipse.osgi.services",
845                         "3.3.100.v20120522-1822"),
846                 mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command",
847                         "0.8.0.v201108120515"),
848                 mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime",
849                         "0.8.0.v201108120515"),
850                 mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell",
851                         "0.8.0.v201110170705"),
852                 mavenBundle("equinoxSDK381", "org.eclipse.equinox.cm",
853                         "1.0.400.v20120522-1841"),
854                 mavenBundle("equinoxSDK381", "org.eclipse.equinox.console",
855                         "1.0.0.v20120522-1841"),
856                 mavenBundle("equinoxSDK381", "org.eclipse.equinox.launcher",
857                         "1.3.0.v20120522-1813"),
858
859                 mavenBundle("geminiweb", "org.eclipse.gemini.web.core",
860                         "2.2.0.RELEASE"),
861                 mavenBundle("geminiweb", "org.eclipse.gemini.web.extender",
862                         "2.2.0.RELEASE"),
863                 mavenBundle("geminiweb", "org.eclipse.gemini.web.tomcat",
864                         "2.2.0.RELEASE"),
865                 mavenBundle("geminiweb",
866                         "org.eclipse.virgo.kernel.equinox.extensions",
867                         "3.6.0.RELEASE").noStart(),
868                 mavenBundle("geminiweb", "org.eclipse.virgo.util.common",
869                         "3.6.0.RELEASE"),
870                 mavenBundle("geminiweb", "org.eclipse.virgo.util.io",
871                         "3.6.0.RELEASE"),
872                 mavenBundle("geminiweb", "org.eclipse.virgo.util.math",
873                         "3.6.0.RELEASE"),
874                 mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi",
875                         "3.6.0.RELEASE"),
876                 mavenBundle("geminiweb",
877                         "org.eclipse.virgo.util.osgi.manifest", "3.6.0.RELEASE"),
878                 mavenBundle("geminiweb",
879                         "org.eclipse.virgo.util.parser.manifest",
880                         "3.6.0.RELEASE"),
881
882                 mavenBundle("org.apache.felix",
883                         "org.apache.felix.dependencymanager", "3.1.0"),
884                 mavenBundle("org.apache.felix",
885                         "org.apache.felix.dependencymanager.shell", "3.0.1"),
886
887                 mavenBundle("com.google.code.gson", "gson", "2.1"),
888                 mavenBundle("org.jboss.spec.javax.transaction",
889                         "jboss-transaction-api_1.1_spec", "1.0.1.Final"),
890                 mavenBundle("org.apache.felix", "org.apache.felix.fileinstall",
891                         "3.1.6"),
892                 mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
893                 mavenBundle("commons-codec", "commons-codec"),
894                 mavenBundle("virgomirror",
895                         "org.eclipse.jdt.core.compiler.batch",
896                         "3.8.0.I20120518-2145"),
897                 mavenBundle("eclipselink", "javax.persistence",
898                         "2.0.4.v201112161009"),
899
900                 mavenBundle("orbit", "javax.activation", "1.1.0.v201211130549"),
901                 mavenBundle("orbit", "javax.annotation", "1.1.0.v201209060031"),
902                 mavenBundle("orbit", "javax.ejb", "3.1.1.v201204261316"),
903                 mavenBundle("orbit", "javax.el", "2.2.0.v201108011116"),
904                 mavenBundle("orbit", "javax.mail.glassfish",
905                         "1.4.1.v201108011116"),
906                 mavenBundle("orbit", "javax.xml.rpc", "1.1.0.v201005080400"),
907                 mavenBundle("orbit", "org.apache.catalina",
908                         "7.0.32.v201211201336"),
909                 // these are bundle fragments that can't be started on its own
910                 mavenBundle("orbit", "org.apache.catalina.ha",
911                         "7.0.32.v201211201952").noStart(),
912                 mavenBundle("orbit", "org.apache.catalina.tribes",
913                         "7.0.32.v201211201952").noStart(),
914                 mavenBundle("orbit", "org.apache.coyote",
915                         "7.0.32.v201211201952").noStart(),
916                 mavenBundle("orbit", "org.apache.jasper",
917                         "7.0.32.v201211201952").noStart(),
918
919                 mavenBundle("orbit", "org.apache.el", "7.0.32.v201211081135"),
920                 mavenBundle("orbit", "org.apache.juli.extras",
921                         "7.0.32.v201211081135"),
922                 mavenBundle("orbit", "org.apache.tomcat.api",
923                         "7.0.32.v201211081135"),
924                 mavenBundle("orbit", "org.apache.tomcat.util",
925                         "7.0.32.v201211201952").noStart(),
926                 mavenBundle("orbit", "javax.servlet.jsp.jstl",
927                         "1.2.0.v201105211821"),
928                 mavenBundle("orbit", "javax.servlet.jsp.jstl.impl",
929                         "1.2.0.v201210211230"),
930
931                 mavenBundle("org.ops4j.pax.exam", "pax-exam-container-native"),
932                 mavenBundle("org.ops4j.pax.exam", "pax-exam-junit4"),
933                 mavenBundle("org.ops4j.pax.exam", "pax-exam-link-mvn"),
934                 mavenBundle("org.ops4j.pax.url", "pax-url-aether"),
935
936                 mavenBundle("org.springframework", "org.springframework.asm",
937                         "3.1.3.RELEASE"),
938                 mavenBundle("org.springframework", "org.springframework.aop",
939                         "3.1.3.RELEASE"),
940                 mavenBundle("org.springframework",
941                         "org.springframework.context", "3.1.3.RELEASE"),
942                 mavenBundle("org.springframework",
943                         "org.springframework.context.support", "3.1.3.RELEASE"),
944                 mavenBundle("org.springframework", "org.springframework.core",
945                         "3.1.3.RELEASE"),
946                 mavenBundle("org.springframework", "org.springframework.beans",
947                         "3.1.3.RELEASE"),
948                 mavenBundle("org.springframework",
949                         "org.springframework.expression", "3.1.3.RELEASE"),
950                 mavenBundle("org.springframework", "org.springframework.web",
951                         "3.1.3.RELEASE"),
952
953                 mavenBundle("org.aopalliance",
954                         "com.springsource.org.aopalliance", "1.0.0"),
955                 mavenBundle("org.springframework",
956                         "org.springframework.web.servlet", "3.1.3.RELEASE"),
957                 mavenBundle("org.springframework.security",
958                         "spring-security-config", "3.1.3.RELEASE"),
959                 mavenBundle("org.springframework.security",
960                         "spring-security-core", "3.1.3.RELEASE"),
961                 mavenBundle("org.springframework.security",
962                         "spring-security-web", "3.1.3.RELEASE"),
963                 mavenBundle("org.springframework.security",
964                         "spring-security-taglibs", "3.1.3.RELEASE"),
965                 mavenBundle("org.springframework",
966                         "org.springframework.transaction", "3.1.3.RELEASE"),
967
968                 mavenBundle("org.ow2.chameleon.management", "chameleon-mbeans",
969                         "1.0.0"),
970                 mavenBundle("org.opendaylight.controller.thirdparty",
971                         "net.sf.jung2", "2.0.1-SNAPSHOT"),
972                 mavenBundle("org.opendaylight.controller.thirdparty",
973                         "com.sun.jersey.jersey-servlet", "1.17-SNAPSHOT"),
974
975                 // Jersey needs to be started before the northbound application
976                 // bundles, using a lower start level
977                 mavenBundle("com.sun.jersey", "jersey-client", "1.17"),
978                 mavenBundle("com.sun.jersey", "jersey-server", "1.17")
979                         .startLevel(2),
980                 mavenBundle("com.sun.jersey", "jersey-core", "1.17")
981                         .startLevel(2),
982                 mavenBundle("com.sun.jersey", "jersey-json", "1.17")
983                         .startLevel(2), junitBundles());
984     }
985 }