diff --git a/package.json b/package.json index 87237d5..924e66a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@pushrocks/smartuniverse", "version": "1.0.20", - "private": false, + "private": true, "description": "messaging service for your micro services", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -32,4 +32,4 @@ "smartsocket": "^1.1.19", "smarttime": "^2.0.0" } -} +} \ No newline at end of file diff --git a/ts/smartuniverse.classes.universe.ts b/ts/smartuniverse.classes.universe.ts index ff3c3a4..c5a7850 100644 --- a/ts/smartuniverse.classes.universe.ts +++ b/ts/smartuniverse.classes.universe.ts @@ -3,7 +3,7 @@ import * as plugins from './smartuniverse.plugins'; import { Handler, Route, Server } from 'smartexpress'; import { UniverseChannel } from './smartuniverse.classes.universechannel'; import { UniverseMessage } from './smartuniverse.classes.universemessage'; -import { UniverseStore } from './smartuniverse.classes.universestore'; +import { UniverseCache } from './smartuniverse.classes.universecache'; import * as paths from './smartuniverse.paths'; @@ -32,7 +32,7 @@ export interface IServerPutMessageRequestBody { */ export class Universe { // subinstances - public universeStore: UniverseStore; + public universeCache: UniverseCache; // options private options: ISmartUniverseConstructorOptions; @@ -54,7 +54,7 @@ export class Universe { constructor(optionsArg: ISmartUniverseConstructorOptions) { this.options = optionsArg; - this.universeStore = new UniverseStore(this.options.messageExpiryInMilliseconds); + this.universeCache = new UniverseCache(this.options.messageExpiryInMilliseconds); } /** @@ -70,10 +70,15 @@ export class Universe { // message handling // adds messages - const addMessageHandler = new Handler('PUT', request => { + const addMessageHandler = new Handler('PUT', async request => { const requestBody: IServerPutMessageRequestBody = request.body; - const message = new UniverseMessage(requestBody.message, requestBody.channel, requestBody.passphrase, requestBody.payload); - this.universeStore.addMessage(message); + const message = new UniverseMessage( + requestBody.message, + requestBody.channel, + requestBody.passphrase, + requestBody.payload + ); + this.universeCache.addMessage(message); console.log(requestBody); return true; }); @@ -82,7 +87,7 @@ export class Universe { const readMessageHandler = new Handler('GET', request => { const done = plugins.smartq.defer(); const requestBody = request.body; - const messageObservable = this.universeStore.readMessagesYoungerThan(requestBody.since); + const messageObservable = this.universeCache.readMessagesYoungerThan(requestBody.since); messageObservable.toArray().subscribe(universeMessageArrayArg => { done.resolve(universeMessageArrayArg); }); diff --git a/ts/smartuniverse.classes.universestore.ts b/ts/smartuniverse.classes.universecache.ts similarity index 54% rename from ts/smartuniverse.classes.universestore.ts rename to ts/smartuniverse.classes.universecache.ts index 8dee0c8..97fb9d6 100644 --- a/ts/smartuniverse.classes.universestore.ts +++ b/ts/smartuniverse.classes.universecache.ts @@ -1,5 +1,6 @@ import * as plugins from './smartuniverse.plugins'; +import { UniverseChannel } from './smartuniverse.classes.universechannel'; import { UniverseMessage } from './smartuniverse.classes.universemessage'; import { Objectmap } from 'lik'; @@ -10,10 +11,25 @@ import { rxjs } from 'smartrx'; /** * universe store handles the creation, storage and retrieval of messages. */ -export class UniverseStore { +export class UniverseCache { public standardMessageExpiry: number; public destructionTime: number = 60000; - public messageStore = new Objectmap(); + + /** + * stores messages for this instance + */ + public messageCache = new Objectmap(); + + /** + * stores the channels that are available within the universe + */ + public channelCache = new Objectmap(); + + /** + * allows messages to be processed in a blacklist mode for further analysis + */ + public blackListChannel = new UniverseChannel(this, 'blacklist', 'nada'); + private lastId: number = 0; // stores the last id constructor(standardMessageExpiryArg: number) { @@ -25,15 +41,17 @@ export class UniverseStore { * @param messageArg * @param attachedPayloadArg */ - public addMessage(messageArg: UniverseMessage) { - this.messageStore.add(messageArg); + public async addMessage(messageArg: UniverseMessage) { + messageArg.setUniverseCache(this); + UniverseChannel.authorizeAMessageForAChannel(this, messageArg); + this.messageCache.add(messageArg); } /** * Read a message from the UniverseStore */ public readMessagesYoungerThan(unixTimeArg?: number): Observable { - const messageObservable = rxjs.Observable.from(this.messageStore.getArray()).filter( + const messageObservable = rxjs.Observable.from(this.messageCache.getArray()).filter( messageArg => { return messageArg.timestamp.isYoungerThanMilliSeconds(this.destructionTime); } diff --git a/ts/smartuniverse.classes.universechannel.ts b/ts/smartuniverse.classes.universechannel.ts index 8348f63..ac63ce3 100644 --- a/ts/smartuniverse.classes.universechannel.ts +++ b/ts/smartuniverse.classes.universechannel.ts @@ -1,61 +1,62 @@ import * as plugins from './smartuniverse.plugins'; import { Objectmap } from 'lik'; +import { UniverseCache } from './smartuniverse.classes.universecache'; +import { UniverseMessage } from './smartuniverse.classes.universemessage'; /** * enables messages to stay within a certain scope. */ export class UniverseChannel { - // ====== // STATIC // ====== - - /** - * stores the channels that are available within the universe - */ - public static channelStore = new Objectmap(); - - /** - * allows messages to be processed in a blacklist mode for further analysis - */ - public static blackListChannel = new UniverseChannel('blacklist', 'nada'); /** * creates new channels * @param channelArg the name of the topic * @param passphraseArg the secret thats used for a certain topic. */ - public static createChannel (channelNameArg: string, passphraseArg: string) { - const newChannel = new UniverseChannel(channelNameArg, passphraseArg); + public static createChannel( + universeCacheArg: UniverseCache, + channelNameArg: string, + passphraseArg: string + ) { + const newChannel = new UniverseChannel(universeCacheArg, channelNameArg, passphraseArg); return newChannel; - }; + } /** * returns boolean wether certain channel exists */ - public static async doesChannelExists (channelNameArg: string) { - const channel = this.channelStore.find(channelArg => { + public static async doesChannelExists(universeCacheArg: UniverseCache, channelNameArg: string) { + const channel = universeCacheArg.channelCache.find(channelArg => { return channelArg.name === channelNameArg; }); - if(channel) { + if (channel) { return true; } else { return false; } } - public static authorizeForChannel (channelNameArg: string, passphraseArg: string) { - const foundChannel = this.channelStore.find(universeChannel => { - const result = universeChannel.authenticate(channelNameArg, passphraseArg); - return result; + public static authorizeAMessageForAChannel( + universeCacheArg: UniverseCache, + universeMessageArg: UniverseMessage + ) { + const foundChannel = universeCacheArg.channelCache.find(universeChannel => { + const result = universeChannel.authenticate(universeMessageArg); + return result; }); - if(foundChannel) { + if (foundChannel) { + universeMessageArg.authenticated = true; + universeMessageArg.universeChannelList.add(foundChannel); return foundChannel; } else { - return this.blackListChannel; + universeMessageArg.authenticated = false; + universeMessageArg.universeChannelList.add(universeCacheArg.blackListChannel); } - }; + } // ======== // INSTANCE @@ -64,22 +65,25 @@ export class UniverseChannel { * the name of the channel */ public name: string; + public universeCacheInstance: UniverseCache; /** * the passphrase for the channel */ public passphrase: string; - constructor(channelNameArg: string, passphraseArg: string) { + constructor(universeCacheArg: UniverseCache, channelNameArg: string, passphraseArg: string) { this.name = channelNameArg; this.passphrase = passphraseArg; - UniverseChannel.channelStore.add(this); } /** * authenticates a client on the server side */ - public authenticate(channelNameArg: string, passphraseArg: string): boolean { - return (this.name === channelNameArg && this.passphrase === passphraseArg); + public authenticate(universeMessageArg: UniverseMessage): boolean { + return ( + this.name === universeMessageArg.requestedChannelName && + this.passphrase === universeMessageArg.requestedChannelPassphrase + ); } } diff --git a/ts/smartuniverse.classes.universemessage.ts b/ts/smartuniverse.classes.universemessage.ts index 154d651..80d30c6 100644 --- a/ts/smartuniverse.classes.universemessage.ts +++ b/ts/smartuniverse.classes.universemessage.ts @@ -1,12 +1,16 @@ import * as plugins from './smartuniverse.plugins'; +import { Objectmap } from 'lik'; + + import { Timer, TimeStamp } from 'smarttime'; -import { UniverseChannel } from './smartuniverse.classes.universechannel'; -import { UniverseStore } from './smartuniverse.classes.universestore'; import { Universe } from './smartuniverse.classes.universe'; +import { UniverseChannel } from './smartuniverse.classes.universechannel'; +import { UniverseCache } from './smartuniverse.classes.universecache'; /** * represents a message within a universe + * acts as a container to save message states like authentication status */ export class UniverseMessage { /** @@ -18,13 +22,25 @@ export class UniverseMessage { public id: number; /** - * the universe store the message is attached to + * the UniverseCache the message is attached to */ - public universeStore: UniverseStore; + public universeCache: UniverseCache; + + /** + * requestedChannelName + */ + public requestedChannelName: string; + public requestedChannelPassphrase: string; + /** * enables unprotected grouping of messages for efficiency purposes. */ - public universeChannel: UniverseChannel; + public universeChannelList = new Objectmap(); + + /** + * wether the message is authenticated + */ + public authenticated: boolean = null; /** * time of creation @@ -47,16 +63,23 @@ export class UniverseMessage { * @param messageArg * @param attachedPayloadArg */ - constructor(messageArg: string, channelNameArg: string, passphraseArg: string, attachedPayloadArg: any) { + constructor( + messageArg: string, + requestedChannelNameArg: string, + passphraseArg: string, + attachedPayloadArg: any + ) { this.timestamp = new TimeStamp(); this.message = messageArg; - this.universeChannel = UniverseChannel.authorizeForChannel(channelNameArg, passphraseArg); + this.requestedChannelName = requestedChannelNameArg; + this.requestedChannelPassphrase = passphraseArg; this.attachedPayload = attachedPayloadArg; + // prevent memory issues this.fallBackDestruction(); } - public setUniverseStore(universeStoreArg: UniverseStore) { - this.universeStore = universeStoreArg; + public setUniverseCache(universeCacheArg: UniverseCache) { + this.universeCache = universeCacheArg; } public setDestructionTimer(selfdestructAfterArg: number) { @@ -64,15 +87,22 @@ export class UniverseMessage { this.destructionTimer = new Timer(selfdestructAfterArg); this.destructionTimer.start(); - // set up self destruction by removing this from the parent messageStore + // set up self destruction by removing this from the parent messageCache this.destructionTimer.completed.then(async () => { - this.universeStore.messageStore.remove(this); + this.universeCache.messageCache.remove(this); }); } else { this.fallBackDestruction(); } } + /** + * handles bad messages for further analysis + */ + handleAsBadMessage() { + console.log('received a bad message'); + } + /** * prevents memory leaks if channels have no default */