package goclidote import ( "fmt" "strconv" "time" "uc-monitor-go-test/cnml" "github.com/AntidoteDB/antidote-go-client" "github.com/golang/glog" ) // DatabaseHost defines the host of the AntidoteDB instance to connect to is running // var DatabaseHost = "localhost" // DatabasePort defines the port of the host where the AntidoteDB instance to connect to is running // var DatabasePort = 8087 // 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 // AntidoteAddItemToSetInBucket save an item to a set in a bucket func AntidoteAddItemToSetInBucket(bucketName string, setName string, itemValue string, DatabaseHost string, DatabasePort int) bool { client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "[AntidoteAddItemToSetInBucket]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, "[AntidoteAddItemToSetInBucket]: Unable to start a transaction using the go client") bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} key := antidoteclient.Key(setName) err = bucket.Update(tx, antidoteclient.SetAdd(key, []byte(itemValue))) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddItemToSetInBucket]: Unable to add value %s to set %s in bucket %s", itemValue, setName, bucketName)) setVal, err := bucket.ReadSet(tx, key) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddItemToSetInBucket]: Unable to read set %s in bucket %s", setName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteAddItemToSetInBucket]: Unable to commit transaction") // Return true if the value belongs now to the set (either it has been added now, or was there already) for _, v := range setVal { if string(v) == itemValue { return true } } // Return false otherwise return false } // AntidoteAddItemToSetInMapInBucket save an item to a set in a map in a bucket func AntidoteAddItemToSetInMapInBucket(bucketName string, mapName string, setName string, itemValue string, DatabaseHost string, DatabasePort int) bool { client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "[AntidoteAddItemToSetInMapInBucket]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, "[AntidoteAddItemToSetInMapInBucket]: Unable to start a transaction using the go client") bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} mapKey := antidoteclient.Key(mapName) setKey := antidoteclient.Key(setName) err = bucket.Update(tx, antidoteclient.MapUpdate(mapKey, antidoteclient.SetAdd(setKey, []byte(itemValue)))) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddItemToSetInMapInBucket]: Unable to add value %s to set %s in bucket %s", itemValue, setName, bucketName)) mapVal, err := bucket.ReadMap(tx, mapKey) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddItemToSetInMapInBucket]: Unable to read set %s in bucket %s", setName, bucketName)) setVal, err := mapVal.Set(setKey) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddItemToSetInMapInBucket]: Unable to read set %s in bucket %s", setName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteAddItemToSetInMapInBucket]: Unable to commit transaction") // Return true if the value belongs now to the set (either it has been added now, or was there already) for _, v := range setVal { if string(v) == itemValue { return true } } // Return false otherwise return false } // AntidoteAddArrayToSetInMapInBucket save an item to a set in a map in a bucket func AntidoteAddArrayToSetInMapInBucket(bucketName string, mapName string, setName string, itemArray []string, DatabaseHost string, DatabasePort int) bool { client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "[AntidoteAddArrayToSetInMapInBucket]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, "[AntidoteAddArrayToSetInMapInBucket]: Unable to start a transaction using the go client") bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} mapKey := antidoteclient.Key(mapName) setKey := antidoteclient.Key(setName) for _, v := range itemArray { err = bucket.Update(tx, antidoteclient.MapUpdate(mapKey, antidoteclient.SetAdd(setKey, []byte(v)))) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddArrayToSetInMapInBucket]: Unable to add value %s to set %s in bucket %s", v, setName, bucketName)) time.Sleep(time.Millisecond) } mapVal, err := bucket.ReadMap(tx, mapKey) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddArrayToSetInMapInBucket]: Unable to read set %s in bucket %s", setName, bucketName)) setVal, err := mapVal.Set(setKey) errCheck(err, ERROR, fmt.Sprintf("[AntidoteAddArrayToSetInMapInBucket]: Unable to read set %s in bucket %s", setName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteAddArrayToSetInMapInBucket]: Unable to commit transaction") // Return true if all values belong now to the set (either they have been added now, or were there already) anyMissing := false for _, v := range itemArray { thisFound := false for _, w := range setVal { if v == string(w) { thisFound = true } if !thisFound { anyMissing = true break } } } // Return if all itemswere found return !anyMissing } // AntidoteAddArrayToSetInMapInMapInBucket save an item to a set in a map in a map in a bucket func AntidoteAddArrayToSetInMapInMapInBucket(bucketName string, outerMapName string, innerMapName string, setName string, itemArray []string, DatabaseHost string, DatabasePort int) bool { funcName := "AntidoteAddArrayToSetInMapInMapInBucket" client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "["+funcName+"]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, "["+funcName+"]: Unable to start a transaction using the go client") bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} outerMapKey := antidoteclient.Key(outerMapName) innerMapKey := antidoteclient.Key(innerMapName) setKey := antidoteclient.Key(setName) for _, v := range itemArray { err = bucket.Update(tx, antidoteclient.MapUpdate(outerMapKey, antidoteclient.MapUpdate(innerMapKey, antidoteclient.SetAdd(setKey, []byte(v))))) errCheck(err, ERROR, fmt.Sprintf("["+funcName+"]: Unable to add value %s to set %s in map %s in map %s in bucket %s", v, setName, innerMapName, outerMapName, bucketName)) time.Sleep(time.Millisecond) } outerMapVal, err := bucket.ReadMap(tx, outerMapKey) errCheck(err, ERROR, fmt.Sprintf("["+funcName+"]: Unable to read map %s in bucket %s", outerMapName, bucketName)) innerMapVal, err := outerMapVal.Map(innerMapKey) errCheck(err, ERROR, fmt.Sprintf("["+funcName+"]: Unable to read map %s in map %s in bucket %s", innerMapName, outerMapName, bucketName)) setVal, err := innerMapVal.Set(setKey) errCheck(err, ERROR, fmt.Sprintf("["+funcName+"]: Unable to read set %s in bucket %s", setName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "["+funcName+"]: Unable to commit transaction") // Return true if all values belong now to the set (either they have been added now, or were there already) anyMissing := false for _, v := range itemArray { thisFound := false for _, w := range setVal { if v == string(w) { thisFound = true } if !thisFound { anyMissing = true break } } } // Return if all itemswere found return !anyMissing } // AntidoteReadRegisterInBucket read a LWWW register in a bucket func AntidoteReadRegisterInBucket(bucketName string, registerName string, DatabaseHost string, DatabasePort int) string { client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "[AntidoteReadRegisterInBucket]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, fmt.Sprintf("[AntidoteReadRegisterInBucket]: Unable to start a transaction using the go client. bucketName: %s, registerName %s, DatabaseHost %s, DatabasePort %d\n", bucketName, registerName, DatabaseHost, DatabasePort)) bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} key := antidoteclient.Key(registerName) setVal, err := bucket.ReadReg(tx, key) errCheck(err, ERROR, fmt.Sprintf("[AntidoteReadRegisterInBucket]: Unable to read register %s in bucket %s", registerName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteReadRegisterInBucket]: Unable to commit transaction") return string(setVal[:]) } // AntidoteSetRegisterInBucket set a LWWW register in a bucket func AntidoteSetRegisterInBucket(bucketName string, registerName string, itemValue string, DatabaseHost string, DatabasePort int) bool { client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, fmt.Sprintf("[AntidoteSetRegisterInBucket]: Unable to create a new AntidoteDB go client. bucketName: %s, registerName %s, itemValue %s, DatabaseHost %s, DatabasePort %d\n", bucketName, registerName, itemValue, DatabaseHost, DatabasePort)) defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, fmt.Sprintf("[AntidoteSetRegisterInBucket]: Unable to start a transaction using the go client. bucketName: %s, registerName %s, itemValue %s, DatabaseHost %s, DatabasePort %d\n", bucketName, registerName, itemValue, DatabaseHost, DatabasePort)) bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} key := antidoteclient.Key(registerName) err = bucket.Update(tx, antidoteclient.RegPut(key, []byte(itemValue))) errCheck(err, ERROR, fmt.Sprintf("[AntidoteSetRegisterInBucket]: Unable to set value %s to register %s in bucket %s", itemValue, registerName, bucketName)) setVal, err := bucket.ReadReg(tx, key) errCheck(err, ERROR, fmt.Sprintf("[AntidoteSetRegisterInBucket]: Unable to read register %s in bucket %s", registerName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteSetRegisterInBucket]: Unable to commit transaction") // Return true if the register value is itemValue if string(setVal[:]) == itemValue { return true } // Return false otherwise return false } // AntidoteRemoveRegisterInBucket remove (set null) a LWWW register in a bucket func AntidoteRemoveRegisterInBucket(bucketName string, registerName string, DatabaseHost string, DatabasePort int) bool { client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "[AntidoteRemoveRegisterInBucket]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, "[AntidoteRemoveRegisterInBucket]: Unable to start a transaction using the go client") bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} key := antidoteclient.Key(registerName) err = bucket.Update(tx, antidoteclient.RegPut(key, []byte(""))) errCheck(err, ERROR, fmt.Sprintf("[AntidoteRemoveRegisterInBucket]: Unable to set a null value to register %s in bucket %s", registerName, bucketName)) regVal, err := bucket.ReadReg(tx, key) errCheck(err, ERROR, fmt.Sprintf("[AntidoteRemoveRegisterInBucket]: Unable to read register %s in bucket %s", registerName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteRemoveRegisterInBucket]: Unable to commit transaction") // Return true if the register value is null (0 length) if len(regVal) == 0 { return true } // Return false otherwise return false } // AntidoteReadItemsFromSetInBucket read items from a set in a bucket func AntidoteReadItemsFromSetInBucket(bucketName string, setName string, DatabaseHost string, DatabasePort int) []string { var items []string client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, fmt.Sprintf("[AntidoteReadItemsFromSetInBucket]: Unable to create a new AntidoteDB go client. bucketName %s, setName %s, DatabaseHost %s, DatabasePort %d\n", bucketName, setName, DatabaseHost, DatabasePort)) defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, fmt.Sprintf("[AntidoteReadItemsFromSetInBucket]: Unable to start a transaction using the go client. bucketName: %s, setName: %s, DatabaseHost %s, DatabasePort %d\n", bucketName, setName, DatabaseHost, DatabasePort)) bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} key := antidoteclient.Key(setName) setVal, err := bucket.ReadSet(tx, key) errCheck(err, ERROR, fmt.Sprintf("[AntidoteReadItemsFromSetInBucket]: Unable to read set %s in bucket %s", setName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteReadItemsFromSetInBucket]: Unable to commit transaction") for _, v := range setVal { items = append(items, string(v)) } return items } // AntidoteRemoveItemFromSetInBucket removes an item from a set in a bucket func AntidoteRemoveItemFromSetInBucket(bucketName string, setName string, itemValue string, DatabaseHost string, DatabasePort int) bool { client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "[AntidoteRemoveItemFromSetInBucket]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, "[AntidoteRemoveItemFromSetInBucket]: Unable to start a transaction using the go client") bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} key := antidoteclient.Key(setName) err = bucket.Update(tx, antidoteclient.SetRemove(key, []byte(itemValue))) errCheck(err, ERROR, fmt.Sprintf("[AntidoteRemoveItemFromSetInBucket]: Unable to remove item %s from set %s in bucket %s", itemValue, setName, bucketName)) setVal, err := bucket.ReadSet(tx, key) errCheck(err, ERROR, fmt.Sprintf("[AntidoteRemoveItemFromSetInBucket]: Unable to read set %s in bucket %s", setName, bucketName)) err = tx.Commit() errCheck(err, ERROR, "[AntidoteRemoveItemFromSetInBucket]: Unable to commit transaction") itemNotInSet := true // Return false if the item remains in the set for _, v := range setVal { if string(v[:]) == itemValue { itemNotInSet = false } } // Return true otherwise (even if it had never been there) return itemNotInSet } // ReadDevicesFromAntidote read all the devices from Antidote using the Go client func ReadDevicesFromAntidote(DatabaseHost string, DatabasePort int) []cnml.DeviceIpv4sGraphserver { var devices []cnml.DeviceIpv4sGraphserver for _, v := range AntidoteReadItemsFromSetInBucket("guifi", "devices", DatabaseHost, DatabasePort) { time.Sleep(time.Millisecond) thisDevID, err := strconv.Atoi(v) errCheck(err, WARNING, fmt.Sprintf("[ReadDevicesFromAntidote]: An error occurred when converting %s to int", v)) //fmt.Printf("%s, ",v) var thisDev cnml.DeviceIpv4sGraphserver thisDev.ID = thisDevID thisDev.GraphServer, err = strconv.Atoi(AntidoteReadRegisterInBucket(fmt.Sprintf("device-%d", thisDevID), "graphserver", DatabaseHost, DatabasePort)) if err != nil { thisDev.GraphServer = 0 } time.Sleep(time.Millisecond) thisDev.Addresses = AntidoteReadItemsFromSetInBucket(fmt.Sprintf("device-%d", thisDevID), "ipv4s", DatabaseHost, DatabasePort) time.Sleep(time.Millisecond) thisDev.SNMPNames = AntidoteReadItemsFromSetInBucket(fmt.Sprintf("device-%d", thisDevID), "snmpnames", DatabaseHost, DatabasePort) devices = append(devices, thisDev) } return devices } // RemoveDevicesFromAntidote removes an array of DeviceIpv4sGraphservers from AntidoteDB func RemoveDevicesFromAntidote(oldDevices []cnml.DeviceIpv4sGraphserver, DatabaseHost string, DatabasePort int) []cnml.DeviceIpv4sGraphserver { var remDevices []cnml.DeviceIpv4sGraphserver // Start an AntidoteDB client client, err := antidoteclient.NewClient(antidoteclient.Host{Name: DatabaseHost, Port: DatabasePort}) errCheck(err, ERROR, "[RemoveDevicesFromAntidote]: Unable to create a new AntidoteDB go client") defer client.Close() tx, err := client.StartTransaction() errCheck(err, ERROR, "[RemoveDevicesFromAntidote]: Unable to start a transaction using the go client") for _, v := range oldDevices { // Remove the graphserver register from the device-id bucket //fmt.Println(v) bucketName := fmt.Sprintf("device-%d", v.ID) registerName := "graphserver" devError := false bucket := antidoteclient.Bucket{Bucket: []byte(bucketName)} key := antidoteclient.Key(registerName) err = bucket.Update(tx, antidoteclient.RegPut(key, []byte(""))) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to set a null value to register %s in bucket %s", registerName, bucketName)) regVal, err := bucket.ReadReg(tx, key) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to read register %s in bucket %s", registerName, bucketName)) //fmt.Println("regVal:", regVal) if len(regVal) != 0 { devError = true } // Empty the ipv4s set from the device-id bucket //fmt.Println("Addresses:", v.Addresses) for _, w := range v.Addresses { // fmt.Println("Address:", w) itemValue := w setName := "ipv4s" key = antidoteclient.Key(setName) err = bucket.Update(tx, antidoteclient.SetRemove(key, []byte(itemValue))) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to remove item %s from set %s in bucket %s", itemValue, setName, bucketName)) setVal, err := bucket.ReadSet(tx, key) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to read set %s in bucket %s", setName, bucketName)) // fmt.Println("Setval:", setVal) itemNotInSet := true for _, x := range setVal { if string(x[:]) == itemValue { itemNotInSet = false } } if !itemNotInSet { devError = true } } // Empty the snmpnames set from the device-id bucket for _, w := range v.SNMPNames { itemValue := w setName := "snmpnames" key = antidoteclient.Key(setName) err = bucket.Update(tx, antidoteclient.SetRemove(key, []byte(itemValue))) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to remove item %s from set %s in bucket %s", itemValue, setName, bucketName)) setVal, err := bucket.ReadSet(tx, key) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to read set %s in bucket %s", setName, bucketName)) itemNotInSet := true for _, x := range setVal { if string(x[:]) == itemValue { itemNotInSet = false } } if !itemNotInSet { devError = true } } // Remove the device from the devices set in the guifi bucket bucketName = "guifi" setName := "devices" itemValue := fmt.Sprintf("%d", v.ID) bucket = antidoteclient.Bucket{Bucket: []byte(bucketName)} key = antidoteclient.Key(setName) err = bucket.Update(tx, antidoteclient.SetRemove(key, []byte(itemValue))) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to remove item %s from set %s in bucket %s", itemValue, setName, bucketName)) setVal, err := bucket.ReadSet(tx, key) errCheck(err, ERROR, fmt.Sprintf("[RemoveDevicesFromAntidote]: Unable to read set %s in bucket %s", setName, bucketName)) itemNotInSet := true for _, w := range setVal { if string(w[:]) == itemValue { itemNotInSet = false } } if !itemNotInSet { devError = true } if devError == false { // Device successfully removed remDevices = append(remDevices, v) } } err = tx.Commit() errCheck(err, ERROR, "[AntidoteRemoveRegisterInBucket]: Unable to commit transaction") return remDevices } // The errCheck function gracefully manages errors, warnings, etc. func errCheck(e error, level int, message string) { if message == "" { message = "Unknown error" } if e != nil { switch level { case FATAL: glog.Infoln(message, e) case ERROR: glog.Errorln(message, e) case WARNING: glog.Warningln(message, e) default: glog.Infoln(message, e) } } }