Candela Technologies Logo
 
http://www.candelatech.com
sales@candelatech.com
+1 360 380 1618 [PST, GMT -8]
Network Testing and Emulation Solutions

Querying the LANforge GUI for JSON Data

Goal: Learn how to configure and query the LANforge GUI for JSON formatted data.

The LANforge GUI (as of release 5.3.6) can be configured to start a lightweight web service listener that can provide data about ports and layer-3 connections. This service can be queried with with any browser or AJAX connection. This feature promises to provide a number of benefits:

  • More rapid polling: using CLI scripts to poll ports on the LANforge manager can add stress and contention to the LANforge manager; polling the GUI will not tax your test scenario.
  • Expanded array of data: the views found in the GUI, like Port Mgr, and Layer-3 tabs, can be represented in JSON format.
  • GUI client synthesized data: many columns in the GUI tabs are synthesized during traffic generation and are not available through the CLI scripting API.
  • Reduced effort when integrating with third party test libraries: many other testing libraries expect JSON formatted input.

Present and potential drawbacks of the GUI JSON data feature:

  • Introductory state: the JSON views/schema of the objects is at a demonstation state. It is likely to change with the next release of LANforge, for example, the JSON objects in 5.3.7 probaby won't match 5.3.6.
  • JSON Features are compiled into the LANforge GUI from Java sources. Adding or extending JSON features is not as simple as adding another Groovy script. We're concerned that Groovy plugins will not perform as well. If you are interested in Groovy plugins that provide JSON data, please discuss your needs with us.
  • Initially limited data views: in 5.3.6, we are providing this as a proof of concept and have chosen to display only data from the Port Manager, Layer-3 Connections, and Layer-3 Endpoints tabs. As requirements develop, we'll develop more data views.

GUI Settings

The LANforge GUI is started using a script (lfclient.bash or lfclient.bat). From a terminal, we call that script with the -httpd switch. By default the GUI will listen on port 8080:

 $ cd /home/lanforge
 $  ./lfclient.bash -httpd

You can specify the port to listen on:

 $ cd /home/lanforge
 $  ./lfclient.bash -httpd 3210

There is not a graphical gui preference to set for the feature at this time.

Example Query

Status

From the terminal we can query the port to find a basic message from the GUI:

 $ curl -sqv http://localhost:8080/
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Tue, 2 May 2017 21:22:57 GMT
< Connection: keep-alive
< Content-Length: 461
<
* Connection #0 to host localhost left intact
"text":"These urls are presently available",
"mappings":{"":"(This page) Provides status and configuration.","/Port/Index":"List of ports in the PortManager tab.","/PortTab":"List of ports in the PortManager tab.","/Layer3/Calc":"Show Layer3 Endpoint calculations","/Port/Calc":"Show port calculations.","/Layer3/Index":"List of ports in the Layer3 tab","/":"(This page) Provides status and configuration."}[{"handler":"candela.lanforge.HttpStatus"},{"uri":""}]

Parsing Results

JSON formatted text is pretty difficult to read, so you might like to know two different utilities that can help you look at it: jq and jsonlint.

Installing and using jq

On Fedora, install jq:

 $ sudo dnf install -y jq

On Ubuntu, install jq:

 $ sudo apt install -y jq

Now we can perform a query:

 $ curl -sq http://localhost:8080/ | jq
[
  {
    "handler": "candela.lanforge.HttpStatus"
  },
  {
    "uri": ""
  },
  {
    "text": "These urls are presently available"
  },
  {
    "mappings": {
      "": "(This page) Provides status and configuration.",
      "/Port/Index": "List of ports in the PortManager tab.",
      "/PortTab": "List of ports in the PortManager tab.",
      "/Layer3/Calc": "Show Layer3 Endpoint calculations",
      "/Port/Calc": "Show port calculations.",
      "/Layer3/Index": "List of ports in the Layer3 tab",
      "/": "(This page) Provides status and configuration."
    }
  }
]

Validating with jsonlint

