Skip to content
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
4 changes: 4 additions & 0 deletions infra-samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Infrastructure Samples

This directory contains sample scripts for initializing external infrastructure resources such as cloud services and databases.
It is intended to help developers quickly set up necessary components for local development, testing, or demonstration purposes.
17 changes: 17 additions & 0 deletions infra-samples/aws/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Samples for AWS

## S3
WebRTC statistics are stored as ZIP files on S3.

### Run
```
$ node ./infra-samples/aws/create-s3-bucket.js
```

## DynamoDB
DynamoDB manages meeting metadata. You can see the schema in [API.md](../../API.md#identity-request)

### Run
```
$ node ./infra-samples/aws/create-dynamodb-table.js
```
164 changes: 164 additions & 0 deletions infra-samples/aws/create-dynamodb-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
const AWS = require('aws-sdk');

const {
RTCSTATS_METADATA_TABLE,
AWS_REGION: region,
RTCSTATS_DYNAMODB_ENDPOINT: endpoint
} = process.env;

const config = endpoint ? { endpoint,
region } : { region };

AWS.config.update(config);

const tableConfig = {
TableName: RTCSTATS_METADATA_TABLE,
AttributeDefinitions: [
{
AttributeName: 'conferenceId',
AttributeType: 'S'
},
{
AttributeName: 'conferenceUrl',
AttributeType: 'S'
},
{
AttributeName: 'dumpId',
AttributeType: 'S'
},
{
AttributeName: 'startDate',
AttributeType: 'N'
},
{
AttributeName: 'sessionId',
AttributeType: 'S'
}
],
KeySchema: [
{
AttributeName: 'conferenceId',
KeyType: 'HASH'
},
{
AttributeName: 'dumpId',
KeyType: 'RANGE'
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 5,
WriteCapacityUnits: 5
},
GlobalSecondaryIndexes: [
{
IndexName: 'conferenceUrl-startDate-index',
KeySchema: [
{
AttributeName: 'conferenceUrl',
KeyType: 'HASH'
},
{
AttributeName: 'startDate',
KeyType: 'RANGE'
}
],
Projection: {
ProjectionType: 'ALL'
},
ProvisionedThroughput: {
ReadCapacityUnits: 5,
WriteCapacityUnits: 5
}
},
{
IndexName: 'conferenceId-startDate-index',
KeySchema: [
{
AttributeName: 'conferenceId',
KeyType: 'HASH'
},
{
AttributeName: 'startDate',
KeyType: 'RANGE'
}
],
Projection: {
ProjectionType: 'ALL'
},
ProvisionedThroughput: {
ReadCapacityUnits: 5,
WriteCapacityUnits: 5
}
},
{
IndexName: 'sessionId-startDate-index',
KeySchema: [
{
AttributeName: 'sessionId',
KeyType: 'HASH'
},
{
AttributeName: 'startDate',
KeyType: 'RANGE'
}
],
Projection: {
ProjectionType: 'ALL'
},
ProvisionedThroughput: {
ReadCapacityUnits: 5,
WriteCapacityUnits: 5
}
}
],
StreamSpecification: {
StreamEnabled: false
}
};

const ddb = new AWS.DynamoDB();


const createTable = () => ddb.createTable(tableConfig, err => {
if (err) {
console.log('Could not create table', err);
}
});

const deleteTable = () => new Promise((resolve, reject) => {
ddb.deleteTable({
TableName: RTCSTATS_METADATA_TABLE
}, (err, data) => {
if (err) {
reject(err);
} else {
console.log(data);
resolve(data);
}
});
});

ddb.listTables(async (err, data) => {
if (err) {
console.error('Could not list tables', err);

return;
}

const tableExists = Boolean(data.TableNames.find(t => t === RTCSTATS_METADATA_TABLE));

if (tableExists) {
try {
console.log('Table exists, deleting and recreating...');

await deleteTable();
createTable();
// eslint-disable-next-line no-catch-shadow, no-shadow
} catch (err) {
console.error('Could not delete table', err);
}
} else {
console.log('Creating new table...');
createTable();
}
});
36 changes: 36 additions & 0 deletions infra-samples/aws/create-s3-bucket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const AWS = require('aws-sdk');

const {
RTCSTATS_S3_BUCKET,
AWS_REGION: region,
RTCSTATS_S3_ENDPOINT: endpoint
} = process.env;

const config = { region };

AWS.config.update(config);

const s3Config = endpoint ? { endpoint } : {};

const bucketConfig = {
Bucket: RTCSTATS_S3_BUCKET
};

const s3 = new AWS.S3(s3Config);


// --- Workaround for LocalStack S3 endpoint issue ---
// The AWS SDK v2 may not handle the endpoint URL correctly, leading to an `InvalidLocationConstraint` error.
// To fix this, we explicitly set only the hostname to an internal property of the SDK.
// See: https://github.com/localstack/localstack/issues/8000
if (endpoint) {
const url = new URL(endpoint);

s3.api.globalEndpoint = url.hostname;
}

s3.createBucket(bucketConfig, err => {
if (err) {
console.error('Could not create bucket:', err);
}
});