Developing lightweight computation at the DSG edge

Commit 2a27c5dd authored by Roger Pueyo Centelles's avatar Roger Pueyo Centelles
Browse files

Arrange source code



Move CNML- and Antidote's API-related types and functions to separate
packages.
Signed-off-by: default avatarRoger Pueyo Centelles <roger.pueyo@guifi.net>
parent c37fd8d5
package apidote
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
// Antidote: save an item to a set in a bucket
func AntidoteAddItemToSetInBucket(bucket string, set string, item string) bool {
request := fmt.Sprintf("http://localhost:3000/set/add/%s/%s/%s", bucket, set, item)
response, err := http.Get(request)
errCheck(err)
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(response.Body)
errCheck(err)
restReply := string(bodyBytes)
if restReply == "ok" {
return true
}
}
return false
}
// Antidote: read items from a set in a bucket
func AntidoteReadItemsFromSetInBucket(bucket string, set string) []string {
request := fmt.Sprintf("http://localhost:3000/set/read/%s/%s", bucket, set)
response, err := http.Get(request)
errCheck(err)
var items []string
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(response.Body)
errCheck(err)
err = json.Unmarshal(bodyBytes, &items)
errCheck(err)
}
return items
}
// Antidote: remove an item from a set in a bucket
func AntidoteRemoveItemFromSetInBucket(bucket string, set string, item string) bool {
request := fmt.Sprintf("http://localhost:3000/set/remove/%s/%s/%s", bucket, set, item)
response, err := http.Get(request)
errCheck(err)
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(response.Body)
errCheck(err)
restReply := string(bodyBytes)
if restReply == "ok" {
return true
}
}
return false
}
// Panic on error
func errCheck(e error) {
if e != nil {
panic(e)
}
}
package cnml
import (
"net"
)
// The Cnml struct comprises the whole CNML
type Cnml struct {
Version float32 `xml:"version,attr"`
ServerID int `xml:"server_id,attr"`
ServerURL string `xml:"server_url,attr"`
Generated string `xml:"generated,attr"`
Nodes Node `xml:"node"`
Classes Class `xml:"class"`
Network Network `xml:"network"`
}
// The Class struct contains some details about the CNML itself
type Class struct {
// NodeDescription int `xml:"node_description,attr"`
Mapping string `xml:"mapping,attr"`
NetworkDescription string `xml:"network_description,attr"`
}
// The Network struct summarizes the network in the CNML
type Network struct {
Nodes int `xml:"nodes,attr"`
Devices int `xml:"devices,attr"`
Ap int `xml:"ap,attr"`
Client int `xml:"client,attr"`
Services int `xml:"services,attr"`
Links int `xml:"links,attr"`
Zone Zone `xml:"zone"`
}
// The Zone struct contains a Guifi zone (i.e. a geographical area)
type Zone struct {
ID int `xml:"id,attr"`
ParentID int `xml:"parent_id,attr"`
Title string `xml:"title,attr"`
TimeZone string `xml:"time_zone,attr"`
GraphServer int `xml:"graph_server,attr"`
Created string `xml:"created,attr"`
Updated string `xml:"updated,attr"`
ZoneNodes int `xml:"zone_nodes,attr"`
Box string `xml:"box,attr"`
AccessPoints int `xml:"access_points,attr"`
Clients int `xml:"client,attr"`
Devices int `xml:"devices,attr"`
Services int `xml:"services,attr"`
Links int `xml:"links,attr"`
Nodes []Node `xml:"node"`
Zones []Zone `xml:"zone"`
}
// The Node struct contains a Guifi node (i.e. a network physical location)
type Node struct {
ID int `xml:"id,attr"`
Title string `xml:"title,attr"`
Lat float32 `xml:"lat,attr"`
Lon float32 `xml:"lon,attr"`
AntennaElevation int `xml:"antenna_elevation,attr"`
Status string `xml:"status,attr"`
GraphServer int `xml:"graph_server,attr"`
Created string `xml:"created,attr"`
Updated string `xml:"updated,attr"`
DevicesCount int `xml:"devices,attr"`
ServicesCount int `xml:"services,attr"`
Devices []Device `xml:"device"`
}
// The Device struct contains a Guifi network device (e.g. a router, a switch)
type Device struct {
ID int `xml:"id,attr"`
MainIpv4 string `xml:"mainipv4,attr"`
Title string `xml:"title,attr"`
Type string `xml:"type,attr"`
Status string `xml:"status,attr"`
GraphServer int `xml:"graph_server,attr"`
Created string `xml:"created,attr"`
Updated string `xml:"updated,attr"`
SnmpIndex string `xml:"snmp_index,attr"`
Firmware string `xml:"firmware,attr"`
Name string `xml:"name,attr"`
Interfaces []Interface `xml:"interface"`
Radios Radio `xml:"radio"`
}
// The Interface struct defines an interface of a Guifi network device
type Interface struct {
ID int `xml:"id,attr"`
Type string `xml:"type,attr"`
Mac string `xml:"mac,attr"`
// Ipv4 net.IPAddr `xml:"ipv4,attr"`
Ipv4 string `xml:"ipv4,attr"`
Mask net.IPMask `xml:"mask,attr"`
}
// The Radio struct defines a wireless interface of a Guifi network device
type Radio struct {
ID int `xml:"id,attr"`
DeviceID int `xml:"device_id,attr"`
Ssid string `xml:"ssid,attr"`
Mode string `xml:"mode,attr"`
Protocol string `xml:"protocol,attr"`
Channel int `xml:"channel,attr"`
AntennaGain int `xml:"antenna_gain,attr"`
ClientsAccepted string `xml:"clients_accepted,attr"`
SnmpName string `xml:"snmp_name,attr"`
}
// The DeviceIpv4Adddresses holds the IPv4 addresses of a device
type DeviceIpv4Adddresses struct {
ID int
Addresses []string
}
// The DeviceAddressesServer lists the IPv4 addresses a GraphServer is assigned
type DeviceAddressesServer struct {
ID int
Addresses []string
GraphServer int
}
// You can edit this code!
// Click here and start typing.
package main
import (
......@@ -9,132 +7,15 @@ import (
"flag"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"strconv"
)
// The Cnml struct comprises the whole CNML
type Cnml struct {
Version float32 `xml:"version,attr"`
ServerID int `xml:"server_id,attr"`
ServerURL string `xml:"server_url,attr"`
Generated string `xml:"generated,attr"`
Nodes Node `xml:"node"`
Classes Class `xml:"class"`
Network Network `xml:"network"`
}
// The Class struct contains some details about the CNML itself
type Class struct {
// NodeDescription int `xml:"node_description,attr"`
Mapping string `xml:"mapping,attr"`
NetworkDescription string `xml:"network_description,attr"`
}
// The Network struct summarizes the network in the CNML
type Network struct {
Nodes int `xml:"nodes,attr"`
Devices int `xml:"devices,attr"`
Ap int `xml:"ap,attr"`
Client int `xml:"client,attr"`
Services int `xml:"services,attr"`
Links int `xml:"links,attr"`
Zone Zone `xml:"zone"`
}
// The Zone struct contains a Guifi zone (i.e. a geographical area)
type Zone struct {
ID int `xml:"id,attr"`
ParentID int `xml:"parent_id,attr"`
Title string `xml:"title,attr"`
TimeZone string `xml:"time_zone,attr"`
GraphServer int `xml:"graph_server,attr"`
Created string `xml:"created,attr"`
Updated string `xml:"updated,attr"`
ZoneNodes int `xml:"zone_nodes,attr"`
Box string `xml:"box,attr"`
AccessPoints int `xml:"access_points,attr"`
Clients int `xml:"client,attr"`
Devices int `xml:"devices,attr"`
Services int `xml:"services,attr"`
Links int `xml:"links,attr"`
Nodes []Node `xml:"node"`
Zones []Zone `xml:"zone"`
}
// The Node struct contains a Guifi node (i.e. a network physical location)
type Node struct {
ID int `xml:"id,attr"`
Title string `xml:"title,attr"`
Lat float32 `xml:"lat,attr"`
Lon float32 `xml:"lon,attr"`
AntennaElevation int `xml:"antenna_elevation,attr"`
Status string `xml:"status,attr"`
GraphServer int `xml:"graph_server,attr"`
Created string `xml:"created,attr"`
Updated string `xml:"updated,attr"`
DevicesCount int `xml:"devices,attr"`
ServicesCount int `xml:"services,attr"`
Devices []Device `xml:"device"`
}
// The Device struct contains a Guifi network device (e.g. a router, a switch)
type Device struct {
ID int `xml:"id,attr"`
MainIpv4 string `xml:"mainipv4,attr"`
Title string `xml:"title,attr"`
Type string `xml:"type,attr"`
Status string `xml:"status,attr"`
GraphServer int `xml:"graph_server,attr"`
Created string `xml:"created,attr"`
Updated string `xml:"updated,attr"`
SnmpIndex string `xml:"snmp_index,attr"`
Firmware string `xml:"firmware,attr"`
Name string `xml:"name,attr"`
Interfaces []Interface `xml:"interface"`
Radios Radio `xml:"radio"`
}
// The Interface struct defines an interface of a Guifi network device
type Interface struct {
ID int `xml:"id,attr"`
Type string `xml:"type,attr"`
Mac string `xml:"mac,attr"`
// Ipv4 net.IPAddr `xml:"ipv4,attr"`
Ipv4 string `xml:"ipv4,attr"`
Mask net.IPMask `xml:"mask,attr"`
}
// The Radio struct defines a wireless interface of a Guifi network device
type Radio struct {
ID int `xml:"id,attr"`
DeviceID int `xml:"device_id,attr"`
Ssid string `xml:"ssid,attr"`
Mode string `xml:"mode,attr"`
Protocol string `xml:"protocol,attr"`
Channel int `xml:"channel,attr"`
AntennaGain int `xml:"antenna_gain,attr"`
ClientsAccepted string `xml:"clients_accepted,attr"`
SnmpName string `xml:"snmp_name,attr"`
}
// The DeviceIpv4Adddresses holds the IPv4 addresses of a device
type DeviceIpv4Adddresses struct {
ID int
Addresses []string
}
// The DeviceAddressesServer lists the IPv4 addresses a GraphServer is assigned
type DeviceAddressesServer struct {
ID int
Addresses []string
GraphServer int
}
"lightkone.guifi.net/uc-monitor-go-test/apidote"
"lightkone.guifi.net/uc-monitor-go-test/cnml"
)
//Default settings and descriptions
var cnmlFile = "cnml.xml"
var cnmlFile = "../assets/cnml/upc.xml"
var cnmlFileHelp = "Filename of the XML file containing the CNML information of a zone"
func initialize() {
......@@ -159,7 +40,7 @@ func main() {
defer xmlFile.Close()
b, _ := ioutil.ReadAll(xmlFile)
var GuifiCnml Cnml
var GuifiCnml cnml.Cnml
err = xml.Unmarshal(b, &GuifiCnml)
errCheck(err)
......@@ -213,13 +94,13 @@ func main() {
dfile.WriteString(string(jdevices))
}
var devsadds []DeviceIpv4Adddresses
var devsaddssrvs []DeviceAddressesServer
var devsadds []cnml.DeviceIpv4Adddresses
var devsaddssrvs []cnml.DeviceAddressesServer
// Export only the bare minimum information needed for the monitoring code
for _, v := range alldevices {
var devadd DeviceIpv4Adddresses
var devaddsrv DeviceAddressesServer
var devadd cnml.DeviceIpv4Adddresses
var devaddsrv cnml.DeviceAddressesServer
devadd.ID = v.ID
devaddsrv.ID = v.ID
......@@ -379,9 +260,9 @@ func main() {
}
// Get an array with all the nodes in a zone and its subzones, recursively
func getNodesInZone(zone Zone) []Node {
func getNodesInZone(zone cnml.Zone) []cnml.Node {
var nodes []Node
var nodes []cnml.Node
//Add the nodes directly placed in the zone
nodes = zone.Nodes
......@@ -396,7 +277,7 @@ func getNodesInZone(zone Zone) []Node {
}
// Return an ints array containing, first, the node ID, then the zones ID path
func getNodeZonesPath(node Node, zone Zone) []int {
func getNodeZonesPath(node cnml.Node, zone cnml.Zone) []int {
var path []int
......@@ -419,7 +300,7 @@ func getNodeZonesPath(node Node, zone Zone) []int {
// Return the ID of the graph server the a device is assigned to, either
// directly or by inheritance in the node or in the zone
func getGraphServerOfDeviceInZone(device Device, zone Zone) int {
func getGraphServerOfDeviceInZone(device cnml.Device, zone cnml.Zone) int {
//Check if the device has a graph server directly assigned
if device.GraphServer > 0 {
......@@ -441,7 +322,7 @@ func getGraphServerOfDeviceInZone(device Device, zone Zone) int {
// Return the ID of the graph server a node is assigned to, either directly
// or by inheritance in the zone
func getGraphServerOfNodeInZone(node Node, zone Zone) int {
func getGraphServerOfNodeInZone(node cnml.Node, zone cnml.Zone) int {
if node.GraphServer > 0 {
return node.GraphServer
......@@ -466,7 +347,7 @@ func getGraphServerOfNodeInZone(node Node, zone Zone) int {
// Return the ID of the graph server a zone is assigned to, either directly
// or by inheritance in the zone
func getGraphServerOfZoneInZone(thiszone Zone, zone Zone) int {
func getGraphServerOfZoneInZone(thiszone cnml.Zone, zone cnml.Zone) int {
if thiszone.GraphServer > 0 {
return thiszone.GraphServer
......@@ -488,7 +369,7 @@ func getGraphServerOfZoneInZone(thiszone Zone, zone Zone) int {
// Get an array with all the IPv4 addresses assigned to a device, being the
// first one its main IPv4 address
func getIpv4AddressesInDevice(device Device) []string {
func getIpv4AddressesInDevice(device cnml.Device) []string {
var ipv4Addresses []string
......@@ -508,9 +389,9 @@ func getIpv4AddressesInDevice(device Device) []string {
}
// Get an array with all the devices in a zone (i.e. in all the zone's nodes)
func getDevicesInZone(zone Zone) []Device {
func getDevicesInZone(zone cnml.Zone) []cnml.Device {
var devices []Device
var devices []cnml.Device
for _, v := range getNodesInZone(zone) {
for _, w := range v.Devices {
......@@ -524,7 +405,7 @@ func getDevicesInZone(zone Zone) []Device {
// Propagate the zone's graph server to the zones and subzones inside the zone,
// recursively, and to the nodes in the zone, in case they don't have a graph
// server assigned
func propagateGraphServerInZone(zone Zone) Zone {
func propagateGraphServerInZone(zone cnml.Zone) cnml.Zone {
//First, propagate the zone's graph server to the nodes in the zone
for k, v := range zone.Nodes {
......@@ -547,7 +428,7 @@ func propagateGraphServerInZone(zone Zone) Zone {
// Propagate the node's graph server to the devices of the node in case they
// don't have a graph_server assigned
func propagateGraphServerInNode(node Node) Node {
func propagateGraphServerInNode(node cnml.Node) cnml.Node {
for k, v := range node.Devices {
if !(v.GraphServer > 0) {
node.Devices[k].GraphServer = node.GraphServer
......@@ -558,9 +439,9 @@ func propagateGraphServerInNode(node Node) Node {
// Get an array with all the zones and subzones inside a zone, by scanning it
// recursively, including the zone itself
func getZonesInZoneInc(zone Zone) []Zone {
func getZonesInZoneInc(zone cnml.Zone) []cnml.Zone {
var zones []Zone
var zones []cnml.Zone
zones = append(zones, zone)
zones = append(zones, getZonesInZoneExc(zone)...)
......@@ -570,9 +451,9 @@ func getZonesInZoneInc(zone Zone) []Zone {
// Get an array with all the zones and subzones inside a zone, by scanning it
// recursively, not including the zone itself
func getZonesInZoneExc(zone Zone) []Zone {
func getZonesInZoneExc(zone cnml.Zone) []cnml.Zone {
var zones []Zone
var zones []cnml.Zone
for _, v := range zone.Zones {
zones = append(zones, getZonesInZoneInc(v)...)
......@@ -582,18 +463,18 @@ func getZonesInZoneExc(zone Zone) []Zone {
}
// Remove a device by its ID from Antidote using João's REST server
func removeDeviceFromAntidote(device DeviceIpv4Adddresses) bool {
return antidoteRemoveItemFromSetInBucket("guifi", "devices", fmt.Sprintf("%d", device.ID))
func removeDeviceFromAntidote(device cnml.DeviceIpv4Adddresses) bool {
return apidote.AntidoteRemoveItemFromSetInBucket("guifi", "devices", fmt.Sprintf("%d", device.ID))
}
// Read all the devices from Antidote using João's REST server
func readDevicesFromAntidote() []DeviceIpv4Adddresses {
var devices []DeviceIpv4Adddresses
func readDevicesFromAntidote() []cnml.DeviceIpv4Adddresses {
var devices []cnml.DeviceIpv4Adddresses
for _, v := range antidoteReadItemsFromSetInBucket("guifi", "devices") {
for _, v := range apidote.AntidoteReadItemsFromSetInBucket("guifi", "devices") {
thisDevID, err := strconv.Atoi(v)
errCheck(err)
var thisDev DeviceIpv4Adddresses
var thisDev cnml.DeviceIpv4Adddresses
thisDev.ID = thisDevID
devices = append(devices, thisDev)
}
......@@ -602,9 +483,9 @@ func readDevicesFromAntidote() []DeviceIpv4Adddresses {
}
// Read all the devices from Antidote using João's REST server
func readDeviceIpv4AddressesFromAntidote(device DeviceIpv4Adddresses) DeviceIpv4Adddresses {
func readDeviceIpv4AddressesFromAntidote(device cnml.DeviceIpv4Adddresses) cnml.DeviceIpv4Adddresses {
for _, v := range antidoteReadItemsFromSetInBucket("guifi", fmt.Sprintf("device-%d", device.ID)) {
for _, v := range apidote.AntidoteReadItemsFromSetInBucket("guifi", fmt.Sprintf("device-%d", device.ID)) {
device.Addresses = append(device.Addresses, v)
}
......@@ -612,108 +493,21 @@ func readDeviceIpv4AddressesFromAntidote(device DeviceIpv4Adddresses) DeviceIpv4
}
// Save a device ID to Antidote using João's REST server
func saveDeviceToAntidote(device DeviceIpv4Adddresses) bool {
return antidoteAddItemToSetInBucket("guifi", "devices", fmt.Sprintf("%d", device.ID))
func saveDeviceToAntidote(device cnml.DeviceIpv4Adddresses) bool {
return apidote.AntidoteAddItemToSetInBucket("guifi", "devices", fmt.Sprintf("%d", device.ID))
}
// Save an IPv4 address to a device
func saveIpv4addresToDeviceToAntidote(device DeviceIpv4Adddresses, address string) bool {
return antidoteAddItemToSetInBucket("guifi", fmt.Sprintf("device-%d", device.ID), address)
}
func removeIpv4addressFromDevice(device DeviceIpv4Adddresses, address string) bool {
return antidoteRemoveItemFromSetInBucket("guifi", fmt.Sprintf("device-%d", device.ID), address)
}
// // Save a device ID and an IPv4 address to Antidote using João's REST server
// func saveDeviceIpv4ToAntidote(ID int, Ipv4 string) bool {
// request := fmt.Sprintf("http://localhost:3000/set/add/guifi/device-%d/%s", ID, Ipv4)
// //fmt.Println("Saving address", Ipv4, "in device", ID, "to AntidoteDB")
// response, err := http.Get(request)
// errCheck(err)
//
// //fmt.Println(response)
// defer response.Body.Close()
//
// if response.StatusCode == http.StatusOK {
// bodyBytes, err := ioutil.ReadAll(response.Body)
// errCheck(err)
// restReply := string(bodyBytes)
//
// if restReply == "ok" {
// //fmt.Println("Success!")
// }
// return true
// }
//
// return false
// }
// Antidote: save an item to a set in a bucket
func antidoteAddItemToSetInBucket(bucket string, set string, item string) bool {
request := fmt.Sprintf("http://localhost:3000/set/add/%s/%s/%s", bucket, set, item)
response, err := http.Get(request)
errCheck(err)
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(response.Body)
errCheck(err)
restReply := string(bodyBytes)
if restReply == "ok" {
return true
}
}
return false
}
// Antidote: read items from a set in a bucket
func antidoteReadItemsFromSetInBucket(bucket string, set string) []string {
request := fmt.Sprintf("http://localhost:3000/set/read/%s/%s", bucket, set)
response, err := http.Get(request)
errCheck(err)
var items []string
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(response.Body)
errCheck(err)
err = json.Unmarshal(bodyBytes, &items)
errCheck(err)
}
return items
func saveIpv4addresToDeviceToAntidote(device cnml.DeviceIpv4Adddresses, address string) bool {
return apidote.AntidoteAddItemToSetInBucket("guifi", fmt.Sprintf("device-%d", device.ID), address)
}
// Antidote: remove an item from a set in a bucket
func antidoteRemoveItemFromSetInBucket(bucket string, set string, item string) bool {
request := fmt.Sprintf("http://localhost:3000/set/remove/%s/%s/%s", bucket, set, item)
response, err := http.Get(request)
errCheck(err)
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(response.Body)
errCheck(err)
restReply := string(bodyBytes)
if restReply == "ok" {
return true
}
}
return false
func removeIpv4addressFromDevice(device cnml.DeviceIpv4Adddresses, address string) bool {
return apidote.AntidoteRemoveItemFromSetInBucket("guifi", fmt.Sprintf("device-%d", device.ID), address)
}
// Check if an int item is in an ints array
fu