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

Reindex operation #363

Merged
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
117 changes: 94 additions & 23 deletions cypress/integration/indices_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import samplePolicy from "../fixtures/sample_policy";

const POLICY_ID = "test_policy_id";
const SAMPLE_INDEX = "sample_index";
const REINDEX_DEST = "index-reindex-01";

describe("Indices", () => {
beforeEach(() => {
Expand Down Expand Up @@ -214,42 +215,46 @@ describe("Indices", () => {
const reindexedIndex = "reindex_opensearch_dashboards_sample_data_ecommerce";
const splittedIndex = "split_opensearch_dashboards_sample_data_logs";
before(() => {
cy.deleteAllIndices();
// Visit ISM OSD
cy.visit(`${Cypress.env("opensearch_dashboards")}/app/${PLUGIN_NAME}#/indices`);

// Common text to wait for to confirm page loaded, give up to 60 seconds for initial load
cy.contains("Rows per page", { timeout: 60000 });

cy.request({
method: "PUT",
url: `${Cypress.env("opensearch")}/opensearch_dashboards_sample_data_logs/_settings`,
body: {
"index.blocks.read_only": false,
method: "POST",
url: `${Cypress.env("opensearch_dashboards")}/api/sample_data/ecommerce`,
headers: {
"osd-xsrf": true,
},
failOnStatusCode: false,
}).then((response) => {
expect(response.status).equal(200);
});

cy.window().then((window) => {
const fetchMethod = (url, method) =>
window.fetch(url, {
method,
headers: {
"osd-version": "2.4.0",
},
});
return Promise.all([
fetchMethod("/api/sample_data/ecommerce", "DELETE").then(() => fetchMethod("/api/sample_data/ecommerce", "POST")),
fetchMethod("/api/sample_data/logs", "DELETE").then(() => fetchMethod("/api/sample_data/logs", "POST")),
]);
});
cy.request({
method: "PUT",
url: `${Cypress.env("opensearch")}/${splittedIndex}/_settings`,
body: {
"index.blocks.read_only": false,
method: "POST",
url: `${Cypress.env("opensearch_dashboards")}/api/sample_data/logs`,
headers: {
"osd-xsrf": true,
},
}).then((response) => {
expect(response.status).equal(200);
});

cy.request({
method: "DELETE",
url: `${Cypress.env("opensearch")}/${reindexedIndex}`,
failOnStatusCode: false,
});
cy.request({
method: "DELETE",
url: `${Cypress.env("opensearch")}/${splittedIndex}`,
failOnStatusCode: false,
});
});

after(() => {
cy.request({
method: "DELETE",
url: `${Cypress.env("opensearch")}/${reindexedIndex}`,
Expand Down Expand Up @@ -298,7 +303,6 @@ describe("Indices", () => {
window.fetch(`/api/ism/apiCaller`, {
headers: {
"content-type": "application/json",
"osd-version": "2.4.0",
},
body: JSON.stringify({
endpoint: "indices.split",
Expand Down Expand Up @@ -437,4 +441,71 @@ describe("Indices", () => {
});
});
});

describe("can perform reindex", () => {
before(() => {
cy.deleteAllIndices();
// Load ecommerce data
cy.request({
method: "POST",
url: `${Cypress.env("opensearch_dashboards")}/api/sample_data/ecommerce`,
headers: {
"osd-xsrf": true,
},
}).then((response) => {
expect(response.status).equal(200);
});
cy.createIndex(SAMPLE_INDEX);
});

it("successfully", () => {
// Confirm we have our initial index
cy.contains(SAMPLE_INDEX);

// Click actions button
cy.get('[data-test-subj="More Action"]').click();

// Delete btn should be disabled if no items selected
cy.get('[data-test-subj="Reindex Action"]').should("have.class", "euiContextMenuItem-isDisabled");

// click any where to hide actions
cy.get("#_selection_column_opensearch_dashboards_sample_data_ecommerce-checkbox").click();
cy.get('[data-test-subj="Reindex Action"]').should("not.exist");

// Click actions button
cy.get('[data-test-subj="More Action"]').click();
// Delete btn should be enabled
cy.get('[data-test-subj="Reindex Action"]').should("exist").should("not.have.class", "euiContextMenuItem-isDisabled").click();

// source index populated
cy.get('[data-test-subj="sourceIndicesComboInput"] .euiBadge__text').contains("opensearch_dashboards_sample_data_ecommerce");

cy.get(`div[data-test-subj="destIndicesComboInput"]`)
.find(`input[data-test-subj="comboBoxSearchInput"]`)
.type(`${REINDEX_DEST}{enter}`);

// dest index settings show up
cy.get('div[data-test-subj="destSettingJsonEditor"]').should("exist");

// input query to reindex subset
cy.get('[data-test-subj="queryJsonEditor"] textarea')
.focus()
.clear()
.type('{"query":{"match":{"category":"Men\'s Clothing"}}}', { parseSpecialCharSequences: false });

// click to perform reindex
cy.get('[data-test-subj="flyout-footer-action-button"]').click();
cy.wait(20);
cy.contains(/Reindex .* success .* taskId .*/);

// Type in REINDEX_DEST in search input
cy.get(`input[type="search"]`).focus().type(REINDEX_DEST);

// Confirm we only see REINDEX_DEST in table
cy.get("tbody > tr").should(($tr) => {
expect($tr, "1 row").to.have.length(1);
expect($tr, "item").to.contain(REINDEX_DEST);
});
});
});
});
1 change: 0 additions & 1 deletion cypress/integration/transforms_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ describe("Transforms", () => {

beforeEach(() => {
// delete test transform and index
cy.request("DELETE", `${Cypress.env("opensearch")}/test_transform*`);
cy.request({
method: "POST",
url: `${Cypress.env("opensearch")}/_plugins/_transform/${TRANSFORM_ID}/_stop`,
Expand Down
2 changes: 1 addition & 1 deletion cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Cypress.Commands.overwrite("request", (originalFn, ...args) => {
});

Cypress.Commands.add("deleteAllIndices", () => {
cy.request("DELETE", `${Cypress.env("opensearch")}/index*,sample*,opensearch_dashboards*`);
cy.request("DELETE", `${Cypress.env("opensearch")}/index*,sample*,opensearch_dashboards*,test*`);
cy.request("DELETE", `${Cypress.env("opensearch")}/.opendistro-ism*?expand_wildcards=all`);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { render } from "@testing-library/react";
import React from "react";
import ReindexAdvancedOptions from "./ReindexAdvancedOptions";

describe("<ReindexAdvancedOptions /> spec", () => {
it("renders the component", async () => {
let component = render(
<ReindexAdvancedOptions
slices="1"
onSlicesChange={() => {}}
pipelines={[]}
selectedPipelines={[]}
onSelectedPipelinesChange={() => {}}
/>
);

expect(component).toMatchSnapshot();
});

it("renders the component with slice error", async () => {
const { getByText } = render(
<ReindexAdvancedOptions
slices="1"
onSlicesChange={() => {}}
sliceErr={"slice must be positive integer or auto"}
pipelines={[]}
selectedPipelines={[]}
onSelectedPipelinesChange={() => {}}
/>
);

expect(getByText("slice must be positive integer or auto")).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { ChangeEvent } from "react";
import CustomFormRow from "../../../../components/CustomFormRow";
import { EuiComboBox, EuiComboBoxOptionOption, EuiFieldText } from "@elastic/eui";

interface ReindexOptionsProps {
slices: string;
onSlicesChange: (e: ChangeEvent<HTMLInputElement>) => void;
sliceErr?: string;
pipelines: EuiComboBoxOptionOption<void>[];
selectedPipelines?: EuiComboBoxOptionOption<void>[];
onSelectedPipelinesChange: (options: EuiComboBoxOptionOption<void>[]) => void;
width?: string;
}

const ReindexAdvancedOptions = (props: ReindexOptionsProps) => {
const { slices, sliceErr, onSlicesChange, pipelines, selectedPipelines, onSelectedPipelinesChange, width } = props;

return (
<div style={{ padding: "10px 10px", width: width }}>
<CustomFormRow
isInvalid={!!sliceErr}
error={sliceErr}
label="Slices"
helpText="Number of sub-tasks OpenSearch should divide this task into. Default is 1, which means OpenSearch should not divide this task. Setting this parameter to auto indicates to OpenSearch that it should automatically decide how many slices to split the task into."
>
<EuiFieldText data-test-subj="slices" value={slices} onChange={onSlicesChange} />
</CustomFormRow>
<CustomFormRow label="Pipeline" helpText="Pipeline pre-process documents before writing into destination">
<EuiComboBox
aria-label="Ingest Pipeline"
placeholder="Select a single pipeline"
singleSelection={{ asPlainText: true }}
options={pipelines}
selectedOptions={selectedPipelines}
onChange={onSelectedPipelinesChange}
/>
</CustomFormRow>
</div>
);
};

export default ReindexAdvancedOptions;
Loading