in api/internal/handler/route/route.go [419:529]
func (h *Handler) Update(c droplet.Context) (interface{}, error) {
input := c.Input().(*UpdateInput)
// check if ID in body is equal ID in path
if err := handler.IDCompare(input.ID, input.Route.ID); err != nil {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
}
// if has id in path, use it
if input.ID != "" {
input.Route.ID = input.ID
}
//check depend
if input.ServiceID != nil {
serviceID := utils.InterfaceToString(input.ServiceID)
_, err := h.svcStore.Get(c.Context(), serviceID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
fmt.Errorf(consts.IDNotFound, "service", input.ServiceID)
}
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
}
}
if input.UpstreamID != nil {
upstreamID := utils.InterfaceToString(input.UpstreamID)
_, err := h.upstreamStore.Get(c.Context(), upstreamID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
fmt.Errorf("upstream id: %s not found", input.UpstreamID)
}
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
}
}
// If route's script_id is set, it must be equals to the route's id.
if input.Route.ScriptID != nil && (utils.InterfaceToString(input.ID) != utils.InterfaceToString(input.Route.ScriptID)) {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
fmt.Errorf("script_id must be the same as id")
}
if input.Script != nil {
script := &entity.Script{}
script.ID = input.ID
script.Script = input.Script
var err error
// Explicitly to lua if input script is of the map type, otherwise
// it will always represent a piece of lua code of the string type.
if scriptConf, ok := input.Script.(map[string]interface{}); ok {
// For lua code of map type, syntax validation is done by
// the generateLuaCode function
input.Route.Script, err = generateLuaCode(scriptConf)
if err != nil {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
}
} else {
// For lua code of string type, use utility func to syntax validation
err = utils.ValidateLuaCode(input.Script.(string))
if err != nil {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
}
}
//save original conf
if _, err = h.scriptStore.Update(c.Context(), script, true); err != nil {
//if not exists, create
if err.Error() == fmt.Sprintf("key: %s is not found", script.ID) {
if _, err := h.scriptStore.Create(c.Context(), script); err != nil {
return handler.SpecCodeResponse(err), err
}
} else {
return handler.SpecCodeResponse(err), err
}
}
// After updating the Script entity, always set route's script_id
// the same as route's id.
input.Route.ScriptID = input.ID
} else {
// If script is unset, script_id must be unset neither.
if input.Route.ScriptID != nil {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
fmt.Errorf("script_id cannot be set if script is unset")
}
//remove exists script
id := utils.InterfaceToString(input.Route.ID)
script, _ := h.scriptStore.Get(c.Context(), id)
if script != nil {
if err := h.scriptStore.BatchDelete(c.Context(), strings.Split(id, ",")); err != nil {
log.Warnf("delete script %s failed", input.Route.ID)
}
}
}
// check name existed
ret, err := handler.NameExistCheck(c.Context(), h.routeStore, "route", input.Name, input.ID)
if err != nil {
return ret, err
}
// create
res, err := h.routeStore.Update(c.Context(), &input.Route, true)
if err != nil {
return handler.SpecCodeResponse(err), err
}
return res, nil
}