Skip to content

Commit

Permalink
Merge pull request #57 from Lakshan-Banneheke/api
Browse files Browse the repository at this point in the history
Api
  • Loading branch information
Lakshan-Banneheke authored Jun 14, 2023
2 parents 484517d + 837a8a2 commit a53a5bd
Show file tree
Hide file tree
Showing 27 changed files with 595 additions and 146 deletions.
3 changes: 3 additions & 0 deletions api/README_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## API for the Brownout Controller

[Api endpoints](https://docs.google.com/document/d/1ntqPBhSBGyOzEjVm63QvFVi7aG04ZEON5NJnUvAAJ7A/edit?usp=sharing)
67 changes: 67 additions & 0 deletions api/battery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package api

import (
"brownout-controller/brownout"
"encoding/json"
"log"
"net/http"
"time"
)

type responseBodyBattery struct {
Battery int
}

// User can use this API endpoint to periodically send the battery percentage to the brownout controller
func handleSetBattery(w http.ResponseWriter, r *http.Request) {

var body responseBodyBattery
err := json.NewDecoder(r.Body).Decode(&body)
if err != nil {
message := "Battery Percentage should be an integer. Example request body: {\"Battery\":45}"
http.Error(w, message, http.StatusBadRequest)
return
}

batteryPercentage := body.Battery

if batteryPercentage < 100 && batteryPercentage > 0 {
brownout.SetBatteryPercentage(batteryPercentage)
w.WriteHeader(http.StatusOK)
} else {
http.Error(w, "Battery Percentage should be an integer between 0 and 100", http.StatusBadRequest)
}
}

type BatteryData struct {
Timestamp int64 `json:"timestamp"`
Battery int `json:"battery"`
}

func handleListenBattery(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}

log.Println("Client Connected to listen battery")
for {
batteryData := BatteryData{
Timestamp: time.Now().Unix(),
Battery: brownout.GetBatteryPercentage(),
}

// Send the data to the client
err := conn.WriteJSON(batteryData)
if err != nil {
log.Println(err)
return
}
log.Println("Battery percentage value written")
log.Printf("Timestamp: %v, Battery: %vW", batteryData.Timestamp, batteryData.Battery)

// Wait for some time before sending the next data
time.Sleep(30 * time.Second)
}
}
32 changes: 0 additions & 32 deletions api/batteryHandler.go

This file was deleted.

155 changes: 155 additions & 0 deletions api/brownout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package api

import (
"brownout-controller/brownout"
"brownout-controller/variables"
"encoding/json"
"github.com/gorilla/mux"
"log"
"net/http"
"strconv"
"time"
)

func handleBrownoutActivation(w http.ResponseWriter, r *http.Request) {
brownout.SetBrownoutActive(true)
go brownout.ActivateBrownout() // The function will be executed in a new thread (goroutine)
w.WriteHeader(http.StatusOK)
}

func handleBrownoutDeactivation(w http.ResponseWriter, r *http.Request) {
brownout.SetBrownoutActive(false)
go brownout.DeactivateBrownout() // The function will be executed in a new thread (goroutine)
w.WriteHeader(http.StatusOK)
}

type BrownoutStatus struct {
Timestamp int64 `json:"timestamp"`
BrownoutActive bool `json:"brownout_active"`
}

func handleListenBrownoutStatus(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}

log.Println("Client Connected to listen brownout status")
for {
brownoutStatus := BrownoutStatus{
Timestamp: time.Now().Unix(),
BrownoutActive: brownout.GetBrownoutActive(),
}

// Send the data to the client
err := conn.WriteJSON(brownoutStatus)
if err != nil {
log.Println(err)
return
}
log.Println("BrownoutActive value written")
log.Printf("Timestamp: %v, BrownoutActive: %v", brownoutStatus.Timestamp, brownoutStatus.BrownoutActive)

// Wait for some time before sending the next data
time.Sleep(1 * time.Second)
}
}

