Developing lightweight computation at the DSG edge

Commit 8ee2b304 authored by Roger Pueyo Centelles's avatar Roger Pueyo Centelles
Browse files

Pending changes?


Signed-off-by: Roger Pueyo Centelles's avatarRoger Pueyo Centelles <rpueyo@ac.upc.edu>
parent 0a052624
This diff is collapsed.
This diff is collapsed.
<div id="assign"></div>
<script src="./svg.min.js"></script>
<script src="/tmp/out.json"></script>
<script>
setTimeout(function(){
window.location.reload(true);
}, 2000);
// data={"devices":["35578","35580","41236","52800","53410","55625","58266","66287","67954","69514","74780","74943","75036","75038","75651","92844"],"monitors":["1","2","3","444"],"assignations":[{"device":"35578","monitors":["2"]},{"device":"35580","monitors":["1"]},{"device":"41236","monitors":["1"]},{"device":"52800","monitors":["1","2"]},{"device":"53410","monitors":["2"]},{"device":"55625","monitors":["1","2"]},{"device":"58266","monitors":["2"]},{"device":"66287","monitors":null},{"device":"67954","monitors":["1","2"]},{"device":"69514","monitors":["1","2"]},{"device":"74780","monitors":["1"]},{"device":"74943","monitors":["1","2"]},{"device":"75036","monitors":["1","2"]},{"device":"75038","monitors":null},{"device":"75651","monitors":["2"]},{"device":"92844","monitors":["1"]}]}
//
// dsata={"devices":["35578","35580","41236","52800","53410","55625","58266","66287","67954","69514","74780","74943","75036","75038","75651","92844"],"monitors":["1","2"],"assignations":[{"device":"35578","monitors":["2"]},{"device":"35580","monitors":["1"]},{"device":"92844","monitors":["1"]}]}
function posItemInArray(theItem, theArray) {
if (theItem !== null && theArray !== null && theArray.length > 0) {
for (k=0; k<theArray.length; k++) {
if (theItem == theArray[k]) {
return k
}
}
}
return -1
}
var wwidth = window.innerWidth -15;
if (wwidth < 400) {
wwidth = 400
}
var wheight = window.innerHeight -15;
if (wheight < 400) {
wheight = 400
}
var rwidth = 150
var rheight = 32
var rspace = 3
var rdist = rheight+rspace
var monX = wwidth-rwidth
var fontsize ="12px"
var dheight = rdist*Math.max(data.devices.length, data.monitors.length)
var drawing = SVG("assign").size(wwidth,dheight)
var devsRects = new Array()
var devsTexts = new Array()
var monsRects = new Array()
var monsTexts = new Array()
var assignsLines = new Array()
if (data.devices !== null ) {
for (i = 0; i < data.devices.length; i++) {
var rect = drawing.rect(rwidth, rheight).attr({
'fill':"#e6ffe6",
'stroke':"gray",
'stroke-width':"2px"
})
rect.y(rdist*i)
devsRects.push(rect)
var text = drawing.text(data.devices[i]).font({
'anchor':"middle",
'size':fontsize
})
text.x(rwidth/2)
text.y(rdist/4+rdist*i)
devsTexts.push(text)
}
}
if (data.monitors !== null ) {
for (i = 0; i < data.monitors.length; i++) {
var rect = drawing.rect(rwidth, rheight).attr({
'fill':"#e6f2ff",
'stroke':"gray",
'stroke-width':"2px"
})
rect.x(monX)
rect.y((dheight/Math.max(1,data.monitors.length+1))*i+rdist*i/2)
monsRects.push(rect)
var text = drawing.text(data.monitors[i]).font({
'anchor':"middle",
'size':fontsize
})
text.x(monX+rwidth/2)
text.y((dheight/Math.max(1,data.monitors.length+1))*i+rdist*i/2+rdist/4)
monsTexts.push(text)
}
}
if (data.assignations !== null) {
for (i = 0; i < data.assignations.length; i++) {
if (data.assignations[i].monitors !== null) {
for (j = 0; j < data.assignations[i].monitors.length; j++) {
var devPos = posItemInArray(data.assignations[i].device, data.devices)
var monPos = posItemInArray(data.assignations[i].monitors[j], data.monitors)
var line = drawing.line(rwidth, rdist/2+devPos*rdist, monX, (dheight/Math.max(1,data.monitors.length+1))*monPos+rdist*monPos/2+rdist/2 ).stroke({ width: 1.5 })
assignsLines.push(line)
}
}
}
}
</script>
This diff is collapsed.
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
}
// The DeviceIpv4sGraphserver lists the IPv4 addresses a GraphServer is assigned
type DeviceIpv4sGraphserver struct {
ID int `json:"Id"`
Addresses []string `json:"Addresses"`
GraphServer int `json:"GraphServer"`
SNMPNames []string `json:"SNMPNames"`
}
// The DeviceMonitorAssignation holds a device with its IPv4 addresses and the
// list of monitors to which it is assigned
type DeviceMonitorAssignation struct {
Device DeviceIpv4Adddresses
MonitorID []string
}
// The AssignChecksum holds...
type AssignChecksum struct {
MonitorID string
Checksum string
}
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"os/signal"
"time"
"uc-monitor-go-test/cnml"
"uc-monitor-go-test/goclidote"
"github.com/golang/glog"
)
type JSONDeviceMonitorAssignation struct {
Device string `json:"device"`
Monitors []string `json:"monitors"`
}
type JSONAllData struct {
Devices []string `json:"devices"`
Monitors []string `json:"monitors"`
Assignations []JSONDeviceMonitorAssignation `json:"assignations"`
}
// Define error levels
// FATAL output code
var FATAL = 1
// ERROR output code
var ERROR = 2
// WARNING output code
var WARNING = 3
// INFO output code
var INFO = 4
// DEFAULTFILEMODE for created files
var DEFAULTFILEMODE os.FileMode = 0755
//Default settings and descriptions
var dbHost = "localhost"
var dbHostHelp = "The hostname or IP address where AntidoteDB is running"
var dbPort = 8087
var dbPortHelp = "The TCP port on which AntidoteDB is listening"
var globalAssignCheckInterval = 5 //60
var globalAssignCheckIntervalHelp = "Interval (in seconds) in which to check for changes in the local devices assignation list"
// Global data structures
var globalAssign []cnml.DeviceMonitorAssignation
var monitorsList []string
var devicesList []string
func main() {
//Initialize the service (read the configuration flags, etc.)
initialize()
// Handle interrupt signals in order to terminate gracefully
signalChan := make(chan os.Signal, 1)
cleanupDone := make(chan bool)
signal.Notify(signalChan, os.Interrupt)
go func() {
for _ = range signalChan {
fmt.Println("\nReceived an interrupt, quitting...")
cleanupDone <- true
}
}()
<-cleanupDone
fmt.Println("\nBye!")
}
// The initialize() function manages the execution parameters, sets timers, etc.
func initialize() {
fmt.Println("Initializing...")
// Manage command line flags and execution settings
initializeFlags()
// Initialize periodic timers
initializeTimers()
// The application is now ininitialized; entering the loop
fmt.Println("Initialization done. Entering infinite loop...")
}
func initializeTimers() {
// Initialize the local assignation check timer
startGlobalAssignTimer()
}
// The initializeFlags function initializes the command line flags
func initializeFlags() {
//Define and parse command line flags
dbHostPtr := flag.String("db_host", dbHost, dbHostHelp)
dbPortPtr := flag.Int("db_port", dbPort, dbPortHelp)
globalAssignCheckIntervalPtr := flag.Int("globalAssignCheckInterval", globalAssignCheckInterval, globalAssignCheckIntervalHelp)
flag.Parse()
dbHost = *dbHostPtr
dbPort = *dbPortPtr
if *globalAssignCheckIntervalPtr > 0 {
globalAssignCheckInterval = *globalAssignCheckIntervalPtr
}
}
func getCnmlDevicesList() []cnml.DeviceIpv4sGraphserver {
return goclidote.ReadDevicesFromAntidote(dbHost, dbPort)
}
func getGlobalAssignationList() []cnml.DeviceMonitorAssignation {
var newAssign []cnml.DeviceMonitorAssignation
for _, v := range getCnmlDevicesList() {
{
var newDev cnml.DeviceMonitorAssignation
newDev.Device.ID = v.ID
newDev.Device.Addresses = v.Addresses
newDev.MonitorID = goclidote.AntidoteReadItemsFromSetInBucket(fmt.Sprintf("device-%d", v.ID), "monitors", dbHost, dbPort)
newAssign = append(newAssign, newDev)
}
}
return newAssign
}
func startGlobalAssignTimer() {
globalAssignTicker := time.NewTicker(time.Duration(globalAssignCheckInterval) * time.Second)
go func() {
for range globalAssignTicker.C {
fmt.Println("Getting monitors list...")
monitorsList = getCurrentMonitorsList()
fmt.Println("The current monitors list contains", len(monitorsList), "monitors")
fmt.Println("Getting devices list...")
devicesList = getCurrentDevicesList()
fmt.Println("The current devices list contains", len(devicesList), "devices")
fmt.Println("Getting global assignation list...")
globalAssign = getGlobalAssignationList()
fmt.Println("The global assignation list contains", len(globalAssign), "devices")
var dataToExport JSONAllData
dataToExport.Devices = devicesList
dataToExport.Monitors = monitorsList
for _, v := range globalAssign {
var newAssg JSONDeviceMonitorAssignation
newAssg.Device = fmt.Sprintf("%d", v.Device.ID)
newAssg.Monitors = v.MonitorID
dataToExport.Assignations = append(dataToExport.Assignations, newAssg)
}
outFile, _ := os.Create("/tmp/out.json")
defer outFile.Close()
jnodes, _ := json.Marshal(dataToExport)
//fmt.Println(string(jnode))
//outFile.WriteString(string(jnodes))
outFile.WriteString(fmt.Sprintf("data = %s", string(jnodes)))
}
}()
}
func getCurrentMonitorsList() []string {
return goclidote.AntidoteReadItemsFromSetInBucket("guifi", "monitors", dbHost, dbPort)
}
func getCurrentDevicesList() []string {
allDevs := goclidote.ReadDevicesFromAntidote(dbHost, dbPort)
var devsID []string
for _, v := range allDevs {
devsID = append(devsID, fmt.Sprintf("%d", v.ID))
}
return devsID
}
func errCheck(e error, level int, message string) {
if message == "" {
message = "Unknown error"
}
if e != nil {
switch level {
case FATAL:
glog.Fatalln(message, e)
case ERROR:
glog.Errorln(message, e)
case WARNING:
glog.Warningln(message, e)
default:
glog.Infoln(message, e)
}
}
}
package main
import (
"fmt"
"github.com/AntidoteDB/antidote-go-client"
)
// Host represents an Antidote server.
// The port needs to be the port of the protocol-buffer interface (usually 8087)
// AntidoteAddItemToSetInBucket save an item to a set in a bucketdcrf
func main1() {
client, err := antidoteclient.NewClient(antidoteclient.Host{"127.0.0.1", 8087})
errCheck(err, "")
defer client.Close()
tx, err := client.StartTransaction()
errCheck(err, "")
bucket := antidoteclient.Bucket{[]byte("bands")}
key := antidoteclient.Key("beatles")
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte("john")))
errCheck(err, "")
setVal, err := bucket.ReadSet(tx, key)
errCheck(err, "")
fmt.Println("(1)")
for _, v := range setVal {
fmt.Println(string(v))
}
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte("paul")))
errCheck(err, "")
setVal, err = bucket.ReadSet(tx, key)
errCheck(err, "")
fmt.Println("(2)")
for _, v := range setVal {
fmt.Println(string(v))
}
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte("george")))
errCheck(err, "")
setVal, err = bucket.ReadSet(tx, key)
errCheck(err, "")
fmt.Println("(3)")
for _, v := range setVal {
fmt.Println(string(v))
}
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte("ringo")))
errCheck(err, "")
setVal, err = bucket.ReadSet(tx, key)
errCheck(err, "")
fmt.Println("(4)")
for _, v := range setVal {
fmt.Println(string(v))
}
err = tx.Commit()
errCheck(err, "")
}
// Panic on error
func errCheck(err error, message string) {
if err != nil {
fmt.Println(message)
panic(err)
}
}
package main
import (
"fmt"
"math/rand"
"time"
"github.com/AntidoteDB/antidote-go-client"
)
// Host represents an Antidote server.
// The port needs to be the port of the protocol-buffer interface (usually 8087)
// AntidoteAddItemToSetInBucket save an item to a set in a bucketdcrf
func main2() {
var myBucket = "device-123"
var myTimestamp = time.Now().UTC()
var myKey = myTimestamp.Format("2006-01-02-15-04-05")
fmt.Println(myKey)
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
fmt.Println(fmt.Sprintf("%d", r1.Intn(100)))
client, err := antidoteclient.NewClient(antidoteclient.Host{"127.0.0.1", 8087})
errCheck(err, "")
defer client.Close()
tx, err := client.StartTransaction()
errCheck(err, "")
bucket := antidoteclient.Bucket{[]byte(myBucket)}
key := antidoteclient.Key(myKey)
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte(fmt.Sprintf("%d", r1.Intn(100)))))
errCheck(err, "")
setVal, err := bucket.ReadSet(tx, key)
errCheck(err, "")
fmt.Println("(1)")
for _, v := range setVal {
fmt.Println(string(v))
}
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte(fmt.Sprintf("%d", r1.Intn(100)))))
errCheck(err, "")
setVal, err = bucket.ReadSet(tx, key)
errCheck(err, "")
fmt.Println("(2)")
for _, v := range setVal {
fmt.Println(string(v))
}
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte(fmt.Sprintf("%d", r1.Intn(100)))))
errCheck(err, "")
setVal, err = bucket.ReadSet(tx, key)
errCheck(err, "")
fmt.Println("(3)")
for _, v := range setVal {
fmt.Println(string(v))
}
err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte(fmt.Sprintf("%d", r1.Intn(100)))))
errCheck(err, "")