From abf188c7683d376a93c6057e2706e05cbced6446 Mon Sep 17 00:00:00 2001 From: AungAyeThan Date: Thu, 3 Nov 2022 00:10:00 +0700 Subject: [PATCH] wip: prepare request body to send data to sheetpilot --- go.mod | 2 +- go.sum | 4 +- internal/controller/sheetpilotcontroller.go | 22 ++++- internal/model/scale.go | 103 ++++++++++++++++++++ internal/scaleservice/scaleservice.go | 6 +- 5 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 internal/model/scale.go diff --git a/go.mod b/go.mod index 559c91d..fd1db65 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 - github.com/sheetpilot/sheet-pilot-proto v0.0.0-20221002024531-181df7ba5484 + github.com/sheetpilot/sheet-pilot-proto v0.0.0-20221030074648-5ffc14269bf3 github.com/sirupsen/logrus v1.9.0 google.golang.org/grpc v1.49.0 ) diff --git a/go.sum b/go.sum index 56e68a6..32441c6 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/sheetpilot/sheet-pilot-proto v0.0.0-20221002024531-181df7ba5484 h1:GSpZek352LjdwzxzZeoVXnk1xXiIKet2WKoVa2CChSE= -github.com/sheetpilot/sheet-pilot-proto v0.0.0-20221002024531-181df7ba5484/go.mod h1:CNFg4Db2CyYvdHQHynosUVK5qXOON4SuPe4jxoeSP+4= +github.com/sheetpilot/sheet-pilot-proto v0.0.0-20221030074648-5ffc14269bf3 h1:y8Vyfv0s48klT0EXJ4TG16X0/M0H1nKnoKzrfkkbiro= +github.com/sheetpilot/sheet-pilot-proto v0.0.0-20221030074648-5ffc14269bf3/go.mod h1:CNFg4Db2CyYvdHQHynosUVK5qXOON4SuPe4jxoeSP+4= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/internal/controller/sheetpilotcontroller.go b/internal/controller/sheetpilotcontroller.go index 6be0305..c4c6180 100644 --- a/internal/controller/sheetpilotcontroller.go +++ b/internal/controller/sheetpilotcontroller.go @@ -1,10 +1,13 @@ package controller import ( + "context" "net/http" + "time" "github.com/gorilla/mux" + "github.com/sheetpilot/sheet-pilot-api/internal/model" "github.com/sheetpilot/sheet-pilot-api/internal/scaleservice" ) @@ -40,10 +43,23 @@ func (controller *SheetPilotController) healthCheck(w http.ResponseWriter, r *ht } func (app *SheetPilotController) scaleProcess(w http.ResponseWriter, r *http.Request) { - // ctx, cancel := context.WithTimeout(context.TODO(), time.Minute) - // defer cancel() + scale, err := model.TransformScaleObject(r.Body) + if err != nil { + return // TODO: return http error + } + + if err := scale.Validate(); err != nil { + return // TODO: return http error + } - // response, err := app.scaleservice.SendScaleRequest(ctx) + ctx, cancel := context.WithTimeout(context.TODO(), time.Minute*3) + defer cancel() + + _, err = app.scaleservice.SendScaleRequest(ctx, scale.UpdatedRow) + if err != nil { + return // TODO: return http error + } + // TODO: return http response using response.Data return } diff --git a/internal/model/scale.go b/internal/model/scale.go new file mode 100644 index 0000000..96d1b25 --- /dev/null +++ b/internal/model/scale.go @@ -0,0 +1,103 @@ +package model + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "reflect" + "regexp" + "strings" + + pb "github.com/sheetpilot/sheet-pilot-proto/scaleservice" +) + +// [{"colName":"Applications","value":"api"},{"colName":"request CPU(string)","value":9},{"colName":"request Memory(string)","value":"5Gi"},{"colName":"limit CPU(string)","value":2},{"colName":"limit Memory(string)","value":"2Gi"},{"colName":"replica_count(int)","value":"6sd"}] +// type Scale struct { +// ColName string `json:"colName"` +// Value interface{} `json:"value"` +// } + +type ScaleObject struct { + Obj []map[string]any `json:"obj"` + + UpdatedRow []*pb.ScaleRequest_Updatedrow +} + +func TransformScaleObject(reqBody io.ReadCloser) (*ScaleObject, error) { + scaleObject := make([]map[string]any, 0) + + decoder := json.NewDecoder(reqBody) + err := decoder.Decode(&scaleObject) + if err != nil { + return nil, errors.New("failed to decode request body") + } + + return &ScaleObject{ + Obj: scaleObject, + }, nil +} + +func (s *ScaleObject) Validate() error { + if len(s.Obj) == 0 { + return errors.New("empty request") + } + + for _, field := range s.Obj { + colName, ok := field["colName"].(string) + if !ok { + return errors.New("invalid request: colName is missing") + } + + value, ok := field["value"] + if !ok { + return errors.New("invalid request: value is missing") + } + + regexStr, dataType, err := s.getTypeRegex(colName) + if err != nil { + return err + } + + if reflect.TypeOf(value).Kind() != dataType { + return fmt.Errorf("value: %v on col %s is not a valid type", value, colName) + } + + r := regexp.MustCompile(regexStr) + + valByte, _ := json.Marshal(value) + if !r.Match(valByte) { + return errors.New("validation error") + } + + s.appendScaleProto(colName, string(valByte), dataType.String()) + } + + return nil +} + +func (s *ScaleObject) appendScaleProto(colName string, value string, dataType string) { + s.UpdatedRow = append(s.UpdatedRow, &pb.ScaleRequest_Updatedrow{ + ColName: colName, + Value: value, + DataType: dataType, + }) +} + +func (s *ScaleObject) getTypeRegex(colName string) (string, reflect.Kind, error) { + allowedTypes := map[string]reflect.Kind{ + "string": reflect.String, + "int": reflect.Int, + } + colNameSperator := strings.Split(colName, "|") + if len(colNameSperator) != 2 { + return "", reflect.Invalid, errors.New("colName is invalid") + } + + valType, ok := allowedTypes[colNameSperator[1]] + if !ok { + return "", reflect.Invalid, fmt.Errorf("invalid column value type: %s", colNameSperator[1]) + } + + return colNameSperator[2], valType, nil +} diff --git a/internal/scaleservice/scaleservice.go b/internal/scaleservice/scaleservice.go index 53ef82d..035bcaa 100644 --- a/internal/scaleservice/scaleservice.go +++ b/internal/scaleservice/scaleservice.go @@ -15,8 +15,10 @@ func New(log *logrus.Entry, client pb.ScaleServiceClient) (*ScaleService, error) return &ScaleService{client: client}, nil } -func (s *ScaleService) SendScaleRequest(ctx context.Context) (*pb.ScaleResponse, error) { - req := &pb.ScaleRequest{} +func (s *ScaleService) SendScaleRequest(ctx context.Context, updatedRow []*pb.ScaleRequest_Updatedrow) (*pb.ScaleResponse, error) { + req := &pb.ScaleRequest{ + UpdatedRow: updatedRow, + } response, err := s.client.ScaleServiceRequest(ctx, req) if err != nil {