Commit ed4709cb authored by Stefan Dähling's avatar Stefan Dähling
Browse files

agency endpoint for updating custom

parent 52650d90
Pipeline #405325 passed with stages
in 3 minutes and 54 seconds
......@@ -255,3 +255,21 @@ func (agency *Agency) getAgencyInfo() (agencyInfo schemas.AgencyInfo, err error)
err = nil
return
}
// updateAgentCustom updates the custom agent config
func (agency *Agency) updateAgentCustom(agentID int, custom string) (err error) {
agentExist := false
agency.mutex.Lock()
for i := range agency.localAgents {
if i == agentID {
agentExist = true
agency.localAgents[i].updateCustomData(custom)
break
}
}
agency.mutex.Unlock()
if !agentExist {
err = errors.New("agent does not exist")
}
return
}
......@@ -142,6 +142,14 @@ func (agent *Agent) GetCustomData() (ret string) {
return
}
// updateCustomData updates custom data
func (agent *Agent) updateCustomData(custom string) {
agent.mutex.Lock()
agent.custom = custom
agent.mutex.Unlock()
return
}
// Terminate terminates the agent
func (agent *Agent) Terminate() {
agent.logInfo.Println("Terminating agent ", agent.GetAgentID())
......
......@@ -163,6 +163,14 @@ func (cli *Client) ReturnMsg(agency string, msg schemas.ACLMessage) (httpStatus
return
}
// PutAgentCustom puts agent custom data
func (cli *Client) PutAgentCustom(agency string, agentID int, custom string) (httpStatus int,
err error) {
_, httpStatus, err = httpretry.Put(cli.httpClient, cli.prefix(agency)+"/api/agency/agents/"+
strconv.Itoa(agentID)+"/custom", []byte(custom), time.Second*2, 2)
return
}
func (cli *Client) prefix(agency string) (ret string) {
ret = "http://" + agency + ":" + strconv.Itoa(cli.Port)
return
......
......@@ -97,6 +97,9 @@ func (agency *Agency) handleAPI(w http.ResponseWriter, r *http.Request) {
if respath[5] == "status" {
cmapErr, httpErr = agency.handleAgentStatus(agentID, w, r)
resvalid = true
} else if respath[5] == "custom" {
cmapErr, httpErr = agency.handleAgentCustom(agentID, w, r)
resvalid = true
}
}
default:
......@@ -235,6 +238,28 @@ func (agency *Agency) handleAgentStatus(agid int, w http.ResponseWriter,
return
}
// handleAgentCustom is the handler for requests to path /api/agency/agents/{agent-id}/custom
func (agency *Agency) handleAgentCustom(agid int, w http.ResponseWriter,
r *http.Request) (cmapErr, httpErr error) {
if r.Method == "PUT" {
// update custom of specified agent
var body []byte
body, cmapErr = ioutil.ReadAll(r.Body)
if cmapErr == nil {
custom := string(body)
cmapErr = agency.updateAgentCustom(agid, custom)
httpErr = httpreply.Updated(w, cmapErr)
} else {
httpErr = httpreply.InvalidBodyError(w)
}
} else {
httpErr = httpreply.MethodNotAllowed(w)
cmapErr = errors.New("Error: Method not allowed on path /api/agency/agents/{agent-id}/" +
"custom")
}
return
}
// listen opens a http server listening and serving request
func (agency *Agency) listen() (err error) {
mux := http.NewServeMux()
......
......@@ -56,28 +56,28 @@ import (
"strconv"
"time"
agcli "git.rwth-aachen.de/acs/public/cloud/mas/clonemap/pkg/agency/client"
dfcli "git.rwth-aachen.de/acs/public/cloud/mas/clonemap/pkg/df/client"
agclient "git.rwth-aachen.de/acs/public/cloud/mas/clonemap/pkg/agency/client"
dfclient "git.rwth-aachen.de/acs/public/cloud/mas/clonemap/pkg/df/client"
"git.rwth-aachen.de/acs/public/cloud/mas/clonemap/pkg/schemas"
)
// AMS contains storage and deployment object
type AMS struct {
stor storage // interface for local or distributed storage
depl deployment // interface for local or cloud deployment
logInfo *log.Logger // logger for info logging
logError *log.Logger // logger for error logging
agencyCli *agcli.Client
dfCli *dfcli.Client
stor storage // interface for local or distributed storage
depl deployment // interface for local or cloud deployment
logInfo *log.Logger // logger for info logging
logError *log.Logger // logger for error logging
agencyClient *agclient.Client
dfClient *dfclient.Client
}
// StartAMS starts an AMS instance. It initializes the cluster and storage object and starts API
// server.
func StartAMS() (err error) {
ams := &AMS{
logError: log.New(os.Stderr, "[ERROR] ", log.LstdFlags),
agencyCli: agcli.New(time.Second*60, time.Second*1, 4),
dfCli: dfcli.New(time.Second*60, time.Second*1, 4),
logError: log.New(os.Stderr, "[ERROR] ", log.LstdFlags),
agencyClient: agclient.New(time.Second*60, time.Second*1, 4),
dfClient: dfclient.New(time.Second*60, time.Second*1, 4),
}
// create storage and deployment object according to specified deployment type
err = ams.init()
......@@ -201,7 +201,16 @@ func (ams *AMS) updateAgentCustom(masID int, agentID int, custom string) (err er
if err != nil {
return
}
// ToDo Post new custom to agency
var agentAddress schemas.Address
agentAddress, err = ams.stor.getAgentAddress(masID, agentID)
if err != nil {
return
}
var httpStatus int
httpStatus, err = ams.agencyClient.PutAgentCustom(agentAddress.Agency, agentID, custom)
if httpStatus != http.StatusOK {
err = errors.New("error updating custom data")
}
return
}
......@@ -250,7 +259,7 @@ func (ams *AMS) startMAS(masID int, masInfo schemas.MASInfo, numAgencies []int)
}
ams.logInfo.Println("Stored MAS data")
if os.Getenv("CLONEMAP_DEPLOYMENT_TYPE") == "local" {
_, err = ams.dfCli.PostGraph(masID, masInfo.Graph)
_, err = ams.dfClient.PostGraph(masID, masInfo.Graph)
if err != nil {
ams.logInfo.Println(err.Error())
// return
......@@ -461,7 +470,7 @@ func (ams *AMS) removeAgent(masID int, agentID int) (err error) {
if err != nil {
return
}
_, err = ams.agencyCli.DeleteAgent(addr.Agency, agentID)
_, err = ams.agencyClient.DeleteAgent(addr.Agency, agentID)
return
}
......@@ -469,7 +478,7 @@ func (ams *AMS) removeAgent(masID int, agentID int) (err error) {
// postAgentToAgency sends a post request to agency with info about agent to start
func (ams *AMS) postAgentToAgency(agentInfo schemas.AgentInfo) (err error) {
var httpStatus int
httpStatus, err = ams.agencyCli.PostAgent(agentInfo.Address.Agency, agentInfo)
httpStatus, err = ams.agencyClient.PostAgent(agentInfo.Address.Agency, agentInfo)
if err != nil {
return
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment