Issue#517 connector task status bug (#747)

* kafka-ui-connectors.yaml fix

* adding tasks status check

* adding new Connector Status

* adding new Connector Status

* [issue-517] connector task status bug #747

Co-authored-by: marselakhmetov <makhmetov@provectus.com>
Co-authored-by: mbovtryuk <mbovtryuk@provectus.com>
This commit is contained in:
Marsel 2021-08-18 14:03:41 +05:00 committed by GitHub
parent 128c67c1cf
commit 7f66f00008
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 93 additions and 49 deletions

View file

@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.provectus.kafka.ui.client.KafkaConnectClients;
import com.provectus.kafka.ui.connect.model.ConnectorTopics;
import com.provectus.kafka.ui.connect.model.TaskStatus;
import com.provectus.kafka.ui.exception.ClusterNotFoundException;
import com.provectus.kafka.ui.exception.ConnectNotFoundException;
import com.provectus.kafka.ui.mapper.ClusterMapper;
@ -13,6 +14,7 @@ import com.provectus.kafka.ui.model.Connector;
import com.provectus.kafka.ui.model.ConnectorAction;
import com.provectus.kafka.ui.model.ConnectorPlugin;
import com.provectus.kafka.ui.model.ConnectorPluginConfigValidationResponse;
import com.provectus.kafka.ui.model.ConnectorState;
import com.provectus.kafka.ui.model.FullConnectorInfo;
import com.provectus.kafka.ui.model.KafkaCluster;
import com.provectus.kafka.ui.model.KafkaConnectCluster;
@ -161,21 +163,30 @@ public class KafkaConnectService {
public Mono<Connector> getConnector(String clusterName, String connectName,
String connectorName) {
return getConnectAddress(clusterName, connectName)
.flatMap(connect ->
KafkaConnectClients.withBaseUrl(connect).getConnector(connectorName)
.flatMap(connect -> KafkaConnectClients.withBaseUrl(connect).getConnector(connectorName)
.map(kafkaConnectMapper::fromClient)
.flatMap(connector ->
KafkaConnectClients.withBaseUrl(connect).getConnectorStatus(connector.getName())
.map(connectorStatus -> {
var status = connectorStatus.getConnector();
connector.status(kafkaConnectMapper.fromClient(status));
return (Connector) new Connector()
Connector result = (Connector) new Connector()
.connect(connectName)
.status(kafkaConnectMapper.fromClient(status))
.type(connector.getType())
.tasks(connector.getTasks())
.name(connector.getName())
.config(connector.getConfig());
if (connectorStatus.getTasks() != null) {
boolean isAnyTaskFailed = connectorStatus.getTasks().stream()
.map(TaskStatus::getState)
.anyMatch(TaskStatus.StateEnum.FAILED::equals);
if (isAnyTaskFailed) {
result.getStatus().state(ConnectorState.TASK_FAILED);
}
}
return result;
})
)
);

View file

@ -8,8 +8,8 @@ import com.provectus.kafka.ui.model.ConnectorPlugin;
import com.provectus.kafka.ui.model.ConnectorPluginConfig;
import com.provectus.kafka.ui.model.ConnectorPluginConfigValidationResponse;
import com.provectus.kafka.ui.model.ConnectorPluginConfigValue;
import com.provectus.kafka.ui.model.ConnectorState;
import com.provectus.kafka.ui.model.ConnectorStatus;
import com.provectus.kafka.ui.model.ConnectorTaskStatus;
import com.provectus.kafka.ui.model.ConnectorType;
import com.provectus.kafka.ui.model.NewConnector;
import com.provectus.kafka.ui.model.TaskId;
@ -171,7 +171,7 @@ public class KafkaConnectServiceTests extends AbstractBaseTest {
Connector expected = (Connector) new Connector()
.connect(connectName)
.status(new ConnectorStatus()
.state(ConnectorTaskStatus.RUNNING)
.state(ConnectorState.RUNNING)
.workerId("kafka-connect:8083"))
.tasks(List.of(new TaskId()
.connector(connectorName)

View file

@ -2285,7 +2285,7 @@ components:
type: object
properties:
state:
$ref: '#/components/schemas/ConnectorTaskStatus'
$ref: '#/components/schemas/ConnectorState'
worker_id:
type: string
required:
@ -2299,6 +2299,15 @@ components:
- PAUSED
- UNASSIGNED
ConnectorState:
type: string
enum:
- RUNNING
- FAILED
- PAUSED
- UNASSIGNED
- TASK_FAILED
ConnectorAction:
type: string
enum:

View file

@ -0,0 +1,21 @@
import cx from 'classnames';
import { ConnectorState } from 'generated-sources';
import React from 'react';
export interface StatusTagProps {
status: ConnectorState;
}
const ConnectorStatusTag: React.FC<StatusTagProps> = ({ status }) => {
const classNames = cx('tag', {
'is-success': status === ConnectorState.RUNNING,
'is-light': status === ConnectorState.PAUSED,
'is-warning': status === ConnectorState.UNASSIGNED,
'is-danger':
status === ConnectorState.FAILED || status === ConnectorState.TASK_FAILED,
});
return <span className={classNames}>{status}</span>;
};
export default ConnectorStatusTag;

View file

@ -1,6 +1,6 @@
import React from 'react';
import { Link, useHistory, useParams } from 'react-router-dom';
import { ConnectorTaskStatus } from 'generated-sources';
import { ConnectorState } from 'generated-sources';
import { ClusterName, ConnectName, ConnectorName } from 'redux/interfaces';
import {
clusterConnectConnectorEditPath,
@ -21,7 +21,7 @@ export interface ActionsProps {
connectorName: ConnectorName
): Promise<void>;
isConnectorDeleting: boolean;
connectorStatus?: ConnectorTaskStatus;
connectorStatus?: ConnectorState;
restartConnector(
clusterName: ClusterName,
connectName: ConnectName,
@ -79,7 +79,7 @@ const Actions: React.FC<ActionsProps> = ({
return (
<div className="buttons">
{connectorStatus === ConnectorTaskStatus.RUNNING && (
{connectorStatus === ConnectorState.RUNNING && (
<button
type="button"
className="button"
@ -93,7 +93,7 @@ const Actions: React.FC<ActionsProps> = ({
</button>
)}
{connectorStatus === ConnectorTaskStatus.PAUSED && (
{connectorStatus === ConnectorState.PAUSED && (
<button
type="button"
className="button"

View file

@ -8,7 +8,7 @@ import ActionsContainer from 'components/Connect/Details/Actions/ActionsContaine
import Actions, {
ActionsProps,
} from 'components/Connect/Details/Actions/Actions';
import { ConnectorTaskStatus } from 'generated-sources';
import { ConnectorState } from 'generated-sources';
import { ConfirmationModalProps } from 'components/common/ConfirmationModal/ConfirmationModal';
const mockHistoryPush = jest.fn();
@ -45,7 +45,7 @@ describe('Actions', () => {
<Actions
deleteConnector={jest.fn()}
isConnectorDeleting={false}
connectorStatus={ConnectorTaskStatus.RUNNING}
connectorStatus={ConnectorState.RUNNING}
restartConnector={jest.fn()}
pauseConnector={jest.fn()}
resumeConnector={jest.fn()}
@ -62,21 +62,21 @@ describe('Actions', () => {
it('matches snapshot when paused', () => {
const wrapper = create(
setupWrapper({ connectorStatus: ConnectorTaskStatus.PAUSED })
setupWrapper({ connectorStatus: ConnectorState.PAUSED })
);
expect(wrapper.toJSON()).toMatchSnapshot();
});
it('matches snapshot when failed', () => {
const wrapper = create(
setupWrapper({ connectorStatus: ConnectorTaskStatus.FAILED })
setupWrapper({ connectorStatus: ConnectorState.FAILED })
);
expect(wrapper.toJSON()).toMatchSnapshot();
});
it('matches snapshot when unassigned', () => {
const wrapper = create(
setupWrapper({ connectorStatus: ConnectorTaskStatus.UNASSIGNED })
setupWrapper({ connectorStatus: ConnectorState.UNASSIGNED })
);
expect(wrapper.toJSON()).toMatchSnapshot();
});
@ -157,7 +157,7 @@ describe('Actions', () => {
const pauseConnector = jest.fn();
const wrapper = mount(
setupWrapper({
connectorStatus: ConnectorTaskStatus.RUNNING,
connectorStatus: ConnectorState.RUNNING,
pauseConnector,
})
);
@ -174,7 +174,7 @@ describe('Actions', () => {
const resumeConnector = jest.fn();
const wrapper = mount(
setupWrapper({
connectorStatus: ConnectorTaskStatus.PAUSED,
connectorStatus: ConnectorState.PAUSED,
resumeConnector,
})
);

View file

@ -1,6 +1,6 @@
import React from 'react';
import { Connector } from 'generated-sources';
import StatusTag from 'components/Connect/StatusTag';
import ConnectorStatusTag from 'components/Connect/ConnectorStatusTag';
export interface OverviewProps {
connector: Connector | null;
@ -38,7 +38,7 @@ const Overview: React.FC<OverviewProps> = ({
<tr>
<th>State</th>
<td>
<StatusTag status={connector.status.state} />
<ConnectorStatusTag status={connector.status.state} />
</td>
</tr>
<tr>

View file

@ -37,9 +37,11 @@ exports[`Overview view matches snapshot 1`] = `
State
</th>
<td>
<mock-StatusTag
status="RUNNING"
/>
<span
className="tag is-success"
>
RUNNING
</span>
</td>
</tr>
<tr>

View file

@ -10,7 +10,7 @@ import Dropdown from 'components/common/Dropdown/Dropdown';
import DropdownDivider from 'components/common/Dropdown/DropdownDivider';
import DropdownItem from 'components/common/Dropdown/DropdownItem';
import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
import StatusTag from 'components/Connect/StatusTag';
import ConnectorStatusTag from 'components/Connect/ConnectorStatusTag';
export interface ListItemProps {
clusterName: ClusterName;
@ -72,7 +72,7 @@ const ListItem: React.FC<ListItemProps> = ({
))}
</div>
</td>
<td>{status && <StatusTag status={status.state} />}</td>
<td>{status && <ConnectorStatusTag status={status.state} />}</td>
<td>
{runningTasks && (
<span

View file

@ -132,7 +132,7 @@ exports[`Connectors ListItem matches snapshot 1`] = `
</div>
</td>
<td>
<StatusTag
<ConnectorStatusTag
status="RUNNING"
>
<span
@ -140,7 +140,7 @@ exports[`Connectors ListItem matches snapshot 1`] = `
>
RUNNING
</span>
</StatusTag>
</ConnectorStatusTag>
</td>
<td>
<span

View file

@ -1,6 +1,7 @@
import {
Connect,
Connector,
ConnectorState,
ConnectorTaskStatus,
ConnectorType,
FullConnectorInfo,
@ -49,7 +50,7 @@ export const connectors: FullConnectorInfo[] = [
type: ConnectorType.SOURCE,
topics: ['test-topic'],
status: {
state: ConnectorTaskStatus.RUNNING,
state: ConnectorState.RUNNING,
},
tasksCount: 2,
failedTasksCount: 0,
@ -61,7 +62,7 @@ export const connectors: FullConnectorInfo[] = [
type: ConnectorType.SINK,
topics: ['test-topic'],
status: {
state: ConnectorTaskStatus.FAILED,
state: ConnectorState.FAILED,
},
tasksCount: 3,
failedTasksCount: 1,
@ -90,7 +91,7 @@ export const connector: Connector = {
name: 'hdfs-source-connector',
type: ConnectorType.SOURCE,
status: {
state: ConnectorTaskStatus.RUNNING,
state: ConnectorState.RUNNING,
workerId: 'kafka-connect0:8083',
},
config: {

View file

@ -1,4 +1,4 @@
import { ConnectorTaskStatus } from 'generated-sources';
import { ConnectorState, ConnectorTaskStatus } from 'generated-sources';
import {
fetchConnectorsAction,
fetchConnectorAction,
@ -23,7 +23,7 @@ const runningConnectorState = {
...connector,
status: {
...connector.status,
state: ConnectorTaskStatus.RUNNING,
state: ConnectorState.RUNNING,
},
},
tasks: tasks.map((task) => ({
@ -44,7 +44,7 @@ const pausedConnectorState = {
...connector,
status: {
...connector.status,
state: ConnectorTaskStatus.PAUSED,
state: ConnectorState.PAUSED,
},
},
tasks: tasks.map((task) => ({

View file

@ -2,7 +2,7 @@ import { getType } from 'typesafe-actions';
import * as actions from 'redux/actions';
import { ConnectState } from 'redux/interfaces/connect';
import { Action } from 'redux/interfaces';
import { ConnectorTaskStatus } from 'generated-sources';
import { ConnectorState, ConnectorTaskStatus } from 'generated-sources';
export const initialState: ConnectState = {
connects: [],
@ -53,7 +53,7 @@ const reducer = (state = initialState, action: Action): ConnectState => {
...state.currentConnector.connector,
status: {
...state.currentConnector.connector?.status,
state: ConnectorTaskStatus.PAUSED,
state: ConnectorState.PAUSED,
},
}
: null,
@ -76,7 +76,7 @@ const reducer = (state = initialState, action: Action): ConnectState => {
...state.currentConnector.connector,
status: {
...state.currentConnector.connector?.status,
state: ConnectorTaskStatus.RUNNING,
state: ConnectorState.RUNNING,
},
}
: null,