Skip to content

Commit 7c67ea2

Browse files
authored
Merge pull request #3587 from RedisInsight/feature/RI-5902-rdi-integration
Feature/ri 5902 rdi integration
2 parents 6f7e606 + e23b017 commit 7c67ea2

22 files changed

+274
-171
lines changed

redisinsight/api/src/modules/rdi/client/api.rdi.client.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,11 @@ export class ApiRdiClient extends RdiClient {
110110
}
111111
}
112112

113-
async dryRunJob(data: RdiDryRunJobDto): Promise<RdiDryRunJobResponseDto> {
113+
async dryRunJob(dto: RdiDryRunJobDto): Promise<RdiDryRunJobResponseDto> {
114114
try {
115-
const response = await this.client.post(RdiUrl.DryRunJob, data);
116-
return response.data;
115+
const { data } = await this.client.post(RdiUrl.DryRunJob, dto);
116+
117+
return data;
117118
} catch (e) {
118119
throw wrapRdiPipelineError(e);
119120
}
@@ -134,20 +135,21 @@ export class ApiRdiClient extends RdiClient {
134135

135136
async getPipelineStatus(): Promise<any> {
136137
try {
137-
const response = await this.client.get(RdiUrl.GetPipelineStatus);
138+
const { data } = await this.client.get(RdiUrl.GetPipelineStatus);
138139

139-
return response.data;
140+
return data;
140141
} catch (e) {
141142
throw wrapRdiPipelineError(e);
142143
}
143144
}
144145

145146
async getStatistics(sections?: string): Promise<RdiStatisticsResult> {
146147
try {
147-
const response = await this.client.get(RdiUrl.GetStatistics, { params: { sections } });
148+
const { data } = await this.client.get(RdiUrl.GetStatistics, { params: { sections } });
149+
148150
return {
149151
status: RdiStatisticsStatus.Success,
150-
data: plainToClass(RdiStatisticsData, convertKeysToCamelCase(response.data)),
152+
data: plainToClass(RdiStatisticsData, convertKeysToCamelCase(data)),
151153
};
152154
} catch (e) {
153155
return { status: RdiStatisticsStatus.Fail, error: e.message };

redisinsight/api/src/modules/rdi/models/rdi.client.metadata.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Session, SessionMetadata } from 'src/common/models/session';
1+
import { SessionMetadata } from 'src/common/models/session';
22
import { Type } from 'class-transformer';
33
import {
44
IsNotEmpty,
@@ -7,7 +7,7 @@ import {
77

88
export class RdiClientMetadata {
99
@IsNotEmpty()
10-
@Type(() => Session)
10+
@Type(() => SessionMetadata)
1111
sessionMetadata: SessionMetadata;
1212

1313
@IsNotEmpty()

redisinsight/api/src/modules/rdi/utils/pipeline.util.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
isArray, unset, set, forEach,
2+
isArray, unset, set, forEach, isObjectLike, isEmpty,
33
} from 'lodash';
44
import { plainToClass } from 'class-transformer';
55
import { RdiPipeline } from 'src/modules/rdi/models';
@@ -21,10 +21,21 @@ export const convertApiDataToRdiJobs = (jobs?: [Record<string, any>]): Record<st
2121
return jobsMap;
2222
};
2323

24-
export const convertApiDataToRdiPipeline = (data: { config?: Record<string, any> } = {}): RdiPipeline => {
24+
export const convertApiDataToRdiPipeline = (data: Record<string, any> = {}): RdiPipeline => {
25+
const entries = data;
26+
27+
// ignore empty root-level entries for pipeline
28+
forEach(data, (entry, key) => {
29+
if (entry && isObjectLike(entry) && isEmpty(entry)) {
30+
entries[key] = undefined;
31+
}
32+
});
33+
2534
const pipeline = {
26-
...data,
27-
jobs: convertApiDataToRdiJobs(data.config.jobs),
35+
config: {
36+
...entries,
37+
},
38+
jobs: convertApiDataToRdiJobs(data.jobs),
2839
};
2940

3041
// do not show jobs in the config area
@@ -46,12 +57,11 @@ export const convertRdiJobsToApiPayload = (jobs: Record<string, any>): Record<st
4657
return payload;
4758
};
4859

49-
export const convertRdiPipelineToApiPayload = (pipeline: RdiPipeline): { config?: Record<string, any> } => {
60+
export const convertRdiPipelineToApiPayload = (pipeline: RdiPipeline): Record<string, any> => {
5061
const payload = {
51-
...pipeline,
52-
jobs: undefined,
62+
...pipeline.config,
5363
};
5464

55-
set(payload, 'config.jobs', convertRdiJobsToApiPayload(pipeline.jobs));
65+
set(payload, 'jobs', convertRdiJobsToApiPayload(pipeline.jobs));
5666
return payload;
5767
};

redisinsight/ui/src/pages/rdi/statistics/StatisticsPage.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isEmpty } from 'lodash'
1+
import { get } from 'lodash'
22
import React, { useEffect } from 'react'
33
import { useDispatch, useSelector } from 'react-redux'
44
import { useParams } from 'react-router-dom'
@@ -12,7 +12,7 @@ import RdiInstancePageTemplate from 'uiSrc/templates/rdi-instance-page-template'
1212
import { formatLongName, Nullable, setTitle } from 'uiSrc/utils'
1313
import { setLastPageContext } from 'uiSrc/slices/app/context'
1414
import { PageNames } from 'uiSrc/constants'
15-
import { IPipelineStatus } from 'uiSrc/slices/interfaces'
15+
import { IPipelineStatus, PipelineStatus } from 'uiSrc/slices/interfaces'
1616
import Clients from './clients'
1717
import DataStreams from './data-streams'
1818
import Empty from './empty'
@@ -22,13 +22,9 @@ import TargetConnections from './target-connections'
2222

2323
import styles from './styles.module.scss'
2424

25-
const isPipelineDeployed = (data: Nullable<IPipelineStatus>) => {
26-
if (!data) {
27-
return false
28-
}
29-
30-
return !isEmpty(data.pipelines)
31-
}
25+
const isPipelineDeployed = (
26+
data: Nullable<IPipelineStatus>
27+
) => get(data, ['pipelines', 'default', 'status']) === PipelineStatus.Ready
3228

3329
const StatisticsPage = () => {
3430
const { rdiInstanceId } = useParams<{ rdiInstanceId: string }>()

redisinsight/ui/src/slices/interfaces/rdi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export enum PipelineStatus {
138138
export interface IPipelineStatus {
139139
components: Record<string, unknown>
140140
pipelines: {
141-
defaults?: {
141+
default?: {
142142
status: PipelineStatus
143143
state: unknown
144144
tasks: unknown

tests/e2e/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"author": "",
2626
"dependencies": {
2727
"axios": "^1.6.0",
28-
"cli-argument-parser": "0.4.5"
28+
"cli-argument-parser": "0.4.5",
29+
"js-yaml": "^4.1.0"
2930
},
3031
"resolutions": {
3132
"@types/lodash": "4.14.192",

tests/e2e/pageObjects/components/monaco-editor.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export class MonacoEditor {
2020
* @param clean if field should be cleaned
2121
*/
2222
async sendTextToMonaco(input: Selector, command: string, clean = true): Promise<void> {
23+
2324
await t.click(input);
2425
if(clean) {
2526
await t
@@ -30,6 +31,28 @@ export class MonacoEditor {
3031
await t.typeText(input, command);
3132
}
3233

34+
/**
35+
* Send lines in monacoEditor without additional space that typeText can add
36+
* @param input The input locator
37+
* @param lines lines
38+
* @param depth level of depth of the object
39+
*/
40+
async insertTextByLines(input: Selector, lines: string[], depth: number): Promise<void> {
41+
for(let i = 0; i < lines.length; i++) {
42+
const line = lines[i];
43+
44+
for(let j = 0; j < depth; j++) {
45+
await t.pressKey('shift+tab');
46+
}
47+
48+
if (line) {
49+
await t.typeText(input, line, { paste: true });
50+
}
51+
await t.pressKey('esc');
52+
await t.pressKey('enter');
53+
}
54+
}
55+
3356
/**
3457
* Get text from monacoEditor
3558
*/

tests/e2e/pageObjects/components/rdi/pipeline-management-panel.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ export class PipelineManagementPanel {
1111

1212
jobNameInput = Selector('[data-testid=inline-item-editor]');
1313
jobItem = Selector('[data-testid*=rdi-nav-job-actions]');
14-
confirmBtn = Selector('[data-testid=confirm-btn]');
14+
confirmBtn = Selector('[data-testid=delete-confirm-btn]');
1515
jobsPipelineTitle = Selector('[class*=rdi__title]');
1616

17+
configHighlightingIcon = Selector('[data-testid=updated-file-config-highlight]');
18+
1719
/**
1820
* Add Job by name
1921
* @param name job name
@@ -28,7 +30,7 @@ export class PipelineManagementPanel {
2830
* @param name job name
2931
*/
3032
async openJobByName(name: string): Promise<void> {
31-
const jobBtnSelector = Selector(`[data-testid=rdi-nav-job-${name}]`);
33+
const jobBtnSelector = await this.getJobByName(name);
3234
await t.click(jobBtnSelector);
3335
}
3436

@@ -52,4 +54,12 @@ export class PipelineManagementPanel {
5254
.typeText(this.jobNameInput, newName, { replace: true })
5355
.click(this.EditorButton.applyBtn);
5456
}
57+
58+
/**
59+
* Get Job by name
60+
* @param name job name
61+
*/
62+
async getJobByName(name: string): Promise<Selector> {
63+
return Selector(`[data-testid=rdi-nav-job-${name}]`);
64+
}
5565
}

tests/e2e/pageObjects/components/rdi/rdi-header.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ export class RdiHeader {
1111
deployConfirmBtn = Selector('[data-testid=deploy-confirm-btn]');
1212

1313
uploadPipelineButton = Selector('[data-testid=upload-pipeline-btn]');
14+
uploadConfirmPipelineButton = Selector('[data-testid=upload-confirm-btn]');
1415
uploadFromFileButton = Selector('[data-testid=upload-file-btn]');
1516
downloadPipelineButton = Selector('[data-testid=download-pipeline-btn]');
1617
importInput = Selector('[data-testid=import-file-modal-filepicker]');
17-
confirmUploadingPipelineBatton = Selector('[data-testid=upload-confirm-btn]');
18+
confirmUploadingPipelineBatton = Selector('[data-testid=submit-btn]');
1819

1920
cloudSignInButton = Selector('[data-testid=cloud-sign-in-btn]');
2021

tests/e2e/pageObjects/components/rdi/test-connection-panel.ts

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ import { TextConnectionSection } from '../../../helpers/constants';
44
export class TestConnectionPanel {
55
endpointRowString = '[data-testid^=table-endpoint]';
66

7-
sidePanel = Selector('[data-testid=test-connection-panel]');
8-
successfulSection = Selector('[data-testid^=success-connections]');
9-
failedSection = Selector('[data-testid^=failed-connections-]');
10-
endpointRow = Selector(this.endpointRowString);
11-
closeSection = Selector('[data-testid=close-test-connections-btn]');
7+
targetName = Selector('[data-testid=table-target-target]');
8+
resultText = Selector('[data-testid=table-result-target]');
129

1310
/**
1411
* Open/Close section
@@ -23,35 +20,4 @@ export class TestConnectionPanel {
2320
await t.click(sectionSelector.find('button'));
2421
}
2522
}
26-
27-
/**
28-
* get number of connection
29-
* @param section Name of section
30-
* @param state State of section
31-
*/
32-
async getNumberOfSection(section: TextConnectionSection): Promise<string> {
33-
const sectionSelector = Selector(`[data-testid^=${section}-connections-]`);
34-
return sectionSelector.find('span[data-testid="number-of-connections"]').textContent;
35-
}
36-
37-
/**
38-
* get row count in the section
39-
* @param section Name of section
40-
*/
41-
async getNumberOfSectionRow(section: TextConnectionSection): Promise<string> {
42-
const sectionSelector = Selector(`[data-testid^=${section}-connections-]`);
43-
const rows = await sectionSelector.find('[data-testid^=table-endpoint]').count;
44-
return rows.toString();
45-
}
46-
47-
/**
48-
* get row endpoint text by index
49-
* @param section Name of section
50-
* @param index index of the row to get text
51-
*/
52-
async getSectionRowTextByIndex(section: TextConnectionSection, index: number): Promise<string> {
53-
const sectionSelector = Selector(`[data-testid^=${section}-connections-]`);
54-
return await (sectionSelector.find(this.endpointRowString).nth(index)).textContent;
55-
}
56-
5723
}

0 commit comments

Comments
 (0)