Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make field ID compatible with both string and int #902

Merged
merged 8 commits into from
Nov 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions api/internal/core/entity/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,30 @@
package entity

import (
"reflect"
"time"

"github.com/apisix/manager-api/internal/utils"
)

type BaseInfo struct {
ID string `json:"id"`
CreateTime int64 `json:"create_time"`
UpdateTime int64 `json:"update_time"`
ID interface{} `json:"id"`
tokers marked this conversation as resolved.
Show resolved Hide resolved
CreateTime int64 `json:"create_time"`
UpdateTime int64 `json:"update_time"`
}

func (info *BaseInfo) GetBaseInfo() *BaseInfo {
return info
}

func (info *BaseInfo) Creating() {
if info.ID == "" {
if info.ID == nil {
info.ID = utils.GetFlakeUidStr()
} else {
// convert to string if it's not
if reflect.TypeOf(info.ID).String() != "string" {
info.ID = utils.InterfaceToString(info.ID)
}
}
info.CreateTime = time.Now().Unix()
info.UpdateTime = time.Now().Unix()
Expand Down Expand Up @@ -71,8 +77,8 @@ type Route struct {
Script interface{} `json:"script,omitempty"`
Plugins map[string]interface{} `json:"plugins,omitempty"`
Upstream *UpstreamDef `json:"upstream,omitempty"`
ServiceID string `json:"service_id,omitempty"`
UpstreamID string `json:"upstream_id,omitempty"`
ServiceID interface{} `json:"service_id,omitempty"`
UpstreamID interface{} `json:"upstream_id,omitempty"`
ServiceProtocol string `json:"service_protocol,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
EnableWebsocket bool `json:"enable_websocket,omitempty"`
Expand Down Expand Up @@ -161,8 +167,8 @@ type Upstream struct {
}

type UpstreamNameResponse struct {
ID string `json:"id"`
Name string `json:"name"`
ID interface{} `json:"id"`
Name string `json:"name"`
}

func (upstream *Upstream) Parse2NameResponse() (*UpstreamNameResponse, error) {
Expand Down Expand Up @@ -203,7 +209,7 @@ type Service struct {
Name string `json:"name,omitempty"`
Desc string `json:"desc,omitempty"`
Upstream *UpstreamDef `json:"upstream,omitempty"`
UpstreamID string `json:"upstream_id,omitempty"`
UpstreamID interface{} `json:"upstream_id,omitempty"`
Plugins map[string]interface{} `json:"plugins,omitempty"`
Script string `json:"script,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
Expand Down
9 changes: 7 additions & 2 deletions api/internal/core/entity/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@

package entity

import "strings"
import (
"strings"

"github.com/apisix/manager-api/internal/utils"
)

type PropertyName string

Expand Down Expand Up @@ -97,7 +101,8 @@ func (comparing ComparingInt) Contains(compared ComparableValue) bool {
func (info BaseInfo) GetProperty(name PropertyName) ComparableValue {
switch name {
case IdProperty:
return ComparingString(info.ID)
id := utils.InterfaceToString(info.ID)
return ComparingString(id)
case CreateTimeProperty:
return ComparingInt(info.CreateTime)
case UpdateTimeProperty:
Expand Down
5 changes: 4 additions & 1 deletion api/internal/core/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/utils"
"github.com/apisix/manager-api/log"
)

Expand Down Expand Up @@ -164,7 +165,9 @@ var defLessFunc = func(i, j interface{}) bool {
if iBase.UpdateTime != jBase.UpdateTime {
return iBase.UpdateTime < jBase.UpdateTime
}
return iBase.ID < jBase.ID
iID := utils.InterfaceToString(iBase.ID)
jID := utils.InterfaceToString(jBase.ID)
return iID < jID
}

func (s *GenericStore) List(input ListInput) (*ListOutput, error) {
Expand Down
4 changes: 3 additions & 1 deletion api/internal/core/store/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/storage"
"github.com/apisix/manager-api/internal/utils"
)

func TestNewGenericStore(t *testing.T) {
Expand Down Expand Up @@ -581,10 +582,11 @@ func TestGenericStore_Create(t *testing.T) {
assert.Equal(t, tc.wantKey, args[1], tc.caseDesc)
input := TestStruct{}
err := json.Unmarshal([]byte(args[2].(string)), &input)
id := utils.InterfaceToString(input.ID)
assert.Nil(t, err)
assert.Equal(t, tc.giveObj.Field1, input.Field1, tc.caseDesc)
assert.Equal(t, tc.giveObj.Field2, input.Field2, tc.caseDesc)
assert.NotEqual(t, 0, len(input.ID), tc.caseDesc)
assert.NotEqual(t, 0, len(id), tc.caseDesc)
assert.NotEqual(t, 0, input.CreateTime, tc.caseDesc)
assert.NotEqual(t, 0, input.UpdateTime, tc.caseDesc)
}).Return(tc.giveErr)
Expand Down
8 changes: 4 additions & 4 deletions api/internal/core/store/storehub.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func InitStores() error {
ObjType: reflect.TypeOf(entity.Route{}),
KeyFunc: func(obj interface{}) string {
r := obj.(*entity.Route)
return r.ID
return utils.InterfaceToString(r.ID)
},
})
if err != nil {
Expand All @@ -101,7 +101,7 @@ func InitStores() error {
ObjType: reflect.TypeOf(entity.Service{}),
KeyFunc: func(obj interface{}) string {
r := obj.(*entity.Service)
return r.ID
return utils.InterfaceToString(r.ID)
},
})
if err != nil {
Expand All @@ -113,7 +113,7 @@ func InitStores() error {
ObjType: reflect.TypeOf(entity.SSL{}),
KeyFunc: func(obj interface{}) string {
r := obj.(*entity.SSL)
return r.ID
return utils.InterfaceToString(r.ID)
},
})
if err != nil {
Expand All @@ -125,7 +125,7 @@ func InitStores() error {
ObjType: reflect.TypeOf(entity.Upstream{}),
KeyFunc: func(obj interface{}) string {
r := obj.(*entity.Upstream)
return r.ID
return utils.InterfaceToString(r.ID)
},
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion api/internal/core/store/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestAPISIXJsonSchemaValidator_Validate(t *testing.T) {

err = validator.Validate(consumer2)
assert.NotNil(t, err)
assert.EqualError(t, err, "scheme validate fail: id: Must validate at least one schema (anyOf)\nid: String length must be greater than or equal to 1\nid: Does not match pattern '^[a-zA-Z0-9-_.]+$'")
assert.EqualError(t, err, "scheme validate fail: id: Must validate at least one schema (anyOf)\nid: Invalid type. Expected: string, given: null")

//check nil obj
err = validator.Validate(nil)
Expand Down
5 changes: 3 additions & 2 deletions api/internal/handler/consumer/consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/store"
"github.com/apisix/manager-api/internal/handler"
"github.com/apisix/manager-api/internal/utils"
)

type Handler struct {
Expand Down Expand Up @@ -99,7 +100,7 @@ func (h *Handler) List(c droplet.Context) (interface{}, error) {

func (h *Handler) Create(c droplet.Context) (interface{}, error) {
input := c.Input().(*entity.Consumer)
if input.ID != "" && input.ID != input.Username {
if input.ID != nil && utils.InterfaceToString(input.ID) != input.Username {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
fmt.Errorf("consumer's id and username must be a same value")
}
Expand All @@ -126,7 +127,7 @@ type UpdateInput struct {

func (h *Handler) Update(c droplet.Context) (interface{}, error) {
input := c.Input().(*UpdateInput)
if input.ID != "" && input.ID != input.Username {
if input.ID != nil && utils.InterfaceToString(input.ID) != input.Username {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
fmt.Errorf("consumer's id and username must be a same value")
}
Expand Down
30 changes: 18 additions & 12 deletions api/internal/handler/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ func (h *Handler) List(c droplet.Context) (interface{}, error) {
var route *entity.Route
for i, item := range ret.Rows {
route = item.(*entity.Route)
script, _ := h.scriptStore.Get(route.ID)
id := utils.InterfaceToString(route.ID)
script, _ := h.scriptStore.Get(id)
if script != nil {
route.Script = script.(*entity.Script).Script
}
Expand Down Expand Up @@ -193,8 +194,9 @@ func generateLuaCode(script map[string]interface{}) (string, error) {
func (h *Handler) Create(c droplet.Context) (interface{}, error) {
input := c.Input().(*entity.Route)
//check depend
if input.ServiceID != "" {
_, err := h.svcStore.Get(input.ServiceID)
if input.ServiceID != nil {
serviceID := utils.InterfaceToString(input.ServiceID)
_, err := h.svcStore.Get(serviceID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
Expand All @@ -203,8 +205,9 @@ func (h *Handler) Create(c droplet.Context) (interface{}, error) {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
}
}
if input.UpstreamID != "" {
_, err := h.upstreamStore.Get(input.UpstreamID)
if input.UpstreamID != nil {
upstreamID := utils.InterfaceToString(input.UpstreamID)
_, err := h.upstreamStore.Get(upstreamID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
Expand All @@ -219,7 +222,7 @@ func (h *Handler) Create(c droplet.Context) (interface{}, error) {
input.ID = utils.GetFlakeUidStr()
}
script := &entity.Script{}
script.ID = input.ID
script.ID = utils.InterfaceToString(input.ID)
script.Script = input.Script
//to lua
var err error
Expand Down Expand Up @@ -257,8 +260,9 @@ func (h *Handler) Update(c droplet.Context) (interface{}, error) {
}

//check depend
if input.ServiceID != "" {
_, err := h.svcStore.Get(input.ServiceID)
if input.ServiceID != nil {
serviceID := utils.InterfaceToString(input.ServiceID)
_, err := h.svcStore.Get(serviceID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
Expand All @@ -267,8 +271,9 @@ func (h *Handler) Update(c droplet.Context) (interface{}, error) {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest}, err
}
}
if input.UpstreamID != "" {
_, err := h.upstreamStore.Get(input.UpstreamID)
if input.UpstreamID != nil {
upstreamID := utils.InterfaceToString(input.UpstreamID)
_, err := h.upstreamStore.Get(upstreamID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
Expand Down Expand Up @@ -306,9 +311,10 @@ func (h *Handler) Update(c droplet.Context) (interface{}, error) {
}
} else {
//remove exists script
script, _ := h.scriptStore.Get(input.Route.ID)
id := utils.InterfaceToString(input.Route.ID)
script, _ := h.scriptStore.Get(id)
if script != nil {
if err := h.scriptStore.BatchDelete(c.Context(), strings.Split(input.Route.ID, ",")); err != nil {
if err := h.scriptStore.BatchDelete(c.Context(), strings.Split(id, ",")); err != nil {
log.Warnf("delete script %s failed", input.Route.ID)
}
}
Expand Down
11 changes: 7 additions & 4 deletions api/internal/handler/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/apisix/manager-api/internal/core/entity"
"github.com/apisix/manager-api/internal/core/store"
"github.com/apisix/manager-api/internal/handler"
"github.com/apisix/manager-api/internal/utils"
)

type Handler struct {
Expand Down Expand Up @@ -118,8 +119,9 @@ func (h *Handler) List(c droplet.Context) (interface{}, error) {
func (h *Handler) Create(c droplet.Context) (interface{}, error) {
input := c.Input().(*entity.Service)

if input.UpstreamID != "" {
_, err := h.upstreamStore.Get(input.UpstreamID)
if input.UpstreamID != nil {
upstreamID := utils.InterfaceToString(input.UpstreamID)
_, err := h.upstreamStore.Get(upstreamID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
Expand Down Expand Up @@ -147,8 +149,9 @@ func (h *Handler) Update(c droplet.Context) (interface{}, error) {
input.Service.ID = input.ID
}

if input.UpstreamID != "" {
_, err := h.upstreamStore.Get(input.UpstreamID)
if input.UpstreamID != nil {
upstreamID := utils.InterfaceToString(input.UpstreamID)
_, err := h.upstreamStore.Get(upstreamID)
if err != nil {
if err == data.ErrNotFound {
return &data.SpecCodeResponse{StatusCode: http.StatusBadRequest},
Expand Down
12 changes: 11 additions & 1 deletion api/internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
package utils

import (
"github.com/sony/sonyflake"
"fmt"
"net"
"os"
"strconv"

"github.com/sony/sonyflake"
)

var _sf *sonyflake.Sonyflake
Expand Down Expand Up @@ -77,3 +79,11 @@ func GetFlakeUid() uint64 {
func GetFlakeUidStr() string {
return strconv.FormatUint(GetFlakeUid(), 10)
}

func InterfaceToString(val interface{}) string {
if val == nil {
return ""
}
str := fmt.Sprintf("%v", val)
return str
}
Loading