diff --git a/src/storage/elasticsearch/Elasticsearch.ts b/src/storage/elasticsearch/Elasticsearch.ts index f82eb3e5..9a749b9c 100644 --- a/src/storage/elasticsearch/Elasticsearch.ts +++ b/src/storage/elasticsearch/Elasticsearch.ts @@ -226,6 +226,43 @@ export class Elasticsearch implements Database { return 'stapps_*_*_*'; } + /** + * Checks for invalid character in alias names and removes them + * @param alias The alias name + * @param uid The UID of the current bulk (for debugging purposes) + */ + private removeAliasChars(alias: string, uid: string | undefined): string { + // spaces are included in some types, so throwing an error in this case would clutter up the log unnecessarily + alias = alias.replace(' ', ''); + // List of invalid characters: https://www.elastic.co/guide/en/elasticsearch/reference/6.6/indices-create-index.html + ['\\', '/', '*', '?', '"', '<', '>', '|', ',', '#'].forEach((value) => { + if (alias.includes(value)) { + alias = alias.replace(value, ''); + logger.warn(`Type of the bulk ${uid} contains an invalid character '${value}'. This can lead to two bulks ` + + `having the same alias despite having different types, as invalid characters are removed automatically. ` + + `New alias name is "${alias}."`); + } + }); + ['-', '_', '+'].forEach((value) => { + if (alias.charAt(0) === value) { + alias = alias.substring(1); + logger.warn(`Type of the bulk ${uid} begins with '${value}'. This can lead to two bulks ` + + `having the same alias despite having different types, as invalid characters are removed automatically. ` + + `New alias name is "${alias}."`); + } + }); + if (alias === '.' || alias === '..') { + logger.warn(`Type of the bulk ${uid} is ${alias}. This is an invalid name, please consider using another ` + + `one, as it will be replaced with 'alias_placeholder', which can lead to strange errors.`); + return 'alias_placeholder'; + } + if (alias.includes(':')) { + logger.warn(`Type of the bulk ${uid} contains a ':'. This isn't an issue now, but will be in future ` + + `Elasticsearch versions!`); + } + return alias; + } + /** * Should be called, when a new bulk was created. Creates a new index and applies a the mapping to the index * @param bulk the bulk process that was created @@ -241,7 +278,7 @@ export class Elasticsearch implements Database { // there already is an index with this type and source. We will index the new one and switch the alias to it // the old one is deleted - const alias = bulk.type; + const alias = this.removeAliasChars(bulk.type, bulk.uid); if (typeof this.aliasMap[alias] === 'undefined') { this.aliasMap[alias] = {}; @@ -295,7 +332,7 @@ export class Elasticsearch implements Database { const index: string = this.getIndex(bulk.type, bulk.source, bulk); // alias for the indices - const alias = bulk.type; + const alias = this.removeAliasChars(bulk.type, bulk.uid); if (typeof this.aliasMap[alias] === 'undefined') { this.aliasMap[alias] = {};