Compare commits

...

7 Commits

Author SHA1 Message Date
57b37cb327 1.0.24 2019-01-30 11:01:49 +01:00
8b17e814cc fix(dependencies): update 2019-01-30 11:01:48 +01:00
f4b8cde347 fix(dependencies): update 2019-01-30 10:56:31 +01:00
3189d4d274 1.0.23 2018-05-30 16:34:07 +02:00
c2d134a6ea fix(websocket): switch to all websocket infrastructure 2018-05-30 16:34:06 +02:00
7552dc1e9f 1.0.22 2018-05-28 12:07:26 +02:00
fe91459510 fix(core): update to transparent universe 2018-05-28 12:07:25 +02:00
16 changed files with 1107 additions and 1470 deletions

View File

@ -3,7 +3,7 @@ image: hosttoday/ht-docker-node:npmci
cache: cache:
paths: paths:
- .yarn/ - .npmci_cache/
key: "$CI_BUILD_STAGE" key: "$CI_BUILD_STAGE"
stages: stages:
@ -26,8 +26,8 @@ mirror:
snyk: snyk:
stage: security stage: security
script: script:
- npmci command yarn global add snyk - npmci command npm install -g snyk
- npmci command yarn install --ignore-scripts - npmci command npm install --ignore-scripts
- npmci command snyk test - npmci command snyk test
tags: tags:
- docker - docker
@ -117,7 +117,7 @@ pages:
image: hosttoday/ht-docker-node:npmci image: hosttoday/ht-docker-node:npmci
stage: metadata stage: metadata
script: script:
- npmci command yarn global add npmpage - npmci command npm install -g npmpage
- npmci command npmpage - npmci command npmpage
tags: tags:
- docker - docker

2305
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "@pushrocks/smartuniverse", "name": "@pushrocks/smartuniverse",
"version": "1.0.21", "version": "1.0.24",
"private": true, "private": true,
"description": "messaging service for your micro services", "description": "messaging service for your micro services",
"main": "dist/index.js", "main": "dist/index.js",
@ -8,28 +8,27 @@
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"test": "(ts-node -O '{\"lib\": [ \"es2015\" ]}' test/test.ts)", "test": "(tstest test/)",
"build": "(npmts)", "build": "(npmts)",
"format": "(gitzone format)" "format": "(gitzone format)"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^9.6.0", "@pushrocks/tapbundle": "^3.0.7",
"tapbundle": "^2.0.0", "@types/node": "^10.12.19"
"ts-node": "^6.0.3", },
"typescript": "^2.8.3" "peerDependencies": {
"rxjs": "*"
}, },
"dependencies": { "dependencies": {
"@pushrocks/smartcli": "^3.0.1", "@pushrocks/lik": "^3.0.4",
"lik": "^2.0.5", "@pushrocks/smartdelay": "^2.0.2",
"nodehash": "^1.0.4", "@pushrocks/smartexpress": "^3.0.10",
"rxjs": "^5.5.8", "@pushrocks/smartfile": "^6.0.12",
"smartdelay": "^1.0.4", "@pushrocks/smarthash": "^2.0.4",
"smartexpress": "^1.0.21", "@pushrocks/smartpromise": "^2.0.5",
"smartfile": "^4.2.28", "@pushrocks/smartrequest": "^1.0.8",
"smartq": "^1.1.8", "@pushrocks/smartrx": "^2.0.3",
"smartrequest": "^1.0.8", "@pushrocks/smartsocket": "^1.1.24",
"smartrx": "^1.0.5", "@pushrocks/smarttime": "^3.0.5"
"smartsocket": "^1.1.19",
"smarttime": "^2.0.0"
} }
} }

View File

