Ver Fonte

[UI] Empty Brokers Component

Oleg Shuralev há 5 anos atrás
pai
commit
97a7bc781a

+ 2 - 0
frontend/src/components/App.tsx

@@ -4,6 +4,7 @@ import {
   Route,
 } from 'react-router-dom';
 import './App.scss';
+import BrokersContainer from './Brokers/BrokersContainer';
 import TopicsContainer from './Topics/TopicsContainer';
 import NavConatiner from './Nav/NavConatiner';
 import PageLoader from './common/PageLoader/PageLoader';
@@ -33,6 +34,7 @@ const App: React.FC<AppProps> = ({
         {isClusterListFetched ? (
           <Switch>
             <Route path="/clusters/:clusterId/topics" component={TopicsContainer} />
+            <Route path="/clusters/:clusterId/brokers" component={BrokersContainer} />
             <Route exact path="/">
               Dashboard
             </Route>

+ 30 - 0
frontend/src/components/Brokers/Brokers.tsx

@@ -0,0 +1,30 @@
+import React from 'react';
+import PageLoader from 'components/common/PageLoader/PageLoader';
+import { ClusterId } from 'types';
+
+interface Props {
+  clusterId: string;
+  isFetched: boolean;
+  fetchBrokers: (clusterId: ClusterId) => void;
+  fetchBrokerMetrics: (clusterId: ClusterId) => void;
+}
+
+const Topics: React.FC<Props> = ({
+  clusterId,
+  isFetched,
+  fetchBrokers,
+  fetchBrokerMetrics,
+}) => {
+  React.useEffect(() => { fetchBrokers(clusterId); }, [fetchBrokers, clusterId]);
+  React.useEffect(() => { fetchBrokerMetrics(clusterId); }, [fetchBrokerMetrics, clusterId]);
+
+  if (isFetched) {
+    return (
+      <div>Brokers of {clusterId}</div>
+    );
+  }
+
+  return (<PageLoader />);
+}
+
+export default Topics;

+ 27 - 0
frontend/src/components/Brokers/BrokersContainer.ts

@@ -0,0 +1,27 @@
+import { connect } from 'react-redux';
+import {
+  fetchBrokers,
+  fetchBrokerMetrics,
+} from 'redux/reducers/brokers/thunks';
+import Brokers from './Brokers';
+import { getIsBrokerListFetched } from 'redux/reducers/brokers/selectors';
+import { RootState, ClusterId } from 'types';
+import { RouteComponentProps } from 'react-router-dom';
+
+interface RouteProps {
+  clusterId: string;
+}
+
+interface OwnProps extends RouteComponentProps<RouteProps> { }
+
+const mapStateToProps = (state: RootState, { match: { params: { clusterId } }}: OwnProps) => ({
+  isFetched: getIsBrokerListFetched(state),
+  clusterId,
+});
+
+const mapDispatchToProps = {
+  fetchBrokers: (clusterId: ClusterId) => fetchBrokers(clusterId),
+  fetchBrokerMetrics: (clusterId: ClusterId) => fetchBrokerMetrics(clusterId),
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Brokers);

+ 17 - 0
frontend/src/lib/api/brokers.ts

@@ -0,0 +1,17 @@
+import {
+  Broker,
+  ClusterId,
+  BrokerMetrics,
+} from 'types';
+import {
+  BASE_URL,
+  BASE_PARAMS,
+} from 'lib/constants';
+
+export const getBrokers = (clusterId: ClusterId): Promise<{ brokers: Broker[] }> =>
+  fetch(`${BASE_URL}/clusters/${clusterId}/brokers`, { ...BASE_PARAMS })
+    .then(res => res.json());
+
+export const getBrokerMetrics = (clusterId: ClusterId): Promise<BrokerMetrics> =>
+  fetch(`${BASE_URL}/clusters/${clusterId}/metrics/broker`, { ...BASE_PARAMS })
+    .then(res => res.json());

+ 1 - 0
frontend/src/lib/api/index.ts

@@ -1,2 +1,3 @@
 export * from './topics';
 export * from './clusters';
+export * from './brokers';

+ 0 - 5
frontend/src/lib/api/topics.ts

@@ -1,7 +1,6 @@
 import {
   TopicName,
   Topic,
-  Broker,
   ClusterId,
 } from 'types';
 import {
@@ -16,7 +15,3 @@ export const getTopic = (name: TopicName): Promise<Topic> =>
 export const getTopics = (clusterId: ClusterId): Promise<Topic[]> =>
   fetch(`${BASE_URL}/clusters/${clusterId}/topics`, { ...BASE_PARAMS })
     .then(res => res.json());
-
-export const getBrokers = (clusterId: ClusterId): Promise<{ brokers: Broker[] }> =>
-  fetch(`${BASE_URL}/clusters/${clusterId}/brokers`, { ...BASE_PARAMS })
-    .then(res => res.json());

+ 4 - 0
frontend/src/redux/reducers/brokers/actionType.ts

@@ -2,6 +2,10 @@ enum ActionType {
   GET_BROKERS__REQUEST = 'GET_BROKERS__REQUEST',
   GET_BROKERS__SUCCESS = 'GET_BROKERS__SUCCESS',
   GET_BROKERS__FAILURE = 'GET_BROKERS__FAILURE',
+
+  GET_BROKER_METRICS__REQUEST = 'GET_BROKER_METRICS__REQUEST',
+  GET_BROKER_METRICS__SUCCESS = 'GET_BROKER_METRICS__SUCCESS',
+  GET_BROKER_METRICS__FAILURE = 'GET_BROKER_METRICS__FAILURE',
 }
 
 export default ActionType;

+ 7 - 1
frontend/src/redux/reducers/brokers/actions.ts

@@ -1,9 +1,15 @@
 import { createAsyncAction} from 'typesafe-actions';
 import ActionType from './actionType';
-import { Broker } from 'types';
+import { Broker, BrokerMetrics } from 'types';
 
 export const fetchBrokersAction = createAsyncAction(
   ActionType.GET_BROKERS__REQUEST,
   ActionType.GET_BROKERS__SUCCESS,
   ActionType.GET_BROKERS__FAILURE,
 )<undefined, Broker[], undefined>();
+
+export const fetchBrokerMetricsAction = createAsyncAction(
+  ActionType.GET_BROKER_METRICS__REQUEST,
+  ActionType.GET_BROKER_METRICS__SUCCESS,
+  ActionType.GET_BROKER_METRICS__FAILURE,
+)<undefined, BrokerMetrics, undefined>();

+ 23 - 4
frontend/src/redux/reducers/brokers/reducer.ts

@@ -1,12 +1,31 @@
-import { Broker, Action } from 'types';
+import { Action, BrokersState, ZooKeeperStatus } from 'types';
 import actionType from 'redux/reducers/actionType';
 
-export const initialState: Broker[] = [];
+export const initialState: BrokersState =  {
+  items: [],
+  brokerCount: 0,
+  zooKeeperStatus: ZooKeeperStatus.offline,
+  activeControllers: 0,
+  networkPoolUsage: 0,
+  requestPoolUsage: 0,
+  onlinePartitionCount: 0,
+  underReplicatedPartitionCount: 0,
+  offlinePartitionCount: 0,
+  diskUsageDistribution: undefined,
+};
 
-const reducer = (state = initialState, action: Action): Broker[] => {
+const reducer = (state = initialState, action: Action): BrokersState => {
   switch (action.type) {
     case actionType.GET_BROKERS__SUCCESS:
-      return action.payload;
+      return {
+        ...state,
+        items: action.payload,
+      };
+    case actionType.GET_BROKER_METRICS__SUCCESS:
+      return {
+        ...state,
+        ...action.payload,
+      };
     default:
       return state;
   }

+ 3 - 3
frontend/src/redux/reducers/brokers/selectors.ts

@@ -1,8 +1,8 @@
 import { createSelector } from 'reselect';
-import { RootState, FetchStatus, Broker } from 'types';
+import { RootState, FetchStatus, BrokersState } from 'types';
 import { createFetchingSelector } from 'redux/reducers/loader/selectors';
 
-const brokersState = ({ brokers }: RootState): Broker[] => brokers;
+const brokersState = ({ brokers }: RootState): BrokersState => brokers;
 
 const getBrokerListFetchingStatus = createFetchingSelector('GET_BROKERS');
 
@@ -11,7 +11,7 @@ export const getIsBrokerListFetched = createSelector(
   (status) => status === FetchStatus.fetched,
 );
 
-const getBrokerList = createSelector(brokersState, (brokers) => brokers);
+const getBrokerList = createSelector(brokersState, ({ items }) => items);
 
 export const getTotalBrokers = createSelector(
   getIsBrokerListFetched,

+ 15 - 2
frontend/src/redux/reducers/brokers/thunks.ts

@@ -1,5 +1,8 @@
-import { getBrokers } from 'lib/api';
-import { fetchBrokersAction } from './actions';
+import { getBrokers, getBrokerMetrics } from 'lib/api';
+import {
+  fetchBrokersAction,
+  fetchBrokerMetricsAction,
+} from './actions';
 import { PromiseThunk, ClusterId } from 'types';
 
 
@@ -12,3 +15,13 @@ export const fetchBrokers = (clusterId: ClusterId): PromiseThunk<void> => async
     dispatch(fetchBrokersAction.failure());
   }
 }
+
+export const fetchBrokerMetrics = (clusterId: ClusterId): PromiseThunk<void> => async (dispatch) => {
+  dispatch(fetchBrokerMetricsAction.request());
+  try {
+    const payload = await getBrokerMetrics(clusterId);
+    dispatch(fetchBrokerMetricsAction.success(payload));
+  } catch (e) {
+    dispatch(fetchBrokerMetricsAction.failure());
+  }
+}

+ 30 - 2
frontend/src/types/broker.ts

@@ -1,4 +1,32 @@
+export type BrokerId = string;
+
 export interface Broker {
-  id: string,
-  host: "broker",
+  brokerId: BrokerId;
+  bytesInPerSec: number;
+  segmentSize: number;
+  partitionReplicas: number;
+  bytesOutPerSec: number;
 };
+
+export enum ZooKeeperStatus { online, offline };
+
+export interface BrokerDiskUsage {
+  brokerId: BrokerId;
+  segmentSize: number;
+}
+
+export interface BrokerMetrics {
+  brokerCount: number;
+  zooKeeperStatus: ZooKeeperStatus;
+  activeControllers: number;
+  networkPoolUsage: number;
+  requestPoolUsage: number;
+  onlinePartitionCount: number;
+  underReplicatedPartitionCount: number;
+  offlinePartitionCount: number;
+  diskUsageDistribution?: string;
+}
+
+export interface BrokersState extends BrokerMetrics {
+  items: Broker[];
+}

+ 2 - 2
frontend/src/types/index.ts

@@ -8,7 +8,7 @@ import * as brokersActions from 'redux/reducers/brokers/actions';
 
 import { Topic } from './topic';
 import { Cluster } from './cluster';
-import { Broker } from './broker';
+import { BrokersState } from './broker';
 import { LoaderState } from './loader';
 
 export * from './topic';
@@ -26,7 +26,7 @@ export enum FetchStatus {
 export interface RootState {
   topics: Topic[];
   clusters: Cluster[];
-  brokers: Broker[];
+  brokers: BrokersState;
   loader: LoaderState;
 }