// Get a variable value
func handleGetVariable(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
params := mux.Vars(r) // Gets params

name := params["name"]
var value any

switch name {
case "policy":
value = variables.POLICY
case "batteryUpper":
value = variables.BATTERY_UPPER_THRESHOLD
case "batteryLower":
value = variables.BATTERY_LOWER_THRESHOLD
case "slaViolationLatency":
value = variables.SLA_VIOLATION_LATENCY
case "slaInterval":
value = variables.SLA_INTERVAL
case "asr":
value = variables.ACCEPTED_SUCCESS_RATE
case "amsr":
value = variables.ACCEPTED_MIN_SUCCESS_RATE
default:
message := "Invalid variable name."
http.Error(w, message, http.StatusBadRequest)
return
}

json.NewEncoder(w).Encode(value)
}

type responseBodyVariable struct {
Value string
}

// Set a variable value
func handleSetVariable(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r) // Gets params
name := params["name"]

var body responseBodyVariable
err := json.NewDecoder(r.Body).Decode(&body)
if err != nil {
message := "Error in request body. Value must be of type string. Example request body: {\"Value\":\"45\"}"
http.Error(w, message, http.StatusBadRequest)
return
}

strValue := body.Value

switch name {
case "policy":
variables.POLICY = strValue
case "batteryUpper":
value, err := strconv.Atoi(strValue)
if err != nil {
message := "Error in request body. Cannot convert value to integer. Example request body: {\"Value\":\"45\"}"
http.Error(w, message, http.StatusBadRequest)
return
}
variables.BATTERY_UPPER_THRESHOLD = value
case "batteryLower":
value, err := strconv.Atoi(strValue)
if err != nil {
message := "Error in request body. Cannot convert value to integer. Example request body: {\"Value\":\"45\"}"
http.Error(w, message, http.StatusBadRequest)
return
}
variables.BATTERY_LOWER_THRESHOLD = value
case "slaViolationLatency":
variables.SLA_VIOLATION_LATENCY = strValue
case "slaInterval":
variables.SLA_INTERVAL = strValue
case "asr":
value, err := strconv.ParseFloat(strValue, 64)
if err != nil {
message := "Error in request body. Cannot convert value to float. Example request body: {\"Value\":\"0.65\"}"
http.Error(w, message, http.StatusBadRequest)
return
}
variables.ACCEPTED_SUCCESS_RATE = value
case "amsr":
value, err := strconv.ParseFloat(strValue, 64)
if err != nil {
message := "Error in request body. Cannot convert value to float. Example request body: {\"Value\":\"0.65\"}"
http.Error(w, message, http.StatusBadRequest)
return
}
variables.ACCEPTED_MIN_SUCCESS_RATE = value
default:
message := "Error in request URL. Name of variable incorrect."
http.Error(w, message, http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
}
18 changes: 0 additions & 18 deletions api/brownoutHandlers.go

This file was deleted.

42 changes: 42 additions & 0 deletions api/deployments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package api

import (
"brownout-controller/constants"
"brownout-controller/kubernetesCluster"
"log"
"net/http"
"time"
)

type DeploymentData struct {
Timestamp int64 `json:"timestamp"`
DeploymentList []kubernetesCluster.Deployment `json:"deployment_list"`
}

func handleListenDeploymentData(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}

log.Println("Client Connected to listen deployment data")
for {

deploymentData := DeploymentData{
Timestamp: time.Now().Unix(),
DeploymentList: kubernetesCluster.GetDeploymentsAll(constants.NAMESPACE),
}

// Send the data to the client
err := conn.WriteJSON(deploymentData)
if err != nil {
log.Println(err)
return
}
log.Println("Deployment data values written")

// Wait for some time before sending the next data
time.Sleep(30 * time.Second)
}
}
42 changes: 42 additions & 0 deletions api/nodes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package api

import (
"brownout-controller/kubernetesCluster"
"log"
"net/http"
"time"
)

type NodeData struct {
Timestamp int64 `json:"timestamp"`
AllNodes []string `json:"nodes_all"`
ActiveNodes []string `json:"nodes_active"`
}

func handleListenNodeData(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}

log.Println("Client Connected to listen node data")
for {
nodeData := NodeData{
Timestamp: time.Now().Unix(),
AllNodes: kubernetesCluster.GetAllNodeNames(),
ActiveNodes: kubernetesCluster.GetActiveNodeNames(),
}

// Send the data to the client
err := conn.WriteJSON(nodeData)
if err != nil {
log.Println(err)
return
}
log.Println("Node data values written")

// Wait for some time before sending the next data
time.Sleep(30 * time.Second)
}
}
Loading

0 comments on commit a53a5bd

Please sign in to comment.