Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.17] [Session Index] Attach alias to index when index name changes (#210176) #210753

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,94 @@ describe('Session index', () => {

expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();
});

it('does not create index if alias exists', async () => {
mockElasticsearchClient.indices.existsTemplate.mockResponse(false);
mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true);
mockElasticsearchClient.indices.exists.mockImplementation(
async ({ index }) => index === aliasName
);

await sessionIndex.initialize();

expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledWith({ index: aliasName });
expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();
});

it('does not create index if index exists', async () => {
mockElasticsearchClient.indices.existsTemplate.mockResponse(false);
mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true);
mockElasticsearchClient.indices.exists.mockImplementation(
async ({ index }) => index === indexName
);

await sessionIndex.initialize();

expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledWith({ index: aliasName });
expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledWith({ index: indexName });
expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledTimes(2);

expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();
});

it('creates index if neither index or alias exists', async () => {
mockElasticsearchClient.indices.existsTemplate.mockResponse(false);
mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true);
mockElasticsearchClient.indices.exists.mockResponse(false);

await sessionIndex.initialize();

expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledWith({ index: aliasName });
expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledWith({ index: indexName });
expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledTimes(2);
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putIndexTemplate).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.create).toHaveBeenCalled();
});

it('attaches alias if no alias present', async () => {
mockElasticsearchClient.indices.existsTemplate.mockResponse(false);
mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true);
mockElasticsearchClient.indices.exists.mockImplementation(
async ({ index }) => index === indexName
);
mockElasticsearchClient.indices.existsAlias.mockResponse(false);

await sessionIndex.initialize();

expect(mockElasticsearchClient.indices.existsAlias).toHaveBeenCalledWith({ name: aliasName });
expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledWith({
index: indexName,
name: aliasName,
});

expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();
});

it('does not attach alias if alias present', async () => {
mockElasticsearchClient.indices.existsTemplate.mockResponse(false);
mockElasticsearchClient.indices.existsIndexTemplate.mockResponse(true);
mockElasticsearchClient.indices.exists.mockResponse(true);
mockElasticsearchClient.indices.existsAlias.mockResponse(true);

await sessionIndex.initialize();

expect(mockElasticsearchClient.indices.existsAlias).toHaveBeenCalledWith({ name: aliasName });
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();
});

