kafka-ui/kafka-ui-react-app/src/redux/actions/thunks/topics.ts
Alexander Krivonosov 98fcc90c6b
Topics' filtration (#405)
* Implement topics' filtration
2021-05-12 16:34:24 +03:00

316 lines
7.8 KiB
TypeScript

import { v4 } from 'uuid';
import {
TopicsApi,
MessagesApi,
Configuration,
Topic,
TopicCreation,
TopicUpdate,
TopicConfig,
TopicColumnsToSort,
} from 'generated-sources';
import {
PromiseThunkResult,
ClusterName,
TopicName,
TopicMessageQueryParams,
TopicFormFormattedParams,
TopicFormDataRaw,
TopicsState,
FailurePayload,
} from 'redux/interfaces';
import { BASE_PARAMS } from 'lib/constants';
import * as actions from 'redux/actions/actions';
import { getResponse } from 'lib/errorHandling';
const apiClientConf = new Configuration(BASE_PARAMS);
export const topicsApiClient = new TopicsApi(apiClientConf);
export const messagesApiClient = new MessagesApi(apiClientConf);
export interface FetchTopicsListParams {
clusterName: ClusterName;
page?: number;
perPage?: number;
showInternal?: boolean;
search?: string;
orderBy?: TopicColumnsToSort;
}
export const fetchTopicsList = (
params: FetchTopicsListParams
): PromiseThunkResult => async (dispatch, getState) => {
dispatch(actions.fetchTopicsListAction.request());
try {
const { topics, pageCount } = await topicsApiClient.getTopics(params);
const newState = (topics || []).reduce(
(memo: TopicsState, topic) => ({
...memo,
byName: {
...memo.byName,
[topic.name]: {
...memo.byName[topic.name],
...topic,
id: v4(),
},
},
allNames: [...memo.allNames, topic.name],
}),
{
...getState().topics,
allNames: [],
totalPages: pageCount || 1,
}
);
dispatch(actions.fetchTopicsListAction.success(newState));
} catch (e) {
dispatch(actions.fetchTopicsListAction.failure());
}
};
export const fetchTopicMessages = (
clusterName: ClusterName,
topicName: TopicName,
queryParams: Partial<TopicMessageQueryParams>
): PromiseThunkResult => async (dispatch) => {
dispatch(actions.fetchTopicMessagesAction.request());
try {
const messages = await messagesApiClient.getTopicMessages({
clusterName,
topicName,
...queryParams,
});
dispatch(actions.fetchTopicMessagesAction.success(messages));
} catch (e) {
dispatch(actions.fetchTopicMessagesAction.failure());
}
};
export const clearTopicMessages = (
clusterName: ClusterName,
topicName: TopicName,
partitions?: number[]
): PromiseThunkResult => async (dispatch) => {
dispatch(actions.clearMessagesTopicAction.request());
try {
await messagesApiClient.deleteTopicMessages({
clusterName,
topicName,
partitions,
});
dispatch(actions.clearMessagesTopicAction.success(topicName));
} catch (e) {
const response = await getResponse(e);
const alert: FailurePayload = {
subject: [clusterName, topicName, partitions].join('-'),
title: `Clear Topic Messages`,
response,
};
dispatch(actions.clearMessagesTopicAction.failure({ alert }));
}
};
export const fetchTopicDetails = (
clusterName: ClusterName,
topicName: TopicName
): PromiseThunkResult => async (dispatch, getState) => {
dispatch(actions.fetchTopicDetailsAction.request());
try {
const topicDetails = await topicsApiClient.getTopicDetails({
clusterName,
topicName,
});
const state = getState().topics;
const newState = {
...state,
byName: {
...state.byName,
[topicName]: {
...state.byName[topicName],
...topicDetails,
},
},
};
dispatch(actions.fetchTopicDetailsAction.success(newState));
} catch (e) {
dispatch(actions.fetchTopicDetailsAction.failure());
}
};
export const fetchTopicConfig = (
clusterName: ClusterName,
topicName: TopicName
): PromiseThunkResult => async (dispatch, getState) => {
dispatch(actions.fetchTopicConfigAction.request());
try {
const config = await topicsApiClient.getTopicConfigs({
clusterName,
topicName,
});
const state = getState().topics;
const newState = {
...state,
byName: {
...state.byName,
[topicName]: {
...state.byName[topicName],
config: config.map((inputConfig) => ({
...inputConfig,
})),
},
},
};
dispatch(actions.fetchTopicConfigAction.success(newState));
} catch (e) {
dispatch(actions.fetchTopicConfigAction.failure());
}
};
const formatTopicCreation = (form: TopicFormDataRaw): TopicCreation => {
const {
name,
partitions,
replicationFactor,
cleanupPolicy,
retentionBytes,
retentionMs,
maxMessageBytes,
minInSyncReplicas,
customParams,
} = form;
return {
name,
partitions,
replicationFactor,
configs: {
'cleanup.policy': cleanupPolicy,
'retention.ms': retentionMs,
'retention.bytes': retentionBytes,
'max.message.bytes': maxMessageBytes,
'min.insync.replicas': minInSyncReplicas,
...Object.values(customParams || {}).reduce(
(result: TopicFormFormattedParams, customParam: TopicConfig) => {
return {
...result,
[customParam.name]: customParam.value,
};
},
{}
),
},
};
};
const formatTopicUpdate = (form: TopicFormDataRaw): TopicUpdate => {
const {
cleanupPolicy,
retentionBytes,
retentionMs,
maxMessageBytes,
minInSyncReplicas,
customParams,
} = form;
return {
configs: {
'cleanup.policy': cleanupPolicy,
'retention.ms': retentionMs,
'retention.bytes': retentionBytes,
'max.message.bytes': maxMessageBytes,
'min.insync.replicas': minInSyncReplicas,
...Object.values(customParams || {}).reduce(
(result: TopicFormFormattedParams, customParam: TopicConfig) => {
return {
...result,
[customParam.name]: customParam.value,
};
},
{}
),
},
};
};
export const createTopic = (
clusterName: ClusterName,
form: TopicFormDataRaw
): PromiseThunkResult => async (dispatch, getState) => {
dispatch(actions.createTopicAction.request());
try {
const topic: Topic = await topicsApiClient.createTopic({
clusterName,
topicCreation: formatTopicCreation(form),
});
const state = getState().topics;
const newState = {
...state,
byName: {
...state.byName,
[topic.name]: {
...topic,
},
},
allNames: [...state.allNames, topic.name],
};
dispatch(actions.createTopicAction.success(newState));
} catch (error) {
const response = await getResponse(error);
const alert: FailurePayload = {
subject: ['schema', form.name].join('-'),
title: `Schema ${form.name}`,
response,
};
dispatch(actions.createTopicAction.failure({ alert }));
}
};
export const updateTopic = (
clusterName: ClusterName,
topicName: TopicName,
form: TopicFormDataRaw
): PromiseThunkResult => async (dispatch, getState) => {
dispatch(actions.updateTopicAction.request());
try {
const topic: Topic = await topicsApiClient.updateTopic({
clusterName,
topicName,
topicUpdate: formatTopicUpdate(form),
});
const state = getState().topics;
const newState = {
...state,
byName: {
...state.byName,
[topic.name]: {
...state.byName[topic.name],
...topic,
},
},
};
dispatch(actions.updateTopicAction.success(newState));
} catch (e) {
dispatch(actions.updateTopicAction.failure());
}
};
export const deleteTopic = (
clusterName: ClusterName,
topicName: TopicName
): PromiseThunkResult => async (dispatch) => {
dispatch(actions.deleteTopicAction.request());
try {
await topicsApiClient.deleteTopic({
clusterName,
topicName,
});
dispatch(actions.deleteTopicAction.success(topicName));
} catch (e) {
dispatch(actions.deleteTopicAction.failure());
}
};