wdp要改造amberi前端的点
# 中英版本国际化
根据打包动态配置中英文设置;及对应修改接口提交参数国际化i18n字段;
require('utils');
const en = require('i18n/en');
const zh = require('i18n/zh');
const Conf = require('conf');
var lang = window.localStorage.lang;
if (!['en', 'zh'].includes(lang)) {
lang = Conf.defaultLang
}
window.localStorage.setItem('lang', lang)
Em.I18n.translations = lang === 'zh' ? zh : en;
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Socket连接问题
添加个超时连接设置;
module.exports = Em.Object.extend({
/**
* @type {Stomp}
*/
client: null,
/**
* @type {string}
*/
webSocketUrl: '{protocol}://{hostname}{port}/api/stomp/v1/websocket',
webSocketUrl2: '{wsApi}/api/stomp/v1/websocket',
/**
* @type {string}
*/
sockJsUrl: '{protocol}://{hostname}{port}/api/stomp/v1',
sockJsUrl2: '{protocol}://{hostname}{port}/api/stomp/v1',
/**
* sockJs should use only alternative options as transport in case when websocket supported but connection fails
* @const
* @type {Array}
*/
sockJsTransports: ['eventsource', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling'],
/**
* @type {boolean}
*/
isConnected: false,
/**
* @type {boolean}
*/
isWebSocketSupported: true,
/**
* @type {number}
* @const
*/
RECONNECT_TIMEOUT: 50000,
/**
* @type {object}
*/
subscriptions: {},
/**
* default headers
* @type {object}
*/
headers: {},
retryNum: 0, // 重连次数
/**
* 在main中初始化调用
* @param {boolean} useSockJS
* @returns {$.Deferred}
*/
connect: function (useSockJS) {
console.debug('Websocket === Start Connection');
this.disconnect(); // 先断掉之前的连接的
const dfd = $.Deferred();
const socket = this.getSocket(useSockJS);
const client = Stomp.over(socket);
const headers = this.get('headers')
client.connect(headers, () => {
this.onConnectionSuccess();
if (!Conf.isPro) client.debug = Em.K;
this.set('client', client);
dfd.resolve();
}, (error) => {
dfd.reject(this.onConnectionError(error));
});
return dfd.promise();
},
getSocket: function () {
var wsApi = (window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host;
var newUrl = this.get('webSocketUrl2').replace('{wsApi}', wsApi)
var socket = new WebSocket(newUrl);
// var xToken = window.localStorage.getItem('X-Token')
// var socket = new WebSocket(newUrl, encodeURIComponent(xToken));
// if ('WebSocket' in window) {
// socket = new WebSocket(newUrl);
// } else if ('MozWebSocket' in window) {
// socket = new window.MozWebSocket(newUrl);
// } else {
// socket = new window.SockJS(newUrl);
// }
return socket
},
getSocketUrl: function (template, isWebsocket) {
const hostname = this.getHostName();
const isSecure = this.isSecure();
const protocol = isWebsocket ? (isSecure ? 'wss' : 'ws') : (isSecure ? 'https' : 'http');
const port = this.getPort();
return template.replace('{hostname}', hostname).replace('{protocol}', protocol).replace('{port}', port);
},
isSecure: function () {
return window.location.protocol === 'https:';
},
getHostName: function () {
return window.location.hostname;
},
getPort: function () {
return window.location.port ? (':' + window.location.port) : '';
},
onConnectionSuccess: function () {
console.debug('Websocket === Connection Success');
this.set('isConnected', true);
},
onConnectionError: function (error) {
console.debug('Websocket === Connection Error', error);
return this.reconnect(false)
},
reconnect: function (useSockJS) {
this.set('isConnected', false);
const subscriptions = Object.assign({}, this.get('subscriptions'));
var retryNum = this.get('retryNum')
if (retryNum == 5) {
console.debug('Websocket === retry fail, then goto login.', this.get('retryNum'));
this.disconnect()
this.set('retryNum', 0)
cookie.deleteCookie('WDPSESSIONID', '', -1)
window.location.href = '#/login' // 重连超过五次跳转到登录页面;
return
}
// 同时触发多次重连优化, 模拟锁机制
if (!this.get('isConnected')) {
setTimeout(() => {
if (!this.get('isConnected')) {
this.set('retryNum', retryNum + 1)
console.debug('Websocket === Reconnecting to WebSocket...', this.get('retryNum'));
this.connect(useSockJS).done(() => {
this.set('subscriptions', {});
for (let i in subscriptions) {
this.subscribe(subscriptions[i].destination, subscriptions[i].handlers['default']);
for (let key in subscriptions[i].handlers) {
key !== 'default' && this.addHandler(subscriptions[i].destination, key, subscriptions[i].handlers[key]);
}
}
});
}
}, this.RECONNECT_TIMEOUT);
}
},
disconnect: function () {
this.set('isConnected', false);
if (this.get('client')) this.get('client').disconnect()
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# Services中组件的预览节点数量控制
started_count/total_count
这两个数据是第一次页面加载获取的;updateComponentsState方法 ,App.componentsStateMapper;LiveNodes/DeadNodes
这两个数据是通过定时器时刻只更新数据;updateServiceMetric方法. App.serviceMetricsMapper;
数据获取对应
if (!this.get('initialAppLoad')) {
var parsedCacheServices = App.cache['services'].map(function(item){
App.serviceMetricsMapper.mapExtendedModel(item);
return self.parseIt(item, self.get('config'));
});
parsedCacheServices = misc.sortByOrder(App.StackService.find().mapProperty('serviceName'), parsedCacheServices);
App.store.safeLoadMany(this.get('model'), parsedCacheServices);
this.set('initialAppLoad', true);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
map: function map(json) {
console.time('App.componentsStateMapper execution time');
var clients = [];
var slaves = [];
var masters = [];
var hasNewComponents = false;
var staleConfigHostsMap = App.cache.staleConfigsComponentHosts;
if (json.items) {
if (!App.isEmptyObject(Em.getWithDefault(App, 'cache.services', {}))) {
hasNewComponents = json.items.mapProperty('ServiceComponentInfo.total_count').reduce(Em.sum, 0) > App.cache.services.mapProperty('host_components.length').reduce(Em.sum, 0);
}
json.items.forEach(function (item) {
var cacheService = App.cache['services'].findProperty('ServiceInfo.service_name', item.ServiceComponentInfo.service_name);
item.stale_config_hosts = staleConfigHostsMap[item.ServiceComponentInfo.component_name] || [];
if (item.ServiceComponentInfo.category === 'CLIENT') {
item.host_names = item.host_components.mapProperty('HostRoles.host_name');
clients.push(this.parseIt(item, this.clientMap));
} else if (item.ServiceComponentInfo.category === 'SLAVE') {
// for now map for slaves and clients are equal but it may vary in future.
item.host_names = item.host_components.mapProperty('HostRoles.host_name');
slaves.push(this.parseIt(item, this.clientMap));
} else if (item.ServiceComponentInfo.category === 'MASTER') {
item.host_names = item.host_components.mapProperty('HostRoles.host_name');
masters.push(this.parseIt(item, this.clientMap));
}
if (cacheService) {
cacheService.client_components = clients.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
cacheService.slave_components = slaves.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
cacheService.master_components = masters.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
}
this.mapExtendedModelComponents(item);
}, this);
}
App.store.safeLoadMany(this.clientModel, clients);
App.store.safeLoadMany(this.slaveModel, slaves);
App.store.safeLoadMany(this.masterModel, masters);
if (hasNewComponents) {
App.get('router.clusterController').triggerQuickLinksUpdate();
}
console.timeEnd('App.componentsStateMapper execution time');
},
/**
*
* @param {object} item
*/
mapExtendedModelComponents: function mapExtendedModelComponents(item) {
var serviceName = item.ServiceComponentInfo.service_name;
var service = App.Service.find(serviceName);
var cacheService = App.cache['services'].findProperty('ServiceInfo.service_name', serviceName);
var extendedModel = this.getExtendedModel(serviceName);
var parsedItem = this.parseIt(item, this.getComponentConfig(item.ServiceComponentInfo.component_name));
if (cacheService) {
for (var i in parsedItem) {
if (service.get('isLoaded')) {
cacheService[i] = parsedItem[i];
service.set(stringUtils.underScoreToCamelCase(i), parsedItem[i]);
if (extendedModel && extendedModel.get('isLoaded')) {
extendedModel.set(stringUtils.underScoreToCamelCase(i), parsedItem[i]);
}
}
}
}
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
hdfsMapper: function hdfsMapper(item) {
var _this = this;
var finalConfig = jQuery.extend({}, this.config);
// Change the JSON so that it is easy to map
var hdfsConfig = this.hdfsConfig,
activeNameNodeConfigInitial = Object.keys(this.activeNameNodeConfig).reduce(function (obj, key) {
return Object.assign({}, obj, _defineProperty({}, key, {}));
}, {});
Object.assign(item, activeNameNodeConfigInitial);
item.components.forEach(function (component) {
var hostComponents = component.host_components,
firstHostComponent = hostComponents[0];
if (_this.isHostComponentPresent(component, 'NAMENODE')) {
//enabled HA
if (hostComponents.length > 1) {
var nameSpacesWithActiveNameNodes = [],
unknownNameNodes = [];
item.active_name_nodes = [];
item.standby_name_nodes = [];
hostComponents.forEach(function (hc) {
var haState = Em.get(hc, 'metrics.dfs.FSNamesystem.HAState'),
hostName = Em.get(hc, 'HostRoles.host_name'),
clusterIdValue = Em.get(hc, 'metrics.dfs.namenode.ClusterId'),
id = 'NAMENODE_' + hostName;
switch (haState) {
case 'active':
nameSpacesWithActiveNameNodes.push(clusterIdValue);
item.active_name_nodes.push(id);
break;
case 'standby':
item.standby_name_nodes.push(id);
break;
default:
unknownNameNodes.push({
hostName: hostName,
clusterIdValue: clusterIdValue
});
break;
}
_this.setNameNodeMetricsProperties(item, hc);
});
unknownNameNodes.forEach(function (nameNode) {
if (nameSpacesWithActiveNameNodes.contains(nameNode.clusterIdValue)) {
item.standby_name_nodes.push('NAMENODE_' + nameNode.hostName);
}
});
} else {
_this.setNameNodeMetricsProperties(item, firstHostComponent);
}
item.nameNodeComponent = component;
finalConfig = jQuery.extend(finalConfig, hdfsConfig);
// Get the live, dead & decommission nodes from string json
if (firstHostComponent.metrics && firstHostComponent.metrics.dfs && firstHostComponent.metrics.dfs.namenode) {
item.metrics_not_available = false;
var decommissionNodesJson = App.parseJSON(firstHostComponent.metrics.dfs.namenode.DecomNodes);
var deadNodesJson = App.parseJSON(firstHostComponent.metrics.dfs.namenode.DeadNodes);
var liveNodesJson = App.parseJSON(firstHostComponent.metrics.dfs.namenode.LiveNodes);
} else {
item.metrics_not_available = true;
}
item.decommission_data_nodes = [];
item.dead_data_nodes = [];
item.live_data_nodes = [];
for (var host in decommissionNodesJson) {
item.decommission_data_nodes.push('DATANODE_' + host);
}
for (var _host in deadNodesJson) {
item.dead_data_nodes.push('DATANODE_' + _host);
}
for (var _host2 in liveNodesJson) {
item.live_data_nodes.push('DATANODE_' + _host2);
}
item.name_node_id = 'NAMENODE_' + firstHostComponent.HostRoles.host_name;
}
if (_this.isHostComponentPresent(component, 'JOURNALNODE')) {
item.journal_nodes = hostComponents.map(function (hc) {
return 'JOURNALNODE_' + hc.HostRoles.host_name;
});
}
if (_this.isHostComponentPresent(component, 'SECONDARY_NAMENODE')) {
item.sname_node_id = 'SECONDARY_NAMENODE_' + firstHostComponent.HostRoles.host_name;
}
});
// Map
var finalJson = this.parseIt(item, finalConfig);
finalJson.quick_links = [1, 2, 3, 4];
return finalJson;
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
解决
有一种情况是,socket断掉后,回导致发送多条数据,数据重复;控制更新范围,越界后,重新reload更新数据;
updateComponentCountOnStateChange: function(componentState) {
const model = App.ClientComponent.getModelByComponentName(componentState.componentName);
const acceptedStates = ['STARTED', 'INSTALLED', 'INIT', 'UNKNOWN', 'INSTALL_FAILED'];
if (model && model.get('isLoaded') && componentState.currentState) {
if (acceptedStates.contains(componentState.previousState)) {
const previousStateProp = this.statusToProperty(componentState.previousState);
let totalCount = model.get('totalCount')
let stateCount = model.get(previousStateProp) - 1
// if(stateCount < 0 ) stateCount = 0
// if(stateCount > totalCount ) stateCount = totalCount
if(!(stateCount >=0 && stateCount <= totalCount)) {
window.location.reload()
return
}
model.set(previousStateProp, stateCount);
}
if (acceptedStates.contains(componentState.currentState)) {
const currentStateProp = this.statusToProperty(componentState.currentState);
let totalCount = model.get('totalCount')
let stateCount = model.get(currentStateProp) + 1
if(!(stateCount >=0 && stateCount <= totalCount)) {
window.location.reload()
return
}
model.set(currentStateProp, stateCount);
}
this.mapExtendedModelComponents(this.componentStateToJSON(model));
}
},
/**
* @param {object} componentState
*/
updateComponentCountOnDelete: function(componentState) {
const model = App.ClientComponent.getModelByComponentName(componentState.componentName);
const acceptedStates = ['STARTED', 'INSTALLED', 'INIT', 'UNKNOWN', 'INSTALL_FAILED'];
if (model) {
model.set('totalCount', model.get('totalCount') - 1);
if (acceptedStates.contains(componentState.lastComponentState)) {
const currentStateProp = this.statusToProperty(componentState.lastComponentState);
let totalCount = model.get('totalCount')
let stateCount = model.get(currentStateProp) - 1
if(!(stateCount >=0 && stateCount <= totalCount)) {
window.location.reload()
return
}
model.set(currentStateProp, stateCount);
}
this.mapExtendedModelComponents(this.componentStateToJSON(model));
}
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# table等相关样式
# 结合admin添加定制菜单
# 内置使用vue
上次更新: 2023/11/17, 05:08:19