mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
Add more test for AMQP functions, improve code structure
This commit is contained in:
parent
2e64946869
commit
cc51913163
7 changed files with 565 additions and 270 deletions
|
@ -23,7 +23,6 @@ package component_configuration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/infrastructure-component"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -61,8 +60,11 @@ func (m *ComponentConfiguration) addToScenario() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// associate IC with component configuration
|
// associate IC with component configuration
|
||||||
var ic infrastructure_component.InfrastructureComponent
|
var ic database.InfrastructureComponent
|
||||||
err = ic.ByID(m.ICID)
|
err = db.Find(&ic, m.ICID).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = db.Model(&ic).Association("ComponentConfigurations").Append(m).Error
|
err = db.Model(&ic).Association("ComponentConfigurations").Append(m).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -80,23 +82,24 @@ func (m *ComponentConfiguration) Update(modifiedConfig ComponentConfiguration) e
|
||||||
// check if IC has been updated
|
// check if IC has been updated
|
||||||
if m.ICID != modifiedConfig.ICID {
|
if m.ICID != modifiedConfig.ICID {
|
||||||
// update IC
|
// update IC
|
||||||
var s infrastructure_component.InfrastructureComponent
|
var ic database.InfrastructureComponent
|
||||||
var s_old infrastructure_component.InfrastructureComponent
|
var ic_old database.InfrastructureComponent
|
||||||
err := s.ByID(modifiedConfig.ICID)
|
err := db.Find(&ic, modifiedConfig.ICID).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = s_old.ByID(m.ICID)
|
err = db.Find(&ic_old, m.ICID).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove component configuration from old IC
|
// remove component configuration from old IC
|
||||||
err = db.Model(&s_old).Association("ComponentConfigurations").Delete(m).Error
|
err = db.Model(&ic_old).Association("ComponentConfigurations").Delete(m).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// add component configuration to new IC
|
// add component configuration to new IC
|
||||||
err = db.Model(&s).Association("ComponentConfigurations").Append(m).Error
|
err = db.Model(&ic).Association("ComponentConfigurations").Append(m).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -121,8 +124,8 @@ func (m *ComponentConfiguration) delete() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ic infrastructure_component.InfrastructureComponent
|
var ic database.InfrastructureComponent
|
||||||
err = ic.ByID(m.ICID)
|
err = db.Find(&ic, m.ICID).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ func sendActionAMQP(action Action) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("AMQP: Sending message", string(msg.Body))
|
//log.Println("AMQP: Sending message", string(msg.Body))
|
||||||
err = client.channel.Publish(VILLAS_EXCHANGE,
|
err = client.channel.Publish(VILLAS_EXCHANGE,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -193,16 +193,16 @@ func sendActionAMQP(action Action) error {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PingAMQP() error {
|
//func PingAMQP() error {
|
||||||
log.Println("AMQP: sending ping command to all ICs")
|
// log.Println("AMQP: sending ping command to all ICs")
|
||||||
|
//
|
||||||
var a Action
|
// var a Action
|
||||||
a.Act = "ping"
|
// a.Act = "ping"
|
||||||
*a.Properties.UUID = ""
|
// *a.Properties.UUID = ""
|
||||||
|
//
|
||||||
err := sendActionAMQP(a)
|
// err := sendActionAMQP(a)
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
|
|
||||||
func CheckConnection() error {
|
func CheckConnection() error {
|
||||||
|
|
||||||
|
@ -256,8 +256,6 @@ func StartAMQP(AMQPurl string, api *gin.RouterGroup) error {
|
||||||
|
|
||||||
func processMessage(message amqp.Delivery) error {
|
func processMessage(message amqp.Delivery) error {
|
||||||
|
|
||||||
log.Println("Processing AMQP message: ", string(message.Body))
|
|
||||||
|
|
||||||
var payload ICUpdate
|
var payload ICUpdate
|
||||||
err := json.Unmarshal(message.Body, &payload)
|
err := json.Unmarshal(message.Body, &payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -265,6 +263,7 @@ func processMessage(message amqp.Delivery) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.Status != nil {
|
if payload.Status != nil {
|
||||||
|
//log.Println("Processing AMQP message: ", string(message.Body))
|
||||||
// if a message contains a "state" field, it is an update for an IC
|
// if a message contains a "state" field, it is an update for an IC
|
||||||
ICUUID := payload.Status.UUID
|
ICUUID := payload.Status.UUID
|
||||||
_, err = uuid.Parse(ICUUID)
|
_, err = uuid.Parse(ICUUID)
|
||||||
|
@ -273,18 +272,160 @@ func processMessage(message amqp.Delivery) error {
|
||||||
return fmt.Errorf("AMQP: UUID not valid: %v, message ignored: %v \n", ICUUID, string(message.Body))
|
return fmt.Errorf("AMQP: UUID not valid: %v, message ignored: %v \n", ICUUID, string(message.Body))
|
||||||
}
|
}
|
||||||
var sToBeUpdated InfrastructureComponent
|
var sToBeUpdated InfrastructureComponent
|
||||||
err = sToBeUpdated.ByUUID(ICUUID)
|
err = sToBeUpdated.byUUID(ICUUID)
|
||||||
|
|
||||||
if err == gorm.ErrRecordNotFound {
|
if err == gorm.ErrRecordNotFound {
|
||||||
// create new record
|
// create new record
|
||||||
err = createNewICviaAMQP(payload)
|
err = createExternalIC(payload)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
// database error
|
// database error
|
||||||
err = fmt.Errorf("AMQP: Database error for IC %v DB error message: %v", ICUUID, err)
|
err = fmt.Errorf("AMQP: Database error for IC %v DB error message: %v", ICUUID, err)
|
||||||
} else {
|
} else {
|
||||||
// update record based on payload
|
// update record based on payload
|
||||||
err = sToBeUpdated.updateICviaAMQP(payload)
|
err = sToBeUpdated.updateExternalIC(payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createExternalIC(payload ICUpdate) error {
|
||||||
|
|
||||||
|
var newICReq AddICRequest
|
||||||
|
newICReq.InfrastructureComponent.UUID = payload.Status.UUID
|
||||||
|
if payload.Status.Name == nil ||
|
||||||
|
payload.Status.Category == nil ||
|
||||||
|
payload.Status.Type == nil {
|
||||||
|
// cannot create new IC because required information (name, type, and/or category missing)
|
||||||
|
return fmt.Errorf("AMQP: Cannot create new IC, required field(s) is/are missing: name, type, category")
|
||||||
|
}
|
||||||
|
newICReq.InfrastructureComponent.Name = *payload.Status.Name
|
||||||
|
newICReq.InfrastructureComponent.Category = *payload.Status.Category
|
||||||
|
newICReq.InfrastructureComponent.Type = *payload.Status.Type
|
||||||
|
|
||||||
|
// add optional params
|
||||||
|
if payload.Status.State != nil {
|
||||||
|
newICReq.InfrastructureComponent.State = *payload.Status.State
|
||||||
|
} else {
|
||||||
|
newICReq.InfrastructureComponent.State = "unknown"
|
||||||
|
}
|
||||||
|
if newICReq.InfrastructureComponent.State == "gone" {
|
||||||
|
// Check if state is "gone" and abort creation of IC in this case
|
||||||
|
log.Println("AMQP: Aborting creation of IC with state gone")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if payload.Status.WS_url != nil {
|
||||||
|
newICReq.InfrastructureComponent.WebsocketURL = *payload.Status.WS_url
|
||||||
|
}
|
||||||
|
if payload.Status.API_url != nil {
|
||||||
|
newICReq.InfrastructureComponent.APIURL = *payload.Status.API_url
|
||||||
|
}
|
||||||
|
if payload.Status.Location != nil {
|
||||||
|
newICReq.InfrastructureComponent.Location = *payload.Status.Location
|
||||||
|
}
|
||||||
|
if payload.Status.Description != nil {
|
||||||
|
newICReq.InfrastructureComponent.Description = *payload.Status.Description
|
||||||
|
}
|
||||||
|
if payload.Status.Uptime != nil {
|
||||||
|
newICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime
|
||||||
|
}
|
||||||
|
// TODO add JSON start parameter scheme
|
||||||
|
|
||||||
|
// set managed externally to true because this IC is created via AMQP
|
||||||
|
newICReq.InfrastructureComponent.ManagedExternally = newTrue()
|
||||||
|
|
||||||
|
// Validate the new IC
|
||||||
|
err := newICReq.validate()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("AMQP: Validation of new IC failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new IC
|
||||||
|
newIC, err := newICReq.createIC(true)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("AMQP: Creating new IC failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// save IC
|
||||||
|
err = newIC.save()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("AMQP: Saving new IC to DB failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("AMQP: Created IC with UUID ", newIC.UUID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *InfrastructureComponent) updateExternalIC(payload ICUpdate) error {
|
||||||
|
|
||||||
|
var updatedICReq UpdateICRequest
|
||||||
|
if payload.Status.State != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.State = *payload.Status.State
|
||||||
|
|
||||||
|
if *payload.Status.State == "gone" {
|
||||||
|
// remove IC from DB
|
||||||
|
log.Println("AMQP: Deleting IC with state gone")
|
||||||
|
err := s.delete(true)
|
||||||
|
if err != nil {
|
||||||
|
// if component could not be deleted there are still configurations using it in the DB
|
||||||
|
// continue with the update to save the new state of the component and get back to the deletion later
|
||||||
|
log.Println("AMQP: Deletion of IC postponed (config(s) associated to it)")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if payload.Status.Type != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.Type = *payload.Status.Type
|
||||||
|
}
|
||||||
|
if payload.Status.Category != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.Category = *payload.Status.Category
|
||||||
|
}
|
||||||
|
if payload.Status.Name != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.Name = *payload.Status.Name
|
||||||
|
}
|
||||||
|
if payload.Status.WS_url != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.WebsocketURL = *payload.Status.WS_url
|
||||||
|
}
|
||||||
|
if payload.Status.API_url != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.APIURL = *payload.Status.API_url
|
||||||
|
}
|
||||||
|
if payload.Status.Location != nil {
|
||||||
|
//postgres.Jsonb{json.RawMessage(`{"location" : " ` + *payload.Status.Location + `"}`)}
|
||||||
|
updatedICReq.InfrastructureComponent.Location = *payload.Status.Location
|
||||||
|
}
|
||||||
|
if payload.Status.Description != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.Description = *payload.Status.Description
|
||||||
|
}
|
||||||
|
if payload.Status.Uptime != nil {
|
||||||
|
updatedICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime
|
||||||
|
}
|
||||||
|
// TODO add JSON start parameter scheme
|
||||||
|
|
||||||
|
// Validate the updated IC
|
||||||
|
err := updatedICReq.validate()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("AMQP: Validation of updated IC failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the updated IC from old IC
|
||||||
|
updatedIC := updatedICReq.updatedIC(*s)
|
||||||
|
|
||||||
|
// Finally update the IC in the DB
|
||||||
|
err = s.update(updatedIC)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("AMQP: Unable to update IC %v in DB: %v", s.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("AMQP: Updated IC with UUID ", s.UUID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTrue() *bool {
|
||||||
|
b := true
|
||||||
|
return &b
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFalse() *bool {
|
||||||
|
b := false
|
||||||
|
return &b
|
||||||
|
}
|
|
@ -22,7 +22,6 @@
|
||||||
package infrastructure_component
|
package infrastructure_component
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/database"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -108,9 +107,9 @@ func addIC(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !newIC.ManagedExternally {
|
if !(newIC.ManagedExternally) {
|
||||||
// Save new IC to DB if not managed externally
|
// Save new IC to DB if not managed externally
|
||||||
err = newIC.Save()
|
err = newIC.save()
|
||||||
|
|
||||||
if helper.DBError(c, err) {
|
if helper.DBError(c, err) {
|
||||||
return
|
return
|
||||||
|
@ -142,6 +141,11 @@ func updateIC(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if oldIC.ManagedExternally {
|
||||||
|
helper.ForbiddenError(c, "Cannot update externally managed component via API")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var req UpdateICRequest
|
var req UpdateICRequest
|
||||||
err := c.BindJSON(&req)
|
err := c.BindJSON(&req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -156,17 +160,10 @@ func updateIC(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the updatedIC from oldIC
|
// Create the updatedIC from oldIC
|
||||||
updatedIC, err := req.updatedIC(oldIC, false)
|
updatedIC := req.updatedIC(oldIC)
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusForbidden, gin.H{
|
|
||||||
"success": false,
|
|
||||||
"message": fmt.Sprintf("%v", err),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally update the IC in the DB
|
// Finally update the IC in the DB
|
||||||
err = oldIC.Update(updatedIC)
|
err = oldIC.update(updatedIC)
|
||||||
if !helper.DBError(c, err) {
|
if !helper.DBError(c, err) {
|
||||||
c.JSON(http.StatusOK, gin.H{"ic": updatedIC.InfrastructureComponent})
|
c.JSON(http.StatusOK, gin.H{"ic": updatedIC.InfrastructureComponent})
|
||||||
}
|
}
|
||||||
|
@ -285,7 +282,7 @@ func sendActionToIC(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//now := time.Now()
|
//now := time.Now()
|
||||||
log.Println("AMQP: Will attempt to send the following actions:", actions)
|
log.Println("AMQP: Sending actions:", actions)
|
||||||
|
|
||||||
for _, action := range actions {
|
for _, action := range actions {
|
||||||
/*if action.When == 0 {
|
/*if action.When == 0 {
|
||||||
|
|
|
@ -32,25 +32,25 @@ type InfrastructureComponent struct {
|
||||||
database.InfrastructureComponent
|
database.InfrastructureComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InfrastructureComponent) Save() error {
|
func (s *InfrastructureComponent) save() error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Create(s).Error
|
err := db.Create(s).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InfrastructureComponent) ByID(id uint) error {
|
func (s *InfrastructureComponent) byID(id uint) error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Find(s, id).Error
|
err := db.Find(s, id).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InfrastructureComponent) ByUUID(uuid string) error {
|
func (s *InfrastructureComponent) byUUID(uuid string) error {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Find(s, "UUID = ?", uuid).Error
|
err := db.Find(s, "UUID = ?", uuid).Error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InfrastructureComponent) Update(updatedIC InfrastructureComponent) error {
|
func (s *InfrastructureComponent) update(updatedIC InfrastructureComponent) error {
|
||||||
|
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
err := db.Model(s).Updates(updatedIC).Error
|
err := db.Model(s).Updates(updatedIC).Error
|
||||||
|
@ -66,6 +66,7 @@ func (s *InfrastructureComponent) delete(receivedViaAMQP bool) error {
|
||||||
action.Properties.UUID = new(string)
|
action.Properties.UUID = new(string)
|
||||||
*action.Properties.UUID = s.UUID
|
*action.Properties.UUID = s.UUID
|
||||||
|
|
||||||
|
log.Println("AMQP: Sending request to delete IC with UUID", s.UUID)
|
||||||
err := sendActionAMQP(action)
|
err := sendActionAMQP(action)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -89,144 +90,3 @@ func (s *InfrastructureComponent) getConfigs() ([]database.ComponentConfiguratio
|
||||||
err := db.Order("ID asc").Model(s).Related(&configs, "ComponentConfigurations").Error
|
err := db.Order("ID asc").Model(s).Related(&configs, "ComponentConfigurations").Error
|
||||||
return configs, len(configs), err
|
return configs, len(configs), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNewICviaAMQP(payload ICUpdate) error {
|
|
||||||
|
|
||||||
var newICReq AddICRequest
|
|
||||||
newICReq.InfrastructureComponent.UUID = payload.Status.UUID
|
|
||||||
if payload.Status.Name == nil ||
|
|
||||||
payload.Status.Category == nil ||
|
|
||||||
payload.Status.Type == nil {
|
|
||||||
// cannot create new IC because required information (name, type, and/or category missing)
|
|
||||||
return fmt.Errorf("AMQP: Cannot create new IC, required field(s) is/are missing: name, type, category")
|
|
||||||
}
|
|
||||||
newICReq.InfrastructureComponent.Name = *payload.Status.Name
|
|
||||||
newICReq.InfrastructureComponent.Category = *payload.Status.Category
|
|
||||||
newICReq.InfrastructureComponent.Type = *payload.Status.Type
|
|
||||||
|
|
||||||
// add optional params
|
|
||||||
if payload.Status.State != nil {
|
|
||||||
newICReq.InfrastructureComponent.State = *payload.Status.State
|
|
||||||
} else {
|
|
||||||
newICReq.InfrastructureComponent.State = "unknown"
|
|
||||||
}
|
|
||||||
if newICReq.InfrastructureComponent.State == "gone" {
|
|
||||||
// Check if state is "gone" and abort creation of IC in this case
|
|
||||||
log.Println("########## AMQP: Aborting creation of IC with state gone")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if payload.Status.WS_url != nil {
|
|
||||||
newICReq.InfrastructureComponent.WebsocketURL = *payload.Status.WS_url
|
|
||||||
}
|
|
||||||
if payload.Status.API_url != nil {
|
|
||||||
newICReq.InfrastructureComponent.APIURL = *payload.Status.API_url
|
|
||||||
}
|
|
||||||
if payload.Status.Location != nil {
|
|
||||||
newICReq.InfrastructureComponent.Location = *payload.Status.Location
|
|
||||||
}
|
|
||||||
if payload.Status.Description != nil {
|
|
||||||
newICReq.InfrastructureComponent.Description = *payload.Status.Description
|
|
||||||
}
|
|
||||||
if payload.Status.Uptime != nil {
|
|
||||||
newICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime
|
|
||||||
}
|
|
||||||
// TODO add JSON start parameter scheme
|
|
||||||
|
|
||||||
// set managed externally to true because this IC is created via AMQP
|
|
||||||
newICReq.InfrastructureComponent.ManagedExternally = newTrue()
|
|
||||||
|
|
||||||
// Validate the new IC
|
|
||||||
err := newICReq.validate()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AMQP: Validation of new IC failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the new IC
|
|
||||||
newIC, err := newICReq.createIC(true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AMQP: Creating new IC failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// save IC
|
|
||||||
err = newIC.Save()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AMQP: Saving new IC to DB failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *InfrastructureComponent) updateICviaAMQP(payload ICUpdate) error {
|
|
||||||
|
|
||||||
var updatedICReq UpdateICRequest
|
|
||||||
if payload.Status.State != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.State = *payload.Status.State
|
|
||||||
|
|
||||||
if *payload.Status.State == "gone" {
|
|
||||||
// remove IC from DB
|
|
||||||
log.Println("########## AMQP: Deleting IC with state gone")
|
|
||||||
err := s.delete(true)
|
|
||||||
if err != nil {
|
|
||||||
// if component could not be deleted there are still configurations using it in the DB
|
|
||||||
// continue with the update to save the new state of the component and get back to the deletion later
|
|
||||||
log.Println("########## AMQP: Deletion of IC postponed (config(s) associated to it)")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if payload.Status.Type != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.Type = *payload.Status.Type
|
|
||||||
}
|
|
||||||
if payload.Status.Category != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.Category = *payload.Status.Category
|
|
||||||
}
|
|
||||||
if payload.Status.Name != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.Name = *payload.Status.Name
|
|
||||||
}
|
|
||||||
if payload.Status.WS_url != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.WebsocketURL = *payload.Status.WS_url
|
|
||||||
}
|
|
||||||
if payload.Status.API_url != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.APIURL = *payload.Status.API_url
|
|
||||||
}
|
|
||||||
if payload.Status.Location != nil {
|
|
||||||
//postgres.Jsonb{json.RawMessage(`{"location" : " ` + *payload.Status.Location + `"}`)}
|
|
||||||
updatedICReq.InfrastructureComponent.Location = *payload.Status.Location
|
|
||||||
}
|
|
||||||
if payload.Status.Description != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.Description = *payload.Status.Description
|
|
||||||
}
|
|
||||||
if payload.Status.Uptime != nil {
|
|
||||||
updatedICReq.InfrastructureComponent.Uptime = *payload.Status.Uptime
|
|
||||||
}
|
|
||||||
// TODO add JSON start parameter scheme
|
|
||||||
|
|
||||||
// set managed externally to true because this IC is updated via AMQP
|
|
||||||
updatedICReq.InfrastructureComponent.ManagedExternally = newTrue()
|
|
||||||
|
|
||||||
// Validate the updated IC
|
|
||||||
err := updatedICReq.validate()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AMQP: Validation of updated IC failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the updated IC from old IC
|
|
||||||
updatedIC, err := updatedICReq.updatedIC(*s, true)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AMQP: Unable to update IC %v : %v", s.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally update the IC in the DB
|
|
||||||
err = s.Update(updatedIC)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("AMQP: Unable to update IC %v in DB: %v", s.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTrue() *bool {
|
|
||||||
b := true
|
|
||||||
return &b
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ func CheckPermissions(c *gin.Context, modeltype database.ModelName, operation da
|
||||||
return false, s
|
return false, s
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.ByID(uint(ICID))
|
err = s.byID(uint(ICID))
|
||||||
if helper.DBError(c, err) {
|
if helper.DBError(c, err) {
|
||||||
return false, s
|
return false, s
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,11 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/helper"
|
||||||
|
component_configuration "git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/component-configuration"
|
||||||
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/routes/scenario"
|
||||||
"github.com/jinzhu/gorm/dialects/postgres"
|
"github.com/jinzhu/gorm/dialects/postgres"
|
||||||
"github.com/streadway/amqp"
|
"github.com/streadway/amqp"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -41,6 +42,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var router *gin.Engine
|
var router *gin.Engine
|
||||||
|
var api *gin.RouterGroup
|
||||||
|
var waitingTime time.Duration = 2
|
||||||
|
|
||||||
type ICRequest struct {
|
type ICRequest struct {
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID string `json:"uuid,omitempty"`
|
||||||
|
@ -53,7 +56,21 @@ type ICRequest struct {
|
||||||
Location string `json:"location,omitempty"`
|
Location string `json:"location,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
StartParameterScheme postgres.Jsonb `json:"startparameterscheme,omitempty"`
|
StartParameterScheme postgres.Jsonb `json:"startparameterscheme,omitempty"`
|
||||||
ManagedExternally *bool `json:"managedexternally,omitempty"`
|
ManagedExternally *bool `json:"managedexternally"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ScenarioRequest struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Running bool `json:"running,omitempty"`
|
||||||
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigRequest struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
ScenarioID uint `json:"scenarioID,omitempty"`
|
||||||
|
ICID uint `json:"icID,omitempty"`
|
||||||
|
StartParameters postgres.Jsonb `json:"startParameters,omitempty"`
|
||||||
|
FileIDs []int64 `json:"fileIDs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ICAction struct {
|
type ICAction struct {
|
||||||
|
@ -84,25 +101,16 @@ func TestMain(m *testing.M) {
|
||||||
defer database.DBpool.Close()
|
defer database.DBpool.Close()
|
||||||
|
|
||||||
router = gin.Default()
|
router = gin.Default()
|
||||||
api := router.Group("/api")
|
api = router.Group("/api")
|
||||||
|
|
||||||
user.RegisterAuthenticate(api.Group("/authenticate"))
|
user.RegisterAuthenticate(api.Group("/authenticate"))
|
||||||
api.Use(user.Authentication(true))
|
api.Use(user.Authentication(true))
|
||||||
RegisterICEndpoints(api.Group("/ic"))
|
RegisterICEndpoints(api.Group("/ic"))
|
||||||
RegisterAMQPEndpoint(api.Group("/ic"))
|
// component configuration endpoints required to associate an IC with a component config
|
||||||
|
component_configuration.RegisterComponentConfigurationEndpoints(api.Group("/configs"))
|
||||||
// connect AMQP client (make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set via command line parameters)
|
// scenario endpoints required here to first add a scenario to the DB
|
||||||
host, err := configuration.GolbalConfig.String("amqp.host")
|
// that can be associated with a new component configuration
|
||||||
user, err := configuration.GolbalConfig.String("amqp.user")
|
scenario.RegisterScenarioEndpoints(api.Group("/scenarios"))
|
||||||
pass, err := configuration.GolbalConfig.String("amqp.pass")
|
|
||||||
|
|
||||||
amqpURI := "amqp://" + user + ":" + pass + "@" + host
|
|
||||||
log.Println("AMQP URI is", amqpURI)
|
|
||||||
|
|
||||||
err = ConnectAMQP(amqpURI)
|
|
||||||
if err != nil {
|
|
||||||
panic(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
@ -112,6 +120,22 @@ func TestAddICAsAdmin(t *testing.T) {
|
||||||
database.MigrateModels()
|
database.MigrateModels()
|
||||||
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
|
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
|
||||||
|
|
||||||
|
// check AMQP connection
|
||||||
|
err := CheckConnection()
|
||||||
|
assert.Errorf(t, err, "connection is nil")
|
||||||
|
|
||||||
|
// connect AMQP client
|
||||||
|
// Make sure that AMQP_HOST, AMQP_USER, AMQP_PASS are set
|
||||||
|
host, err := configuration.GolbalConfig.String("amqp.host")
|
||||||
|
user, err := configuration.GolbalConfig.String("amqp.user")
|
||||||
|
pass, err := configuration.GolbalConfig.String("amqp.pass")
|
||||||
|
amqpURI := "amqp://" + user + ":" + pass + "@" + host
|
||||||
|
|
||||||
|
// AMQP Connection startup is tested here
|
||||||
|
// Not repeated in other tests because it is only needed once
|
||||||
|
err = StartAMQP(amqpURI, api)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// authenticate as admin
|
// authenticate as admin
|
||||||
token, err := helper.AuthenticateForTest(router,
|
token, err := helper.AuthenticateForTest(router,
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
|
@ -146,7 +170,7 @@ func TestAddICAsAdmin(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
|
@ -178,6 +202,30 @@ func TestAddICAsAdmin(t *testing.T) {
|
||||||
fmt.Sprintf("/api/ic/%v", newICID+1), "GET", nil)
|
fmt.Sprintf("/api/ic/%v", newICID+1), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 404, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
newExternalIC := ICRequest{
|
||||||
|
UUID: helper.ICB.UUID,
|
||||||
|
WebsocketURL: helper.ICB.WebsocketURL,
|
||||||
|
APIURL: helper.ICB.APIURL,
|
||||||
|
Type: helper.ICB.Type,
|
||||||
|
Name: helper.ICB.Name,
|
||||||
|
Category: helper.ICB.Category,
|
||||||
|
State: helper.ICB.State,
|
||||||
|
Location: helper.ICB.Location,
|
||||||
|
Description: helper.ICB.Description,
|
||||||
|
StartParameterScheme: helper.ICB.StartParameterScheme,
|
||||||
|
ManagedExternally: newTrue(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// test creation of external IC (should lead to emission of AMQP message to VILLAS)
|
||||||
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
|
"/api/ic", "POST", helper.KeyModels{"ic": newExternalIC})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
// Compare POST's response with the newExternalIC
|
||||||
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newExternalIC})
|
||||||
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddICAsUser(t *testing.T) {
|
func TestAddICAsUser(t *testing.T) {
|
||||||
|
@ -201,7 +249,7 @@ func TestAddICAsUser(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should fail with unprocessable entity 422 error code
|
// This should fail with unprocessable entity 422 error code
|
||||||
|
@ -233,7 +281,7 @@ func TestUpdateICAsAdmin(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
|
@ -277,6 +325,54 @@ func TestUpdateICAsAdmin(t *testing.T) {
|
||||||
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
err = helper.CompareResponse(resp, helper.KeyModels{"ic": newIC})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// fake an IC update (create) message
|
||||||
|
var update ICUpdate
|
||||||
|
update.Status = new(ICStatus)
|
||||||
|
update.Status.UUID = helper.ICB.UUID
|
||||||
|
update.Status.State = new(string)
|
||||||
|
*update.Status.State = "idle"
|
||||||
|
update.Status.Name = new(string)
|
||||||
|
*update.Status.Name = helper.ICB.Name
|
||||||
|
update.Status.Category = new(string)
|
||||||
|
*update.Status.Category = helper.ICB.Category
|
||||||
|
update.Status.Type = new(string)
|
||||||
|
*update.Status.Type = helper.ICB.Type
|
||||||
|
|
||||||
|
payload, err := json.Marshal(update)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
msg := amqp.Publishing{
|
||||||
|
DeliveryMode: 2,
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
ContentType: "application/json",
|
||||||
|
ContentEncoding: "utf-8",
|
||||||
|
Priority: 0,
|
||||||
|
Body: payload,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = CheckConnection()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = client.channel.Publish(VILLAS_EXCHANGE,
|
||||||
|
"",
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
msg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Wait until externally managed IC is created (happens async)
|
||||||
|
time.Sleep(waitingTime * time.Second)
|
||||||
|
|
||||||
|
// try to update this IC
|
||||||
|
var updatedIC ICRequest
|
||||||
|
updatedIC.Name = "a new name"
|
||||||
|
updatedIC.ManagedExternally = newTrue()
|
||||||
|
|
||||||
|
// Should result in forbidden return code 403
|
||||||
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
|
fmt.Sprintf("/api/ic/%v", 2), "PUT", helper.KeyModels{"ic": updatedIC})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equalf(t, 403, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateICAsUser(t *testing.T) {
|
func TestUpdateICAsUser(t *testing.T) {
|
||||||
|
@ -300,7 +396,7 @@ func TestUpdateICAsUser(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
|
@ -347,7 +443,7 @@ func TestDeleteICAsAdmin(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
|
@ -379,6 +475,58 @@ func TestDeleteICAsAdmin(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, finalNumber, initialNumber-1)
|
assert.Equal(t, finalNumber, initialNumber-1)
|
||||||
|
|
||||||
|
// fake an IC update (create) message
|
||||||
|
var update ICUpdate
|
||||||
|
update.Status = new(ICStatus)
|
||||||
|
update.Status.UUID = helper.ICB.UUID
|
||||||
|
update.Status.State = new(string)
|
||||||
|
*update.Status.State = "idle"
|
||||||
|
update.Status.Name = new(string)
|
||||||
|
*update.Status.Name = helper.ICB.Name
|
||||||
|
update.Status.Category = new(string)
|
||||||
|
*update.Status.Category = helper.ICB.Category
|
||||||
|
update.Status.Type = new(string)
|
||||||
|
*update.Status.Type = helper.ICB.Type
|
||||||
|
|
||||||
|
payload, err := json.Marshal(update)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
msg := amqp.Publishing{
|
||||||
|
DeliveryMode: 2,
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
ContentType: "application/json",
|
||||||
|
ContentEncoding: "utf-8",
|
||||||
|
Priority: 0,
|
||||||
|
Body: payload,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = CheckConnection()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = client.channel.Publish(VILLAS_EXCHANGE,
|
||||||
|
"",
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
msg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Wait until externally managed IC is created (happens async)
|
||||||
|
time.Sleep(waitingTime * time.Second)
|
||||||
|
|
||||||
|
// Delete the added external IC (triggers an AMQP message, but should not remove the IC from the DB)
|
||||||
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
|
fmt.Sprintf("/api/ic/%v", 2), "DELETE", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
// Again count the number of all the ICs returned
|
||||||
|
finalNumberAfterExtneralDelete, err := helper.LengthOfResponse(router, token,
|
||||||
|
"/api/ic", "GET", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, finalNumber+1, finalNumberAfterExtneralDelete)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteICAsUser(t *testing.T) {
|
func TestDeleteICAsUser(t *testing.T) {
|
||||||
|
@ -402,7 +550,7 @@ func TestDeleteICAsUser(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
"/api/ic", "POST", helper.KeyModels{"ic": newIC})
|
||||||
|
@ -453,7 +601,7 @@ func TestGetAllICs(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
|
@ -471,8 +619,9 @@ func TestGetAllICs(t *testing.T) {
|
||||||
Location: helper.ICB.Location,
|
Location: helper.ICB.Location,
|
||||||
Description: helper.ICB.Description,
|
Description: helper.ICB.Description,
|
||||||
StartParameterScheme: helper.ICB.StartParameterScheme,
|
StartParameterScheme: helper.ICB.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICB.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
|
|
||||||
code, resp, err = helper.TestEndpoint(router, token,
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newICB})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICB})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -519,7 +668,7 @@ func TestGetConfigsOfIC(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
|
@ -531,7 +680,6 @@ func TestGetConfigsOfIC(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test GET ic/ID/confis
|
// test GET ic/ID/confis
|
||||||
// TODO how to properly test this without using component configuration endpoints?
|
|
||||||
numberOfConfigs, err := helper.LengthOfResponse(router, token,
|
numberOfConfigs, err := helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/ic/%v/configs", newICID), "GET", nil)
|
fmt.Sprintf("/api/ic/%v/configs", newICID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -545,7 +693,6 @@ func TestGetConfigsOfIC(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// test GET ic/ID/configs
|
// test GET ic/ID/configs
|
||||||
// TODO how to properly test this without using component configuration endpoints?
|
|
||||||
numberOfConfigs, err = helper.LengthOfResponse(router, token,
|
numberOfConfigs, err = helper.LengthOfResponse(router, token,
|
||||||
fmt.Sprintf("/api/ic/%v/configs", newICID), "GET", nil)
|
fmt.Sprintf("/api/ic/%v/configs", newICID), "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -582,7 +729,7 @@ func TestSendActionToIC(t *testing.T) {
|
||||||
Location: helper.ICA.Location,
|
Location: helper.ICA.Location,
|
||||||
Description: helper.ICA.Description,
|
Description: helper.ICA.Description,
|
||||||
StartParameterScheme: helper.ICA.StartParameterScheme,
|
StartParameterScheme: helper.ICA.StartParameterScheme,
|
||||||
ManagedExternally: &helper.ICA.ManagedExternally,
|
ManagedExternally: newFalse(),
|
||||||
}
|
}
|
||||||
code, resp, err := helper.TestEndpoint(router, token,
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
"/api/ic", "POST", helper.KeyModels{"ic": newICA})
|
||||||
|
@ -615,24 +762,23 @@ func TestSendActionToIC(t *testing.T) {
|
||||||
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
assert.Equalf(t, 400, code, "Response body: \n%v\n", resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateUpdateDeleteViaAMQPRecv(t *testing.T) {
|
func TestCreateUpdateViaAMQPRecv(t *testing.T) {
|
||||||
|
|
||||||
database.DropTables()
|
database.DropTables()
|
||||||
database.MigrateModels()
|
database.MigrateModels()
|
||||||
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
|
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
|
||||||
|
|
||||||
|
// authenticate as admin
|
||||||
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// fake an IC update message
|
// fake an IC update message
|
||||||
var update ICUpdate
|
var update ICUpdate
|
||||||
update.Status = new(ICStatus)
|
update.Status = new(ICStatus)
|
||||||
update.Status.UUID = helper.ICA.UUID
|
update.Status.UUID = helper.ICA.UUID
|
||||||
update.Status.State = new(string)
|
update.Status.State = new(string)
|
||||||
*update.Status.State = "idle"
|
*update.Status.State = "idle"
|
||||||
update.Status.Name = new(string)
|
|
||||||
*update.Status.Name = helper.ICA.Name
|
|
||||||
update.Status.Category = new(string)
|
|
||||||
*update.Status.Category = helper.ICA.Category
|
|
||||||
update.Status.Type = new(string)
|
|
||||||
*update.Status.Type = helper.ICA.Type
|
|
||||||
|
|
||||||
payload, err := json.Marshal(update)
|
payload, err := json.Marshal(update)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -648,6 +794,50 @@ func TestCreateUpdateDeleteViaAMQPRecv(t *testing.T) {
|
||||||
|
|
||||||
err = CheckConnection()
|
err = CheckConnection()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
err = client.channel.Publish(VILLAS_EXCHANGE,
|
||||||
|
"",
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
msg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(waitingTime * time.Second)
|
||||||
|
|
||||||
|
// get the length of the GET all ICs response for user
|
||||||
|
number, err := helper.LengthOfResponse(router, token,
|
||||||
|
"/api/ic", "GET", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 0, number)
|
||||||
|
|
||||||
|
// complete the (required) data of an IC
|
||||||
|
update.Status.Name = new(string)
|
||||||
|
*update.Status.Name = helper.ICA.Name
|
||||||
|
update.Status.Category = new(string)
|
||||||
|
*update.Status.Category = helper.ICA.Category
|
||||||
|
update.Status.Type = new(string)
|
||||||
|
*update.Status.Type = helper.ICA.Type
|
||||||
|
update.Status.Uptime = new(float64)
|
||||||
|
*update.Status.Uptime = -1.0
|
||||||
|
update.Status.WS_url = new(string)
|
||||||
|
*update.Status.WS_url = helper.ICA.WebsocketURL
|
||||||
|
update.Status.API_url = new(string)
|
||||||
|
*update.Status.API_url = helper.ICA.APIURL
|
||||||
|
update.Status.Description = new(string)
|
||||||
|
*update.Status.Description = helper.ICA.Description
|
||||||
|
update.Status.Location = new(string)
|
||||||
|
*update.Status.Location = helper.ICA.Location
|
||||||
|
|
||||||
|
payload, err = json.Marshal(update)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
msg = amqp.Publishing{
|
||||||
|
DeliveryMode: 2,
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
ContentType: "application/json",
|
||||||
|
ContentEncoding: "utf-8",
|
||||||
|
Priority: 0,
|
||||||
|
Body: payload,
|
||||||
|
}
|
||||||
|
|
||||||
err = client.channel.Publish(VILLAS_EXCHANGE,
|
err = client.channel.Publish(VILLAS_EXCHANGE,
|
||||||
"",
|
"",
|
||||||
|
@ -656,14 +846,10 @@ func TestCreateUpdateDeleteViaAMQPRecv(t *testing.T) {
|
||||||
msg)
|
msg)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
time.Sleep(4 * time.Second)
|
time.Sleep(waitingTime * time.Second)
|
||||||
// authenticate as admin
|
|
||||||
token, err := helper.AuthenticateForTest(router,
|
|
||||||
"/api/authenticate", "POST", helper.AdminCredentials)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// get the length of the GET all ICs response for user
|
// get the length of the GET all ICs response for user
|
||||||
number, err := helper.LengthOfResponse(router, token,
|
number, err = helper.LengthOfResponse(router, token,
|
||||||
"/api/ic", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, number)
|
assert.Equal(t, 1, number)
|
||||||
|
@ -689,13 +875,121 @@ func TestCreateUpdateDeleteViaAMQPRecv(t *testing.T) {
|
||||||
msg)
|
msg)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
time.Sleep(4 * time.Second)
|
time.Sleep(waitingTime * time.Second)
|
||||||
// get the length of the GET all ICs response for user
|
// get the length of the GET all ICs response for user
|
||||||
number, err = helper.LengthOfResponse(router, token,
|
number, err = helper.LengthOfResponse(router, token,
|
||||||
"/api/ic", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, number)
|
assert.Equal(t, 1, number)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteICViaAMQPRecv(t *testing.T) {
|
||||||
|
|
||||||
|
database.DropTables()
|
||||||
|
database.MigrateModels()
|
||||||
|
assert.NoError(t, helper.DBAddAdminAndUserAndGuest())
|
||||||
|
|
||||||
|
// authenticate as admin
|
||||||
|
token, err := helper.AuthenticateForTest(router,
|
||||||
|
"/api/authenticate", "POST", helper.AdminCredentials)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// fake an IC update message
|
||||||
|
var update ICUpdate
|
||||||
|
update.Status = new(ICStatus)
|
||||||
|
update.Status.UUID = helper.ICA.UUID
|
||||||
|
update.Status.State = new(string)
|
||||||
|
*update.Status.State = "idle"
|
||||||
|
// complete the (required) data of an IC
|
||||||
|
update.Status.Name = new(string)
|
||||||
|
*update.Status.Name = helper.ICA.Name
|
||||||
|
update.Status.Category = new(string)
|
||||||
|
*update.Status.Category = helper.ICA.Category
|
||||||
|
update.Status.Type = new(string)
|
||||||
|
*update.Status.Type = helper.ICA.Type
|
||||||
|
update.Status.Uptime = new(float64)
|
||||||
|
*update.Status.Uptime = -1.0
|
||||||
|
update.Status.WS_url = new(string)
|
||||||
|
*update.Status.WS_url = helper.ICA.WebsocketURL
|
||||||
|
update.Status.API_url = new(string)
|
||||||
|
*update.Status.API_url = helper.ICA.APIURL
|
||||||
|
update.Status.Description = new(string)
|
||||||
|
*update.Status.Description = helper.ICA.Description
|
||||||
|
update.Status.Location = new(string)
|
||||||
|
*update.Status.Location = helper.ICA.Location
|
||||||
|
|
||||||
|
payload, err := json.Marshal(update)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
msg := amqp.Publishing{
|
||||||
|
DeliveryMode: 2,
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
ContentType: "application/json",
|
||||||
|
ContentEncoding: "utf-8",
|
||||||
|
Priority: 0,
|
||||||
|
Body: payload,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = CheckConnection()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = client.channel.Publish(VILLAS_EXCHANGE,
|
||||||
|
"",
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
msg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(waitingTime * time.Second)
|
||||||
|
|
||||||
|
// get the length of the GET all ICs response for user
|
||||||
|
number, err := helper.LengthOfResponse(router, token,
|
||||||
|
"/api/ic", "GET", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, number)
|
||||||
|
|
||||||
|
// add scenario
|
||||||
|
newScenario := ScenarioRequest{
|
||||||
|
Name: helper.ScenarioA.Name,
|
||||||
|
Running: helper.ScenarioA.Running,
|
||||||
|
StartParameters: helper.ScenarioA.StartParameters,
|
||||||
|
}
|
||||||
|
|
||||||
|
code, resp, err := helper.TestEndpoint(router, token,
|
||||||
|
"/api/scenarios", "POST", helper.KeyModels{"scenario": newScenario})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
// Compare POST's response with the newScenario
|
||||||
|
err = helper.CompareResponse(resp, helper.KeyModels{"scenario": newScenario})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Read newScenario's ID from the response
|
||||||
|
newScenarioID, err := helper.GetResponseID(resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Add component config and associate with IC and scenario
|
||||||
|
newConfig := ConfigRequest{
|
||||||
|
Name: helper.ConfigA.Name,
|
||||||
|
ScenarioID: uint(newScenarioID),
|
||||||
|
ICID: 1,
|
||||||
|
StartParameters: helper.ConfigA.StartParameters,
|
||||||
|
FileIDs: helper.ConfigA.FileIDs,
|
||||||
|
}
|
||||||
|
|
||||||
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
|
"/api/configs", "POST", helper.KeyModels{"config": newConfig})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
// Compare POST's response with the newConfig
|
||||||
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": newConfig})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Read newConfig's ID from the response
|
||||||
|
newConfigID, err := helper.GetResponseID(resp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// modify status update to state "gone"
|
// modify status update to state "gone"
|
||||||
*update.Status.State = "gone"
|
*update.Status.State = "gone"
|
||||||
payload, err = json.Marshal(update)
|
payload, err = json.Marshal(update)
|
||||||
|
@ -710,6 +1004,7 @@ func TestCreateUpdateDeleteViaAMQPRecv(t *testing.T) {
|
||||||
Body: payload,
|
Body: payload,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attempt to delete IC (should not work immediately because IC is still associated with component config)
|
||||||
err = client.channel.Publish(VILLAS_EXCHANGE,
|
err = client.channel.Publish(VILLAS_EXCHANGE,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -717,15 +1012,27 @@ func TestCreateUpdateDeleteViaAMQPRecv(t *testing.T) {
|
||||||
msg)
|
msg)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
time.Sleep(4 * time.Second)
|
time.Sleep(waitingTime * time.Second)
|
||||||
|
|
||||||
|
// get the length of the GET all ICs response for user
|
||||||
|
number, err = helper.LengthOfResponse(router, token,
|
||||||
|
"/api/ic", "GET", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, number)
|
||||||
|
|
||||||
|
// Delete component config from earlier
|
||||||
|
code, resp, err = helper.TestEndpoint(router, token,
|
||||||
|
fmt.Sprintf("/api/configs/%v", newConfigID), "DELETE", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equalf(t, 200, code, "Response body: \n%v\n", resp)
|
||||||
|
|
||||||
|
// Compare DELETE's response with the newConfig
|
||||||
|
err = helper.CompareResponse(resp, helper.KeyModels{"config": newConfig})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// get the length of the GET all ICs response for user
|
// get the length of the GET all ICs response for user
|
||||||
number, err = helper.LengthOfResponse(router, token,
|
number, err = helper.LengthOfResponse(router, token,
|
||||||
"/api/ic", "GET", nil)
|
"/api/ic", "GET", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 0, number)
|
assert.Equal(t, 0, number)
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateDeleteViaAMQPSend(t *testing.T) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ package infrastructure_component
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jinzhu/gorm/dialects/postgres"
|
"github.com/jinzhu/gorm/dialects/postgres"
|
||||||
"github.com/nsf/jsondiff"
|
"github.com/nsf/jsondiff"
|
||||||
|
@ -60,7 +59,6 @@ type validUpdatedIC struct {
|
||||||
Location string `form:"Location" validate:"omitempty"`
|
Location string `form:"Location" validate:"omitempty"`
|
||||||
Description string `form:"Description" validate:"omitempty"`
|
Description string `form:"Description" validate:"omitempty"`
|
||||||
StartParameterScheme postgres.Jsonb `form:"StartParameterScheme" validate:"omitempty"`
|
StartParameterScheme postgres.Jsonb `form:"StartParameterScheme" validate:"omitempty"`
|
||||||
ManagedExternally *bool `form:"ManagedExternally" validate:"required"`
|
|
||||||
Uptime float64 `form:"Uptime" validate:"omitempty"`
|
Uptime float64 `form:"Uptime" validate:"omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,43 +132,36 @@ func (r *AddICRequest) createIC(receivedViaAMQP bool) (InfrastructureComponent,
|
||||||
*action.Properties.UUID = r.InfrastructureComponent.UUID
|
*action.Properties.UUID = r.InfrastructureComponent.UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("########## AMQP: Sending request to create new IC")
|
log.Println("AMQP: Sending request to create new IC")
|
||||||
err = sendActionAMQP(action)
|
err = sendActionAMQP(action)
|
||||||
|
|
||||||
// s remains empty
|
|
||||||
|
|
||||||
} else {
|
|
||||||
s.UUID = r.InfrastructureComponent.UUID
|
|
||||||
s.WebsocketURL = r.InfrastructureComponent.WebsocketURL
|
|
||||||
s.APIURL = r.InfrastructureComponent.APIURL
|
|
||||||
s.Type = r.InfrastructureComponent.Type
|
|
||||||
s.Name = r.InfrastructureComponent.Name
|
|
||||||
s.Category = r.InfrastructureComponent.Category
|
|
||||||
s.Location = r.InfrastructureComponent.Location
|
|
||||||
s.Description = r.InfrastructureComponent.Description
|
|
||||||
s.StartParameterScheme = r.InfrastructureComponent.StartParameterScheme
|
|
||||||
s.ManagedExternally = *r.InfrastructureComponent.ManagedExternally
|
|
||||||
s.Uptime = -1.0 // no uptime available
|
|
||||||
if r.InfrastructureComponent.State != "" {
|
|
||||||
s.State = r.InfrastructureComponent.State
|
|
||||||
} else {
|
|
||||||
s.State = "unknown"
|
|
||||||
}
|
|
||||||
// set last update to creation time of IC
|
|
||||||
s.StateUpdateAt = time.Now().Format(time.RFC1123)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.UUID = r.InfrastructureComponent.UUID
|
||||||
|
s.WebsocketURL = r.InfrastructureComponent.WebsocketURL
|
||||||
|
s.APIURL = r.InfrastructureComponent.APIURL
|
||||||
|
s.Type = r.InfrastructureComponent.Type
|
||||||
|
s.Name = r.InfrastructureComponent.Name
|
||||||
|
s.Category = r.InfrastructureComponent.Category
|
||||||
|
s.Location = r.InfrastructureComponent.Location
|
||||||
|
s.Description = r.InfrastructureComponent.Description
|
||||||
|
s.StartParameterScheme = r.InfrastructureComponent.StartParameterScheme
|
||||||
|
s.ManagedExternally = *r.InfrastructureComponent.ManagedExternally
|
||||||
|
s.Uptime = -1.0 // no uptime available
|
||||||
|
if r.InfrastructureComponent.State != "" {
|
||||||
|
s.State = r.InfrastructureComponent.State
|
||||||
|
} else {
|
||||||
|
s.State = "unknown"
|
||||||
|
}
|
||||||
|
// set last update to creation time of IC
|
||||||
|
s.StateUpdateAt = time.Now().Format(time.RFC1123)
|
||||||
|
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UpdateICRequest) updatedIC(oldIC InfrastructureComponent, receivedViaAMQP bool) (InfrastructureComponent, error) {
|
func (r *UpdateICRequest) updatedIC(oldIC InfrastructureComponent) InfrastructureComponent {
|
||||||
// Use the old InfrastructureComponent as a basis for the updated InfrastructureComponent `s`
|
// Use the old InfrastructureComponent as a basis for the updated InfrastructureComponent `s`
|
||||||
s := oldIC
|
s := oldIC
|
||||||
|
|
||||||
if s.ManagedExternally && !receivedViaAMQP {
|
|
||||||
// externally managed IC cannot be updated via API, only via AMQP
|
|
||||||
return s, fmt.Errorf("cannot update externally managed IC %v", s.Name)
|
|
||||||
}
|
|
||||||
if r.InfrastructureComponent.UUID != "" {
|
if r.InfrastructureComponent.UUID != "" {
|
||||||
s.UUID = r.InfrastructureComponent.UUID
|
s.UUID = r.InfrastructureComponent.UUID
|
||||||
}
|
}
|
||||||
|
@ -207,10 +198,6 @@ func (r *UpdateICRequest) updatedIC(oldIC InfrastructureComponent, receivedViaAM
|
||||||
s.Description = r.InfrastructureComponent.Description
|
s.Description = r.InfrastructureComponent.Description
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.InfrastructureComponent.ManagedExternally != nil {
|
|
||||||
s.ManagedExternally = *r.InfrastructureComponent.ManagedExternally
|
|
||||||
}
|
|
||||||
|
|
||||||
// set last update time
|
// set last update time
|
||||||
s.StateUpdateAt = time.Now().Format(time.RFC1123)
|
s.StateUpdateAt = time.Now().Format(time.RFC1123)
|
||||||
|
|
||||||
|
@ -225,5 +212,5 @@ func (r *UpdateICRequest) updatedIC(oldIC InfrastructureComponent, receivedViaAM
|
||||||
s.StartParameterScheme = r.InfrastructureComponent.StartParameterScheme
|
s.StartParameterScheme = r.InfrastructureComponent.StartParameterScheme
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue