Skip to content

Commit 4ffa0c0

Browse files
author
Chris Wiechmann
committed
Added the option to rollover multiple indices with a wildcard alias
1 parent 8dfff1c commit 4ffa0c0

6 files changed

Lines changed: 126 additions & 20 deletions

File tree

api-builder-plugin-fn-elasticsearch/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [1.0.16] 2020-12-15
8+
### Added
9+
- Added the option to rollover multiple indicies based on a wildcard alias
10+
711
## [1.0.15] 2020-12-10
812
### Added
913
- Added the option to disable the Elasticsearch connection validation during startup (e.g. environment variable: VALIDATE_ELASTIC_CONNECTION=false)

api-builder-plugin-fn-elasticsearch/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@axway-api-builder-ext/api-builder-plugin-fn-elasticsearch",
3-
"version": "1.0.15",
3+
"version": "1.0.16",
44
"description": "Integrate Elasticsearch into your API-Builder flow to combine search data for instance with other data available in your flow.",
55
"author": "Chris Wiechmann <cwiechmann@axway.com> (http://www.axway.com)",
66
"license": "Apache-2.0",

api-builder-plugin-fn-elasticsearch/src/actions/indices.js

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,42 @@ const { ElasticsearchClient } = require('./ElasticsearchClient');
1717
*/
1818

