Skip to content

Commit

Permalink
Support insertion of records in the ledger (#2 #1)
Browse files Browse the repository at this point in the history
* Mimic basic document insertion in the ledger

* Constrain POST data to yup schema (close #3)

* Simplify the async chain

* Augment the inserted document with a unique ID
  • Loading branch information
basilesimon committed May 26, 2021
1 parent 588358a commit 18b76f6
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 102 deletions.
21 changes: 21 additions & 0 deletions index.ts
@@ -1,9 +1,14 @@
import express, { Application, Request, Response } from 'express';
import { config } from 'dotenv';
import sdk from 'aws-sdk';
import { uniqueID } from './src/helpers';
const { QLDB } = sdk;

import { DOC_TABLE_NAME } from './src/qldb-Constants.js';
import { listLedgers } from './src/qldb-ListLedgers';
import { insertDocuments } from './src/qldb-InsertDocument';

import { RecordSchema } from './src/schemas';

// set up .env variables as environment variables
config();
Expand All @@ -30,6 +35,22 @@ app.get(
}
);

app.post(
'/insert-doc',
async (req: Request, res: Response): Promise<Response> => {
const payload: { title: string; url: string } = req.body;
const document = { sku: uniqueID(), ...payload };
return RecordSchema.validate(document, { strict: true, stripUnknown: true })
.then(() => {
const result = insertDocuments(DOC_TABLE_NAME, document);
return res.status(200).send(result);
})
.catch(e =>
res.status(422).send(`${e.name} (type ${e.type}): ${e.message}`)
);
}
);

try {
app.listen(port, (): void => {
console.log(`Connected successfully on port ${port}`);
Expand Down
24 changes: 12 additions & 12 deletions init.js
Expand Up @@ -21,19 +21,19 @@ config();
const main = async function () {
try {
const qldbDriver = getQldbDriver();
await qldbDriver.executeLambda(async (txn) => {
await qldbDriver.executeLambda(async txn => {
Promise.all([
// createTable(txn, DOC_TABLE_NAME),
// createIndex(txn, DOC_TABLE_NAME, DOC_INDEX_KEY),
// insertDocuments(txn, DOC_TABLE_NAME, Documents),
await qldbDriver.executeLambda(async (txn) => {
const results = (
await txn.execute('SELECT * FROM Document')
).getResultList();
for (let result of results) {
console.log(result); // prints [String: 'TOYENC486FH']
}
}),
createTable(txn, DOC_TABLE_NAME),
createIndex(txn, DOC_TABLE_NAME, DOC_INDEX_KEY),
insertDocuments(txn, DOC_TABLE_NAME, Documents),
// await qldbDriver.executeLambda(async (txn) => {
// const results = (
// await txn.execute('SELECT * FROM Document')
// ).getResultList();
// for (let result of results) {
// console.log(result); // prints [String: 'TOYENC486FH']
// }
// }),
]);
});
} catch (e) {
Expand Down
62 changes: 62 additions & 0 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 package.json
Expand Up @@ -22,7 +22,9 @@
"express": "^4.17.1",
"ion-js": "^4.0.0",
"jsbi": "^3.1.2",
"node-fetch": "^2.6.1"
"nanoid": "^3.1.23",
"node-fetch": "^2.6.1",
"yup": "^0.32.9"
},
"scripts": {
"init": "node init.js",
Expand Down
8 changes: 8 additions & 0 deletions src/helpers.ts
@@ -0,0 +1,8 @@
import { nanoid } from 'nanoid';

/**
* Use Nano-ID unique string generator
* https://github.com/ai/nanoid/
* @returns A unique string
*/
export const uniqueID = (): string => nanoid();
52 changes: 0 additions & 52 deletions src/qldb-ConnectToLedger.js

This file was deleted.

71 changes: 71 additions & 0 deletions src/qldb-ConnectToLedger.ts
@@ -0,0 +1,71 @@
/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: MIT-0
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { QldbDriver, RetryConfig } from 'amazon-qldb-driver-nodejs';
import { ClientConfiguration } from 'aws-sdk/clients/qldbsession';

import { LEDGER_NAME } from './qldb-Constants';

const qldbDriver: QldbDriver = createQldbDriver();

/**
* Create a driver for creating sessions.
* @param ledgerName The name of the ledger to create the driver on.
* @param serviceConfigurationOptions The configurations for the AWS SDK client that the driver uses.
* @returns The driver for creating sessions.
*/
export function createQldbDriver(
ledgerName: string = LEDGER_NAME,
serviceConfigurationOptions: ClientConfiguration = { region: 'eu-central-1' }
): QldbDriver {
const retryLimit = 4;
const maxConcurrentTransactions = 10;
//Use driver's default backoff function (and hence, no second parameter provided to RetryConfig)
const retryConfig: RetryConfig = new RetryConfig(retryLimit);
const qldbDriver: QldbDriver = new QldbDriver(
ledgerName,
serviceConfigurationOptions,
10,
retryConfig
);
return qldbDriver;
}

export function getQldbDriver(): QldbDriver {
return qldbDriver;
}

/**
* Connect to a session for a given ledger using default settings.
* @returns Promise which fulfills with void.
*/
var main = async function (): Promise<void> {
try {
console.log('Listing table names...');
const tableNames: string[] = await qldbDriver.getTableNames();
tableNames.forEach((tableName: string): void => {
console.log(tableName);
});
} catch (e) {
console.log(`Unable to create session: ${e}`);
}
};

if (require.main === module) {
main();
}
19 changes: 0 additions & 19 deletions src/qldb-InsertDocument.js

This file was deleted.

29 changes: 29 additions & 0 deletions src/qldb-InsertDocument.ts
@@ -0,0 +1,29 @@
import {
QldbDriver,
Result,
TransactionExecutor,
} from 'amazon-qldb-driver-nodejs';
import { getQldbDriver } from './qldb-ConnectToLedger';

/**
* Insert documents into a table in a QLDB ledger.
* @param tableName Name of the table to insert documents into.
* @param documents List of documents to insert.
* @returns Promise which fulfills with with a {@linkcode Result} object.
*/
export const insertDocuments = async function (
tableName: string,
documents: object
): Promise<Result> {
try {
const qldbDriver: QldbDriver = getQldbDriver();
const statement: string = `INSERT INTO ${tableName} ?`;
let r = qldbDriver.executeLambda(async (txn: TransactionExecutor) => {
let results = await txn.execute(statement, documents);
return results;
});
return r;
} catch (e) {
console.log(`Unable to insert documents: ${e}`);
}
};

0 comments on commit 18b76f6

Please sign in to comment.