On Fedora, install php-jsonlint:

 $ sudo dnf install -y php-jsonlint

On Ubuntu, install jsonlint:

 $ sudo apt install -y jsonlint

Running jsonlint-php is not nearly as exciting:

 $ curl -sq http://localhost:8080/ | jsonlint-php
Valid JSON

Data Views

Ports

/Port/Index
Provides a digest of ports and their state:
 $ curl -sq http://localhost:8080/Port/Index
[{"handler":"candela.lanforge.HttpPortIndex"},{"uri":"Port/Index"},
{"header":["eid","name","phantom","down"]},
{"data":[
          ["1.0.0","eth0","false","false"],
          ["1.1.0","eth0","false","false"],
          ["1.2.0","eth0","false","false"],
          ["1.1.1","eth1","false","false"],
          ["1.2.1","eth1","false","false"],
          ["1.1.2","wiphy0","false","false"],
          ["1.2.2","wiphy0","false","false"],
          ["1.1.3","wiphy1","false","false"],
          ["1.2.3","wiphy1","false","false"],
          ["1.1.4","wiphy2","false","false"],
          ["1.2.4","wiphy2","false","false"],
          ["1.1.5","wlan0","false","true"],
          ["1.2.5","wlan0","false","false"],
          ["1.1.6","wlan1","false","true"],
          ["1.2.6","wlan1","false","false"],
          ["1.1.7","wlan2","false","true"],
          ["1.2.7","wlan2","false","false"],
          ["1.1.8","vap100","false","false"],
          ["1.1.9","vap110","false","false"],
          ["1.1.10","vap120","false","false"],
          ["1.1.11","b100","false","false"],
          ["1.1.12","r100a","false","false"],
          ["1.1.13","r100b","false","false"],
          ["1.1.14","r101a","false","false"],
          ["1.1.15","r101b","false","false"]
]}]
/PortTab

PortTab provides data found in Port Mgr tab. The configuration of the Port Mgr tab (Add-Remove Table Columns) will show in this response.

 $ curl -sq "http://localhost:8080/PortTab"
