blob: 496482584019c22a6ac2a670d51163d98be4c3af [file] [log] [blame]
import * as _ from 'lodash';
export interface IReplica {
instanceName: string;
externalView: string;
idealState: string;
}
export class Partition {
name: string;
replicas: IReplica[];
get isReady() {
return !_.some(
this.replicas,
(replica) =>
!replica.externalView || replica.externalView != replica.idealState
);
}
constructor(name: string) {
this.name = name;
this.replicas = [];
}
}
export class Resource {
readonly name: string;
// TODO vxu: convert it to an enum in future if necessary
readonly alive: boolean;
readonly cluster: string;
// meta data
readonly idealStateMode: string;
readonly rebalanceMode: string;
readonly stateModel: string;
readonly partitionCount: number;
readonly replicaCount: number;
readonly idealState: any;
readonly externalView: any;
readonly partitions: Partition[];
get enabled(): boolean {
// there are two cases meaning enabled both:
// HELIX_ENABLED: true or no such item in idealState
return _.get(this.idealState, 'simpleFields.HELIX_ENABLED') != 'false';
}
get online(): boolean {
return !_.isEmpty(this.externalView);
}
constructor(
cluster: string,
name: string,
config: any,
idealState: any,
externalView: any
) {
this.cluster = cluster;
this.name = name;
externalView = externalView || {};
// ignore config for now since config component will fetch itself
this.idealStateMode = idealState.simpleFields.IDEAL_STATE_MODE;
this.rebalanceMode = idealState.simpleFields.REBALANCE_MODE;
this.stateModel = idealState.simpleFields.STATE_MODEL_DEF_REF;
this.partitionCount = +idealState.simpleFields.NUM_PARTITIONS;
this.replicaCount = +idealState.simpleFields.REPLICAS;
// fetch partition names from externalView.mapFields is (relatively) more stable
this.partitions = [];
for (const partitionName in externalView.mapFields) {
const partition = new Partition(partitionName);
// in FULL_ATUO mode, externalView is more important
// if preferences list exists, fetch instances from it, else whatever
if (
this.rebalanceMode != 'FULL_AUTO' &&
idealState.listFields[partitionName]
) {
for (const replicaName of idealState.listFields[partitionName]) {
partition.replicas.push(<IReplica>{
instanceName: replicaName,
externalView: _.get(externalView, [
'mapFields',
partitionName,
replicaName,
]),
idealState: _.get(idealState, [
'mapFields',
partitionName,
replicaName,
]),
});
}
} else if (
this.rebalanceMode != 'FULL_AUTO' &&
idealState.mapFields[partitionName]
) {
for (const replicaName in idealState.mapFields[partitionName]) {
partition.replicas.push(<IReplica>{
instanceName: replicaName,
externalView: _.get(externalView, [
'mapFields',
partitionName,
replicaName,
]),
idealState: _.get(idealState, [
'mapFields',
partitionName,
replicaName,
]),
});
}
} else {
for (const replicaName in externalView.mapFields[partitionName]) {
partition.replicas.push(<IReplica>{
instanceName: replicaName,
externalView: _.get(externalView, [
'mapFields',
partitionName,
replicaName,
]),
idealState: _.get(idealState, [
'mapFields',
partitionName,
replicaName,
]),
});
}
}
// sort replicas by states
partition.replicas = _.sortBy(partition.replicas, 'externalView');
this.partitions.push(partition);
}
this.idealState = idealState;
this.externalView = externalView;
}
}