Expand All @@ -116,7 +203,6 @@ describe('Session index', () => {

expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.deleteIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.getMapping).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putMapping).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledWith(
Expand All @@ -140,7 +226,6 @@ describe('Session index', () => {

expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.deleteIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.getMapping).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putMapping).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledWith(
Expand All @@ -162,7 +247,6 @@ describe('Session index', () => {
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledWith(
getSessionIndexSettings({ indexName, aliasName })
);
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();
});

it('deletes legacy & modern index templates if needed and creates index if it does not exist', async () => {
Expand All @@ -182,7 +266,6 @@ describe('Session index', () => {
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledWith(
getSessionIndexSettings({ indexName, aliasName })
);
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();
});

it('deletes modern index template if needed and creates index if it does not exist', async () => {
Expand All @@ -197,7 +280,6 @@ describe('Session index', () => {
expect(mockElasticsearchClient.indices.deleteIndexTemplate).toHaveBeenCalledWith({
name: indexTemplateName,
});
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledWith(
getSessionIndexSettings({ indexName, aliasName })
);
Expand All @@ -215,12 +297,6 @@ describe('Session index', () => {
expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.deleteIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledWith({
index: indexName,
name: aliasName,
});
});

it('updates mappings for existing index without version in the meta', async () => {
Expand All @@ -241,11 +317,6 @@ describe('Session index', () => {
expect(mockElasticsearchClient.indices.deleteIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledWith({
index: indexName,
name: aliasName,
});
expect(mockElasticsearchClient.indices.getMapping).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.getMapping).toHaveBeenCalledWith({ index: indexName });
expect(mockElasticsearchClient.indices.putMapping).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -273,11 +344,6 @@ describe('Session index', () => {
expect(mockElasticsearchClient.indices.deleteIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledWith({
index: indexName,
name: aliasName,
});
expect(mockElasticsearchClient.indices.getMapping).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.getMapping).toHaveBeenCalledWith({ index: indexName });
expect(mockElasticsearchClient.indices.putMapping).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -305,11 +371,6 @@ describe('Session index', () => {
expect(mockElasticsearchClient.indices.deleteIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();

expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).toHaveBeenCalledWith({
index: indexName,
name: aliasName,
});
expect(mockElasticsearchClient.indices.getMapping).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.getMapping).toHaveBeenCalledWith({ index: indexName });
expect(mockElasticsearchClient.indices.putMapping).not.toHaveBeenCalled();
Expand All @@ -325,7 +386,6 @@ describe('Session index', () => {
assertExistenceChecksPerformed();
expect(mockElasticsearchClient.indices.deleteTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.deleteIndexTemplate).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.getMapping).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putMapping).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledWith(
Expand Down Expand Up @@ -462,7 +522,6 @@ describe('Session index', () => {

expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();
expect(mockElasticsearchClient.search).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.bulk).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.closePointInTime).toHaveBeenCalledTimes(1); // since we attempted to delete sessions, we still refresh the index
Expand Down Expand Up @@ -1445,7 +1504,6 @@ describe('Session index', () => {

expect(mockElasticsearchClient.indices.exists).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.create).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();

expect(mockElasticsearchClient.create).toHaveBeenCalledTimes(2);
expect(mockElasticsearchClient.create).toHaveBeenNthCalledWith(
Expand Down Expand Up @@ -1502,7 +1560,6 @@ describe('Session index', () => {

expect(mockElasticsearchClient.indices.exists).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.create).not.toHaveBeenCalled();
expect(mockElasticsearchClient.indices.putAlias).not.toHaveBeenCalled();

expect(mockElasticsearchClient.create).toHaveBeenCalledTimes(1);
expect(mockElasticsearchClient.create).toHaveBeenCalledWith(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,22 @@ export class SessionIndex {
);
}

private async attachAliasToIndex() {
// Prior to https://github.com/elastic/kibana/pull/134900, sessions would be written directly against the session index.
// Now, we write sessions against a new session index alias. This call ensures that the alias exists, and is attached to the index.
// This operation is safe to repeat, even if the alias already exists. This seems safer than retrieving the index details, and inspecting
// it to see if the alias already exists.
try {
await this.options.elasticsearchClient.indices.putAlias({
index: this.indexName,
name: this.aliasName,
});
} catch (err) {
this.options.logger.error(`Failed to attach alias to session index: ${err.message}`);
throw err;
}
}

/**
* Creates the session index if it doesn't already exist.
*/
Expand Down Expand Up @@ -667,24 +683,22 @@ export class SessionIndex {
return;
}

this.options.logger.debug(
'Session index already exists. Attaching alias to the index and ensuring up-to-date mappings...'
);
const isIndexNameAlias = await this.options.elasticsearchClient.indices.existsAlias({
name: this.aliasName,
});

// Prior to https://github.com/elastic/kibana/pull/134900, sessions would be written directly against the session index.
// Now, we write sessions against a new session index alias. This call ensures that the alias exists, and is attached to the index.
// This operation is safe to repeat, even if the alias already exists. This seems safer than retrieving the index details, and inspecting
// it to see if the alias already exists.
try {
await this.options.elasticsearchClient.indices.putAlias({
index: this.indexName,
name: this.aliasName,
});
} catch (err) {
this.options.logger.error(`Failed to attach alias to session index: ${err.message}`);
throw err;
if (!isIndexNameAlias) {
this.options.logger.debug(
'Session index already exists with no alias. Attaching alias to the index.'
);

await this.attachAliasToIndex();
}

this.options.logger.debug(
'Session index already exists. Ensuring up-to-date index mappings...'
);

let indexMappingsVersion: string | undefined;
try {
const indexMappings = await this.options.elasticsearchClient.indices.getMapping({
Expand Down