diff --git a/Dockerfile b/Dockerfile index 4cf6f86..649dc8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,6 +27,7 @@ ENV MEMBER_TYPE= ENV DATABASE_NAME= ENV COLLECTION_NAME= ENV MEMORY= +ENV NO_STORAGE= # install signal-handler wrapper RUN apt-get -y install dumb-init # set start command @@ -38,4 +39,4 @@ RUN npm install -g npm@${NPM_TAG} ENV NODE_ENV production RUN npm ci --omit=dev USER node -CMD ["sh", "-c", "node ./server.js --host=0.0.0.0 --port=80 --memory=${MEMORY} --silent=${SILENT} --member-type=${MEMBER_TYPE} --connection-uri=${CONNECTION_URI} --database-name=${DATABASE_NAME} --collection-name=${COLLECTION_NAME}"] +CMD ["sh", "-c", "node ./server.js --host=0.0.0.0 --port=80 --no-storage=${NO_STORAGE} --memory=${MEMORY} --silent=${SILENT} --member-type=${MEMBER_TYPE} --connection-uri=${CONNECTION_URI} --database-name=${DATABASE_NAME} --collection-name=${COLLECTION_NAME}"] diff --git a/package-lock.json b/package-lock.json index f5485c8..ff5b86a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -437,6 +437,7 @@ "version": "7.23.9", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -631,6 +632,7 @@ "@babel/code-frame": "^7.23.5", "@babel/parser": "^7.23.9", "@babel/types": "^7.23.9" + }, "engines": { "node": ">=6.9.0" @@ -3284,6 +3286,7 @@ "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.2.2", "socks": "^2.7.1" + }, "peerDependenciesMeta": { "@aws-sdk/credential-providers": { @@ -3295,6 +3298,7 @@ "gcp-metadata": { "optional": true }, + "kerberos": { "optional": true }, diff --git a/src/member-controller.ts b/src/member-controller.ts index 983c965..eb9d32a 100644 --- a/src/member-controller.ts +++ b/src/member-controller.ts @@ -50,18 +50,30 @@ export class MemberController { } public async postMember(member: Member, quads: Quad[]) { - const ids = quads.filter(x => x.predicate.value === ns.rdf.type && x.object.value === this._memberType); + if (!quads) { + throw new Error('Quads cannot be undefined'); + } - if (ids && ids.length === 1 && ids[0]) { - const id = ids[0].subject.value; - const exists = await this._storage.exists(id); - if (exists) { - console.warn(`[WARNING] overriding id '${id}'`); + const ids = quads.filter(x => x.predicate.value === ns.rdf.type && x.object.value === this._memberType); + + switch (ids.length) { + case 1: { + const id = ids[0]?.subject.value || ''; + const exists = await this._storage.exists(id); + if (exists) { + console.warn(`[WARNING] overriding id '${id}'`); + } + return this._storage.insertOrUpdate(id, member); + } + case 0: { + console.warn('[WARNING] missing id:\n', member.body); + break; + } + default: { + console.warn('[WARNING] missing unique id:\n', ids); + break; } - return this._storage.insertOrUpdate(id, member); } - - console.warn('[WARNING] missing unique id:\n', ids); return undefined; } diff --git a/src/no-storage.ts b/src/no-storage.ts new file mode 100644 index 0000000..af4fb80 --- /dev/null +++ b/src/no-storage.ts @@ -0,0 +1,54 @@ +import { Member } from "member"; +import { IStorage } from "./storage"; + +export class NoStorage implements IStorage { + private _count = 0; + + get storageTypeName(): string { + return 'None'; + } + + get memberTypeName(): string { + return '(none)'; + } + + initialize(): Promise { + return new Promise(resolve => { resolve();}); + } + + terminate(): Promise { + return new Promise(resolve => { resolve();}); + } + + count(): Promise { + return new Promise(resolve => resolve(this._count)); + } + + lastIds(_: number): Promise { + return new Promise(resolve => resolve([])); + } + + member(_: string): Promise { + return new Promise(resolve => resolve(undefined)); + } + + exists(_: string): Promise { + return new Promise(resolve => resolve(false)); + } + + insertOrUpdate(id: string, _: Member): Promise { + return new Promise(resolve => { + this._count += 1; + resolve(id); + }); + } + + deleteAll(): Promise { + return new Promise(resolve => { + const count = this._count; + this._count = 0; + resolve(count); + }); + } + +} diff --git a/src/server.ts b/src/server.ts index bae47c2..4fccaa5 100644 --- a/src/server.ts +++ b/src/server.ts @@ -5,7 +5,8 @@ import minimist from 'minimist' import { Parser, Quad } from 'n3'; import { MongoStorage } from './mongo-storage'; import { MemoryStorage } from './memory-storage'; -import { IStorage } from 'storage'; +import { IStorage } from './storage'; +import { NoStorage } from './no-storage'; interface ParsedMember extends Member{ quads: Quad[]; @@ -31,8 +32,15 @@ if (!memberType) { } const useMemoryStorage: boolean = (/true/i).test(args['memory']); -const storage: IStorage = useMemoryStorage - ? new MemoryStorage(collectionName) +const useNoStorage: boolean = (/true/i).test(args['no-storage']); + +if(useMemoryStorage && useNoStorage) { + exitWithError('you cannot specify to use both "memory" and "no-storage".'); +} + +const storage: IStorage = + useMemoryStorage ? new MemoryStorage(collectionName) + : useNoStorage ? new NoStorage() : new MongoStorage(connectionUri, databaseName, collectionName); if(!silent) {