Skip to content

Commit

Permalink
fix account consumtionAmount api
Browse files Browse the repository at this point in the history
  • Loading branch information
bxy4543 committed Aug 7, 2024
1 parent b2f61d6 commit cd7837b
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 31 deletions.
2 changes: 1 addition & 1 deletion service/account/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func GetConsumptionAmount(c *gin.Context) {
c.JSON(http.StatusUnauthorized, gin.H{"error": fmt.Sprintf("authenticate error : %v", err)})
return
}
amount, err := dao.DBClient.GetConsumptionAmount(req.Owner, req.Namespace, req.AppType, req.TimeRange.StartTime, req.TimeRange.EndTime)
amount, err := dao.DBClient.GetConsumptionAmount(*req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to get consumption amount : %v", err)})
return
Expand Down
81 changes: 51 additions & 30 deletions service/account/dao/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type Interface interface {
GetBasicCostDistribution(req helper.GetCostAppListReq) (map[string]int64, error)
GetCostAppList(req helper.GetCostAppListReq) (helper.CostAppListResp, error)
Disconnect(ctx context.Context) error
GetConsumptionAmount(user, namespace, appType string, startTime, endTime time.Time) (int64, error)
GetConsumptionAmount(req helper.ConsumptionRecordReq) (int64, error)
GetRechargeAmount(ops types.UserQueryOpts, startTime, endTime time.Time) (int64, error)
GetPropertiesUsedAmount(user string, startTime, endTime time.Time) (map[string]int64, error)
GetAccount(ops types.UserQueryOpts) (*types.Account, error)
Expand Down Expand Up @@ -462,10 +462,6 @@ func (m *MongoDB) getAppStoreCosts(matchConditions bson.D, skip, limit int) (*co
return &results, nil
}

func (m *MongoDB) GetConsumptionAmount(user, namespace, appType string, startTime, endTime time.Time) (int64, error) {
return m.getAmountWithType(0, user, namespace, appType, startTime, endTime)
}

func (m *MongoDB) GetCostOverview(req helper.GetCostAppListReq) (resp helper.CostOverviewResp, rErr error) {
appResp, err := m.GetCostAppList(req)
if err != nil {
Expand All @@ -474,7 +470,7 @@ func (m *MongoDB) GetCostOverview(req helper.GetCostAppListReq) (resp helper.Cos
}
resp.LimitResp = appResp.LimitResp
for _, app := range appResp.Apps {
totalAmount, err := m.GetTotalAppCost(req.Owner, app.Namespace, app.AppName, app.AppType)
totalAmount, err := m.getTotalAppCost(req, app)
if err != nil {
rErr = fmt.Errorf("failed to get total app cost: %w", err)
return
Expand All @@ -489,18 +485,41 @@ func (m *MongoDB) GetCostOverview(req helper.GetCostAppListReq) (resp helper.Cos
return
}

func (m *MongoDB) GetTotalAppCost(owner string, namespace string, appName string, appType uint8) (int64, error) {
func (m *MongoDB) getTotalAppCost(req helper.GetCostAppListReq, app helper.CostApp) (int64, error) {
owner := req.Owner
namespace := app.Namespace
appName := app.AppName
appType := app.AppType
if req.StartTime.IsZero() {
req.StartTime = time.Now().UTC().Add(-time.Hour * 24 * 30)
req.EndTime = time.Now().UTC()
}
match := bson.M{
"owner": owner,
"namespace": namespace,
"app_costs.name": appName,
"app_type": appType,
"time": bson.M{
"$gte": req.StartTime,
"$lte": req.EndTime,
},
}
appStoreMatch := bson.M{
"owner": owner,
"namespace": namespace,
"app_name": appName,
"app_type": appType,
"time": bson.M{
"$gte": req.StartTime,
"$lte": req.EndTime,
},
}
var pipeline mongo.Pipeline

if appType == resources.AppType[resources.AppStore] {
// If appType is 8, match app_name and app_type directly
pipeline = mongo.Pipeline{
{{Key: "$match", Value: bson.D{
{Key: "owner", Value: owner},
{Key: "namespace", Value: namespace},
{Key: "app_name", Value: appName},
{Key: "app_type", Value: appType},
}}},
{{Key: "$match", Value: appStoreMatch}},
{{Key: "$group", Value: bson.D{
{Key: "_id", Value: nil},
{Key: "totalAmount", Value: bson.D{{Key: "$sum", Value: "$amount"}}},
Expand All @@ -509,12 +528,7 @@ func (m *MongoDB) GetTotalAppCost(owner string, namespace string, appName string
} else {
// Otherwise, match inside app_costs
pipeline = mongo.Pipeline{
{{Key: "$match", Value: bson.D{
{Key: "owner", Value: owner},
{Key: "namespace", Value: namespace},
{Key: "app_costs.name", Value: appName},
{Key: "app_type", Value: appType},
}}},
{{Key: "$match", Value: match}},
{{Key: "$unwind", Value: "$app_costs"}},
{{Key: "$match", Value: bson.D{
{Key: "app_costs.name", Value: appName},
Expand Down Expand Up @@ -987,29 +1001,36 @@ func (m *MongoDB) Disconnect(ctx context.Context) error {
return m.Client.Disconnect(ctx)
}

func (m *MongoDB) getAmountWithType(_type int64, user, namespace, _appType string, startTime, endTime time.Time) (int64, error) {
func (m *MongoDB) GetConsumptionAmount(req helper.ConsumptionRecordReq) (int64, error) {
owner, namespace, appType, appName, startTime, endTime := req.Owner, req.Namespace, req.AppType, req.AppName, req.TimeRange.StartTime, req.TimeRange.EndTime
timeMatchValue := bson.D{primitive.E{Key: "$gte", Value: startTime}, primitive.E{Key: "$lte", Value: endTime}}
matchValue := bson.D{
primitive.E{Key: "time", Value: timeMatchValue},
primitive.E{Key: "owner", Value: user},
primitive.E{Key: "type", Value: _type},
primitive.E{Key: "owner", Value: owner},
}
if appType != "" {
matchValue = append(matchValue, primitive.E{Key: "app_type", Value: resources.AppType[strings.ToUpper(appType)]})
}
if namespace != "" {
matchValue = append(matchValue, primitive.E{Key: "namespace", Value: namespace})
}
if _appType != "" {
matchValue = append(matchValue, primitive.E{Key: "app_type", Value: resources.AppType[strings.ToUpper(_appType)]})
unwindMatchValue := bson.D{
primitive.E{Key: "time", Value: timeMatchValue},
}
matchStage := bson.D{
primitive.E{
Key: "$match", Value: matchValue,
},
if appType != "" && appName != "" {
if appType != resources.AppStore {
unwindMatchValue = append(unwindMatchValue, primitive.E{Key: "app_costs.name", Value: appName})
} else {
unwindMatchValue = append(unwindMatchValue, primitive.E{Key: "app_name", Value: appName})
}
}
pipeline := bson.A{
matchStage,
bson.D{{Key: "$match", Value: matchValue}},
bson.D{{Key: "$unwind", Value: "$app_costs"}},
bson.D{{Key: "$match", Value: unwindMatchValue}},
bson.D{{Key: "$group", Value: bson.M{
"_id": nil,
"total": bson.M{"$sum": "$amount"},
"total": bson.M{"$sum": "$app_costs.amount"},
}}},
}

Expand Down
56 changes: 56 additions & 0 deletions service/account/dao/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,62 @@ func TestMongoDB_GetAppCostTimeRange(t *testing.T) {
t.Logf("costAppList: %v", timeRange)
}

func TestMongoDB_GetConsumptionAmount(t *testing.T) {
dbCTX := context.Background()
m, err := newAccountForTest(os.Getenv("MONGO_URI"), "", "")
if err != nil {
t.Fatalf("NewAccountInterface() error = %v", err)
return
}
defer func() {
if err = m.Disconnect(dbCTX); err != nil {
t.Errorf("failed to disconnect mongo: error = %v", err)
}
}()
req := helper.GetCostAppListReq{
Auth: &helper.Auth{
Owner: "uy771xun",
},
Namespace: "ns-uy771xun",
AppType: "APP-STORE",
AppName: "wordpress-nljzdohs",
LimitReq: helper.LimitReq{
TimeRange: helper.TimeRange{
StartTime: time.Now().Add(-24 * time.Hour * 300),
EndTime: time.Now(),
},
PageSize: 20,
Page: 1,
},
}
costs, err := m.GetCostOverview(req)
if err != nil {
t.Fatalf("failed to get cost app list: %v", err)
}
t.Logf("GetCostOverview: %v", costs)
amountAll := int64(0)
for _, cost := range costs.Overviews {
amountAll += cost.Amount
}
t.Logf("amountAll: %v", amountAll)
amount2, err := m.GetConsumptionAmount(helper.ConsumptionRecordReq{
Auth: &helper.Auth{
Owner: req.Owner,
},
TimeRange: helper.TimeRange{
StartTime: req.StartTime,
EndTime: req.EndTime,
},
Namespace: req.Namespace,
AppType: req.AppType,
AppName: req.AppName,
})
if err != nil {
t.Fatalf("failed to get cost app list: %v", err)
}
t.Logf("GetConsumptionAmount: %v", amount2)
}

func TestMongoDB_GetAppCost1(t *testing.T) {
dbCTX := context.Background()
m, err := newAccountForTest(os.Getenv("MONGO_URI"), "", "")
Expand Down
4 changes: 4 additions & 0 deletions service/account/helper/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ type ConsumptionRecordReq struct {
// @Summary App type
// @Description App type
AppType string `json:"appType,omitempty" bson:"appType" example:"app"`

// @Summary App Name
// @Description App Name
AppName string `json:"appName,omitempty" bson:"appName" example:"app"`
}

type NamespaceBillingHistoryResp struct {
Expand Down
8 changes: 8 additions & 0 deletions service/go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
Expand Down Expand Up @@ -782,6 +783,7 @@ github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8=
github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
Expand Down Expand Up @@ -1104,6 +1106,7 @@ golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -1132,6 +1135,7 @@ golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNss
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand Down Expand Up @@ -1179,6 +1183,7 @@ google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI=
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY=
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg=
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 h1:m8v1xLLLzMe1m5P+gCTF8nJB9epwZQUBERm20Oy1poQ=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
Expand All @@ -1203,6 +1208,7 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
Expand All @@ -1220,6 +1226,7 @@ google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpX
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
Expand Down Expand Up @@ -1286,6 +1293,7 @@ k8s.io/kms v0.29.0/go.mod h1:mB0f9HLxRXeXUfHfn1A7rpwOlzXI1gIWu86z6buNoYA=
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 h1:trsWhjU5jZrx6UvFu4WzQDrN7Pga4a7Qg+zcfcj64PA=
Expand Down

0 comments on commit cd7837b

Please sign in to comment.