mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-02 03:29:03 +00:00
MINOR: fix the recent run not showing for data-insight application (#15811)
* fix the recent run not showing for application * supported unit test for the same * used ingestionRecentRuns for application run status * limit the records shown * change the file logsViewer from component to page * minor fix
This commit is contained in:
parent
ba561c9674
commit
05dfd4ddfd
@ -193,8 +193,8 @@ const UpdateTagsPage = withSuspenseFallback(
|
||||
React.lazy(() => import('../../pages/TasksPage/UpdateTagPage/UpdateTagPage'))
|
||||
);
|
||||
|
||||
const LogsViewer = withSuspenseFallback(
|
||||
React.lazy(() => import('../../pages/LogsViewer/LogsViewer.component'))
|
||||
const LogsViewerPage = withSuspenseFallback(
|
||||
React.lazy(() => import('../../pages/LogsViewerPage/LogsViewerPage'))
|
||||
);
|
||||
|
||||
const DataInsightPage = withSuspenseFallback(
|
||||
@ -402,7 +402,7 @@ const AuthenticatedAppRouter: FunctionComponent = () => {
|
||||
component={TestSuiteDetailsPage}
|
||||
path={ROUTES.TEST_SUITES_WITH_FQN}
|
||||
/>
|
||||
<Route exact component={LogsViewer} path={ROUTES.LOGS} />
|
||||
<Route exact component={LogsViewerPage} path={ROUTES.LOGS} />
|
||||
<Route
|
||||
exact
|
||||
component={TestSuiteIngestionPage}
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
} from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { IngestionPipeline } from '../../../../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||
import { mockDataInsightApplicationRun } from '../../../../../mocks/LogsViewerPage.mock';
|
||||
import { getRunHistoryForPipeline } from '../../../../../rest/ingestionPipelineAPI';
|
||||
import ConnectionStepCard from '../../../../common/TestConnection/ConnectionStepCard/ConnectionStepCard';
|
||||
import { IngestionRecentRuns } from './IngestionRecentRuns.component';
|
||||
@ -337,4 +338,17 @@ describe('Test IngestionRecentRun component', () => {
|
||||
await screen.findByText(/testConnectionStepCard/)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not fetch getRunHistoryForPipeline in case of Application', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<IngestionRecentRuns
|
||||
isApplicationType
|
||||
appRuns={mockDataInsightApplicationRun.data}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
expect(getRunHistoryForPipeline).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@ -43,8 +43,10 @@ import ConnectionStepCard from '../../../../common/TestConnection/ConnectionStep
|
||||
import './ingestion-recent-run.style.less';
|
||||
|
||||
interface Props {
|
||||
ingestion: IngestionPipeline;
|
||||
ingestion?: IngestionPipeline;
|
||||
classNames?: string;
|
||||
appRuns?: PipelineStatus[];
|
||||
isApplicationType?: boolean;
|
||||
}
|
||||
const queryParams = {
|
||||
startTs: getEpochMillisForPastDays(1),
|
||||
@ -54,6 +56,8 @@ const queryParams = {
|
||||
export const IngestionRecentRuns: FunctionComponent<Props> = ({
|
||||
ingestion,
|
||||
classNames,
|
||||
appRuns,
|
||||
isApplicationType,
|
||||
}: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const [recentRunStatus, setRecentRunStatus] = useState<PipelineStatus[]>([]);
|
||||
@ -137,27 +141,30 @@ export const IngestionRecentRuns: FunctionComponent<Props> = ({
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await getRunHistoryForPipeline(
|
||||
ingestion.fullyQualifiedName ?? '',
|
||||
ingestion?.fullyQualifiedName ?? '',
|
||||
queryParams
|
||||
);
|
||||
|
||||
const runs = response.data.splice(0, 5).reverse() ?? [];
|
||||
|
||||
setRecentRunStatus(
|
||||
runs.length === 0 && ingestion.pipelineStatuses
|
||||
runs.length === 0 && ingestion?.pipelineStatuses
|
||||
? [ingestion.pipelineStatuses]
|
||||
: runs
|
||||
);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [ingestion, ingestion.fullyQualifiedName]);
|
||||
}, [ingestion, ingestion?.fullyQualifiedName]);
|
||||
|
||||
useEffect(() => {
|
||||
if (ingestion.fullyQualifiedName) {
|
||||
if (isApplicationType && appRuns) {
|
||||
setRecentRunStatus(appRuns.splice(0, 5).reverse() ?? []);
|
||||
setLoading(false);
|
||||
} else if (ingestion?.fullyQualifiedName) {
|
||||
fetchPipelineStatus();
|
||||
}
|
||||
}, [ingestion, ingestion.fullyQualifiedName]);
|
||||
}, [ingestion, ingestion?.fullyQualifiedName]);
|
||||
|
||||
const handleRunStatusClick = (status: PipelineStatus) => {
|
||||
setExpandedKeys([]);
|
||||
|
||||
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { PipelineState } from '../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||
|
||||
export const mockLogsData = {
|
||||
ingestion_task: 'test Logs',
|
||||
total: '6',
|
||||
after: '1',
|
||||
};
|
||||
|
||||
export const mockIngestionPipeline = {
|
||||
id: 'c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
name: 'test-redshift_metadata_ZeCajs9g',
|
||||
displayName: 'test-redshift_metadata_ZeCajs9g',
|
||||
pipelineType: 'metadata',
|
||||
owner: {
|
||||
id: 'e43cdd2e-7698-4e06-8cb4-dbcdf401d6dc',
|
||||
type: 'user',
|
||||
name: 'admin',
|
||||
fullyQualifiedName: 'admin',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/users/e43cdd2e-7698-4e06-8cb4-dbcdf401d6dc',
|
||||
},
|
||||
fullyQualifiedName: 'test-redshift.test-redshift_metadata_ZeCajs9g',
|
||||
sourceConfig: {
|
||||
config: {
|
||||
type: 'DatabaseMetadata',
|
||||
markDeletedTables: true,
|
||||
markAllDeletedTables: false,
|
||||
includeTables: true,
|
||||
includeViews: true,
|
||||
includeTags: true,
|
||||
useFqnForFiltering: true,
|
||||
},
|
||||
},
|
||||
openMetadataServerConnection: {
|
||||
clusterName: 'openmetadata',
|
||||
type: 'OpenMetadata',
|
||||
hostPort: 'http://openmetadata-server:8585/api',
|
||||
authProvider: 'openmetadata',
|
||||
verifySSL: 'no-ssl',
|
||||
securityConfig: {
|
||||
jwtToken: 'test_token',
|
||||
},
|
||||
secretsManagerProvider: 'noop',
|
||||
},
|
||||
airflowConfig: {
|
||||
pausePipeline: false,
|
||||
concurrency: 1,
|
||||
pipelineTimezone: 'UTC',
|
||||
retries: 3,
|
||||
retryDelay: 300,
|
||||
pipelineCatchup: false,
|
||||
scheduleInterval: '*/5 * * * *',
|
||||
maxActiveRuns: 1,
|
||||
workflowDefaultView: 'tree',
|
||||
workflowDefaultViewOrientation: 'LR',
|
||||
},
|
||||
service: {
|
||||
id: '086ad38c-dd10-42ae-a58b-1c72ee6e7f50',
|
||||
type: 'databaseService',
|
||||
name: 'test-redshift',
|
||||
fullyQualifiedName: 'test-redshift',
|
||||
description: '',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/services/databaseServices/086ad38c-dd10-42ae-a58b-1c72ee6e7f50',
|
||||
},
|
||||
pipelineStatuses: [
|
||||
{
|
||||
runId: 'scheduled__2022-10-20T04:35:00+00:00',
|
||||
state: 'running',
|
||||
startDate: 1666240861500,
|
||||
timestamp: 1666240500000,
|
||||
},
|
||||
],
|
||||
loggerLevel: 'DEBUG',
|
||||
deployed: true,
|
||||
enabled: true,
|
||||
href: 'http://localhost:8585/api/v1/services/ingestionPipelines/c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
version: 0.1,
|
||||
updatedAt: 1666240859704,
|
||||
updatedBy: 'admin',
|
||||
deleted: false,
|
||||
};
|
||||
|
||||
export const mockDataInsightApplication = {
|
||||
id: '8437b08f-404a-4129-8448-610323daf51e',
|
||||
name: 'DataInsightsApplication',
|
||||
displayName: 'Data Insights',
|
||||
description:
|
||||
// eslint-disable-next-line max-len
|
||||
'**Data Insights: A Revolutionary Tool for Metadata Analysis and Data Management**\n\n**Comprehensive Data Analytics:** Dive deep into the world of data with our advanced analytics, crafted to transform raw metadata into valuable insights.',
|
||||
fullyQualifiedName: 'DataInsightsApplication',
|
||||
version: 0.1,
|
||||
updatedAt: 1712299044226,
|
||||
updatedBy: 'admin',
|
||||
href: 'http://localhost:8585/api/v1/apps/8437b08f-404a-4129-8448-610323daf51e',
|
||||
deleted: false,
|
||||
provider: 'user',
|
||||
developer: 'Collate Inc.',
|
||||
developerUrl: 'https://www.getcollate.io',
|
||||
privacyPolicyUrl: 'https://www.getcollate.io',
|
||||
supportEmail: 'support@getcollate.io',
|
||||
className: 'org.openmetadata.service.apps.bundles.insights.DataInsightsApp',
|
||||
appType: 'external',
|
||||
scheduleType: 'Scheduled',
|
||||
permission: 'All',
|
||||
bot: {
|
||||
id: '2f38b35d-bc91-4412-af2a-294644d44b2c',
|
||||
type: 'bot',
|
||||
name: 'DataInsightsApplicationBot',
|
||||
fullyQualifiedName: 'DataInsightsApplicationBot',
|
||||
deleted: false,
|
||||
},
|
||||
runtime: {
|
||||
enabled: 'true',
|
||||
},
|
||||
allowConfiguration: false,
|
||||
system: false,
|
||||
appConfiguration: {},
|
||||
preview: false,
|
||||
appSchedule: {
|
||||
scheduleTimeline: 'Custom',
|
||||
cronExpression: '0 0 * * *',
|
||||
},
|
||||
appScreenshots: ['DataInsightsPic1.png'],
|
||||
};
|
||||
|
||||
export const mockDataInsightApplicationRun = {
|
||||
data: [
|
||||
{
|
||||
runId: '7852085e-2ef3-44d1-8c95-dd8c14d33895',
|
||||
pipelineState: PipelineState.Success,
|
||||
startDate: 1712299055158,
|
||||
timestamp: 1712299055158,
|
||||
endDate: 1712299060061,
|
||||
status: [
|
||||
{
|
||||
name: 'OpenMetadata Insights',
|
||||
records: 71,
|
||||
updated_records: 0,
|
||||
warnings: 0,
|
||||
errors: 0,
|
||||
filtered: 0,
|
||||
failures: [],
|
||||
},
|
||||
{
|
||||
name: 'OpenMetadata',
|
||||
records: 71,
|
||||
updated_records: 0,
|
||||
warnings: 0,
|
||||
errors: 0,
|
||||
filtered: 0,
|
||||
failures: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
paging: {
|
||||
before: 'MTcxMjIxMzc0NjM1Ng==',
|
||||
after: 'MTcxMjMwMDE0NjM1Ng==',
|
||||
total: 1,
|
||||
},
|
||||
};
|
||||
|
||||
export const mockLatestDataInsightApplicationRunLogs = {
|
||||
data_insight_task:
|
||||
// eslint-disable-next-line max-len
|
||||
"31103bd4cfc9\n*** Found local files:\n*** * /opt/airflow/logs/dag_id=OpenMetadata_dataInsight/run_id=manual__2024-04-05T06:37:28+00:00/task_id=data_insight_task/attempt=1.log\n[2024-04-05T06:37:35.052+0000] {taskinstance.py:1159} INFO - Dependencies all met for dep_context=non-requeueable deps ti=<TaskInstance: OpenMetadata_dataInsight.data_insight_task manual__2024-04-05T06:37:28+00:00 [queued]>\n[2024-04-05T06:37:35.057+0000] {taskinstance.py:1159} INFO - Dependencies all met for dep_context=requeueable deps ti=<TaskInstance: OpenMetadata_dataInsight.data_insight_task manual__2024-04-05T06:37:28+00:00 [queued]>\n[2024-04-05T06:37:35.057+0000] {taskinstance.py:1361} INFO - Starting attempt 1 of 1\n[2024-04-05T06:37:35.065+0000] {taskinstance.py:1382} INFO - Executing <Task(CustomPythonOperator): data_insight_task> on 2024-04-05 06:37:28+00:00\n[2024-04-05T06:37:35.068+0000] {standard_task_runner.py:57} INFO - Started process 40504 to run task\n[2024-04-05T06:37:35.072+0000] {standard_task_runner.py:84} INFO - Running: ['airflow', 'tasks', 'run', 'OpenMetadata_dataInsight', 'data_insight_task', 'manual__2024-04-05T06:37:28+00:00', '--job-id', '81', '--raw', '--subdir', 'DAGS_FOLDER/OpenMetadata_dataInsight.py', '--cfg-path', '/tmp/tmpu41_kxxp']\n[2024-04-05T06:37:35.073+0000] {standard_task_runner.py:85} INFO - Job 81: Subtask data_insight_task\n[2024-04-05T06:37:35.099+0000] {task_command.py:416} INFO - Running <TaskInstance: OpenMetadata_dataInsight.data_insight_task manual__2024-04-05T06:37:28+00:00 [running]> on host 31103bd4cfc9\n[2024-04-05T06:37:35.151+0000] {taskinstance.py:1662} INFO - Exporting env vars: AIRFLOW_CTX_DAG_OWNER='openmetadata' AIRFLOW_CTX_DAG_ID='OpenMetadata_dataInsight' AIRFLOW_CTX_TASK_ID='data_insight_task' AIRFLOW_CTX_EXECUTION_DATE='2024-04-05T06:37:28+00:00",
|
||||
total: '1',
|
||||
};
|
||||
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const mockLogsData = {
|
||||
ingestion_task: 'test Logs',
|
||||
total: '6',
|
||||
after: '1',
|
||||
};
|
||||
|
||||
export const mockIngestionPipeline = {
|
||||
id: 'c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
name: 'test-redshift_metadata_ZeCajs9g',
|
||||
displayName: 'test-redshift_metadata_ZeCajs9g',
|
||||
pipelineType: 'metadata',
|
||||
owner: {
|
||||
id: 'e43cdd2e-7698-4e06-8cb4-dbcdf401d6dc',
|
||||
type: 'user',
|
||||
name: 'admin',
|
||||
fullyQualifiedName: 'admin',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/users/e43cdd2e-7698-4e06-8cb4-dbcdf401d6dc',
|
||||
},
|
||||
fullyQualifiedName: 'test-redshift.test-redshift_metadata_ZeCajs9g',
|
||||
sourceConfig: {
|
||||
config: {
|
||||
type: 'DatabaseMetadata',
|
||||
markDeletedTables: true,
|
||||
markAllDeletedTables: false,
|
||||
includeTables: true,
|
||||
includeViews: true,
|
||||
includeTags: true,
|
||||
useFqnForFiltering: true,
|
||||
},
|
||||
},
|
||||
openMetadataServerConnection: {
|
||||
clusterName: 'openmetadata',
|
||||
type: 'OpenMetadata',
|
||||
hostPort: 'http://openmetadata-server:8585/api',
|
||||
authProvider: 'openmetadata',
|
||||
verifySSL: 'no-ssl',
|
||||
securityConfig: {
|
||||
jwtToken: 'test_token',
|
||||
},
|
||||
secretsManagerProvider: 'noop',
|
||||
},
|
||||
airflowConfig: {
|
||||
pausePipeline: false,
|
||||
concurrency: 1,
|
||||
pipelineTimezone: 'UTC',
|
||||
retries: 3,
|
||||
retryDelay: 300,
|
||||
pipelineCatchup: false,
|
||||
scheduleInterval: '*/5 * * * *',
|
||||
maxActiveRuns: 1,
|
||||
workflowDefaultView: 'tree',
|
||||
workflowDefaultViewOrientation: 'LR',
|
||||
},
|
||||
service: {
|
||||
id: '086ad38c-dd10-42ae-a58b-1c72ee6e7f50',
|
||||
type: 'databaseService',
|
||||
name: 'test-redshift',
|
||||
fullyQualifiedName: 'test-redshift',
|
||||
description: '',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/services/databaseServices/086ad38c-dd10-42ae-a58b-1c72ee6e7f50',
|
||||
},
|
||||
pipelineStatuses: [
|
||||
{
|
||||
runId: 'scheduled__2022-10-20T04:35:00+00:00',
|
||||
state: 'running',
|
||||
startDate: 1666240861500,
|
||||
timestamp: 1666240500000,
|
||||
},
|
||||
],
|
||||
loggerLevel: 'DEBUG',
|
||||
deployed: true,
|
||||
enabled: true,
|
||||
href: 'http://localhost:8585/api/v1/services/ingestionPipelines/c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
version: 0.1,
|
||||
updatedAt: 1666240859704,
|
||||
updatedBy: 'admin',
|
||||
deleted: false,
|
||||
};
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@ -13,8 +13,20 @@
|
||||
|
||||
import { act, render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import LogsViewer from './LogsViewer.component';
|
||||
import { mockIngestionPipeline, mockLogsData } from './mocks/LogsViewer.mock';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import {
|
||||
mockDataInsightApplication,
|
||||
mockDataInsightApplicationRun,
|
||||
mockIngestionPipeline,
|
||||
mockLatestDataInsightApplicationRunLogs,
|
||||
mockLogsData,
|
||||
} from '../../mocks/LogsViewerPage.mock';
|
||||
import {
|
||||
getApplicationByName,
|
||||
getExternalApplicationRuns,
|
||||
getLatestApplicationRuns,
|
||||
} from '../../rest/applicationAPI';
|
||||
import LogsViewerPage from './LogsViewerPage';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useParams: jest.fn().mockReturnValue({
|
||||
@ -60,10 +72,28 @@ jest.mock(
|
||||
})
|
||||
);
|
||||
|
||||
describe('LogsViewer.component', () => {
|
||||
jest.mock('./LogsViewerPageSkeleton.component', () => {
|
||||
return jest.fn().mockImplementation(() => <p>LogsViewerPageSkeleton</p>);
|
||||
});
|
||||
|
||||
jest.mock('../../rest/applicationAPI', () => ({
|
||||
getApplicationByName: jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve(mockDataInsightApplication)),
|
||||
getExternalApplicationRuns: jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve(mockDataInsightApplicationRun)),
|
||||
getLatestApplicationRuns: jest
|
||||
.fn()
|
||||
.mockImplementation(() =>
|
||||
Promise.resolve(mockLatestDataInsightApplicationRunLogs)
|
||||
),
|
||||
}));
|
||||
|
||||
describe('LogsViewerPage.component', () => {
|
||||
it('On initial, component should render', async () => {
|
||||
await act(async () => {
|
||||
render(<LogsViewer />);
|
||||
render(<LogsViewerPage />);
|
||||
|
||||
expect(
|
||||
await screen.findByText('TitleBreadcrumb.component')
|
||||
@ -78,4 +108,39 @@ describe('LogsViewer.component', () => {
|
||||
|
||||
expect(logElement).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should fetch api for application logs', async () => {
|
||||
(useParams as jest.Mock).mockReturnValue({
|
||||
logEntityType: 'apps',
|
||||
fqn: 'DataInsightsApplication',
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(<LogsViewerPage />);
|
||||
});
|
||||
|
||||
expect(getApplicationByName).toHaveBeenCalled();
|
||||
expect(getExternalApplicationRuns).toHaveBeenCalled();
|
||||
expect(getLatestApplicationRuns).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should show basic configuration for application in right panel', async () => {
|
||||
(useParams as jest.Mock).mockReturnValue({
|
||||
logEntityType: 'apps',
|
||||
fqn: 'DataInsightsApplication',
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
render(<LogsViewerPage />);
|
||||
});
|
||||
|
||||
expect(screen.getByText('Type')).toBeInTheDocument();
|
||||
expect(screen.getByText('Custom')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Schedule')).toBeInTheDocument();
|
||||
expect(screen.getByText('0 0 * * *')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Recent Runs')).toBeInTheDocument();
|
||||
expect(screen.getByText('IngestionRecentRuns')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@ -11,9 +11,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Button, Col, Row, Space, Tag, Typography } from 'antd';
|
||||
import { Button, Col, Row, Space, Typography } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import { isEmpty, isNil, isUndefined, startCase, toNumber } from 'lodash';
|
||||
import { isEmpty, isNil, isUndefined, toNumber } from 'lodash';
|
||||
import React, {
|
||||
Fragment,
|
||||
useCallback,
|
||||
@ -31,20 +31,18 @@ import TitleBreadcrumb from '../../components/common/TitleBreadcrumb/TitleBreadc
|
||||
import PageLayoutV1 from '../../components/PageLayoutV1/PageLayoutV1';
|
||||
import { IngestionRecentRuns } from '../../components/Settings/Services/Ingestion/IngestionRecentRun/IngestionRecentRuns.component';
|
||||
import { GlobalSettingOptions } from '../../constants/GlobalSettings.constants';
|
||||
import { PIPELINE_INGESTION_RUN_STATUS } from '../../constants/pipeline.constants';
|
||||
import { PipelineType } from '../../generated/api/services/ingestionPipelines/createIngestionPipeline';
|
||||
import { App, AppScheduleClass } from '../../generated/entity/applications/app';
|
||||
import { AppRunRecord } from '../../generated/entity/applications/appRunRecord';
|
||||
import {
|
||||
IngestionPipeline,
|
||||
PipelineState,
|
||||
PipelineStatus,
|
||||
} from '../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||
import { Include } from '../../generated/type/include';
|
||||
import { Paging } from '../../generated/type/paging';
|
||||
import { useFqn } from '../../hooks/useFqn';
|
||||
import {
|
||||
getApplicationByName,
|
||||
getApplicationRuns,
|
||||
getExternalApplicationRuns,
|
||||
getLatestApplicationRuns,
|
||||
} from '../../rest/applicationAPI';
|
||||
import {
|
||||
@ -54,11 +52,11 @@ import {
|
||||
import { getEpochMillisForPastDays } from '../../utils/date-time/DateTimeUtils';
|
||||
import { getLogBreadCrumbs } from '../../utils/LogsViewer.utils';
|
||||
import { showErrorToast } from '../../utils/ToastUtils';
|
||||
import './logs-viewer.style.less';
|
||||
import LogViewerSkeleton from './LogsViewer-skeleton.component';
|
||||
import { LogViewerParams } from './LogsViewer.interfaces';
|
||||
import './logs-viewer-page.style.less';
|
||||
import { LogViewerParams } from './LogsViewerPage.interfaces';
|
||||
import LogViewerPageSkeleton from './LogsViewerPageSkeleton.component';
|
||||
|
||||
const LogsViewer = () => {
|
||||
const LogsViewerPage = () => {
|
||||
const { logEntityType } = useParams<LogViewerParams>();
|
||||
const { fqn: ingestionName } = useFqn();
|
||||
|
||||
@ -68,7 +66,7 @@ const LogsViewer = () => {
|
||||
const [logs, setLogs] = useState<string>('');
|
||||
const [ingestionDetails, setIngestionDetails] = useState<IngestionPipeline>();
|
||||
const [appData, setAppData] = useState<App>();
|
||||
const [appLatestRun, setAppLatestRun] = useState<AppRunRecord>();
|
||||
const [appRuns, setAppRuns] = useState<PipelineStatus[]>([]);
|
||||
const [paging, setPaging] = useState<Paging>();
|
||||
|
||||
const isApplicationType = useMemo(
|
||||
@ -84,13 +82,13 @@ const LogsViewer = () => {
|
||||
if (isApplicationType) {
|
||||
const currentTime = Date.now();
|
||||
const oneDayAgo = getEpochMillisForPastDays(1);
|
||||
const { data } = await getApplicationRuns(ingestionName, {
|
||||
const { data } = await getExternalApplicationRuns(ingestionName, {
|
||||
startTs: oneDayAgo,
|
||||
endTs: currentTime,
|
||||
});
|
||||
|
||||
const logs = await getLatestApplicationRuns(ingestionName);
|
||||
setAppLatestRun(data[0]);
|
||||
setAppRuns(data);
|
||||
setLogs(logs.data_insight_task || logs.application_task);
|
||||
|
||||
return;
|
||||
@ -267,28 +265,18 @@ const LogsViewer = () => {
|
||||
};
|
||||
|
||||
const recentRuns = useMemo(() => {
|
||||
if (isApplicationType) {
|
||||
if (!isUndefined(ingestionDetails) || appRuns) {
|
||||
return (
|
||||
<Tag
|
||||
className="ingestion-run-badge latest"
|
||||
color={
|
||||
PIPELINE_INGESTION_RUN_STATUS[
|
||||
(appLatestRun?.status as unknown as PipelineState) ??
|
||||
PipelineState.Failed
|
||||
]
|
||||
}
|
||||
data-testid="pipeline-status">
|
||||
{startCase(appLatestRun?.status)}
|
||||
</Tag>
|
||||
<IngestionRecentRuns
|
||||
appRuns={appRuns}
|
||||
ingestion={ingestionDetails}
|
||||
isApplicationType={isApplicationType}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (ingestionDetails?.fullyQualifiedName) {
|
||||
return <IngestionRecentRuns ingestion={ingestionDetails} />;
|
||||
}
|
||||
|
||||
return '--';
|
||||
}, [logEntityType, appLatestRun, ingestionDetails]);
|
||||
}, [isApplicationType, appRuns, ingestionDetails]);
|
||||
|
||||
const logSummaries = useMemo(() => {
|
||||
const scheduleClass = appData?.appSchedule as AppScheduleClass;
|
||||
@ -396,10 +384,10 @@ const LogsViewer = () => {
|
||||
</Col>
|
||||
</Row>
|
||||
) : (
|
||||
<LogViewerSkeleton />
|
||||
<LogViewerPageSkeleton />
|
||||
)}
|
||||
</PageLayoutV1>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogsViewer;
|
||||
export default LogsViewerPage;
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@ -14,7 +14,7 @@
|
||||
import { Col, Row, Skeleton } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
const LogViewerSkeleton = () => {
|
||||
const LogViewerPageSkeleton = () => {
|
||||
return (
|
||||
<Row className="border-top justify-between" gutter={[16, 16]}>
|
||||
<Col className="p-md border-right" span={18}>
|
||||
@ -47,4 +47,4 @@ const LogViewerSkeleton = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default LogViewerSkeleton;
|
||||
export default LogViewerPageSkeleton;
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
@ -17,6 +17,7 @@ import { DataInsightLatestRun } from '../components/Settings/Applications/AppDet
|
||||
import { App } from '../generated/entity/applications/app';
|
||||
import { AppRunRecord } from '../generated/entity/applications/appRunRecord';
|
||||
import { CreateAppRequest } from '../generated/entity/applications/createAppRequest';
|
||||
import { PipelineStatus } from '../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||
import { ListParams } from '../interface/API.interface';
|
||||
import { getEncodedFqn } from '../utils/StringsUtils';
|
||||
import APIClient from './index';
|
||||
@ -71,6 +72,20 @@ export const getApplicationRuns = async (
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getExternalApplicationRuns = async (
|
||||
appName: string,
|
||||
params?: AppListParams
|
||||
) => {
|
||||
const response = await APIClient.get<PagingResponse<PipelineStatus[]>>(
|
||||
`${BASE_URL}/name/${getEncodedFqn(appName)}/status`,
|
||||
{
|
||||
params,
|
||||
}
|
||||
);
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getLatestApplicationRuns = async (appName: string) => {
|
||||
const response = await APIClient.get<DataInsightLatestRun>(
|
||||
`${BASE_URL}/name/${getEncodedFqn(appName)}/logs`
|
||||
|
||||
@ -25,7 +25,7 @@ import {
|
||||
import { PipelineServiceClientResponse } from '../generated/entity/services/ingestionPipelines/pipelineServiceClientResponse';
|
||||
import { Paging } from '../generated/type/paging';
|
||||
import { ListParams } from '../interface/API.interface';
|
||||
import { IngestionPipelineLogByIdInterface } from '../pages/LogsViewer/LogsViewer.interfaces';
|
||||
import { IngestionPipelineLogByIdInterface } from '../pages/LogsViewerPage/LogsViewerPage.interfaces';
|
||||
import { getEncodedFqn } from '../utils/StringsUtils';
|
||||
import APIClient from './index';
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user