Skip to content

Commit

Permalink
Merge pull request #915 from openmeterio/fix/api-improvements
Browse files Browse the repository at this point in the history
fix: improve entitlements API
  • Loading branch information
turip authored May 17, 2024
2 parents a37cfe5 + 0e37fe9 commit b02e623
Show file tree
Hide file tree
Showing 26 changed files with 1,085 additions and 503 deletions.
413 changes: 262 additions & 151 deletions api/api.gen.go

Large diffs are not rendered by default.

478 changes: 323 additions & 155 deletions api/client/go/client.gen.go

Large diffs are not rendered by default.

108 changes: 89 additions & 19 deletions api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,27 @@ paths:
List features.
tags:
- Entitlements (Experimental)
parameters:
- $ref: "#/components/parameters/ledgerQueryLimit"
- $ref: "#/components/parameters/ledgerQueryOffset"
- name: orderBy
in: query
required: false
description: Order by field
schema:
type: string
enum:
- id
- createdAt
- updatedAt
default: id
- name: includeArchived
in: query
required: false
description: Include archived features.
schema:
type: boolean
default: false
responses:
"200":
description: List of features.
Expand Down Expand Up @@ -730,30 +751,34 @@ paths:
- name: subject
in: query
required: false
description: Query a specific ledger
description: Query ledgers specific to subjects.
schema:
type: array
items:
type: string
description: |
A metering subject to list the ledger of.
- name: limit
- name: subjectSimilarTo
in: query
required: false
description: Number of ledgers to return
description: Query ledgers with subjects that are similar to the provided text.
schema:
type: integer
minimum: 1
maximum: 1000
default: 1000
example: 1000
- name: offset
type: string
description: |
A text fragment to search for.
- $ref: "#/components/parameters/ledgerQueryLimit"
- $ref: "#/components/parameters/ledgerQueryOffset"
- name: orderBy
in: query
required: false
description: Start returning ledgers from this offset
description: Order by field
schema:
type: integer
type: string
enum:
- subject
- createdAt
- id
default: id
responses:
"200":
description: List of the matching ledgers.
Expand Down Expand Up @@ -843,6 +868,7 @@ paths:
parameters:
- $ref: "#/components/parameters/ledgerID"
- $ref: "#/components/parameters/ledgerQueryLimit"
- $ref: "#/components/parameters/ledgerQueryOffset"
- name: from
in: query
required: true
Expand Down Expand Up @@ -1231,6 +1257,20 @@ components:
If the feature is archived, it will not be used for grants or usage.
type: boolean
example: false
createdAt:
readOnly: true
description: |
The time the feature was created.
type: string
format: date-time
example: "2023-01-01T00:00:00Z"
updatedAt:
readOnly: true
description: |
The time the feature was last updated.
type: string
format: date-time
example: "2023-01-01T00:00:00Z"
CreateLedger:
x-go-type-import:
path: github.com/openmeterio/openmeter/internal/credit
Expand Down Expand Up @@ -1330,6 +1370,12 @@ components:
readOnly: true
type: string
example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
createdAt:
description: |
The time the ledger was created.
type: string
format: date-time
example: "2023-01-01T00:00:00Z"
LedgerEntry:
x-go-type-import:
path: github.com/openmeterio/openmeter/internal/credit
Expand Down Expand Up @@ -1487,19 +1533,12 @@ components:
description: |
Grants are used to increase balance of specific subjects.
required:
- id
- type
- amount
- featureID
- effectiveAt
- expiration
properties:
id:
description: |
Readonly unique ULID identifier of the grant.
readOnly: true
type: string
example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
type:
$ref: "#/components/schemas/LedgerGrantType"
amount:
Expand Down Expand Up @@ -1546,6 +1585,20 @@ components:
type: string
example:
stripePaymentId: "pi_4OrAkhLvyihio9p51h9iiFnB"
createdAt:
readOnly: true
description: |
The time the grant was created.
type: string
format: date-time
example: "2023-01-01T00:00:00Z"
updatedAt:
readOnly: true
description: |
The time the grant was last updated.
type: string
format: date-time
example: "2023-01-01T00:00:00Z"
LedgerGrantResponse:
x-go-type-import:
path: github.com/openmeterio/openmeter/internal/credit
Expand All @@ -1555,7 +1608,14 @@ components:
- type: object
required:
- subject
- id
properties:
id:
description: |
Readonly unique ULID identifier of the grant.
readOnly: true
type: string
example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
subject:
description: |
The subject to grant the amount to.
Expand Down Expand Up @@ -1995,6 +2055,16 @@ components:
maximum: 1000
default: 1000
example: 100
ledgerQueryOffset:
name: offset
in: query
required: false
description: Number of entries to skip
schema:
type: integer
minimum: 0
default: 0
example: 100
queryFrom:
name: from
in: query
Expand Down
27 changes: 21 additions & 6 deletions e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,12 @@ func TestCredit(t *testing.T) {
Archived: &archived,
}