[{"handler":"candela.lanforge.HttpPortTab"},
{"uri":"PortTab"},
{"header":["Port","Phantom","Down","Parent Dev","Device","IP","RX Bytes","AP","Connections","SSID","Gateway IP","MAC","bps RX","bps TX"]},
{"data":[["1.1.00","false","false","","eth0","192.168.100.26","4,097,857,554","","0","","192.168.100.1","00:90:0b:29:06:f8","109,695","340,974"],
  ["1.1.01","false","false","","eth1","10.26.1.1","1,651,636,119,416","","0","","0.0.0.0","00:90:0b:29:06:f9","0","0"],
  ["1.1.02","false","false","","wiphy0","0.0.0.0","3,217,297,499","","0","","0.0.0.0","00:0e:8e:4e:5a:56","2,794","106"],
  ["1.1.03","false","false","","wiphy1","0.0.0.0","4,462,247,651","","0","","0.0.0.0","00:0e:8e:4e:57:91","20,632","230"],
  ["1.1.04","false","false","","wiphy2","0.0.0.0","4,294,994,299","","0","","0.0.0.0","00:0e:8e:3e:27:5b","21,066","268"],
  ["1.1.05","false","true","wiphy0","wlan0","0.0.0.0","0","Not-Associated","0","","0.0.0.0","00:0e:8e:4e:5a:56","0","0"],
  ["1.1.06","false","true","wiphy1","wlan1","0.0.0.0","0","Not-Associated","0","","0.0.0.0","00:0e:8e:4e:57:91","0","0"],
  ["1.1.11","false","false","","b100","10.26.4.1","9,128,638,764","","0","","0.0.0.0","00:0e:8e:c9:6f:5b","0","0"],
  ["1.1.12","false","false","r100b","r100a","0.0.0.0","850,541,375,484","","0","","0.0.0.0","a6:95:6a:90:14:1e","0","131"],
  ["1.1.13","false","false","r100a","r100b","10.26.4.13","845,854,312,922","","0","","10.26.4.1","6a:c4:3f:13:13:dc","125","0"],
  ["1.1.14","false","false","r101b","r101a","0.0.0.0","845,854,004,368","","0","","0.0.0.0","62:e7:56:85:97:1b","0","190"],
  ["1.1.15","false","false","r101a","r101b","10.26.4.14","850,541,680,988","","0","","10.26.4.1","e2:31:8e:2e:b9:86","194","0"],
  ["1.2.0","false","false","","eth0","192.168.100.42","1,285,507,529","","0","","192.168.100.1","00:90:0b:40:64:c6","5,331","85,739"],
  ["1.2.1","false","false","","eth1","10.26.1.2","11,741,736,214","","0","","10.26.1.1","00:90:0b:40:64:c7","0","0"],
  ["1.2.2","false","false","","wiphy0","0.0.0.0","656,227,422,653","","0","","0.0.0.0","00:0e:8e:43:36:e9","6,276","6"],
  ["1.2.3","false","false","","wiphy1","0.0.0.0","591,417,884,328","","0","","0.0.0.0","00:0e:8e:43:3a:62","7,391","6"],
  ["1.2.4","false","false","","wiphy2","0.0.0.0","564,127,688,199","","0","","0.0.0.0","00:0e:8e:43:37:63","7,002","6"],
  ["1.1.07","false","true","wiphy2","wlan2","0.0.0.0","0","Not-Associated","0","","0.0.0.0","00:0e:8e:3e:27:5b","0","0"],
  ["1.1.08","false","false","wiphy0","vap100","0.0.0.0","3,071,654,503","","0","jedtest-40","0.0.0.0","00:0e:8e:ef:49:56","0","0"],
  ["1.1.09","false","false","wiphy1","vap110","0.0.0.0","3,071,656,850","","0","jedtest-36","0.0.0.0","00:0e:8e:d1:b1:91","0","0"],
  ["1.1.10","false","false","wiphy2","vap120","0.0.0.0","3,071,657,075","","0","jedtest-44","0.0.0.0","00:0e:8e:c9:6f:5b","0","0"],
  ["1.2.5","false","false","wiphy0","wlan0","10.26.4.12","548,247,399,423","00:0E:8E:EF:49:56","9","jedtest-40","10.26.4.1","00:0e:8e:43:36:e9","0","0"],
  ["1.2.6","false","false","wiphy1","wlan1","10.26.4.11","548,246,490,732","00:0E:8E:D1:B1:91","12","jedtest-36","10.26.4.1","00:0e:8e:43:3a:62","0","0"],
  ["1.2.7","false","false","wiphy2","wlan2","10.26.4.10","548,245,803,601","00:0E:8E:C9:6F:5B","9","jedtest-44","10.26.4.1","00:0e:8e:43:37:63","0","0"]
]}]
/Port/Calc

The path provides port calculations similar to the Port Calculations window. It requires one or more EID parameters. You can specify the eids as a comma separated list: ?eid=1.2.3,1.2.4 or a series of query parameters: ?eid=1.2.3&eid=1.2.4

curl -sq "http://localhost:8080/Port/Calc?eid=1.1.15"
[{"handler":"candela.lanforge.HttpPortTabSsData"},
{"uri":"Port/Calc"},
{"1.1.15":
  {"TimeStamp":"1493767726537",
  "Name":"r101b",
  "EID":"1.1.15",
  "Resource":"jedtest",
  "tx_pkts":"48631077",
  "rx_pkts":"48697662",
  "tx_bytes":"845854005290",
  "rx_bytes":"850541798136",
  "tx_errors":"0",
  "rx_errors":"0",
  "tx_dropped":"0",
  "rx_dropped_pkts":"0",
  "rx_multicast":"0",
  "rx_collisions":"0",
  "rx_length":"0",
  "rx_overrun":"0",
  "rx_crc":"0",
  "rx_frame":"0",
  "rx_fifo":"0",
  "rx_missed":"0",
  "tx_aborted":"0",
  "tx_carrier":"0",
  "tx_fifo":"0",
  "tx_heartbeat":"0",
  "tx_window":"0",
  "rx_signal":"0",
  "link_speed":"10000000000",
  "rx_link_speed":"10000000000",
  "frequency":"0",
  "portal_login_ok":"0",
  "portal_login_fail":"0",
  "portal_logout_ok":"0",
  "portal_logout_fail":"0",
  "dhcp_neg_ms":"1699",
  "conn_count":"0",
  "last_conn_ms":"0",
  "connect_duration_us":"0",
  "disconn_duration_us":"0",
  "anqp_duration_us":"0",
  "4way_duration_us":"01493767729321"}
}]
        

