Browse Source

volume-server JSON config

David Sehnal 5 years ago
parent
commit
3c831b549a
2 changed files with 75 additions and 7 deletions
  1. 47 4
      src/servers/volume/config.ts
  2. 28 3
      src/servers/volume/server.ts

+ 47 - 4
src/servers/volume/config.ts

@@ -6,6 +6,7 @@
  */
 
 import * as argparse from 'argparse'
+import { ObjectKeys } from '../../mol-util/type-helpers';
 
 export function addLimitsArgs(parser: argparse.ArgumentParser) {
     parser.addArgument([ '--maxRequestBlockCount' ], {
@@ -63,11 +64,33 @@ export function addServerArgs(parser: argparse.ArgumentParser) {
         help: [
             'Map `id`s for a `type` to a file path.',
             'Example: x-ray \'../../data/mdb/xray/${id}-ccp4.mdb\'',
-            'Note: Can be specified multiple times.'
+            '',
+            '  - JS expressions can be used with in the ${}, e.g. \'${id.substr(1, 2)}/${id}.mdb\'',
+            '  - Can be specified multiple times.',
+            '  - The "TYPE" variable (e.g. "x-ray") is arbitrary and depends on how you plan to use the server.',
+            '    By default, Mol* Viewer uses "x-ray" and "em", but any particular use case may vary. '
         ].join('\n'),
     });
 }
 
+export function addJsonConfigArgs(parser: argparse.ArgumentParser) {
+    parser.addArgument(['--cfg'], { 
+        help: [
+            'JSON config file path',
+            'If a property is not specified, cmd line param/OS variable/default value are used.'
+        ].join('\n'),
+        required: false 
+    });
+    parser.addArgument(['--printCfg'], { help: 'Print current config for validation and exit.', required: false, nargs: 0 });
+    parser.addArgument(['--printCfgTemplate'], { help: 'Prints default JSON config template to be modified and exits.', required: false, nargs: 0 });
+}
+
+export interface ServerJsonConfig {
+    cfg?: string,
+    printCfg?: any,
+    printCfgTemplate?: any
+}
+
 const DefaultServerConfig = {
     apiPrefix: '/VolumeServer',
     defaultPort: 1337,
@@ -77,8 +100,17 @@ const DefaultServerConfig = {
 }
 export type ServerConfig = typeof DefaultServerConfig
 export const ServerConfig = { ...DefaultServerConfig }
+
 export function setServerConfig(config: ServerConfig) {
-    Object.assign(ServerConfig, config)
+    for (const k of ObjectKeys(ServerConfig)) {
+        if (config[k]) (ServerConfig as any)[k] = config[k];
+    }
+}
+
+export function validateServerConfig() {
+    if (!ServerConfig.idMap || ServerConfig.idMap.length === 0) {
+        throw new Error(`Please provide 'idMap' configuration. See [-h] for available options.`);
+    }
 }
 
 const DefaultLimitsConfig = {
@@ -97,10 +129,21 @@ const DefaultLimitsConfig = {
 export type LimitsConfig = typeof DefaultLimitsConfig
 export const LimitsConfig = { ...DefaultLimitsConfig }
 export function setLimitsConfig(config: LimitsConfig) {
-    Object.assign(LimitsConfig, config)
+    for (const k of ObjectKeys(LimitsConfig)) {
+        if (config[k]) (LimitsConfig as any)[k] = config[k];
+    }
 }
 
 export function setConfig(config: ServerConfig & LimitsConfig) {
     setServerConfig(config)
     setLimitsConfig(config)
-}
+}
+
+export const ServerConfigTemplate: ServerConfig & LimitsConfig = {
+    ...DefaultServerConfig,
+    idMap: [
+        ['x-ray', './path-to-xray-data/${id.substr(1, 2)}/${id}.mdb'],
+        ['em', './path-to-em-data/emd-${id}.mdb']
+    ] as [string, string][],
+    ...DefaultLimitsConfig
+}

+ 28 - 3
src/servers/volume/server.ts

@@ -14,8 +14,9 @@ import init from './server/web-api'
 import VERSION from './server/version'
 import { ConsoleLogger } from '../../mol-util/console-logger'
 import { State } from './server/state'
-import { addServerArgs, addLimitsArgs, LimitsConfig, setConfig, ServerConfig } from './config';
+import { addServerArgs, addLimitsArgs, LimitsConfig, setConfig, ServerConfig, addJsonConfigArgs, ServerJsonConfig, ServerConfigTemplate, validateServerConfig } from './config';
 import * as argparse from 'argparse'
+import * as fs from 'fs'
 
 function setupShutdown() {
     if (ServerConfig.shutdownTimeoutVarianceMinutes > ServerConfig.shutdownTimeoutMinutes) {
@@ -48,11 +49,35 @@ const parser = new argparse.ArgumentParser({
     addHelp: true,
     description: `VolumeServer ${VERSION}, (c) 2018-2019, Mol* contributors`
 });
+addJsonConfigArgs(parser);
 addServerArgs(parser)
 addLimitsArgs(parser)
 
-const config: ServerConfig & LimitsConfig = parser.parseArgs()
-setConfig(config) // sets the config for global use
+const config: ServerConfig & LimitsConfig & ServerJsonConfig = parser.parseArgs()
+
+if (config.printCfgTemplate !== null) {
+    console.log(JSON.stringify(ServerConfigTemplate, null, 2));
+    process.exit(0);
+}
+
+try {
+    setConfig(config) // sets the config for global use
+
+    if (config.cfg) {
+        const cfg = JSON.parse(fs.readFileSync(config.cfg, 'utf8')) as ServerConfig & LimitsConfig;
+        setConfig(cfg);
+    }
+
+    if (config.printCfg !== null) {
+        console.log(JSON.stringify({ ...ServerConfig, ...LimitsConfig }, null, 2));
+        process.exit(0);
+    }
+
+    validateServerConfig();
+} catch (e) {
+    console.error('' + e);
+    process.exit(1);
+}
 
 const port = process.env.port || ServerConfig.defaultPort;