@ -5,8 +5,8 @@ import * as smartuniverse from '../ts/index';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
let testUniverse: smartuniverse.Universe; let testUniverse: smartuniverse.Universe;
let testUniverseClient: smartuniverse.UniverseClient; let testUniverseClient: smartuniverse.ClientUniverse;
let testMessageObservable: Observable<smartuniverse.UniverseMessage>; let testClientChannel: smartuniverse.ClientUniverseChannel;
tap.test('first test', async () => { tap.test('first test', async () => {
testUniverse = new smartuniverse.Universe({ testUniverse = new smartuniverse.Universe({
@ -20,10 +20,19 @@ tap.test('add a message to the SmartUniverse', async () => {
// testing message handling // testing message handling
tap.test('create smartuniverse client', async () => { tap.test('create smartuniverse client', async () => {
testUniverseClient = new smartuniverse.UniverseClient({ testUniverseClient = new smartuniverse.ClientUniverse({
serverAddress: 'http://localhost:8765' serverAddress: 'http://localhost:8765'
}); });
expect(testUniverseClient).to.be.instanceof(smartuniverse.UniverseClient); expect(testUniverseClient).to.be.instanceof(smartuniverse.ClientUniverse);
});
tap.test('should add a channel to the universe', async () => {
await testUniverse.addChannel('testChannel', 'testPassword');
});
tap.test('should get a observable correctly', async () => {
testClientChannel = await testUniverseClient.getChannel('testChannel');
expect(testClientChannel).to.be.instanceof(smartuniverse.ClientUniverseChannel);
}); });
tap.test('should send a message correctly', async () => { tap.test('should send a message correctly', async () => {
@ -32,10 +41,6 @@ tap.test('should send a message correctly', async () => {
}); });
}); });
tap.test('should get a observable correctly', async () => {
testMessageObservable = testUniverseClient.getMessageObservable();
});
tap.test('should receive a message correctly', async () => {}); tap.test('should receive a message correctly', async () => {});
tap.test('should disconnect the client correctly', async () => { tap.test('should disconnect the client correctly', async () => {

View File

@ -1,3 +1,10 @@
// Client classes
export * from './smartuniverse.classes.clientuniverse';
export * from './smartuniverse.classes.clientuniversechannel';
// Server classes
export * from './smartuniverse.classes.universe'; export * from './smartuniverse.classes.universe';
export * from './smartuniverse.classes.universeclient'; export * from './smartuniverse.classes.universecache';
export * from './smartuniverse.classes.universechannel';
export * from './smartuniverse.classes.universemessage'; export * from './smartuniverse.classes.universemessage';
export * from './smartuniverse.interfaces';

View File

@ -1,14 +1,16 @@
import * as plugins from './smartuniverse.plugins'; import * as plugins from './smartuniverse.plugins';
import { Objectmap } from 'lik';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { Smartsocket, SmartsocketClient } from 'smartsocket'; import { Smartsocket, SmartsocketClient } from 'smartsocket';
import * as url from 'url'; import * as url from 'url';
import { import {
ClientUniverseChannel,
IServerGetMessagesRequestBody, IServerGetMessagesRequestBody,
IServerPutMessageRequestBody IServerPutMessageRequestBody,
} from './smartuniverse.classes.universe'; UniverseMessage
import { UniverseMessage } from './smartuniverse.classes.universemessage'; } from './';
export interface IClientOptions { export interface IClientOptions {
serverAddress: string; serverAddress: string;
@ -18,10 +20,12 @@ export interface IClientOptions {
* this class is for client side only!!! * this class is for client side only!!!
* allows connecting to a universe server * allows connecting to a universe server
*/ */
export class UniverseClient { export class ClientUniverse {
public options; public options;
private socketClient: plugins.smartsocket.SmartsocketClient; public socketClient: plugins.smartsocket.SmartsocketClient;
private observableIntake: plugins.smartrx.ObservableIntake<UniverseMessage>; public observableIntake: plugins.smartrx.ObservableIntake<UniverseMessage>;
public channelCache = new Objectmap<ClientUniverseChannel>();
constructor(optionsArg: IClientOptions) { constructor(optionsArg: IClientOptions) {
this.options = optionsArg; this.options = optionsArg;
@ -38,7 +42,21 @@ export class UniverseClient {
}); });
} }
public getMessageObservable() { public async getChannel(channelName: string): Promise<ClientUniverseChannel> {
await this.checkConnection();
const clientUniverseChannel = await ClientUniverseChannel.createClientUniverseChannel(
this,
channelName
);
this.channelCache.add(clientUniverseChannel);
return clientUniverseChannel;
}
public close() {
this.socketClient.disconnect();
}
private async checkConnection() {
if (!this.socketClient && !this.observableIntake) { if (!this.socketClient && !this.observableIntake) {
const parsedURL = url.parse(this.options.serverAddress); const parsedURL = url.parse(this.options.serverAddress);
this.socketClient = new SmartsocketClient({ this.socketClient = new SmartsocketClient({
@ -51,10 +69,5 @@ export class UniverseClient {
this.observableIntake = new plugins.smartrx.ObservableIntake(); this.observableIntake = new plugins.smartrx.ObservableIntake();
this.socketClient.connect(); this.socketClient.connect();
} }
return this.observableIntake.observable;
}
public close() {
this.socketClient.disconnect();
} }
} }

View File

@ -0,0 +1,34 @@
import * as plugins from './smartuniverse.plugins';
import { ClientUniverse, IUniverseChannel } from './';
export class ClientUniverseChannel implements IUniverseChannel {
// ======
// STATIC
// ======
public static async createClientUniverseChannel(
clientUniverseArg: ClientUniverse,
channelName: string
): Promise<ClientUniverseChannel> {
const clientChannel = new ClientUniverseChannel(clientUniverseArg);
await clientChannel.transmitSubscription();
return clientChannel;
}
// ========
// INSTANCE
// ========
public clientUniverse: ClientUniverse;
constructor(clientUniverseArg: ClientUniverse) {
this.clientUniverse = clientUniverseArg;
}
/**
* tells the universe about this instances interest into a channel
*/
public async transmitSubscription() {
this.clientUniverse.socketClient;
}
}

View File

@ -0,0 +1,15 @@
import * as plugins from './smartuniverse.plugins';
import { IUniverseMessage } from './';
export class ClientUniverseMessage implements IUniverseMessage {
// ======
// STATIC
// ======
createMessage(messageArg: string, payloadArg: any) {}
// ========
// INSTANCE
// ========
constructor(messageArg, payloadArg) {}
}

View File

@ -1,9 +1,7 @@
import * as plugins from './smartuniverse.plugins'; import * as plugins from './smartuniverse.plugins';
import { Handler, Route, Server } from 'smartexpress'; import { Handler, Route, Server } from 'smartexpress';
import { UniverseChannel } from './smartuniverse.classes.universechannel'; import { UniverseCache, UniverseChannel, UniverseMessage } from './';
import { UniverseMessage } from './smartuniverse.classes.universemessage';
import { UniverseCache } from './smartuniverse.classes.universecache';
import * as paths from './smartuniverse.paths'; import * as paths from './smartuniverse.paths';
@ -57,6 +55,14 @@ export class Universe {
this.universeCache = new UniverseCache(this.options.messageExpiryInMilliseconds); this.universeCache = new UniverseCache(this.options.messageExpiryInMilliseconds);
} }
/**
* adds a channel to the Universe
*/
public async addChannel(nameArg: string, passphraseArg: string) {
const newChannel = new UniverseChannel(this.universeCache, nameArg, passphraseArg);
this.universeCache.channelMap.add(newChannel);
}
/** /**
* initiates a server * initiates a server
*/ */
@ -68,46 +74,26 @@ export class Universe {
port: portArg port: portArg
}); });
// message handling
// adds messages
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.universeCache.addMessage(message);
console.log(requestBody);
return true;
});
// gets messages
const readMessageHandler = new Handler('GET', request => {
const done = plugins.smartq.defer<UniverseMessage[]>();
const requestBody = request.body;
const messageObservable = this.universeCache.readMessagesYoungerThan(requestBody.since);
messageObservable.toArray().subscribe(universeMessageArrayArg => {
done.resolve(universeMessageArrayArg);
});
return done.promise;
});
// create new Route for messages
const messageRoute = new Route(this.smartexpressServer, 'message');
messageRoute.addHandler(addMessageHandler);
messageRoute.addHandler(readMessageHandler);
const leaderElectionRoute = new Route(this.smartexpressServer, 'leadelection');
// TODO: implement Handlers for leader election
// add websocket upgrade // add websocket upgrade
this.smartsocket = new plugins.smartsocket.Smartsocket({ this.smartsocket = new plugins.smartsocket.Smartsocket({
port: 12345 // fix this within smartsocket port: 12345 // fix this within smartsocket
}); });
this.smartsocket.setExternalServer('express', this.smartexpressServer as any); // should work with express as well const ClientRole = new plugins.smartsocket.SocketRole({
name: 'clientuniverse',
passwordHash: 'clientuniverse' // authentication happens on another level
});
this.smartsocket.addSocketRoles([ClientRole]);
const SubscriptionSocketFunction = new plugins.smartsocket.SocketFunction({
allowedRoles: [ClientRole],
funcName: 'channelSubscription',
funcDef: () => {}
});
this.smartsocket.setExternalServer('express', this.smartexpressServer as any);
// should work with express as well
this.smartsocket.start(); this.smartsocket.start();
await this.smartexpressServer.start(); await this.smartexpressServer.start();

View File

@ -12,26 +12,27 @@ import { rxjs } from 'smartrx';
* universe store handles the creation, storage and retrieval of messages. * universe store handles the creation, storage and retrieval of messages.
*/ */
export class UniverseCache { export class UniverseCache {
// ========
// INSTANCE
// ========
public standardMessageExpiry: number; public standardMessageExpiry: number;
public destructionTime: number = 60000; public destructionTime: number = 60000;
/** /**
* stores messages for this instance * stores messages for this instance
*/ */
public messageCache = new Objectmap<UniverseMessage>(); public messageMap = new Objectmap<UniverseMessage>();
/** /**
* stores the channels that are available within the universe * stores the channels that are available within the universe
*/ */
public channelCache = new Objectmap<UniverseChannel>(); public channelMap = new Objectmap<UniverseChannel>();
/** /**
* allows messages to be processed in a blacklist mode for further analysis * allows messages to be processed in a blacklist mode for further analysis
*/ */
public blackListChannel = new UniverseChannel(this, 'blacklist', 'nada'); public blackListChannel = new UniverseChannel(this, 'blacklist', 'nada');
private lastId: number = 0; // stores the last id
constructor(standardMessageExpiryArg: number) { constructor(standardMessageExpiryArg: number) {
this.standardMessageExpiry = standardMessageExpiryArg; this.standardMessageExpiry = standardMessageExpiryArg;
} }
@ -44,14 +45,14 @@ export class UniverseCache {
public async addMessage(messageArg: UniverseMessage) { public async addMessage(messageArg: UniverseMessage) {
messageArg.setUniverseCache(this); messageArg.setUniverseCache(this);
UniverseChannel.authorizeAMessageForAChannel(this, messageArg); UniverseChannel.authorizeAMessageForAChannel(this, messageArg);
this.messageCache.add(messageArg); this.messageMap.add(messageArg);
} }
/** /**
* Read a message from the UniverseStore * Read a message from the UniverseStore
*/ */
public readMessagesYoungerThan(unixTimeArg?: number): Observable<UniverseMessage> { public readMessagesYoungerThan(unixTimeArg?: number): Observable<UniverseMessage> {
const messageObservable = rxjs.Observable.from(this.messageCache.getArray()).filter( const messageObservable = rxjs.Observable.from(this.messageMap.getArray()).filter(
messageArg => { messageArg => {
return messageArg.timestamp.isYoungerThanMilliSeconds(this.destructionTime); return messageArg.timestamp.isYoungerThanMilliSeconds(this.destructionTime);
} }

View File

@ -30,7 +30,7 @@ export class UniverseChannel {
* returns boolean wether certain channel exists * returns boolean wether certain channel exists
*/ */
public static async doesChannelExists(universeCacheArg: UniverseCache, channelNameArg: string) { public static async doesChannelExists(universeCacheArg: UniverseCache, channelNameArg: string) {
const channel = universeCacheArg.channelCache.find(channelArg => { const channel = universeCacheArg.channelMap.find(channelArg => {
return channelArg.name === channelNameArg; return channelArg.name === channelNameArg;
}); });
if (channel) { if (channel) {
@ -44,7 +44,7 @@ export class UniverseChannel {
universeCacheArg: UniverseCache, universeCacheArg: UniverseCache,
universeMessageArg: UniverseMessage universeMessageArg: UniverseMessage
) { ) {
const foundChannel = universeCacheArg.channelCache.find(universeChannel => { const foundChannel = universeCacheArg.channelMap.find(universeChannel => {
const result = universeChannel.authenticate(universeMessageArg); const result = universeChannel.authenticate(universeMessageArg);
return result; return result;
}); });
@ -86,4 +86,6 @@ export class UniverseChannel {
this.passphrase === universeMessageArg.requestedChannelPassphrase this.passphrase === universeMessageArg.requestedChannelPassphrase
); );
} }
public pushToClients(messageArg: UniverseMessage) {}
} }

View File

@ -2,7 +2,6 @@ import * as plugins from './smartuniverse.plugins';
import { Objectmap } from 'lik'; import { Objectmap } from 'lik';
import { Timer, TimeStamp } from 'smarttime'; import { Timer, TimeStamp } from 'smarttime';
import { Universe } from './smartuniverse.classes.universe'; import { Universe } from './smartuniverse.classes.universe';
import { UniverseChannel } from './smartuniverse.classes.universechannel'; import { UniverseChannel } from './smartuniverse.classes.universechannel';
@ -89,7 +88,7 @@ export class UniverseMessage {
// set up self destruction by removing this from the parent messageCache // set up self destruction by removing this from the parent messageCache
this.destructionTimer.completed.then(async () => { this.destructionTimer.completed.then(async () => {
this.universeCache.messageCache.remove(this); this.universeCache.messageMap.remove(this);
}); });
} else { } else {
this.fallBackDestruction(); this.fallBackDestruction();

View File

@ -1,14 +0,0 @@
import * as plugins from './smartuniverse.plugins';
import { Universe } from './index';
process.env.CLI = 'true';
const universeCli = new plugins.smartcli.Smartcli();
universeCli.standardTask().subscribe(async argvArg => {
const standardUniverse = new Universe({
messageExpiryInMilliseconds: 60000
});
await standardUniverse.initServer(8765);
});

View File

@ -0,0 +1,3 @@
export interface IUniverseChannel {}
export interface IUniverseMessage {}

View File

@ -1,4 +1,3 @@
import * as smartcli from '@pushrocks/smartcli';
import * as lik from 'lik'; import * as lik from 'lik';
import * as nodehash from 'nodehash'; import * as nodehash from 'nodehash';
import * as path from 'path'; import * as path from 'path';
@ -15,7 +14,6 @@ export {
lik, lik,
nodehash, nodehash,
path, path,
smartcli,
smartdelay, smartdelay,
smartexpress, smartexpress,
smartfile, smartfile,

View File

@ -1,12 +1,6 @@
{ {
"extends": [ "extends": ["tslint:latest", "tslint-config-prettier"],
"tslint:latest",
"tslint-config-prettier"
],
"rules": { "rules": {
"semicolon": [ "semicolon": [true, "always"]
true,
"always"
]
} }
} }