Skip to content

Commit

Permalink
feat: implement consumer/get and subscription/get invocation hand…
Browse files Browse the repository at this point in the history
…lers (#220)

`consumer/get` required wiring up the space metrics table in the
upload-api stack to get space allocation metrics, which we call
"allocation" in w3admin. Currently just returning 1 billion as the
"total" space for all consumers since we don't currently check anyway,
but we should figure out where this lives when we tackle billing in the
near future.

Also implement `getStorageProviders` per
storacha/w3up#862

Also add `subscriptions` to the `customer/get` response, per
storacha/w3up#863

---------

Co-authored-by: Vasco Santos <[email protected]>
  • Loading branch information
travis and vasco-santos authored Aug 31, 2023
1 parent f9df569 commit e1c0507
Show file tree
Hide file tree
Showing 14 changed files with 356 additions and 75 deletions.
140 changes: 104 additions & 36 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion stacks/upload-api-stack.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function UploadApiStack({ stack, app }) {

// Get references to constructs created in other stacks
const { carparkBucket } = use(CarparkStack)
const { storeTable, uploadTable, delegationBucket, delegationTable, adminMetricsTable, consumerTable, subscriptionTable, rateLimitTable } = use(UploadDbStack)
const { storeTable, uploadTable, delegationBucket, delegationTable, adminMetricsTable, spaceMetricsTable, consumerTable, subscriptionTable, rateLimitTable } = use(UploadDbStack)
const { invocationBucket, taskBucket, workflowBucket, ucanStream } = use(UcanInvocationStack)

// Setup API
Expand All @@ -45,6 +45,7 @@ export function UploadApiStack({ stack, app }) {
subscriptionTable,
rateLimitTable,
adminMetricsTable,
spaceMetricsTable,
carparkBucket,
invocationBucket,
taskBucket,
Expand All @@ -57,6 +58,7 @@ export function UploadApiStack({ stack, app }) {
UPLOAD_TABLE_NAME: uploadTable.tableName,
CONSUMER_TABLE_NAME: consumerTable.tableName,
SUBSCRIPTION_TABLE_NAME: subscriptionTable.tableName,
SPACE_METRICS_TABLE_NAME: spaceMetricsTable.tableName,
RATE_LIMIT_TABLE_NAME: rateLimitTable.tableName,
DELEGATION_TABLE_NAME: delegationTable.tableName,
DELEGATION_BUCKET_NAME: delegationBucket.bucketName,
Expand Down
4 changes: 2 additions & 2 deletions upload-api/functions/metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export async function metricsGet () {
}

/**
* @param {import('../tables/metrics.js').MetricsTable} metricsTable
* @param {import('../types.js').MetricsTable} metricsTable
*/
export async function getMetrics (metricsTable) {
const metricsList = await metricsTable.get()
Expand All @@ -57,7 +57,7 @@ export async function getMetrics (metricsTable) {

/**
* @param {Metrics} metrics
* @param {import('../tables/metrics.js').MetricsTable} metricsTable
* @param {import('../types.js').MetricsTable} metricsTable
*/
export async function recordMetrics (metrics, metricsTable) {
const fetchedMetrics = await getMetrics(metricsTable)
Expand Down
6 changes: 5 additions & 1 deletion upload-api/functions/ucan-invocation-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { createDelegationsStore } from '../buckets/delegations-store.js'
import { createSubscriptionTable } from '../tables/subscription.js'
import { createConsumerTable } from '../tables/consumer.js'
import { createRateLimitTable } from '../tables/rate-limit.js'
import { createSpaceMetricsTable } from '../tables/space-metrics.js'

Sentry.AWSLambda.init({
environment: process.env.SST_STAGE,
Expand Down Expand Up @@ -85,6 +86,7 @@ export async function ucanInvocationRouter(request) {
CONSUMER_TABLE_NAME: consumerTableName = '',
SUBSCRIPTION_TABLE_NAME: subscriptionTableName = '',
DELEGATION_TABLE_NAME: delegationTableName = '',
SPACE_METRICS_TABLE: spaceMetricsTableName = '',
RATE_LIMIT_TABLE_NAME: rateLimitTableName = '',
R2_ENDPOINT: r2DelegationBucketEndpoint = '',
R2_ACCESS_KEY_ID: r2DelegationBucketAccessKeyId = '',
Expand Down Expand Up @@ -125,7 +127,9 @@ export async function ucanInvocationRouter(request) {
endpoint: dbEndpoint
});
const rateLimitsStorage = createRateLimitTable(AWS_REGION, rateLimitTableName)
const provisionsStorage = useProvisionStore(subscriptionTable, consumerTable, parseServiceDids(providers))
const spaceMetricsTable = createSpaceMetricsTable(AWS_REGION, spaceMetricsTableName)

const provisionsStorage = useProvisionStore(subscriptionTable, consumerTable, spaceMetricsTable, parseServiceDids(providers))
const delegationsStorage = createDelegationsTable(AWS_REGION, delegationTableName, { bucket: delegationBucket, invocationBucket, workflowBucket })

const server = createUcantoServer(serviceSigner, {
Expand Down
5 changes: 4 additions & 1 deletion upload-api/functions/validate-email.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
PendingValidateEmail,
} from '../html.jsx'
import { createRateLimitTable } from '../tables/rate-limit.js'
import { createSpaceMetricsTable } from '../tables/space-metrics.js'

Sentry.AWSLambda.init({
environment: process.env.SST_STAGE,
Expand Down Expand Up @@ -67,6 +68,7 @@ function createAuthorizeContext () {
AWS_REGION = '',
DELEGATION_TABLE_NAME = '',
RATE_LIMIT_TABLE_NAME = '',
SPACE_METRICS_TABLE_NAME = '',
R2_ENDPOINT = '',
R2_ACCESS_KEY_ID = '',
R2_SECRET_ACCESS_KEY = '',
Expand Down Expand Up @@ -94,13 +96,14 @@ function createAuthorizeContext () {
const consumerTable = createConsumerTable(AWS_REGION, CONSUMER_TABLE_NAME, {
endpoint: dbEndpoint
});
const spaceMetricsTable = createSpaceMetricsTable(AWS_REGION, SPACE_METRICS_TABLE_NAME)
return {
// TODO: we should set URL from a different env var, doing this for now to avoid that refactor
url: new URL(ACCESS_SERVICE_URL),
email: new Email({ token: POSTMARK_TOKEN }),
signer: getServiceSigner({ UPLOAD_API_DID, PRIVATE_KEY }),
delegationsStorage: createDelegationsTable(AWS_REGION, DELEGATION_TABLE_NAME, { bucket: delegationBucket, invocationBucket, workflowBucket }),
provisionsStorage: useProvisionStore(subscriptionTable, consumerTable, parseServiceDids(PROVIDERS)),
provisionsStorage: useProvisionStore(subscriptionTable, consumerTable, spaceMetricsTable, parseServiceDids(PROVIDERS)),
rateLimitsStorage: createRateLimitTable(AWS_REGION, RATE_LIMIT_TABLE_NAME)
}
}
Expand Down
2 changes: 1 addition & 1 deletion upload-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@web-std/fetch": "^4.1.0",
"@web3-storage/access": "^14.0.0",
"@web3-storage/capabilities": "^9.0.0",
"@web3-storage/upload-api": "^5.0.0",
"@web3-storage/upload-api": "^5.2.0",
"@web3-storage/w3infra-ucan-invocation": "*",
"multiformats": "^11.0.1",
"nanoid": "^4.0.2",
Expand Down
Loading

0 comments on commit e1c0507

Please sign in to comment.