Skip to content

Commit

Permalink
[Discover] Cancel S3 Queries Using SQL Plugin (#9355)
Browse files Browse the repository at this point in the history
  • Loading branch information
sejli authored Feb 19, 2025
1 parent 3918797 commit 3c90fa3
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 7 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/9355.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- Deletes S3 Jobs in Backend when Original Query is Canceled ([#9355](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/9355))
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DS_API,
DSM_API,
S3_CLUSTER,
JOBS_API,
} from '../../../../../utils/apps/query_enhancements/constants';
import { getRandomizedWorkspaceName } from '../../../../../utils/apps/query_enhancements/shared';
import { prepareTestSuite } from '../../../../../utils/helpers';
Expand Down Expand Up @@ -90,6 +91,11 @@ const s3DatasetTestSuite = () => {
cy.deleteWorkspaceByName(workspace);
cy.visit('/app/home');
cy.osd.createInitialWorkspaceWithDataSource(S3_CLUSTER.name, workspace);
cy.navigateToWorkSpaceSpecificPage({
workspaceName: workspace,
page: 'discover',
isEnhancement: true,
});
});
afterEach(() => {
cy.deleteWorkspaceByName(workspace);
Expand Down Expand Up @@ -141,6 +147,40 @@ const s3DatasetTestSuite = () => {
cy.getElementByTestId('docTable').should('be.visible');
cy.getElementByTestId('docTable').find('tr').should('have.length', 11);
});

it('aborts and cancels previous query when new query is started', function () {
cy.getElementByTestId(`datasetSelectorButton`).click();
cy.getElementByTestId(`datasetSelectorAdvancedButton`).click();

cy.get(`[title="S3 Connections"]`).click();
cy.get(`[title="BasicS3Connection"]`).click();
cy.get(`[title="mys3"]`).click();
cy.get(`[title="default"]`).click();
cy.get(`[title="http_logs"]`).click();
cy.getElementByTestId('datasetSelectorNext').click();
cy.get(`[class="euiModalHeader__title"]`).should('contain', 'Step 2: Configure data');

cy.getElementByTestId('advancedSelectorLanguageSelect').select('OpenSearch SQL');
cy.getElementByTestId('advancedSelectorConfirmButton').click();

// Need to wait a bit for initial query to start
cy.wait(3000);

cy.intercept('DELETE', `**/${JOBS_API.DELETE}*`).as('cancelRequest');
cy.getElementByTestId(`querySubmitButton`).click();

cy.wait('@cancelRequest').then((interception) => {
console.log('interception.request.url:', interception.request.url);
// Verify the request had the correct query parameters
expect(interception.request.url).to.include('queryId=');
expect(interception.request.url).to.include('id=');
});

cy.waitForSearch();
cy.get(`[data-test-subj="queryResultCompleteMsg"]`).should('be.visible');
cy.getElementByTestId('docTable').should('be.visible');
cy.getElementByTestId('docTable').find('tr').should('have.length', 11);
});
});
}
);
Expand Down
5 changes: 5 additions & 0 deletions cypress/utils/apps/query_enhancements/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ export const DS_API = {
};
export const DSM_API = '/internal/data-source-management/fetchDataSourceMetaData';

export const BASE_QUERY_ENHANCEMENTS_API = '/api/enhancements';
export const JOBS_API = {
DELETE: `${BASE_QUERY_ENHANCEMENTS_API}/jobs`,
};

export const INDEX_WITH_TIME_1 = 'data_logs_small_time_1';
export const INDEX_WITHOUT_TIME_1 = 'data_logs_small_no_time_1';
export const INDEX_WITH_TIME_2 = 'data_logs_small_time_2';
Expand Down
34 changes: 28 additions & 6 deletions src/plugins/query_enhancements/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
QueryStatusConfig,
QueryStatusOptions,
} from './types';
import { API } from './constants';

export const formatDate = (dateString: string) => {
const date = new Date(dateString);
Expand Down Expand Up @@ -57,13 +58,34 @@ export const fetch = (context: EnhancedFetchContext, query: Query, aggConfig?: Q
pollQueryResultsParams: context.body?.pollQueryResultsParams,
timeRange: context.body?.timeRange,
});

return from(
http.fetch({
method: 'POST',
path,
body,
signal,
})
http
.fetch({
method: 'POST',
path,
body,
signal,
})
.catch(async (error) => {
if (error.name === 'AbortError' && context.body?.pollQueryResultsParams?.queryId) {
// Cancel job
try {
await http.fetch({
method: 'DELETE',
path: API.DATA_SOURCE.ASYNC_JOBS,
query: {
id: query.dataset?.dataSource?.id,
queryId: context.body?.pollQueryResultsParams.queryId,
},
});
} catch (cancelError) {
// eslint-disable-next-line no-console
console.error('Failed to cancel query:', cancelError);
}
throw error;
}
})
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,31 @@ export function registerDataSourceConnectionsRoutes(
}
}
);

router.delete(
{
path: API.DATA_SOURCE.ASYNC_JOBS,
validate: {
query: schema.object({
id: schema.string(),
queryId: schema.nullable(schema.string()),
}),
},
},
async (context, request, response) => {
try {
const client = request.query.id
? context.dataSource.opensearch.legacy.getClient(request.query.id).callAPI
: defaultClient.asScoped(request).callAsCurrentUser;

await client('enhancements.deleteJob', {
queryId: request.query.queryId,
});
return response.noContent();
} catch (error) {
const statusCode = error.statusCode === 500 ? 503 : error.statusCode || 503;
return response.custom({ statusCode, body: error.message });
}
}
);
}
2 changes: 1 addition & 1 deletion src/plugins/query_enhancements/server/utils/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export const OpenSearchEnhancements = (client: any, config: any, components: any
});

enhancements.deleteJob = createAction(client, components, {
endpoint: `${URI.ASYNC_QUERY}/<%=queryId%>`,
endpoint: `${URI.ASYNC_QUERY}`,
method: 'DELETE',
paramKey: 'queryId',
});
Expand Down

0 comments on commit 3c90fa3

Please sign in to comment.