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