1919
async function indicesRollover(params, options) {
20-
const elasticSearchConfig = options.pluginConfig.elastic;
21-
22-
if (typeof elasticSearchConfig.node === 'undefined' && typeof elasticSearchConfig.nodes === 'undefined') {
23-
options.logger.error('Elasticsearch configuration is invalid: nodes or node is missing.');
24-
throw new Error('Elasticsearch configuration is invalid: nodes or node is missing.');
25-
}
26-
if (!params.alias) {
20+
var { alias, wildcardAlias } = params;
21+
var { logger } = options;
22+
var client = new ElasticsearchClient().client;
23+
debugger;
24+
if (!alias) {
2725
throw new Error('Missing required parameter: alias');
2826
}
27+
var aliasesToRollover = [];
2928
// The alias might be a string or an object
30-
if(typeof params.alias === 'object') {
31-
if(Object.keys(params.alias).length === 0 && params.alias.constructor === Object) {
32-
throw new Error(`Given rollover alias object is empty.`);
33-
}
34-
for(var alias in params.alias) {
35-
params.alias = alias;
29+
if(typeof alias === 'object') {
30+
for(var alias in alias) {
31+
aliasesToRollover.push(alias);
3632
break; // Only one alias is supported.
3733
}
34+
} else {
35+
aliasesToRollover.push(alias);
36+
}
37+
// Is the given alias is a wildcard, search for other indicies starting with this alias
38+
if(wildcardAlias) {
39+
aliasesToRollover = [];
40+
logger.debug(`Rolling over all indicies starting with alias: ${alias}`);
41+
var indicesFound = await client.indices.getAlias({name: `${alias}*`}, { ignore: [404], maxRetries: 3 });
42+
for (const index of Object.values(indicesFound.body)) {
43+
var indexAlias = Object.keys(index.aliases)[0];
44+
aliasesToRollover.push(indexAlias);
45+
}
46+
}
47+
if(aliasesToRollover.length == 0) {
48+
throw new Error(`No index found to rollover for alias: ${JSON.stringify(alias)}`);
3849
}
3950
try {
40-
var client = new ElasticsearchClient(elasticSearchConfig).client;
41-
var result = await client.indices.rollover( params, { ignore: [404], maxRetries: 3 });
42-
51+
var result = [];
52+
for(alias of aliasesToRollover) {
53+
var rolloverResult = await client.indices.rollover( { alias: alias }, { ignore: [404], maxRetries: 3 });
54+
result.push(rolloverResult);
55+
}
4356
return result;
4457
} catch (e) {
4558
if(e instanceof Error) throw e;

api-builder-plugin-fn-elasticsearch/src/flow-nodes.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -929,12 +929,21 @@ flow-nodes:
929929
schema:
930930
default: false
931931
type: boolean
932+
wildcardAlias:
933+
name: Wildcard alias
934+
description: Given alias is considered as a prefix. All indicies starting with the alias, will be rolled up.
935+
required: false
936+
group: Advanced
937+
initialType: boolean
938+
schema:
939+
default: false
940+
type: boolean
932941
returns:
933942
name: Next
934943
description: Acknowledge message about the rollover.
935944
context: $.result
936945
schema:
937-
type: object
946+
type: array
938947
throws:
939948
name: Error
940949
description: An unexpected error was encountered.

api-builder-plugin-fn-elasticsearch/test/indices/indices-Test.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('Indices rollover tests', () => {
2929
expect(output).to.equal('error');
3030
});
3131

32-
it('should pass without with a valid alias name', async () => {
32+
it('should pass with with a valid alias name', async () => {
3333
const mockedFn = setupElasticsearchMock(client, 'indices.rollover', './test/mock/indices/rolloverResponse.json', false);
3434

3535
const inputParameter = { alias: 'apigw-traffic-summary' };
@@ -53,6 +53,21 @@ describe('Indices rollover tests', () => {
5353
expect(mockedFn.lastCall.arg).to.deep.equals({ alias: 'apigw-traffic-summary' });
5454
});
5555

56+
it('should pass if the alias is a wildcard - Should rollover all indicies', async () => {
57+
const mockedIndicesGetAliasResponse = setupElasticsearchMock(client, 'indices.getAlias', './test/mock/indices/twoIndicesForAliasFoundResponse.json', false);
58+
const mockedRolloverResponse = setupElasticsearchMock(client, 'indices.rollover', './test/mock/indices/rolloverResponse.json', false);
59+
//
60+
61+
const inputParameter = { alias: 'apigw-traffic-summary', wildcardAlias: true };
62+
const { value, output } = await flowNode.indicesRollover(inputParameter);
63+
debugger;
64+
expect(output).to.equal('next');
65+
expect(mockedIndicesGetAliasResponse.callCount).to.equals(1);
66+
expect(mockedRolloverResponse.callCount).to.equals(2);
67+
// Given object should be translated into a single alias string
68+
expect(mockedRolloverResponse.lastCall.arg).to.deep.equals({ alias: 'apigw-traffic-summary-us-dc1' });
69+
});
70+
5671
it('should gracefully handle, if the alias object is empty', async () => {
5772
const mockedFn = setupElasticsearchMock(client, 'indices.rollover', './test/mock/indices/rolloverResponse.json', false);
5873

@@ -62,7 +77,7 @@ describe('Indices rollover tests', () => {
6277
expect(output).to.equal('error');
6378
expect(mockedFn.callCount).to.equals(0);
6479
expect(value).to.be.instanceOf(Error)
65-
.and.to.have.property('message', 'Given rollover alias object is empty.');
80+
.and.to.have.property('message', 'No index found to rollover for alias: {}');
6681
});
6782
});
6883

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"body": {
3+
"apigw-traffic-summary-000002": {
4+
"aliases": {
5+
"apigw-traffic-summary": {
6+
7+
}
8+
}
9+
},
10+
"apigw-traffic-summary-us-dc1-000001": {
11+
"aliases": {
12+
"apigw-traffic-summary-us-dc1": {
13+
14+
}
15+
}
16+
}
17+
},
18+
"statusCode": 200,
19+
"headers": {
20+
"content-type": "application/json; charset=UTF-8",
21+
"content-length": "159"
22+
},
23+
"meta": {
24+
"context": null,
25+
"request": {
26+
"params": {
27+
"method": "GET",
28+
"path": "/_alias/apigw-traffic-summary*",
29+
"body": null,
30+
"querystring": "",
31+
"headers": {
32+
"user-agent": "elasticsearch-js/7.10.0 (win32 10.0.19041-x64; Node.js v12.13.1)"
33+
},
34+
"timeout": 30000
35+
},
36+
"options": {
37+
"ignore": [
38+
404
39+
],
40+
"maxRetries": 3
41+
},
42+
"id": 1
43+
},
44+
"name": "elasticsearch-js",
45+
"connection": {
46+
"url": "http://api-env:9200/",
47+
"id": "http://api-env:9200/",
48+
"headers": {
49+
50+
},
51+
"deadCount": 0,
52+
"resurrectTimeout": 0,
53+
"_openRequests": 0,
54+
"status": "alive",
55+
"roles": {
56+
"master": true,
57+
"data": true,
58+
"ingest": true,
59+
"ml": false
60+
}
61+
},
62+
"attempts": 0,
63+
"aborted": false
64+
}
65+
}

0 commit comments

Comments
 (0)