Skip to content

Commit

Permalink
Server: Added command to test a storage connection
Browse files Browse the repository at this point in the history
  • Loading branch information
laurent22 committed Nov 11, 2021
1 parent 4879edc commit c6dec0a
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 56 deletions.
54 changes: 0 additions & 54 deletions packages/server/src/commands/ImportContentCommand.ts

This file was deleted.

108 changes: 108 additions & 0 deletions packages/server/src/commands/StorageCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { PositionalOptions, Options } from 'yargs';
import Logger from '@joplin/lib/Logger';
import BaseCommand, { RunContext } from './BaseCommand';
import parseStorageConnectionString from '../models/items/storage/parseStorageConnectionString';
import loadStorageDriver from '../models/items/storage/loadStorageDriver';
import uuidgen from '../utils/uuidgen';
import { Context } from '../models/items/storage/StorageDriverBase';

const logger = Logger.create('ImportContentCommand');

enum ArgvCommand {
Import = 'import',
CheckConnection = 'check-connection',
}

interface Argv {
command: ArgvCommand;
connection: string;
batchSize?: number;
}

export default class StorageCommand extends BaseCommand {

public command() {
return 'storage <command>';
}

public description() {
return 'import content to storage';
}

public positionals(): Record<string, PositionalOptions> {
return {
'command': {
description: 'command to execute',
choices: [
ArgvCommand.Import,
ArgvCommand.CheckConnection,
],
},
};
}

public options(): Record<string, Options> {
return {
'batch-size': {
type: 'number',
description: 'Item batch size',
},
'connection': {
description: 'storage connection string',
type: 'string',
},
};
}

public async run(argv: Argv, runContext: RunContext): Promise<void> {
const commands: Record<ArgvCommand, Function> = {
[ArgvCommand.Import]: async () => {
if (!argv.connection) throw new Error('--connection option is required');

const toStorageConfig = parseStorageConnectionString(argv.connection);
const batchSize = argv.batchSize || 1000;

logger.info('Importing to storage:', toStorageConfig);
logger.info(`Batch size: ${batchSize}`);

await runContext.models.item().importContentToStorage(toStorageConfig, {
batchSize: batchSize || 1000,
logger: logger as Logger,
});
},

[ArgvCommand.CheckConnection]: async () => {
const storageConfig = parseStorageConnectionString(argv.connection);
const driver = await loadStorageDriver(storageConfig, runContext.db, { assignDriverId: false });
const itemId = `testingconnection${uuidgen(8)}`;
const itemContent = Buffer.from(uuidgen(8));
const context: Context = { models: runContext.models };

try {
await driver.write(itemId, itemContent, context);
} catch (error) {
error.message = `Could not write content to storage: ${error.message}`;
throw error;
}

if (!(await driver.exists(itemId, context))) {
throw new Error(`Written item does not exist: ${itemId}`);
}

const readContent = await driver.read(itemId, context);
if (readContent.toString() !== itemContent.toString()) throw new Error(`Could not read back written item. Expected: ${itemContent.toString()}. Got: ${readContent.toString()}`);

await driver.delete(itemId, context);

if (await driver.exists(itemId, context)) {
throw new Error(`Deleted item still exist: ${itemId}`);
}

logger.info('Item was written, read back and deleted without any error.');
},
};

await commands[argv.command]();
}

}
4 changes: 2 additions & 2 deletions packages/server/src/utils/setupCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import yargs = require('yargs');
import BaseCommand from '../commands/BaseCommand';
import DbCommand from '../commands/DbCommand';
import DeleteOldChangesCommand from '../commands/DeleteOldChangesCommand';
import ImportContentCommand from '../commands/ImportContentCommand';
import StorageCommand from '../commands/StorageCommand';
import MigrateCommand from '../commands/MigrateCommand';

export interface Commands {
Expand All @@ -17,7 +17,7 @@ export default async function setupCommands(): Promise<Commands> {
new MigrateCommand(),
new DbCommand(),
new DeleteOldChangesCommand(),
new ImportContentCommand(),
new StorageCommand(),
];

for (const cmd of commands) {
Expand Down

0 comments on commit c6dec0a

Please sign in to comment.