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:
Ashish Gupta 2024-04-06 12:04:21 +05:30 committed by GitHub
parent ba561c9674
commit 05dfd4ddfd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 324 additions and 146 deletions

View File

@ -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}

View File

@ -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();
});
});

View File

@ -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([]);

View File

@ -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',
};

View File

@ -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,
};

View File

@ -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();
});
});

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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`

View File

@ -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';