Skip to content
Merged
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 @@ -103,11 +103,11 @@ const reIndexKnowledgeBase = createObservabilityAIAssistantServerRoute({
requiredPrivileges: ['ai_assistant'],
},
},
handler: async (resources): Promise<{ result: boolean }> => {
handler: async (resources): Promise<{ success: boolean }> => {
const client = await resources.service.getClient({ request: resources.request });
const { inference_id: inferenceId } = resources.params.query;
const result = await client.reIndexKnowledgeBaseWithLock(inferenceId);
return { result };
await client.reIndexKnowledgeBaseWithLock(inferenceId);
return { success: true };
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import { hasKbWriteIndex } from './has_kb_index';
import { getInferenceIdFromWriteIndex } from './get_inference_id_from_write_index';
import { reIndexKnowledgeBaseWithLock } from './reindex_knowledge_base';
import { isSemanticTextUnsupportedError } from '../startup_migrations/run_startup_migrations';
import { isKnowledgeBaseIndexWriteBlocked } from './index_write_block_utils';

interface Dependencies {
core: CoreSetup<ObservabilityAIAssistantPluginStartDependencies>;
Expand Down Expand Up @@ -461,12 +460,6 @@ export class KnowledgeBaseService {
);
}

if (isKnowledgeBaseIndexWriteBlocked(error)) {
throw new Error(
`Writes to the knowledge base are currently blocked due to an Elasticsearch write index block. This is most likely due to an ongoing re-indexing operation. Please try again later. Error: ${error.message}`
);
}

throw error;
}
};
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ import { CoreSetup } from '@kbn/core/server';
import { LockManagerService } from '@kbn/lock-manager';
import { resourceNames } from '..';
import { ObservabilityAIAssistantPluginStartDependencies } from '../../types';
import {
addIndexWriteBlock,
hasIndexWriteBlock,
removeIndexWriteBlock,
} from './index_write_block_utils';
import { createKnowledgeBaseIndex } from './create_knowledge_base_index';
import { updateKnowledgeBaseWriteIndexAlias } from './update_knowledge_base_index_alias';

Expand All @@ -34,47 +29,13 @@ export async function reIndexKnowledgeBaseWithLock({
asInternalUser: ElasticsearchClient;
};
inferenceId: string;
}): Promise<boolean> {
}): Promise<void> {
const lmService = new LockManagerService(core, logger);
return lmService.withLock(KB_REINDEXING_LOCK_ID, () =>
reIndexKnowledgeBaseWithWriteIndexBlock({
logger: logger.get('kb-reindex'),
esClient,
inferenceId,
})
reIndexKnowledgeBase({ logger, esClient, inferenceId })
);
}

async function reIndexKnowledgeBaseWithWriteIndexBlock({
logger,
esClient,
inferenceId,
}: {
logger: Logger;
esClient: { asInternalUser: ElasticsearchClient };
inferenceId: string;
}): Promise<boolean> {
logger.debug('Initializing re-indexing of knowledge base...');
if (await hasIndexWriteBlock({ esClient, index: resourceNames.writeIndexAlias.kb })) {
throw new Error(
`Write block is already set on the knowledge base index: ${resourceNames.writeIndexAlias.kb}`
);
}

try {
await addIndexWriteBlock({ esClient, index: resourceNames.writeIndexAlias.kb });
await reIndexKnowledgeBase({ logger, esClient, inferenceId });
logger.info('Re-indexing knowledge base completed successfully.');
} catch (error) {
logger.error(`Re-indexing knowledge base failed: ${error.message}`);
throw error;
} finally {
await removeIndexWriteBlock({ esClient, index: resourceNames.writeIndexAlias.kb });
}

return true;
}