assert.Equal(t, expected, resp.JSON201)
require.NotEmpty(t, *resp.JSON201.CreatedAt)
require.NotEmpty(t, *resp.JSON201.UpdatedAt)
resp.JSON201.CreatedAt = nil
resp.JSON201.UpdatedAt = nil

require.Equal(t, expected, resp.JSON201)
})

var ledgerID credit.LedgerID
Expand Down Expand Up @@ -566,6 +571,9 @@ func TestCredit(t *testing.T) {
require.NoError(t, err)
require.Equal(t, http.StatusConflict, resp.StatusCode(), "Invalid status code [response_body=%s]", string(resp.Body))

require.NotEmpty(t, resp.ApplicationproblemJSON409.ConflictingEntity.CreatedAt)
resp.ApplicationproblemJSON409.ConflictingEntity.CreatedAt = time.Time{}

require.Equal(t,
credit.Ledger{
ID: ledgerID,
Expand All @@ -579,7 +587,7 @@ func TestCredit(t *testing.T) {
effectiveAt, _ := time.Parse(time.RFC3339, "2024-01-01T00:01:00Z")

// Get feature
featureListResp, err := client.ListFeaturesWithResponse(context.Background())
featureListResp, err := client.ListFeaturesWithResponse(context.Background(), nil)
require.NoError(t, err)
require.Equal(t, http.StatusOK, featureListResp.StatusCode())
require.NotNil(t, featureListResp.JSON200)
Expand All @@ -606,6 +614,9 @@ func TestCredit(t *testing.T) {
require.NoError(t, err)
require.Equal(t, http.StatusCreated, resp.StatusCode(), "Invalid status code [response_body=%s]", resp.Body)

require.NotEmpty(t, resp.JSON201.CreatedAt)
require.NotEmpty(t, resp.JSON201.UpdatedAt)

expected := &credit.Grant{
ID: resp.JSON201.ID,
LedgerID: ledgerID,
Expand All @@ -621,9 +632,11 @@ func TestCredit(t *testing.T) {
Duration: "DAY",
Count: 1,
},
CreatedAt: resp.JSON201.CreatedAt,
UpdatedAt: resp.JSON201.UpdatedAt,
}

assert.Equal(t, expected, resp.JSON201)
require.Equal(t, expected, resp.JSON201)
})

t.Run("Balance", func(t *testing.T) {
Expand All @@ -637,7 +650,7 @@ func TestCredit(t *testing.T) {
grant := grants[0]

// Get feature
featureListResp, err := client.ListFeaturesWithResponse(context.Background())
featureListResp, err := client.ListFeaturesWithResponse(context.Background(), nil)
require.NoError(t, err)
require.Equal(t, http.StatusOK, featureListResp.StatusCode())
require.NotNil(t, featureListResp.JSON200)
Expand Down Expand Up @@ -683,7 +696,7 @@ func TestCredit(t *testing.T) {
parentGrant := parentGrants[0]

// Get feature
featureListResp, err := client.ListFeaturesWithResponse(context.Background())
featureListResp, err := client.ListFeaturesWithResponse(context.Background(), nil)
require.NoError(t, err)
require.Equal(t, http.StatusOK, featureListResp.StatusCode())
require.NotNil(t, featureListResp.JSON200)
Expand Down Expand Up @@ -733,9 +746,11 @@ func TestCredit(t *testing.T) {
Duration: "DAY",
Count: 1,
},
CreatedAt: grants[0].CreatedAt,
UpdatedAt: grants[0].UpdatedAt,
},
}

assert.Equal(t, expected, resp.JSON200)
require.Equal(t, expected, resp.JSON200)
})
}
10 changes: 0 additions & 10 deletions internal/credit/balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,7 @@ type GrantBalance struct {
Balance float64 `json:"balance"`
}

// Render implements the chi renderer interface.
func (c GrantBalance) Render(w http.ResponseWriter, r *http.Request) error {
return nil
}

type FeatureBalance struct {
Feature
Balance float64 `json:"balance"`
}

// Render implements the chi renderer interface.
func (c FeatureBalance) Render(w http.ResponseWriter, r *http.Request) error {
return nil
}
36 changes: 31 additions & 5 deletions internal/credit/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,42 @@ type ListGrantsParams struct {
Limit int
}

type FeatureOrderBy string

const (
FeatureOrderByCreatedAt FeatureOrderBy = "created_at"
FeatureOrderByUpdatedAt FeatureOrderBy = "updated_at"
FeatureOrderByID FeatureOrderBy = "id"
)

type ListFeaturesParams struct {
Namespace string
IncludeArchived bool
Offset int
Limit int
OrderBy FeatureOrderBy
}

type LedgerOrderBy string

const (
LedgerOrderByCreatedAt LedgerOrderBy = "created_at"
LedgerOrderBySubject LedgerOrderBy = "subject"
LedgerOrderByID LedgerOrderBy = "id"
)

type ListLedgersParams struct {
Namespace string
Subjects []string
Offset int
Limit int
Namespace string
Subjects []string
SubjectLike string
Offset int
Limit int
OrderBy LedgerOrderBy
}

type Pagination struct {
Offset int
Limit int
}

type Connector interface {
Expand All @@ -40,7 +66,7 @@ type Connector interface {

// Credit
GetBalance(ctx context.Context, ledgerID NamespacedLedgerID, cutline time.Time) (Balance, error)
GetHistory(ctx context.Context, ledgerID NamespacedLedgerID, from time.Time, to time.Time, limit int) (LedgerEntryList, error)
GetHistory(ctx context.Context, ledgerID NamespacedLedgerID, from time.Time, to time.Time, pagination Pagination) (LedgerEntryList, error)
GetHighWatermark(ctx context.Context, ledgerID NamespacedLedgerID) (HighWatermark, error)
Reset(ctx context.Context, reset Reset) (Reset, []Grant, error)

Expand Down
10 changes: 4 additions & 6 deletions internal/credit/credit.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,6 @@ type Reset struct {
EffectiveAt time.Time `json:"effectiveAt"`
}

// Render implements the chi renderer interface.
func (c Reset) Render(w http.ResponseWriter, r *http.Request) error {
return nil
}

// Grant is used to increase balance of specific subjects.
type Grant struct {
Namespace string `json:"-"`
Expand Down Expand Up @@ -167,6 +162,9 @@ type Grant struct {

// Void The voided date.
Void bool `json:"void"`

CreatedAt *time.Time `json:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
}

func (c Grant) ExpirationDate() time.Time {
Expand Down Expand Up @@ -236,7 +234,7 @@ type LockErrNotObtainedError struct {
}

func (e *LockErrNotObtainedError) Error() string {
return fmt.Sprintf("lock not obtained ledger %s.%s", e.Namespace, e.ID)
return fmt.Sprintf("lock not obtained ledger %s", e.ID)
}

type LedgerAlreadyExistsError struct {
Expand Down
3 changes: 3 additions & 0 deletions internal/credit/creditdriver/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ package creditdriver
const (
// DefaultLedgerQueryLimit specifies how many entries to return by default for credit related queries
DefaultLedgerQueryLimit = 1000

// MaxLedgerQueryLimit specifies the maximum number of entries to return for credit related queries
MaxLedgerQueryLimit = 1000
)
Loading

0 comments on commit b02e623

Please sign in to comment.