Skip to content

Commit 536a13d

Browse files
easyCZroboquat
authored andcommitted
[usage] Find running and stopped instances in ledger reconciler
1 parent dc9fbe4 commit 536a13d

File tree

4 files changed

+83
-2
lines changed

4 files changed

+83
-2
lines changed

components/usage/pkg/apiv1/usage.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,42 @@ func (s *UsageService) GetCostCenter(ctx context.Context, in *v1.GetCostCenterRe
181181
}, nil
182182
}
183183

184+
func (s *UsageService) ReconcileUsageWithLedger(ctx context.Context, req *v1.ReconcileUsageWithLedgerRequest) (*v1.ReconcileUsageWithLedgerResponse, error) {
185+
from := req.GetFrom().AsTime()
186+
to := req.GetTo().AsTime()
187+
188+
logger := log.
189+
WithField("from", from).
190+
WithField("to", to)
191+
192+
if to.Before(from) {
193+
return nil, status.Errorf(codes.InvalidArgument, "To must not be before From")
194+
}
195+
196+
stopped, err := db.FindStoppedWorkspaceInstancesInRange(ctx, s.conn, from, to)
197+
if err != nil {
198+
logger.WithError(err).Errorf("Failed to find stopped workspace instances.")
199+
return nil, status.Errorf(codes.Internal, "failed to query for stopped instances")
200+
}
201+
logger.Infof("Found %d stopped workspace instances in range.", len(stopped))
202+
203+
running, err := db.FindRunningWorkspaceInstances(ctx, s.conn)
204+
if err != nil {
205+
logger.WithError(err).Errorf("Failed to find running workspace instances.")
206+
return nil, status.Errorf(codes.Internal, "failed to query for running instances")
207+
}
208+
logger.Infof("Found %d running workspaces since the beginning of time.", len(running))
209+
210+
usageDrafts, err := db.FindAllDraftUsage(ctx, s.conn)
211+
if err != nil {
212+
logger.WithError(err).Errorf("Failed to find all draft usage records.")
213+
return nil, status.Errorf(codes.Internal, "failed to find all draft usage records")
214+
}
215+
logger.Infof("Found %d draft usage records.", len(usageDrafts))
216+
217+
return &v1.ReconcileUsageWithLedgerResponse{}, nil
218+
}
219+
184220
func NewUsageService(conn *gorm.DB, reportGenerator *ReportGenerator, contentSvc contentservice.Interface) *UsageService {
185221
return &UsageService{
186222
conn: conn,

components/usage/pkg/apiv1/usage_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,41 @@ func TestReportGenerator_GenerateUsageReportTable(t *testing.T) {
556556
})
557557
}
558558
}
559+
560+
func TestUsageService_ReconcileUsageWithLedger(t *testing.T) {
561+
dbconn := dbtest.ConnectForTests(t)
562+
from := time.Date(2022, 05, 1, 0, 00, 00, 00, time.UTC)
563+
to := time.Date(2022, 05, 1, 1, 00, 00, 00, time.UTC)
564+
565+
// stopped instances
566+
dbtest.CreateWorkspaceInstances(t, dbconn, dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{
567+
StoppingTime: db.NewVarcharTime(from.Add(1 * time.Minute)),
568+
}))
569+
570+
// running instances
571+
dbtest.CreateWorkspaceInstances(t, dbconn, dbtest.NewWorkspaceInstance(t, db.WorkspaceInstance{}))
572+
573+
// usage drafts
574+
dbtest.CreateUsageRecords(t, dbconn, dbtest.NewUsage(t, db.Usage{
575+
Kind: db.WorkspaceInstanceUsageKind,
576+
Draft: true,
577+
}))
578+
579+
srv := baseserver.NewForTests(t,
580+
baseserver.WithGRPC(baseserver.MustUseRandomLocalAddress(t)),
581+
)
582+
583+
v1.RegisterUsageServiceServer(srv.GRPC(), NewUsageService(dbconn, nil, nil))
584+
baseserver.StartServerForTests(t, srv)
585+
586+
conn, err := grpc.Dial(srv.GRPCAddress(), grpc.WithTransportCredentials(insecure.NewCredentials()))
587+
require.NoError(t, err)
588+
589+
client := v1.NewUsageServiceClient(conn)
590+
591+
_, err = client.ReconcileUsageWithLedger(context.Background(), &v1.ReconcileUsageWithLedgerRequest{
592+
From: timestamppb.New(from),
593+
To: timestamppb.New(to),
594+
})
595+
require.NoError(t, err)
596+
}

components/usage/pkg/db/dbtest/usage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func NewUsage(t *testing.T, record db.Usage) db.Usage {
2323
Description: "some description",
2424
CreditCents: 42,
2525
EffectiveTime: db.VarcharTime{},
26-
Kind: "workspaceinstance",
26+
Kind: db.WorkspaceInstanceUsageKind,
2727
WorkspaceInstanceID: uuid.New(),
2828
}
2929

components/usage/pkg/db/usage.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,20 @@ import (
1414
"gorm.io/gorm/clause"
1515
)
1616

17+
type UsageKind string
18+
19+
const (
20+
WorkspaceInstanceUsageKind UsageKind = "workspaceinstance"
21+
InvoiceUsageKind = "invoice"
22+
)
23+
1724
type Usage struct {
1825
ID uuid.UUID `gorm:"primary_key;column:id;type:char;size:36;" json:"id"`
1926
AttributionID AttributionID `gorm:"column:attributionId;type:varchar;size:255;" json:"attributionId"`
2027
Description string `gorm:"column:description;type:varchar;size:255;" json:"description"`
2128
CreditCents int64 `gorm:"column:creditCents;type:bigint;" json:"creditCents"`
2229
EffectiveTime VarcharTime `gorm:"column:effectiveTime;type:varchar;size:255;" json:"effectiveTime"`
23-
Kind string `gorm:"column:kind;type:char;size:10;" json:"kind"`
30+
Kind UsageKind `gorm:"column:kind;type:char;size:10;" json:"kind"`
2431
WorkspaceInstanceID uuid.UUID `gorm:"column:workspaceInstanceId;type:char;size:36;" json:"workspaceInstanceId"`
2532
Draft bool `gorm:"column:draft;type:boolean;" json:"draft"`
2633
Metadata datatypes.JSON `gorm:"column:metadata;type:text;size:65535" json:"metadata"`

0 commit comments

Comments
 (0)