async function reIndexKnowledgeBase({
logger,
esClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function aiAssistantApiIntegrationTests({
loadTestFile(require.resolve('./knowledge_base/knowledge_base_setup.spec.ts'));
loadTestFile(require.resolve('./knowledge_base/knowledge_base_status.spec.ts'));
loadTestFile(require.resolve('./knowledge_base/knowledge_base_user_instructions.spec.ts'));
loadTestFile(require.resolve('./knowledge_base/knowledge_base.spec.ts'));
loadTestFile(require.resolve('./knowledge_base/knowledge_base_basic_operations.spec.ts'));
loadTestFile(
require.resolve('./knowledge_base/knowledge_base_change_model_from_elser_to_e5.spec.ts')
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
// Sparse vector field was introduced in Elasticsearch 8.11
// The semantic text field was added to the knowledge base index in 8.17
// Indices created in 8.10 do not support semantic text field and need to be reindexed
describe('when upgrading from 8.10 to 8.18', function () {
describe('Knowledge base: when upgrading from 8.10 to 8.18', function () {
// Intentionally skipped in all serverless environnments (local and MKI)
// because the migration scenario being tested is not relevant to MKI and Serverless.
this.tags(['skipServerless']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
// In 8.16 and earlier embeddings were stored in the `ml.tokens` field
// In 8.17 `ml.tokens` is replaced with `semantic_text` field and the custom ELSER inference endpoint "obs_ai_assistant_kb_inference" is introduced
// When upgrading we must ensure that the semantic_text field is populated
describe('when upgrading from 8.16 to 8.17', function () {
describe('Knowledge base: when upgrading from 8.16 to 8.17', function () {
// Intentionally skipped in all serverless environnments (local and MKI)
// because the migration scenario being tested is not relevant to MKI and Serverless.
this.tags(['skipServerless']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
// In 8.19 / 9.1 the custom inference endpoint ("obs_ai_assistant_kb_inference") is replaced with the preconfigured endpoint ".elser-2-elasticsearch"
// We need to make sure that the custom inference endpoint continues to work after the migration

describe('when upgrading from 8.18 to 8.19', function () {
describe('Knowledge base: when upgrading from 8.18 to 8.19', function () {
this.tags(['skipServerless']);

before(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
return res.body.entries;
}

describe('Knowledge base', function () {
describe('Knowledge base: Basic operations', function () {
before(async () => {
await deployTinyElserAndSetupKb(getService);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon

type KnowledgeBaseEsEntry = Awaited<ReturnType<typeof getKnowledgeBaseEntriesFromEs>>[0];

describe('when changing from ELSER to E5-like model', function () {
describe('Knowledge base: when changing from ELSER to E5-like model', function () {
let elserEntriesFromApi: KnowledgeBaseEntry[];
let elserEntriesFromEs: KnowledgeBaseEsEntry[];
let elserInferenceId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantApi');
const es = getService('es');

describe('POST /internal/observability_ai_assistant/kb/reindex', function () {
describe('Knowledge base: POST /internal/observability_ai_assistant/kb/reindex', function () {
// Intentionally skipped in all serverless environnments (local and MKI)
// because the migration scenario being tested is not relevant to MKI and Serverless.
this.tags(['skipServerless']);
Expand Down Expand Up @@ -82,7 +82,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon

const iterations = 5;
describe(`when running ${iterations} re-index operations in sequence`, () => {
let results: Array<{ status: number; result: boolean; errorMessage: string | undefined }>;
let results: Array<{ status: number; success: boolean; errorMessage: string | undefined }>;
let initialIndexSequenceNumber: number;

before(async () => {
Expand All @@ -103,7 +103,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
it('every re-index operation succeeds', async () => {
const successResults = results.filter((result) => result.status === 200);
expect(successResults).to.have.length(iterations);
expect(successResults.every((r) => r.result === true)).to.be(true);
expect(successResults.every((r) => r.success === true)).to.be(true);
});

it('no requests should fail', async () => {
Expand All @@ -126,7 +126,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon

return {
status: res.status,
result: res.body.result,
success: res.body.success,
errorMessage: 'message' in res.body ? (res.body.message as string) : undefined,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
const ml = getService('ml');
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantApi');

describe('/internal/observability_ai_assistant/kb/setup', function () {
describe('Knowledge base: POST /internal/observability_ai_assistant/kb/setup', function () {
before(async () => {
await teardownTinyElserModelAndInferenceEndpoint(getService);
await restoreIndexAssets(observabilityAIAssistantAPIClient, es);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ import {
export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) {
const observabilityAIAssistantAPIClient = getService('observabilityAIAssistantApi');

describe('/internal/observability_ai_assistant/kb/status', function () {
// see details: https://github.com/elastic/kibana/issues/219217
this.tags(['failsOnMKI']);

describe('Knowledge base: GET /internal/observability_ai_assistant/kb/status', function () {
it('returns correct status before knowledge base is setup', async () => {
const res = await observabilityAIAssistantAPIClient.editor({
endpoint: 'GET /internal/observability_ai_assistant/kb/status',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon
const log = getService('log');
const retry = getService('retry');

describe('Knowledge base user instructions', function () {
describe('Knowledge base: user instructions', function () {
before(async () => {
await deployTinyElserAndSetupKb(getService);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function WarmupModelApiTest({ getService }: DeploymentAgnosticFtr
});
}

describe('/internal/observability_ai_assistant/kb/warmup_model', function () {
describe('Knowledge base: POST /internal/observability_ai_assistant/kb/warmup_model', function () {
const inferenceId = TINY_ELSER_INFERENCE_ID;

before(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,6 @@ export async function getConcreteWriteIndexFromAlias(es: Client) {
return writeIndex;
}

export async function hasIndexWriteBlock(es: Client, index: string) {
const response = await es.indices.getSettings({ index });
const writeBlockSetting = Object.values(response)[0]?.settings?.index?.blocks?.write;
return writeBlockSetting === 'true' || writeBlockSetting === true;
}

export async function getKbIndexCreatedVersion(es: Client) {
const indexSettings = await es.indices.getSettings({
index: resourceNames.writeIndexAlias.kb,
Expand Down