aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTyler Schicke <tschicke@gmail.com>2020-01-07 23:35:14 -0800
committerTyler Schicke <tschicke@gmail.com>2020-01-07 23:57:32 -0800
commit786d25a4f8db1db8795f04a17fba392636e5f891 (patch)
tree6973a067fda8e79a14e70ee8fcd4685752fb0bb0 /src
parent23d5f6b28a93a3c66c0bd7776d6a42073cc55afb (diff)
Various features/fixes to allow running on Linux w/o MongoDB or Solr
- Added new launch config option for chromium - Changed port for TypeScript server debugger to account for worker process - Updated packages to versions that work with current node/npm - Update IDatabase interface - Updated MemoryDatabase to work properly with Dash - Added some workarounds for in memory database as they currently don't support users, so you must be guest, which means the guest needs to be able to do things it usually can't - Added environment variable to disable search. This doesn't fully disable search yet, but it is enough to not throw major errors when Solr isn't running - Added logic to support using an in memory DB instead of MongoDB
Diffstat (limited to 'src')
-rw-r--r--src/client/DocServer.ts4
-rw-r--r--src/client/northstar/dash-nodes/HistogramBinPrimitiveCollection.ts4
-rw-r--r--src/client/northstar/dash-nodes/HistogramBoxPrimitives.tsx4
-rw-r--r--src/server/IDatabase.ts4
-rw-r--r--src/server/MemoryDatabase.ts32
-rw-r--r--src/server/RouteManager.ts5
-rw-r--r--src/server/Session/session.ts5
-rw-r--r--src/server/Websocket/Websocket.ts10
-rw-r--r--src/server/authentication/models/current_user_utils.ts2
-rw-r--r--src/server/database.ts12
-rw-r--r--src/server/index.ts16
-rw-r--r--src/server/server_Initialization.ts4
12 files changed, 73 insertions, 29 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 47c63bfb7..dbe8e58b9 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -254,7 +254,7 @@ export namespace DocServer {
const fieldMap: { [id: string]: RefField } = {};
const proms: Promise<void>[] = [];
for (const field of fields) {
- if (field !== undefined) {
+ if (field !== undefined && field !== null) {
// deserialize
const prom = SerializationHelper.Deserialize(field).then(deserialized => {
fieldMap[field.id] = deserialized;
@@ -421,4 +421,4 @@ export namespace DocServer {
function respondToDelete(ids: string | string[]) {
_respondToDelete(ids);
}
-} \ No newline at end of file
+}
diff --git a/src/client/northstar/dash-nodes/HistogramBinPrimitiveCollection.ts b/src/client/northstar/dash-nodes/HistogramBinPrimitiveCollection.ts
index 3e9145a1b..6b36ffc9e 100644
--- a/src/client/northstar/dash-nodes/HistogramBinPrimitiveCollection.ts
+++ b/src/client/northstar/dash-nodes/HistogramBinPrimitiveCollection.ts
@@ -3,7 +3,7 @@ import { AttributeTransformationModel } from "../../northstar/core/attribute/Att
import { ChartType } from '../../northstar/model/binRanges/VisualBinRange';
import { AggregateFunction, Bin, Brush, DoubleValueAggregateResult, HistogramResult, MarginAggregateParameters, MarginAggregateResult } from "../../northstar/model/idea/idea";
import { ModelHelpers } from "../../northstar/model/ModelHelpers";
-import { LABColor } from '../../northstar/utils/LABcolor';
+import { LABColor } from '../../northstar/utils/LABColor';
import { PIXIRectangle } from "../../northstar/utils/MathUtil";
import { StyleConstants } from "../../northstar/utils/StyleContants";
import { HistogramBox } from "./HistogramBox";
@@ -237,4 +237,4 @@ export class HistogramBinPrimitiveCollection {
// }
return StyleConstants.HIGHLIGHT_COLOR;
}
-} \ No newline at end of file
+}
diff --git a/src/client/northstar/dash-nodes/HistogramBoxPrimitives.tsx b/src/client/northstar/dash-nodes/HistogramBoxPrimitives.tsx
index 5a16b3782..66d91cc1d 100644
--- a/src/client/northstar/dash-nodes/HistogramBoxPrimitives.tsx
+++ b/src/client/northstar/dash-nodes/HistogramBoxPrimitives.tsx
@@ -5,7 +5,7 @@ import { Utils as DashUtils, emptyFunction } from '../../../Utils';
import { FilterModel } from "../../northstar/core/filter/FilterModel";
import { ModelHelpers } from "../../northstar/model/ModelHelpers";
import { ArrayUtil } from "../../northstar/utils/ArrayUtil";
-import { LABColor } from '../../northstar/utils/LABcolor';
+import { LABColor } from '../../northstar/utils/LABColor';
import { PIXIRectangle } from "../../northstar/utils/MathUtil";
import { StyleConstants } from "../../northstar/utils/StyleContants";
import { HistogramBinPrimitiveCollection, HistogramBinPrimitive } from "./HistogramBinPrimitiveCollection";
@@ -119,4 +119,4 @@ export class HistogramBoxPrimitives extends React.Component<HistogramPrimitivesP
</svg>
</div>;
}
-} \ No newline at end of file
+}
diff --git a/src/server/IDatabase.ts b/src/server/IDatabase.ts
index a7e3e2b0a..f1f450731 100644
--- a/src/server/IDatabase.ts
+++ b/src/server/IDatabase.ts
@@ -16,6 +16,8 @@ export interface IDatabase {
insert(value: any, collectionName?: string): Promise<void>;
getDocument(id: string, fn: (result?: Transferable) => void, collectionName?: string): void;
- getDocuments(ids: string[], fn: (result?: Transferable[]) => void, collectionName?: string): void;
+ getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName?: string): void;
visit(ids: string[], fn: (result: any) => string[] | Promise<string[]>, collectionName?: string): Promise<void>;
+
+ query(query: { [key: string]: any }, projection?: { [key: string]: 0 | 1 }, collectionName?: string): Promise<mongodb.Cursor>;
}
diff --git a/src/server/MemoryDatabase.ts b/src/server/MemoryDatabase.ts
index 8bf6abdd8..a14a68d17 100644
--- a/src/server/MemoryDatabase.ts
+++ b/src/server/MemoryDatabase.ts
@@ -17,8 +17,26 @@ export class MemoryDatabase implements IDatabase {
public update(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateWriteOpResult) => void, _upsert?: boolean, collectionName = DocumentsCollection): Promise<void> {
const collection = this.getCollection(collectionName);
- collection[id] = { ...collection[id], ...value };
- callback(null, {} as any);
+ if ("$set" in value) {
+ let currentVal = collection[id] ?? (collection[id] = {});
+ const val = value["$set"];
+ for (const key in val) {
+ const keys = key.split(".");
+ for (let i = 0; i < keys.length - 1; i++) {
+ const k = keys[i];
+ if (typeof currentVal[k] === "object") {
+ currentVal = currentVal[k];
+ } else {
+ currentVal[k] = {};
+ currentVal = currentVal[k];
+ }
+ }
+ currentVal[keys[keys.length - 1]] = val[key];
+ }
+ } else {
+ collection[id] = value;
+ }
+ callback(null as any, {} as any);
return Promise.resolve(undefined);
}
@@ -29,7 +47,7 @@ export class MemoryDatabase implements IDatabase {
public delete(query: any, collectionName?: string): Promise<mongodb.DeleteWriteOpResultObject>;
public delete(id: string, collectionName?: string): Promise<mongodb.DeleteWriteOpResultObject>;
public delete(id: any, collectionName = DocumentsCollection): Promise<mongodb.DeleteWriteOpResultObject> {
- const i = id["_id"] ?? id;
+ const i = id.id ?? id;
delete this.getCollection(collectionName)[i];
return Promise.resolve({} as any);
@@ -41,7 +59,7 @@ export class MemoryDatabase implements IDatabase {
}
public insert(value: any, collectionName = DocumentsCollection): Promise<void> {
- const id = value._id;
+ const id = value.id;
this.getCollection(collectionName)[id] = value;
return Promise.resolve();
}
@@ -49,7 +67,7 @@ export class MemoryDatabase implements IDatabase {
public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = NewDocumentsCollection): void {
fn(this.getCollection(collectionName)[id]);
}
- public getDocuments(ids: string[], fn: (result?: Transferable[]) => void, collectionName = DocumentsCollection): void {
+ public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection): void {
fn(ids.map(id => this.getCollection(collectionName)[id]));
}
@@ -70,4 +88,8 @@ export class MemoryDatabase implements IDatabase {
}
}
}
+
+ public query(): Promise<mongodb.Cursor> {
+ throw new Error("Can't query a MemoryDatabase");
+ }
}
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index 25259bd88..75bf5f3b1 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -85,7 +85,10 @@ export default class RouteManager {
const { method, subscription, secureHandler: onValidation, publicHandler: onUnauthenticated, errorHandler: onError } = initializer;
const isRelease = this._isRelease;
const supervised = async (req: express.Request, res: express.Response) => {
- const { user, originalUrl: target } = req;
+ let { user, originalUrl: target } = req;
+ if (process.env.DB === "MEM" && !user) {
+ user = { id: "guest", email: "", userDocumentId: "guestDocId" };
+ }
const core = { req, res, isRelease };
const tryExecute = async (toExecute: (args: any) => any | Promise<any>, args: any) => {
try {
diff --git a/src/server/Session/session.ts b/src/server/Session/session.ts
index b22b6404d..a3e6c4e16 100644
--- a/src/server/Session/session.ts
+++ b/src/server/Session/session.ts
@@ -264,7 +264,8 @@ export namespace Session {
serverPort: ports.server,
socketPort: ports.socket,
pollingIntervalSeconds,
- session_key: key
+ session_key: key,
+ DB: process.env.DB
});
log(cyan(`spawned new server worker with process id ${activeWorker.process.pid}`));
// an IPC message handler that executes actions on the master thread when prompted by the active worker
@@ -435,4 +436,4 @@ export namespace Session {
};
}
-} \ No newline at end of file
+}
diff --git a/src/server/Websocket/Websocket.ts b/src/server/Websocket/Websocket.ts
index 578147d60..6dda6956e 100644
--- a/src/server/Websocket/Websocket.ts
+++ b/src/server/Websocket/Websocket.ts
@@ -28,7 +28,7 @@ export namespace WebSocket {
function initialize(isRelease: boolean) {
const endpoint = io();
- endpoint.on("connection", function (socket: Socket) {
+ endpoint.on("connection", function(socket: Socket) {
_socket = socket;
socket.use((_packet, next) => {
@@ -83,7 +83,9 @@ export namespace WebSocket {
export async function deleteFields() {
await Database.Instance.deleteAll();
- await Search.clear();
+ if (process.env.DISABLE_SEARCH !== "true") {
+ await Search.clear();
+ }
await Database.Instance.deleteAll('newDocuments');
}
@@ -92,7 +94,9 @@ export namespace WebSocket {
await Database.Instance.deleteAll('newDocuments');
await Database.Instance.deleteAll('sessions');
await Database.Instance.deleteAll('users');
- await Search.clear();
+ if (process.env.DISABLE_SEARCH !== "true") {
+ await Search.clear();
+ }
}
function barReceived(socket: SocketIO.Socket, userEmail: string) {
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 220c37e2b..36d4cd2f2 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -322,4 +322,4 @@ export class CurrentUserUtils {
};
return recurs([] as Attribute[], schema ? schema.rootAttributeGroup : undefined);
}
-} \ No newline at end of file
+}
diff --git a/src/server/database.ts b/src/server/database.ts
index 3039baedc..83ce865c6 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -6,6 +6,7 @@ import { DashUploadUtils } from './DashUploadUtils';
import { Credentials } from 'google-auth-library';
import { GoogleApiServerUtils } from './apis/google/GoogleApiServerUtils';
import { IDatabase } from './IDatabase';
+import { MemoryDatabase } from './MemoryDatabase';
import * as mongoose from 'mongoose';
export namespace Database {
@@ -263,7 +264,16 @@ export namespace Database {
}
}
- export const Instance = new Database();
+ function getDatabase() {
+ switch (process.env.DB) {
+ case "MEM":
+ return new MemoryDatabase();
+ default:
+ return new Database();
+ }
+ }
+
+ export const Instance: IDatabase = getDatabase();
export namespace Auxiliary {
diff --git a/src/server/index.ts b/src/server/index.ts
index f18e9abb6..85242bef7 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -5,7 +5,7 @@ import * as path from 'path';
import { Database } from './database';
import { DashUploadUtils } from './DashUploadUtils';
import RouteSubscriber from './RouteSubscriber';
-import initializeServer from './server_initialization';
+import initializeServer from './server_Initialization';
import RouteManager, { Method, _success, _permission_denied, _error, _invalid, PublicHandler } from './RouteManager';
import * as qs from 'query-string';
import UtilManager from './ApiManagers/UtilManager';
@@ -38,11 +38,13 @@ async function preliminaryFunctions() {
await GoogleCredentialsLoader.loadCredentials();
GoogleApiServerUtils.processProjectCredentials();
await DashUploadUtils.buildFileDirectories();
- await log_execution({
- startMessage: "attempting to initialize mongodb connection",
- endMessage: "connection outcome determined",
- action: Database.tryInitializeConnection
- });
+ if (process.env.DB !== "MEM") {
+ await log_execution({
+ startMessage: "attempting to initialize mongodb connection",
+ endMessage: "connection outcome determined",
+ action: Database.tryInitializeConnection
+ });
+ }
}
/**
@@ -152,4 +154,4 @@ if (process.env.RELEASE) {
sessionAgent.launch();
} else {
launchServer();
-} \ No newline at end of file
+}
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index cbe070293..9f67c1dda 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -86,7 +86,7 @@ function buildWithMiddleware(server: express.Express) {
resave: true,
cookie: { maxAge: week },
saveUninitialized: true,
- store: new MongoStore({ url: Database.url })
+ store: process.env.DB === "MEM" ? new session.MemoryStore() : new MongoStore({ url: Database.url })
}),
flash(),
expressFlash(),
@@ -152,4 +152,4 @@ function registerCorsProxy(server: express.Express) {
});
}).pipe(res);
});
-} \ No newline at end of file
+}