Connections

Layer-3 information is organized in a similar way.

/Layer3/Index
This path provides a digest of layer 3 connections and their status.
 $ curl -sq 'http://localhost:8080/Layer3/Index'
[{"handler":"candela.lanforge.HttpLayer3Index"},
{"uri":"Layer3/Index"},
{"header":["Eid","Name","State","EidA","EidB"]},
{"data":[
  ["2.1","u-e1-w0","Stopped","1.2.5.2","1.2.1.1"],
  ["3.1","u-e1-w1","Stopped","1.2.6.4","1.2.1.3"],
  ["4.1","u-e1-w2","Stopped","1.2.7.6","1.2.1.5"],
  ["7.1","test-rr-10G","Stopped","1.1.15.12","1.1.13.11"]
]}]
/Layer3/Calc

This path provides data similar to the Layer-3 Calculations window. Notice that the pattern of the EID for connections is ordered as [CX_INDEX].[TYPE], unlike ports that are identified like [SHELF].[RESOURCE].[PORT_INDEX] This [TYPE] identifier should correspond to the end of the EID for endpoints, which are [SHELF].[RESOURCE].[PORT_INDEX].[ENDPOINT_INDEX].[TYPE]. The following example queries endpoint data for two connections, 2.1 and 4.1:

$ curl -sq "http://localhost:8080/Layer3/Calc?eid=2.1,4.1"
[{"handler":"candela.lanforge.HttpLayer3TabSsData"},
{"uri":"Layer3/Calc"},
{"header":[
  "TimeStamp","Name","EID","CX-Name","IS_RUNNING","tx_rate","bps_tx_rate_3s","rx_rate","bps_rx_rate_3s","rx_drop%x1000","tx_pkts","rx_pkts","tx_bytes","rx_bytes","rx_dropped_pkts","rx_dup_pkts","rx_ooo_pkts","rx_wrong_dev","rx_crc_failed","rx_bit_errors","TCP-RTX","conn_timeouts","conn_established","conn_active","tcp_CWND","min_conn_duration_ms","max_conn_duration_ms","min_reconn_pause_ms","max_reconn_pause_ms","pattern","min_pkt_size","max_pkt_size","min_tx_rate","max_tx_rate","running_for","last_report","destination_addr","source_addr","min_latency","avg_latency","max_latency","box_width","lat_0","lat_1","lat_2","lat_3","lat_4","lat_5","lat_6","lat_7","lat_8","lat_9","lat_10","lat_11","lat_12","lat_13","lat_14","lat_15","min_rt_latency","avg_rt_latency","max_rt_latency","rt_box_width","rt_lat_0","rt_lat_1","rt_lat_2","rt_lat_3","rt_lat_4","rt_lat_5","rt_lat_6","rt_lat_7","rt_lat_8","rt_lat_9","rt_lat_10","rt_lat_11","rt_lat_12","rt_lat_13","rt_lat_14","rt_lat_15","min_drop_amt","avg_drop_amt","max_drop_amt","drop_box_width","drop_amt_0","drop_amt_1","drop_amt_2","drop_amt_3","drop_amt_4","drop_amt_5","drop_amt_6","drop_amt_7","drop_amt_8","drop_amt_9","drop_amt_10","drop_amt_11","drop_amt_12","drop_amt_13","drop_amt_14","drop_amt_15","RptTimer","files_replayed","Avg-Jitter","rx_pkts_ll","tx_pkts_ll","rx_bytes_ll","tx_bytes_ll","cx_dropped_pkts","Rx-First-Pkt-ms","min_gap","avg_gap","max_gap","gap_box_width","gap_0","gap_1","gap_2","gap_3","gap_4","gap_5","gap_6","gap_7","gap_8","gap_9","gap_10","gap_11","gap_12","gap_13","gap_14","gap_15"
]},
{
  "2.1":{
    "tx_data":[
      "1493770429164","u-e1-w0-A","1.2.1.1.1","u-e1-w0","false","9990794","10010814","52973","53077","0","1886","10","2776192","14720","0","0","0","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","10000000","10000000","2","0","10.26.4.12:33008","10.26.1.2:33007","0","0.9","1","1","10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","1.9","2","1","10","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0.0","0","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1000","0","0","10","1886","15140","2855404","0","211","206","2150346.9","21501576","1","4","0","3","3","0","0","0","0","0","0","0","0","0","0","0","0"
    ],
    "rx_data":[
      "1493770429164","u-e1-w0-B","1.2.5.2.1","u-e1-w0","false","52973","53077","9985497","10005506","53","10","1885","14720","2774720","0","0","0","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","56000","56000","2","0","10.26.1.2:33007","10.26.4.12:33008","0","1.148","4","1","1583","293","9","0","0","0","0","0","0","0","0","0","0","0","0","0","0","2.148","5","1","794","773","139","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0.0","0","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1000","0","0","1885","10","2853890","15140","1","2","0","1.181","21501351","1","1389","388","106","1","1","0","0","0","0","0","0","0","0","0","0","0"
    ]
  },
  {
    "4.1":{
      "tx_data":[
        "1493748925591","u-e1-w2-A","1.2.1.5.1","u-e1-w2","false","9999315","10008210","55994","59453","10","362118446","2027796","533038352512","2984915712","231","0","3","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","10000000","10000000","426459","0","10.26.4.10:33006","10.26.1.2:33005","0","0.642","6","1","2017386","5956","2618","1251","313","118","70","52","23","4","1","2","2","0","0","0","0","1.647","7","1","780042","1224907","18988","2557","902","183","92","75","38","7","1","2","2","0","0","0","0","2.783","0","1","46","12","16","8","1","0","0","0","0","0","0","0","0","0","0","0","1000","0","0","2027796","362118446","3070083144","548247327244","206","212","205","210.29","216","1","247795","320437","447206","439229","405276","72556","32087","36076","27046","43","29","16","0","0","0","0"
      ],
      "rx_data":[
        "1493748925591","u-e1-w2-B","1.2.7.6.1","u-e1-w2","false","55999","59453","9999263","10012176","0","2028002","362116541","2985218944","533035548352","70202","0","812","0","0","0","0","0","1","0","0","4294967295","0","0","0","INCREASING","1472","1472","56000","56000","426459","0","10.26.1.2:33005","10.26.4.10:33006","0","1.085","16","1","339286622","21098161","1179805","356224","91200","39017","28599","19845","12984","3469","611","4","0","0","0","0","0","1.938","16","1","134861468","211216818","14792147","870910","218717","67800","39273","28252","15267","4075","819","816","0","0","0","0","0","66.701","0","1","41","10","22","41","88","145","223","167","93","26","19","0","0","0","0","0","1000","0","0","362116541","2028002","548244443074","3070395028","1905","2","0","1.171","16","1","274233813","75937349","11696502","219321","25431","2541","1040","327","173","42","1","0","0","0","0","0"
      ]
    }}]

Candela  Technologies, 2417 Main Street, Suite 201, Ferndale, WA 98248, USA
www.candelatech.com | sales@candelatech.com | +1.360.380.1618
Google+ | Facebook | LinkedIn | Blog