Best JavaScript code snippet using cypress
cluster_app_server_list.js
Source: cluster_app_server_list.js 
1var app = angular.module('sentinelDashboardApp');2app.controller('SentinelClusterAppServerListController', ['$scope', '$stateParams', 'ngDialog',3    'MachineService', 'ClusterStateService',4    function ($scope, $stateParams, ngDialog, MachineService, ClusterStateService) {5        $scope.app = $stateParams.app;6        const UNSUPPORTED_CODE = 4041;7        const CLUSTER_MODE_CLIENT = 0;8        const CLUSTER_MODE_SERVER = 1;9        const DEFAULT_CLUSTER_SERVER_PORT = 18730;10        const DEFAULT_NAMESPACE = 'default';11        const DEFAULT_MAX_ALLOWED_QPS = 20000;12        // tmp for dialog temporary data.13        $scope.tmp = {14            curClientChosen: [],15            curRemainingClientChosen: [],16            curChosenServer: {},17        };18        $scope.remainingMachineList = [];19        function convertSetToString(set) {20            if (set === undefined) {21                return '';22            }23            if (set.length === 1 && set[0] === DEFAULT_NAMESPACE) {24                return DEFAULT_NAMESPACE;25            }26            let s = '';27            for (let i = 0; i < set.length; i++) {28                let ns = set[i];29                if (ns !== DEFAULT_NAMESPACE) {30                    s = s + ns;31                    if (i < set.length - 1) {32                        s = s + ',';33                    }34                }35            }36            return s;37        }38        function convertStrToNamespaceSet(str) {39            if (str === undefined || str === '') {40                return [];41            }42            let arr = [];43            let spliced = str.split(',');44            spliced.forEach((v) => {45                arr.push(v.trim());46            });47            return arr;48        }49        function processAppSingleData(data) {50            if (data.state.server && data.state.server.namespaceSet) {51                data.state.server.namespaceSetStr = convertSetToString(data.state.server.namespaceSet);52                data.mode = data.state.stateInfo.mode;53            }54        }55        function removeFromArr(arr, v) {56            for (let i = 0; i < arr.length; i++) {57                if (arr[i] === v) {58                    arr.splice(i, 1);59                    break;60                }61            }62        }63        function removeFromArrIf(arr, f) {64            for (let i = 0; i < arr.length; i++) {65                if (f(arr[i]) === true) {66                    arr.splice(i, 1);67                    break;68                }69            }70        }71        function resetAssignDialogChosen() {72            $scope.tmp.curClientChosen = [];73            $scope.tmp.curRemainingClientChosen = [];74        }75        function generateMachineId(e) {76            return e.ip + '@' + e.commandPort;77        }78        function applyClusterMap(appClusterMachineList) {79            if (!appClusterMachineList) {80                return;81            }82            let tmpMap = new Map();83            let serverCommandPortMap = new Map();84            $scope.clusterMap = [];85            $scope.remainingMachineList = [];86            let tmpServerList = [];87            let tmpClientList = [];88            appClusterMachineList.forEach((e) => {89                if (e.mode === CLUSTER_MODE_CLIENT) {90                    tmpClientList.push(e);91                } else if (e.mode === CLUSTER_MODE_SERVER) {92                    tmpServerList.push(e);93                } else {94                    $scope.remainingMachineList.push(generateMachineId(e));95                }96            });97            tmpServerList.forEach((e) => {98                let ip = e.ip;99                let machineId = ip + '@' + e.commandPort;100                let group = {101                    ip: ip,102                    machineId: machineId,103                    port: e.state.server.port,104                    clientSet: [],105                    namespaceSetStr: e.state.server.namespaceSetStr,106                    maxAllowedQps: e.state.server.flow.maxAllowedQps,107                    belongToApp: true,108                };109                if (!tmpMap.has(machineId)) {110                    tmpMap.set(machineId, group);111                }112                serverCommandPortMap.set(ip + ':' + e.state.server.port, e.commandPort);113            });114            tmpClientList.forEach((e) => {115                let ip = e.ip;116                let machineId = ip + '@' + e.commandPort;117                let targetServer = e.state.client.clientConfig.serverHost;118                let targetPort = e.state.client.clientConfig.serverPort;119                if (targetServer === undefined || targetServer === '' ||120                    targetPort === undefined || targetPort <= 0) {121                    $scope.remainingMachineList.push(generateMachineId(e));122                    return;123                }124                let serverHostPort = targetServer + ':' + targetPort;125                if (serverCommandPortMap.has(serverHostPort)) {126                    let serverCommandPort = serverCommandPortMap.get(serverHostPort);127                    let g;128                    if (serverCommandPort < 0) {129                        // Not belong to this app.130                        g = tmpMap.get(serverHostPort);131                    } else {132                        // Belong to this app.133                        g = tmpMap.get(targetServer + '@' + serverCommandPort);134                    }135                    g.clientSet.push(machineId);136                } else {137                    let group = {138                        ip: targetServer,139                        machineId: serverHostPort,140                        port: targetPort,141                        clientSet: [machineId],142                        belongToApp: false,143                    };144                    tmpMap.set(serverHostPort, group);145                    // Indicates that it's not belonging to current app.146                    serverCommandPortMap.set(serverHostPort, -1);147                }148                // if (!tmpMap.has(serverHostPort)) {149                //     let group = {150                //         ip: targetServer,151                //         machineId: targetServer,152                //         port: targetPort,153                //         clientSet: [machineId],154                //         belongToApp: false,155                //     };156                //     tmpMap.set(targetServer, group);157                // } else {158                //     let g = tmpMap.get(targetServer);159                //     g.clientSet.push(machineId);160                // }161            });162            tmpMap.forEach((v) => {163                if (v !== undefined) {164                    $scope.clusterMap.push(v);165                }166            });167        }168        $scope.notChosenServer = (id) => {169            return id !== $scope.serverAssignDialogData.serverData.currentServer;170        };171        $scope.onCurrentServerChange = () => {172            resetAssignDialogChosen();173        };174        $scope.moveToServerGroup = () => {175            $scope.tmp.curRemainingClientChosen.forEach(e => {176                $scope.serverAssignDialogData.serverData.clientSet.push(e);177                removeFromArr($scope.remainingMachineList, e);178            });179            resetAssignDialogChosen();180        };181        $scope.moveToRemainingSharePool = () => {182            $scope.tmp.curClientChosen.forEach(e => {183                $scope.remainingMachineList.push(e);184                removeFromArr($scope.serverAssignDialogData.serverData.clientSet, e);185            });186            resetAssignDialogChosen();187        };188        function parseIpFromMachineId(machineId) {189            if (machineId.indexOf(':') !== -1) {190                return machineId.split(':')[0];191            }192            if (machineId.indexOf('@') === -1) {193                return machineId;194            }195            let arr = machineId.split('@');196            return arr[0];197        }198        function retrieveClusterAssignInfoOfApp() {199            ClusterStateService.fetchClusterUniversalStateOfApp($scope.app).success(function (data) {200                if (data.code === 0 && data.data) {201                    $scope.loadError = undefined;202                    $scope.appClusterMachineList = data.data;203                    $scope.appClusterMachineList.forEach(processAppSingleData);204                    applyClusterMap($scope.appClusterMachineList);205                } else {206                    $scope.appClusterMachineList = {};207                    if (data.code === UNSUPPORTED_CODE) {208                        $scope.loadError = {message: '该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã'}209                    } else {210                        $scope.loadError = {message: data.msg};211                    }212                }213            }).error(() => {214                $scope.loadError = {message: 'æªç¥é误'};215            });216        }217        $scope.newServerDialog = () => {218            retrieveClusterAssignInfoOfApp();219            $scope.serverAssignDialogData = {220                title: 'æ°å¢ Token Server',221                type: 'add',222                confirmBtnText: 'ä¿å',223                serverData: {224                    serverType: 0,225                    clientSet: [],226                    serverPort: DEFAULT_CLUSTER_SERVER_PORT,227                    maxAllowedQps: DEFAULT_MAX_ALLOWED_QPS,228                }229            };230            $scope.serverAssignDialog = ngDialog.open({231                template: '/app/views/dialog/cluster/cluster-server-assign-dialog.html',232                width: 1000,233                overlay: true,234                scope: $scope235            });236        };237        $scope.modifyServerAssignConfig = (serverVO) => {238            let id = serverVO.id;239            ClusterStateService.fetchClusterUniversalStateOfApp($scope.app).success(function (data) {240                if (data.code === 0 && data.data) {241                    $scope.loadError = undefined;242                    $scope.appClusterMachineList = data.data;243                    $scope.appClusterMachineList.forEach(processAppSingleData);244                    applyClusterMap($scope.appClusterMachineList);245                    let clusterMap = $scope.clusterMap;246                    let d;247                    for (let i = 0; i < clusterMap.length; i++) {248                        if (clusterMap[i].machineId === id) {249                            d = clusterMap[i];250                        }251                    }252                    if (!d) {253                        alert('ç¶æé误');254                        return;255                    }256                    $scope.serverAssignDialogData = {257                        title: 'Token Server åé
ç¼è¾',258                        type: 'edit',259                        confirmBtnText: 'ä¿å',260                        serverData: {261                            currentServer: d.machineId,262                            belongToApp: serverVO.belongToApp,263                            serverPort: d.port,264                            clientSet: d.clientSet,265                        }266                    };267                    if (d.maxAllowedQps !== undefined) {268                        $scope.serverAssignDialogData.serverData.maxAllowedQps = d.maxAllowedQps;269                    }270                    $scope.serverAssignDialog = ngDialog.open({271                        template: '/app/views/dialog/cluster/cluster-server-assign-dialog.html',272                        width: 1000,273                        overlay: true,274                        scope: $scope275                    });276                } else {277                    if (data.code === UNSUPPORTED_CODE) {278                        $scope.loadError = {message: '该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã'}279                    } else {280                        $scope.loadError = {message: data.msg};281                    }282                }283            }).error(() => {284                $scope.loadError = {message: 'æªç¥é误'};285            });286        };287        function getRemainingMachineList() {288            return $scope.remainingMachineList.filter((e) => $scope.notChosenServer(e));289        }290        function doApplyNewSingleServerAssign() {291            let ok = confirm('æ¯å¦ç¡®è®¤æ§è¡åæ´ï¼');292            if (!ok) {293                return;294            }295            let serverData = $scope.serverAssignDialogData.serverData;296            let belongToApp = serverData.serverType == 0; // don't modify here!297            let machineId = serverData.currentServer;298            let request = {299                clusterMap: {300                    machineId: machineId,301                    ip: parseIpFromMachineId(machineId),302                    port: serverData.serverPort,303                    clientSet: serverData.clientSet,304                    belongToApp: belongToApp,305                    maxAllowedQps: serverData.maxAllowedQps,306                },307                remainingList: getRemainingMachineList(),308            };309            ClusterStateService.applyClusterSingleServerAssignOfApp($scope.app, request).success((data) => {310                if (data.code === 0 && data.data) {311                    let failedServerSet = data.data.failedServerSet;312                    let failedClientSet = data.data.failedClientSet;313                    if (failedClientSet.length === 0 && failedServerSet.length === 0) {314                        alert('å
¨é¨æ¨éæå');315                    } else {316                        let failedSet = [];317                        if (failedServerSet) {318                            failedServerSet.forEach((e) => {319                                failedSet.push(e);320                            });321                        }322                        if (failedClientSet) {323                            failedClientSet.forEach((e) => {324                                failedSet.push(e);325                            });326                        }327                        alert('æ¨é宿¯ã失败æºå¨å表ï¼' + JSON.stringify(failedSet));328                    }329                    location.reload();330                } else {331                    if (data.code === UNSUPPORTED_CODE) {332                        alert('该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã');333                    } else {334                        alert('æ¨é失败ï¼' + data.msg);335                    }336                }337            }).error(() => {338                alert('æªç¥é误');339            });340        }341        function doApplySingleServerAssignEdit() {342            let ok = confirm('æ¯å¦ç¡®è®¤æ§è¡åæ´ï¼');343            if (!ok) {344                return;345            }346            let serverData = $scope.serverAssignDialogData.serverData;347            let machineId = serverData.currentServer;348            let request = {349                clusterMap: {350                    machineId: machineId,351                    ip: parseIpFromMachineId(machineId),352                    port: serverData.serverPort,353                    clientSet: serverData.clientSet,354                    belongToApp: serverData.belongToApp,355                },356                remainingList: $scope.remainingMachineList,357            };358            if (serverData.maxAllowedQps !== undefined) {359                request.clusterMap.maxAllowedQps = serverData.maxAllowedQps;360            }361            ClusterStateService.applyClusterSingleServerAssignOfApp($scope.app, request).success((data) => {362                if (data.code === 0 && data.data) {363                    let failedServerSet = data.data.failedServerSet;364                    let failedClientSet = data.data.failedClientSet;365                    if (failedClientSet.length === 0 && failedServerSet.length === 0) {366                        alert('å
¨é¨æ¨éæå');367                    } else {368                        let failedSet = [];369                        failedServerSet.forEach(failedSet.push);370                        failedClientSet.forEach(failedSet.push);371                        alert('æ¨é宿¯ã失败æºå¨å表ï¼' + JSON.stringify(failedSet));372                    }373                    location.reload();374                } else {375                    if (data.code === UNSUPPORTED_CODE) {376                        alert('该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã');377                    } else {378                        alert('æ¨é失败ï¼' + data.msg);379                    }380                }381            }).error(() => {382                alert('æªç¥é误');383            });384        }385        $scope.saveAssignForDialog = () => {386            if (!checkAssignDialogValid()) {387                return;388            }389            if ($scope.serverAssignDialogData.type === 'add') {390                doApplyNewSingleServerAssign();391            } else if ($scope.serverAssignDialogData.type === 'edit') {392                doApplySingleServerAssignEdit();393            } else {394                alert('æªç¥çæä½');395            }396        };397        function checkAssignDialogValid() {398            let serverData = $scope.serverAssignDialogData.serverData;399            if (serverData.currentServer === undefined || serverData.currentServer === '') {400                alert('请æå®ææç Token Server');401                return false;402            }403            if (serverData.serverPort === undefined || serverData.serverPort <= 0 || serverData.serverPort > 65535) {404                alert('请è¾å
¥åæ³ç端å£å¼');405                return false;406            }407            if (serverData.maxAllowedQps !== undefined && serverData.maxAllowedQps < 0) {408                alert('请è¾å
¥åæ³çæå¤§å
许 QPS');409                return false;410            }411            return true;412        }413        $scope.viewConnectionDetail = (serverVO) => {414            $scope.connectionDetailDialogData = {415                serverData: serverVO416            };417            $scope.connectionDetailDialog = ngDialog.open({418                template: '/app/views/dialog/cluster/cluster-server-connection-detail-dialog.html',419                width: 700,420                overlay: true,421                scope: $scope422            });423        };424        function generateRequestLimitDataStr(limitData) {425            if (limitData.length === 1 && limitData[0].namespace === DEFAULT_NAMESPACE) {426                 return 'default: ' + limitData[0].currentQps + ' / ' + limitData[0].maxAllowedQps;427            }428            for (let i = 0; i < limitData.length; i++) {429                let crl = limitData[i];430                if (crl.namespace === $scope.app) {431                    return '' + crl.currentQps + ' / ' + crl.maxAllowedQps;432                }433            }434            return '0';435        }436        function processServerListData(serverVO) {437            if (serverVO.state && serverVO.state.namespaceSet) {438                serverVO.state.namespaceSetStr = convertSetToString(serverVO.state.namespaceSet);439            }440            if (serverVO.state && serverVO.state.requestLimitData) {441                serverVO.state.requestLimitDataStr = generateRequestLimitDataStr(serverVO.state.requestLimitData);442            }443        }444        $scope.generateConnectionSet = (data) => {445            let connectionSet = data;446            let s = '';447            if (connectionSet) {448                s = s + '[';449                for (let i = 0; i < connectionSet.length; i++) {450                    s = s + connectionSet[i].address;451                    if (i < connectionSet.length - 1) {452                        s = s + ', ';453                    }454                }455                s = s + ']';456            } else {457                s = '[]';458            }459            return s;460        };461        function retrieveClusterServerInfo() {462            ClusterStateService.fetchClusterServerStateOfApp($scope.app).success(function (data) {463                if (data.code === 0 && data.data) {464                    $scope.loadError = undefined;465                    $scope.serverVOList = data.data;466                    $scope.serverVOList.forEach(processServerListData);467                } else {468                    $scope.serverVOList = {};469                    if (data.code === UNSUPPORTED_CODE) {470                        $scope.loadError = {message: '该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã'}471                    } else {472                        $scope.loadError = {message: data.msg};473                    }474                }475            }).error(() => {476                $scope.loadError = {message: 'æªç¥é误'};477            });478        }479        retrieveClusterServerInfo();480        let confirmUnbindServerDialog;481        $scope.unbindServer = (id) => {482            $scope.pendingUnbindIds = [id];483            $scope.confirmDialog = {484                title: 'ç§»é¤ Token Server',485                type: 'unbind_token_server',486                attentionTitle: '请确认æ¯å¦ç§»é¤ä»¥ä¸ Token Serverï¼è¯¥ server ä¸ç client ä¹ä¼è§£é¤åé
ï¼',487                attention: id + '',488                confirmBtnText: 'ç§»é¤',489            };490            confirmUnbindServerDialog = ngDialog.open({491                template: '/app/views/dialog/confirm-dialog.html',492                scope: $scope,493                overlay: true494            });495        };496        function apiUnbindServerAssign(ids) {497            ClusterStateService.applyClusterServerBatchUnbind($scope.app, ids).success((data) => {498                if (data.code === 0 && data.data) {499                    let failedServerSet = data.data.failedServerSet;500                    let failedClientSet = data.data.failedClientSet;501                    if (failedClientSet.length === 0 && failedServerSet.length === 0) {502                        alert('æå');503                    } else {504                        alert('æä½æ¨é宿¯ï¼é¨å失败æºå¨å表ï¼' + JSON.stringify(failedClientSet));505                    }506                    location.reload();507                } else {508                    if (data.code === UNSUPPORTED_CODE) {509                        alert('该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã');510                    } else {511                        alert('æ¨é失败ï¼' + data.msg);512                    }513                }514            }).error(() => {515                alert('æªç¥é误');516            });517            // confirmUnbindServerDialog.close();518        }519        // Confirm function for confirm dialog.520        $scope.confirm = () => {521            if ($scope.confirmDialog.type === 'unbind_token_server') {522                apiUnbindServerAssign($scope.pendingUnbindIds);523            } else {524                console.error('Error dialog when unbinding token server');525            }526        };...machines.js
Source: machines.js 
1/**2 * This module contains Redux bits for loading tenancy external ips.3 */4import { merge, map } from 'rxjs/operators';5import { combineEpics, ofType } from 'redux-observable';6import { createTenancyResource, nextStateEntry } from './resource';7import { actions as externalIpActions } from './external-ips';8const {9    actions: resourceActions,10    actionCreators: resourceActionCreators,11    reducer: resourceReducer,12    epic: resourceEpic13} = createTenancyResource('machine', {14    isActive: machine => (['BUILD', 'DELETED'].includes(machine.status.type) || !!machine.task),15    // Just convert the string date to a Date object16    transform: machine =>17        machine.hasOwnProperty('created') ?18            { ...machine, created: new Date(machine.created) } :19            machine20});21export const actions = {22    ...resourceActions,23    FETCH_LOGS: 'TENANCIES/MACHINE/FETCH_LOGS',24    FETCH_LOGS_SUCCEEDED: 'TENANCIES/MACHINE/FETCH_LOGS_SUCCEEDED',25    FETCH_LOGS_FAILED: 'TENANCIES/MACHINE/FETCH_LOGS_FAILED',26    FETCH_FIREWALL_RULES: 'TENANCIES/MACHINE/FETCH_FIREWALL_RULES',27    FETCH_FIREWALL_RULES_SUCCEEDED: 'TENANCIES/MACHINE/FETCH_FIREWALL_RULES_SUCCEEDED',28    FETCH_FIREWALL_RULES_FAILED: 'TENANCIES/MACHINE/FETCH_FIREWALL_RULES_FAILED',29    ADD_FIREWALL_RULE: 'TENANCIES/MACHINE/ADD_FIREWALL_RULE',30    ADD_FIREWALL_RULE_SUCCEEDED: 'TENANCIES/MACHINE/ADD_FIREWALL_RULE_SUCCEEDED',31    ADD_FIREWALL_RULE_FAILED: 'TENANCIES/MACHINE/ADD_FIREWALL_RULE_FAILED',32    REMOVE_FIREWALL_RULE: 'TENANCIES/MACHINE/REMOVE_FIREWALL_RULE',33    REMOVE_FIREWALL_RULE_SUCCEEDED: 'TENANCIES/MACHINE/REMOVE_FIREWALL_RULE_SUCCEEDED',34    REMOVE_FIREWALL_RULE_FAILED: 'TENANCIES/MACHINE/REMOVE_FIREWALL_RULE_FAILED',35    START: 'TENANCIES/MACHINE/START',36    START_SUCCEEDED: 'TENANCIES/MACHINE/START_SUCCEEDED',37    START_FAILED: 'TENANCIES/MACHINE/START_FAILED',38    STOP: 'TENANCIES/MACHINE/STOP',39    STOP_SUCCEEDED: 'TENANCIES/MACHINE/STOP_SUCCEEDED',40    STOP_FAILED: 'TENANCIES/MACHINE/STOP_FAILED',41    RESTART: 'TENANCIES/MACHINE/RESTART',42    RESTART_SUCCEEDED: 'TENANCIES/MACHINE/RESTART_SUCCEEDED',43    RESTART_FAILED: 'TENANCIES/MACHINE/RESTART_FAILED',44};45export const actionCreators = {46    ...resourceActionCreators,47    fetchLogs: (tenancyId, machineId) => ({48        type: actions.FETCH_LOGS,49        tenancyId,50        machineId,51        apiRequest: true,52        // All errors are reported via the modal UI53        failSilently: true,54        successAction: actions.FETCH_LOGS_SUCCEEDED,55        failureAction: actions.FETCH_LOGS_FAILED,56        options: {57            url: `/api/tenancies/${tenancyId}/machines/${machineId}/logs/`,58            method: 'GET'59        }60    }),61    fetchFirewallRules: (tenancyId, machineId) => ({62        type: actions.FETCH_FIREWALL_RULES,63        tenancyId,64        machineId,65        apiRequest: true,66        // All errors are reported via the modal UI67        failSilently: true,68        successAction: actions.FETCH_FIREWALL_RULES_SUCCEEDED,69        failureAction: actions.FETCH_FIREWALL_RULES_FAILED,70        options: {71            url: `/api/tenancies/${tenancyId}/machines/${machineId}/firewall_rules/`,72            method: 'GET'73        }74    }),75    addFirewallRule: (tenancyId, machineId, data) => ({76        type: actions.ADD_FIREWALL_RULE,77        tenancyId,78        machineId,79        apiRequest: true,80        successAction: actions.ADD_FIREWALL_RULE_SUCCEEDED,81        failureAction: actions.ADD_FIREWALL_RULE_FAILED,82        options: {83            url: `/api/tenancies/${tenancyId}/machines/${machineId}/firewall_rules/`,84            method: 'POST',85            body: data || {}86        }87    }),88    removeFirewallRule: (tenancyId, machineId, ruleId) => ({89        type: actions.REMOVE_FIREWALL_RULE,90        tenancyId,91        machineId,92        ruleId,93        apiRequest: true,94        successAction: actions.REMOVE_FIREWALL_RULE_SUCCEEDED,95        failureAction: actions.REMOVE_FIREWALL_RULE_FAILED,96        options: {97            url: `/api/tenancies/${tenancyId}/machines/${machineId}/firewall_rules/${ruleId}/`,98            method: 'DELETE'99        }100    }),101    start: (tenancyId, machineId) => ({102        type: actions.START,103        tenancyId,104        machineId,105        apiRequest: true,106        successAction: actions.START_SUCCEEDED,107        failureAction: actions.START_FAILED,108        options: {109            url: `/api/tenancies/${tenancyId}/machines/${machineId}/start/`,110            method: 'POST'111        }112    }),113    stop: (tenancyId, machineId) => ({114        type: actions.STOP,115        tenancyId,116        machineId,117        apiRequest: true,118        successAction: actions.STOP_SUCCEEDED,119        failureAction: actions.STOP_FAILED,120        options: {121            url: `/api/tenancies/${tenancyId}/machines/${machineId}/stop/`,122            method: 'POST'123        }124    }),125    restart: (tenancyId, machineId) => ({126        type: actions.RESTART,127        tenancyId,128        machineId,129        apiRequest: true,130        successAction: actions.RESTART_SUCCEEDED,131        failureAction: actions.RESTART_FAILED,132        options: {133            url: `/api/tenancies/${tenancyId}/machines/${machineId}/restart/`,134            method: 'POST'135        }136    })137};138export function reducer(state, action) {139    switch(action.type) {140        case actions.FETCH_LOGS:141            // Only register the fetch if we know about the machine142            if( state.data.hasOwnProperty(action.machineId) )143                return {144                    ...state,145                    data: Object.assign(146                        {},147                        state.data,148                        nextStateEntry(149                            state,150                            action.machineId,151                            { fetchingLogs: true }152                        )153                    ),154                };155            else156                return state;157        case actions.FETCH_LOGS_SUCCEEDED:158            // Only store the logs if we already know about the machine159            if( state.data.hasOwnProperty(action.request.machineId) )160                return {161                    ...state,162                    data: Object.assign(163                        {},164                        state.data,165                        nextStateEntry(166                            state,167                            action.request.machineId,168                            {169                                logs: action.payload.logs,170                                fetchingLogs: false,171                                fetchLogsError: undefined172                            }173                        )174                    ),175                };176            else177                return state;178        case actions.FETCH_LOGS_FAILED:179            // Only store the error if we already know about the machine180            if( state.data.hasOwnProperty(action.request.machineId) )181                return {182                    ...state,183                    data: Object.assign(184                        {},185                        state.data,186                        nextStateEntry(187                            state,188                            action.request.machineId,189                            { fetchLogsError: action.payload, fetchingLogs: false }190                        )191                    ),192                };193            else194                return state;195        case actions.FETCH_FIREWALL_RULES:196            // Only register the fetch if we know about the machine197            if( state.data.hasOwnProperty(action.machineId) )198                return {199                    ...state,200                    data: Object.assign(201                        {},202                        state.data,203                        nextStateEntry(204                            state,205                            action.machineId,206                            { fetchingFirewallRules: true }207                        )208                    ),209                };210            else211                return state;212        case actions.FETCH_FIREWALL_RULES_SUCCEEDED:213            // Only store the logs if we already know about the machine214            if( state.data.hasOwnProperty(action.request.machineId) )215                return {216                    ...state,217                    data: Object.assign(218                        {},219                        state.data,220                        nextStateEntry(221                            state,222                            action.request.machineId,223                            {224                                firewallRules: action.payload,225                                fetchingFirewallRules: false,226                                fetchFirewallRulesError: undefined227                            }228                        )229                    ),230                };231            else232                return state;233        case actions.FETCH_FIREWALL_RULES_FAILED:234            // Only store the error if we already know about the machine235            if( state.data.hasOwnProperty(action.request.machineId) )236                return {237                    ...state,238                    data: Object.assign(239                        {},240                        state.data,241                        nextStateEntry(242                            state,243                            action.request.machineId,244                            {245                                fetchFirewallRulesError: action.payload,246                                fetchingFirewallRules: false247                            }248                        )249                    ),250                };251            else252                return state;253        case actions.ADD_FIREWALL_RULE:254            // Only register the fetch if we know about the machine255            if( state.data.hasOwnProperty(action.machineId) )256                return {257                    ...state,258                    data: Object.assign(259                        {},260                        state.data,261                        nextStateEntry(262                            state,263                            action.machineId,264                            { addingFirewallRule: true }265                        )266                    ),267                };268            else269                return state;270        case actions.ADD_FIREWALL_RULE_SUCCEEDED:271            // Only store the logs if we already know about the machine272            if( state.data.hasOwnProperty(action.request.machineId) )273                return {274                    ...state,275                    data: Object.assign(276                        {},277                        state.data,278                        nextStateEntry(279                            state,280                            action.request.machineId,281                            {282                                firewallRules: action.payload,283                                addingFirewallRule: false284                            }285                        )286                    ),287                };288            else289                return state;290        case actions.ADD_FIREWALL_RULE_FAILED:291            // Only store the error if we already know about the machine292            if( state.data.hasOwnProperty(action.request.machineId) )293                return {294                    ...state,295                    data: Object.assign(296                        {},297                        state.data,298                        nextStateEntry(299                            state,300                            action.request.machineId,301                            { addingFirewallRule: false }302                        )303                    ),304                };305            else306                return state;307        case actions.REMOVE_FIREWALL_RULE:308            // Only register the fetch if we know about the machine309            if( state.data.hasOwnProperty(action.machineId) )310                return {311                    ...state,312                    data: Object.assign(313                        {},314                        state.data,315                        nextStateEntry(316                            state,317                            action.machineId,318                            { removingFirewallRule: action.ruleId }319                        )320                    ),321                };322            else323                return state;324        case actions.REMOVE_FIREWALL_RULE_SUCCEEDED:325            // Only store the logs if we already know about the machine326            if( state.data.hasOwnProperty(action.request.machineId) )327                return {328                    ...state,329                    data: Object.assign(330                        {},331                        state.data,332                        nextStateEntry(333                            state,334                            action.request.machineId,335                            {336                                firewallRules: action.payload,337                                removingFirewallRule: undefined338                            }339                        )340                    ),341                };342            else343                return state;344        case actions.REMOVE_FIREWALL_RULE_FAILED:345            // Only store the error if we already know about the machine346            if( state.data.hasOwnProperty(action.request.machineId) )347                return {348                    ...state,349                    data: Object.assign(350                        {},351                        state.data,352                        nextStateEntry(353                            state,354                            action.request.machineId,355                            { removingFirewallRule: undefined }356                        )357                    ),358                };359            else360                return state;361        case actions.START:362        case actions.STOP:363        case actions.RESTART:364            // Only set the updating flag to true if we know about the machine365            if( state.data.hasOwnProperty(action.machineId) )366                return {367                    ...state,368                    data: Object.assign(369                        {},370                        state.data,371                        nextStateEntry(372                            state,373                            action.machineId,374                            { updating: true }375                        )376                    ),377                };378            else379                return state;380        case actions.START_SUCCEEDED:381        case actions.STOP_SUCCEEDED:382        case actions.RESTART_SUCCEEDED:383            // The updated machine is in the payload, so merge it384            return {385                ...state,386                data: Object.assign(387                    {},388                    state.data,389                    nextStateEntry(390                        state,391                        action.payload.id,392                        { ...action.payload, updating: false }393                    )394                ),395            };396        case actions.START_FAILED:397        case actions.STOP_FAILED:398        case actions.RESTART_FAILED:399            // Only set the updating flag to false if we know about the machine400            if( state.data.hasOwnProperty(action.request.machineId) )401                return {402                    ...state,403                    data: Object.assign(404                        {},405                        state.data,406                        nextStateEntry(407                            state,408                            action.request.machineId,409                            { updating: false }410                        )411                    ),412                };413            else414                return state;415        // When an external IP is being updated to set the machine ID, mark416        // that machine as updating417        case externalIpActions.UPDATE:418            if( state.data.hasOwnProperty(action.options.body.machine_id) )419                return {420                    ...state,421                    data: Object.assign(422                        {},423                        state.data,424                        nextStateEntry(425                            state,426                            action.options.body.machine_id,427                            { updating: true }428                        )429                    ),430                };431            else432                return state;433        case externalIpActions.UPDATE_SUCCEEDED:434        case externalIpActions.UPDATE_FAILED:435            if( state.data.hasOwnProperty(action.request.options.body.machine_id) )436                return {437                    ...state,438                    data: Object.assign(439                        {},440                        state.data,441                        nextStateEntry(442                            state,443                            action.request.options.body.machine_id,444                            { updating: false }445                        )446                    ),447                };448            else449                return state;450        default:451            // Any other actions, apply the resource reducer452            return resourceReducer(state, action);453    }454}455export const epic = combineEpics(456    resourceEpic,457    // When a power action takes place on a machine, refresh the machine458    action$ => action$.pipe(459        ofType(actions.START_SUCCEEDED),460        merge(action$.pipe(ofType(actions.STOP_SUCCEEDED))),461        merge(action$.pipe(ofType(actions.RESTART_SUCCEEDED))),462        map(action =>463            actionCreators.fetchOne(action.request.tenancyId, action.payload.id)464        )465    )...datamediator.js
Source: datamediator.js 
1/**2 * @fileOverview Deferred data loader / cacher singleton. Provides vboxDataMediator3 * @author Ian Moore (imoore76 at yahoo dot com)4 * @version $Id: datamediator.js 591 2015-04-11 22:40:47Z imoore76 $5 * @copyright Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com)6 */78/**9 * vboxVMDataMediator10 * 11 * @see jQuery.deferred12 * @namespace vboxVMDataMediator13 */14var vboxVMDataMediator = {15	16	/* Promises for data */17	promises : {18		'getVMDetails':{},19		'getVMRuntimeData':{}20	},21	22	/* Holds Basic VM data */23	vmData : null,24	25	/* Holds VM details */26	vmDetailsData : {},27	28	/* Holds VM runtime data */29	vmRuntimeData : {},30		31	/* Expire cached promise / data */32	expireVMDetails: function(vmid) {33		vboxVMDataMediator.promises.getVMDetails[vmid] = null;34		vboxVMDataMediator.vmDetailsData[vmid] = null;35	},36	expireVMRuntimeData: function(vmid) {37		vboxVMDataMediator.promises.getVMRuntimeData[vmid] = null;38		vboxVMDataMediator.vmRuntimeData[vmid] = null;39	},40	expireAll: function() {41		for(var i in vboxVMDataMediator.promises) {42			if(typeof(i) != 'string') continue;43			vboxVMDataMediator.promises[i] = {};44		}45		vboxVMDataMediator.vmData = null;46		vboxVMDataMediator.vmRuntimeData = {};47		vboxVMDataMediator.vmDetailsData = {};48	},49	50	/**51	 * Get basic vm data52	 * 53	 * @param vmid {String} ID of VM54	 * @returns {Object} vm data55	 */56	getVMData: function(vmid) {57		58		// VMList must exist59		if(!vboxVMDataMediator.vmData) {60			return;61		}62		63		return vboxVMDataMediator.vmData[vmid];64		65	},66	67	/**68	 * Return list of machines, subscribe to running VM events69	 * and start the event listener70	 * 71	 * @returns {Object} promise72	 */73	getVMList: function() {74	75		// Return array from existing data76		if(vboxVMDataMediator.vmData) {77			var list = [];78			for(var i in vboxVMDataMediator.vmData) {79				if(typeof i != 'string') continue;80				if(i == 'host') continue;81				list.push(vboxVMDataMediator.vmData[i]);82			}83			return list;84		}85		86		87		var mList = $.Deferred();88		$.when(vboxAjaxRequest('vboxGetMachines')).done(function(d) {89			90			var vmData = {};91			var subscribeList = [];9293			for(var i = 0; i < d.responseData.length; i++) {94				95				// Enforce VM ownership96			    if($('#vboxPane').data('vboxConfig').enforceVMOwnership && !$('#vboxPane').data('vboxSession').admin && d.vmlist[i].owner != $('#vboxPane').data('vboxSession').user) {97			    	continue;98			    }99100				vmData[d.responseData[i].id] = d.responseData[i];101				102				if(vboxVMStates.isRunning({'state':d.responseData[i].state}) || vboxVMStates.isPaused({'state':d.responseData[i].state}))103					subscribeList[subscribeList.length] = d.responseData[i].id;104				105			}106			107			// Start event listener108			$.when(vboxEventListener.start(subscribeList)).done(function(){109				vboxVMDataMediator.vmData = vmData;110				mList.resolve(d.responseData);		111				112			}).fail(function() {113				mList.reject();114			});115			116			117		}).fail(function() {118			mList.reject();119		});120		121		return mList.promise();122	},123	124	/**125	 * Get VM details data126	 * 127	 * @param vmid {String} ID of VM to get data for128	 * @param forceRefresh {Boolean} force refresh of VM data129	 * @returns {Object} vm data or promise130	 */131	getVMDetails: function(vmid, forceRefresh) {132		133		// Data exists134		if(vboxVMDataMediator.vmDetailsData[vmid] && !forceRefresh) {135			vboxVMDataMediator.promises.getVMDetails[vmid] = null;136			return vboxVMDataMediator.vmDetailsData[vmid];137		}138		139		// Promise does not yet exist?140		if(!vboxVMDataMediator.promises.getVMDetails[vmid]) {141			142			vboxVMDataMediator.promises.getVMDetails[vmid] = $.Deferred();143144			$.when(vboxAjaxRequest('machineGetDetails',{vm:vmid})).done(function(d){145				vboxVMDataMediator.vmDetailsData[d.responseData.id] = d.responseData;146				vboxVMDataMediator.promises.getVMDetails[vmid].resolve(d.responseData);147			}).fail(function(){148				vboxVMDataMediator.promises.getVMDetails[vmid].reject();149				vboxVMDataMediator.promises.getVMDetails[vmid] = null;150			});151152		}		153		return vboxVMDataMediator.promises.getVMDetails[vmid];154	},155	156	/**157	 * Get VM's runtime data158	 * 159	 * @param vmid {String} ID of VM to get data for160	 * @returns {Object} VM runtime data or promise161	 */162	getVMRuntimeData: function(vmid) {163164		// Data exists165		if(vboxVMDataMediator.vmRuntimeData[vmid]) {166			vboxVMDataMediator.promises.getVMRuntimeData[vmid] = null;167			return vboxVMDataMediator.vmRuntimeData[vmid];168		}169		170		// Promise does not yet exist?171		if(!vboxVMDataMediator.promises.getVMRuntimeData[vmid]) {172			173			vboxVMDataMediator.promises.getVMRuntimeData[vmid] = $.Deferred();174175			$.when(vboxAjaxRequest('machineGetRuntimeData',{vm:vmid})).done(function(d){176				vboxVMDataMediator.vmRuntimeData[d.responseData.id] = d.responseData;177				if(vboxVMDataMediator.promises.getVMRuntimeData[vmid])178					vboxVMDataMediator.promises.getVMRuntimeData[vmid].resolve(d.responseData);179			}).fail(function(){180				vboxVMDataMediator.promises.getVMRuntimeData[vmid].reject();181				vboxVMDataMediator.promises.getVMRuntimeData[vmid] = null;182			});183184		}		185		return vboxVMDataMediator.promises.getVMRuntimeData[vmid];186	},187	188	/**189	 * Return all data for a VM190	 * @param vmid {String} ID of VM to get data for191	 * @returns promise192	 */193	getVMDataCombined : function(vmid) {194		195		// Special case for 'host'196		if(vmid == 'host') {197			var def = $.Deferred();198			$.when(vboxVMDataMediator.getVMDetails(vmid)).done(function(d){199				def.resolve(d);200			}).fail(function(){201				def.reject();202			});203			return def.promise();204		}205		206		if(!vboxVMDataMediator.vmData[vmid]) return;207		208		var runtime = function() { return {};};209		if(vboxVMStates.isRunning({'state':vboxVMDataMediator.vmData[vmid].state}) || vboxVMStates.isPaused({'state':vboxVMDataMediator.vmData[vmid].state})) {210			runtime = vboxVMDataMediator.getVMRuntimeData(vmid);211		}212		213		var def = $.Deferred();214		$.when(vboxVMDataMediator.getVMDetails(vmid), runtime, vboxVMDataMediator.getVMData(vmid)).done(function(d1,d2,d3){215			def.resolve($.extend(true,{},d1,d2,d3));216		}).fail(function(){217			def.reject();218		});219		return def.promise();220		221	},222	223	/**224	 * Get new VM data225	 * @param vmid {String} ID of VM to get data for226	 * @returns {Object} promise227	 */228	refreshVMData : function(vmid) {229		230		// Special case for host231		if(vmid == 'host') {232			$('#vboxPane').trigger('vboxOnMachineDataChanged', [{machineId:'host'}]);233			$('#vboxPane').trigger('vboxEvents', [[{eventType:'OnMachineDataChanged',machineId:'host'}]]);234			return;235		}236		237		if(!vboxVMDataMediator.vmData[vmid]) return;238		239		var def = $.Deferred();240		$.when(vboxAjaxRequest('vboxGetMachines',{'vm':vmid})).done(function(d) {241			vm = d.responseData[0];242			vboxVMDataMediator.vmData[vm.id] = vm;243			def.resolve();244			$('#vboxPane').trigger('vboxOnMachineDataChanged', [{machineId:vm.id,enrichmentData:vm}]);245			$('#vboxPane').trigger('vboxEvents', [[{eventType:'OnMachineDataChanged',machineId:vm.id,enrichmentData:vm}]]);246		}).fail(function(){247			def.reject();248		});249		250		return def.promise();251	}252253};254255/* Events to bind for vboxVMDataMediator when everything is loaded */256$(document).ready(function(){257258	/*259	 * 260	 * VirtualBox events261	 * 262	 */263	264	// Raw event to data handlers265	$('#vboxPane').on('vboxOnMachineDataChanged',function(e, eventData) {266		267		vboxVMDataMediator.expireVMDetails(eventData.machineId);268		vboxVMDataMediator.expireVMRuntimeData(eventData.machineId);269		270		if(vboxVMDataMediator.vmData[eventData.machineId] && eventData.enrichmentData) {271			$.extend(true, vboxVMDataMediator.vmData[eventData.machineId], eventData.enrichmentData);272			// $.extend doesn't seem to handle this for some reason273			vboxVMDataMediator.vmData[eventData.machineId].groups = eventData.enrichmentData.groups; 274		}275	276	// Machine state change277	}).on('vboxOnMachineStateChanged', function(e, eventData) {278279		// Only care about it if its in our list280		if(vboxVMDataMediator.vmData[eventData.machineId]) {281			282			vboxVMDataMediator.vmData[eventData.machineId].state = eventData.state;283			vboxVMDataMediator.vmData[eventData.machineId].lastStateChange = eventData.enrichmentData.lastStateChange;284			vboxVMDataMediator.vmData[eventData.machineId].currentStateModified = eventData.enrichmentData.currentStateModified;285			286			// If it's running, subscribe to its events287			if(vboxVMStates.isRunning({'state':eventData.state}) || vboxVMStates.isPaused({'state':eventData.state})) {288				289				// If we already have runtime data, assume we were already subscribed290				if(!vboxVMDataMediator.vmRuntimeData[eventData.machineId]) {291					292					// Tell event listener to subscribe to this machine's events293					vboxEventListener.subscribeVMEvents(eventData.machineId);294				}295				296			} else {297				vboxVMDataMediator.expireVMRuntimeData(eventData.machineId);298			}299		}300		301	// Session state change302	}).on('vboxOnSessionStateChanged', function(e, eventData) {303		304		if(vboxVMDataMediator.vmData[eventData.machineId])305			vboxVMDataMediator.vmData[eventData.machineId].sessionState = eventData.state;306307	308	// Snapshot changed309	}).on('vboxOnSnapshotTaken vboxOnSnapshotDeleted vboxOnSnapshotChanged vboxOnSnapshotRestored',function(e,eventData) {310		311		if(vboxVMDataMediator.vmData[eventData.machineId]) {312			313			vboxVMDataMediator.vmData[eventData.machineId].currentSnapshotName = eventData.enrichmentData.currentSnapshotName;314			vboxVMDataMediator.vmData[eventData.machineId].currentStateModified = eventData.enrichmentData.currentStateModified;315			316			// Get media again317			$.when(vboxAjaxRequest('vboxGetMedia')).done(function(d){$('#vboxPane').data('vboxMedia',d.responseData);});318			319		}320		if(vboxVMDataMediator.vmDetailsData[eventData.machineId])321			vboxVMDataMediator.vmDetailsData[eventData.machineId].snapshotCount = eventData.enrichmentData.snapshotCount;322		323	// Expire all data for a VM when machine is unregistered324	}).on('vboxOnMachineRegistered', function(e, eventData) {325		326		if(!eventData.registered) {327			vboxVMDataMediator.expireVMDetails(eventData.machineId);328			vboxVMDataMediator.expireVMRuntimeData(eventData.machineId);329			vboxVMDataMediator.vmData[eventData.machineId] = null;330			331		} else if(eventData.enrichmentData) {332		333			// Enforce VM ownership334		    if($('#vboxPane').data('vboxConfig').enforceVMOwnership && !$('#vboxPane').data('vboxSession').admin && eventData.enrichmentData.owner != $('#vboxPane').data('vboxSession').user) {335		    	return;336		    }337		    338		    vboxVMDataMediator.vmData[eventData.enrichmentData.id] = eventData.enrichmentData;339340		}341342	//}).on('vboxOnCPUChanged', function(e, vmid) {343	344		/*345		case 'OnCPUChanged':346			$data['cpu'] = $eventDataObject->cpu;347			$data['add'] = $eventDataObject->add;348			$data['dedupId'] .= '-' . $data['cpu'];349			break;350		*/351352	}).on('vboxOnNetworkAdapterChanged', function(e, eventData) {353		354		if(vboxVMDataMediator.vmRuntimeData[eventData.machineId]) {355			$.extend(vboxVMDataMediator.vmRuntimeData[eventData.machineId].networkAdapters[eventData.networkAdapterSlot], eventData.enrichmentData);356		}357		358359	/* Storage controller of VM changed */360	//}).on('vboxOnStorageControllerChanged', function() {361		/*362        case 'OnStorageControllerChanged':363        	$data['machineId'] = $eventDataObject->machineId;364        	$data['dedupId'] .= '-'. $data['machineId'];365        	break;366        */367		368	}).on('vboxOnMediumChanged', function(e, eventData) {369		370		/* Medium attachment changed */371		if(vboxVMDataMediator.vmRuntimeData[eventData.machineId]) {372			for(var a = 0; a < vboxVMDataMediator.vmRuntimeData[eventData.machineId].storageControllers.length; a++) {373				if(vboxVMDataMediator.vmRuntimeData[eventData.machineId].storageControllers[a].name == eventData.controller) {374					for(var b = 0; b < vboxVMDataMediator.vmRuntimeData[eventData.machineId].storageControllers[a].mediumAttachments.length; b++) {375						if(vboxVMDataMediator.vmRuntimeData[eventData.machineId].storageControllers[a].mediumAttachments[b].port == eventData.port &&376								vboxVMDataMediator.vmRuntimeData[eventData.machineId].storageControllers[a].mediumAttachments[b].device == eventData.device) {377							378							vboxVMDataMediator.vmRuntimeData[eventData.machineId].storageControllers[a].mediumAttachments[b].medium = (eventData.medium ? {id:eventData.medium} : null);379							break;380						}381					}382					break;383				}384			}385		}386		387	/* Shared folders changed */388	//}).on('vboxOnSharedFolderChanged', function() {389390	// VRDE runtime info391	}).on('vboxOnVRDEServerChanged', function(e, eventData) {392393		if(vboxVMDataMediator.vmRuntimeData[eventData.machineId]) {394			$.extend(true,vboxVMDataMediator.vmRuntimeData[eventData.machineId].VRDEServer, eventData.enrichmentData);395		}396397	398	// This only fires when it is enabled399	}).on('vboxOnVRDEServerInfoChanged', function(e, eventData) {400401		if(vboxVMDataMediator.vmRuntimeData[eventData.machineId]) {402			vboxVMDataMediator.vmRuntimeData[eventData.machineId].VRDEServerInfo.port = eventData.enrichmentData.port;403			vboxVMDataMediator.vmRuntimeData[eventData.machineId].VRDEServer.enabled = eventData.enrichmentData.enabled;404		}405406		407	// Execution cap408	}).on('vboxOnCPUExecutionCapChanged', function(e, eventData) {409		410		if(vboxVMDataMediator.vmRuntimeData[eventData.machineId]) {411			vboxVMDataMediator.vmRuntimeData[eventData.machineId].CPUExecutionCap = eventData.executionCap;412		}413414	// Special cases for where phpvirtualbox keeps its extra data415	}).on('vboxOnExtraDataChanged', function(e, eventData) {416		417		// No vm id is a global change418		if(!eventData.machineId || !vboxVMDataMediator.vmData[eventData.machineId]) return;419		420		switch(eventData.key) {421422			// Startup mode423			case 'pvbx/startupMode':424				if(vboxVMDataMediator.vmDetailsData[eventData.machineId])425					vboxVMDataMediator.vmDetailsData[eventData.machineId].startupMode = eventData.value;426				break;427			428			// Owner429			case 'phpvb/sso/owner':430				vboxVMDataMediator.vmData[eventData.machineId].owner = eventData.value;431				break;432			433			// Custom icon434			case 'phpvb/icon':435				436				vboxVMDataMediator.vmData[eventData.machineId].customIcon = eventData.value;437				438				if(vboxVMDataMediator.vmDetailsData[eventData.machineId])439					vboxVMDataMediator.vmDetailsData[eventData.machineId].customIcon = eventData.value;440				441				442				break;443			444			// First time run445			case 'GUI/FirstRun':446				if(vboxVMDataMediator.vmDetailsData[eventData.machineId])447					vboxVMDataMediator.vmDetailsData[eventData.machineId].GUI.FirstRun = eventData.value;448				break;449				450		}451		452		453	/*454	 * 455	 * phpVirtualBox events456	 * 457	 */458		459	// Expire everything when host changes460	}).on('hostChange',function(){461		vboxVMDataMediator.expireAll();462	463	});464	
...cluster_app_assign_manage.js
Source: cluster_app_assign_manage.js 
1var app = angular.module('sentinelDashboardApp');2app.controller('SentinelClusterAppAssignManageController', ['$scope', '$stateParams', 'ngDialog',3    'MachineService', 'ClusterStateService',4    function ($scope, $stateParams, ngDialog, MachineService, ClusterStateService) {5        $scope.app = $stateParams.app;6        const UNSUPPORTED_CODE = 4041;7        const CLUSTER_MODE_CLIENT = 0;8        const CLUSTER_MODE_SERVER = 1;9        const DEFAULT_CLUSTER_SERVER_PORT = 18730;10        $scope.tmp = {11            curClientChosen: [],12            curRemainingClientChosen: [],13            curChosenServer: {},14        };15        function convertSetToString(set) {16            if (set === undefined) {17                return '';18            }19            let s = '';20            for (let i = 0; i < set.length; i++) {21                s = s + set[i];22                if (i < set.length - 1) {23                    s = s + ',';24                }25            }26            return s;27        }28        function convertStrToNamespaceSet(str) {29            if (str === undefined || str === '') {30                return [];31            }32            let arr = [];33            let spliced = str.split(',');34            spliced.forEach((v) => {35                arr.push(v.trim());36            });37            return arr;38        }39        function processAppSingleData(data) {40            if (data.state.server && data.state.server.namespaceSet) {41                data.state.server.namespaceSetStr = convertSetToString(data.state.server.namespaceSet);42                data.mode = data.state.stateInfo.mode;43            }44        }45        function removeFromArr(arr, v) {46            for (let i = 0; i < arr.length; i++) {47                if (arr[i] === v) {48                    arr.splice(i, 1);49                    break;50                }51            }52        }53        function resetChosen() {54            $scope.tmp.curClientChosen = [];55            $scope.tmp.curRemainingClientChosen = [];56        }57        function generateMachineId(e) {58            return e.ip + '@' + e.commandPort;59        }60        function applyClusterMap(appClusterMachineList) {61            if (!appClusterMachineList) {62                return;63            }64            let tmpMap = new Map();65            $scope.clusterMap = [];66            $scope.remainingClientAddressList = [];67            let tmpServerList = [];68            let tmpClientList = [];69            appClusterMachineList.forEach((e) => {70                if (e.mode === CLUSTER_MODE_CLIENT) {71                    tmpClientList.push(e);72                } else if (e.mode === CLUSTER_MODE_SERVER) {73                    tmpServerList.push(e);74                } else {75                    $scope.remainingClientAddressList.push(generateMachineId(e));76                }77            });78            tmpServerList.forEach((e) => {79                let ip = e.ip;80                let machineId = ip + '@' + e.commandPort;81                let group = {82                    ip: ip,83                    machineId: machineId,84                    port: e.state.server.port,85                    clientSet: [],86                    namespaceSetStr: e.state.server.namespaceSetStr,87                    belongToApp: true,88                };89                if (!tmpMap.has(ip)) {90                    tmpMap.set(ip, group);91                }92            });93            tmpClientList.forEach((e) => {94                let ip = e.ip;95                let machineId = ip + '@' + e.commandPort;96                let targetServer = e.state.client.clientConfig.serverHost;97                let targetPort = e.state.client.clientConfig.serverPort;98                if (targetServer === undefined || targetServer === '' ||99                    targetPort === undefined || targetPort <= 0) {100                    $scope.remainingClientAddressList.push(generateMachineId(e));101                    return;102                }103                if (!tmpMap.has(targetServer)) {104                    let group = {105                        ip: targetServer,106                        machineId: targetServer,107                        port: targetPort,108                        clientSet: [machineId],109                        belongToApp: false,110                    };111                    tmpMap.set(targetServer, group);112                } else {113                    let g = tmpMap.get(targetServer);114                    g.clientSet.push(machineId);115                }116            });117            tmpMap.forEach((v) => {118                if (v !== undefined) {119                    $scope.clusterMap.push(v);120                }121            });122        }123        $scope.onCurrentServerChange = () => {124            resetChosen();125        };126        $scope.remainingClientAddressList = [];127        $scope.moveToServerGroup = () => {128            let chosenServer = $scope.tmp.curChosenServer;129            if (!chosenServer || !chosenServer.machineId) {130                return;131            }132            $scope.tmp.curRemainingClientChosen.forEach(e => {133                chosenServer.clientSet.push(e);134                removeFromArr($scope.remainingClientAddressList, e);135            });136            resetChosen();137        };138        $scope.moveToRemainingSharePool = () => {139            $scope.tmp.curClientChosen.forEach(e => {140                $scope.remainingClientAddressList.push(e);141                removeFromArr($scope.tmp.curChosenServer.clientSet, e);142            });143            resetChosen();144        };145        function parseIpFromMachineId(machineId) {146            if (machineId.indexOf('@') === -1) {147                return machineId;148            }149            let arr = machineId.split('@');150            return arr[0];151        }152        $scope.addToServerList = () => {153            let group;154            $scope.tmp.curRemainingClientChosen.forEach(e => {155                group = {156                    machineId: e,157                    ip: parseIpFromMachineId(e),158                    port: DEFAULT_CLUSTER_SERVER_PORT,159                    clientSet: [],160                    namespaceSetStr: 'default,' + $scope.app,161                    belongToApp: true,162                };163                $scope.clusterMap.push(group);164                removeFromArr($scope.remainingClientAddressList, e);165                $scope.tmp.curChosenServer = group;166            });167            resetChosen();168        };169        $scope.removeFromServerList = () => {170            let chosenServer = $scope.tmp.curChosenServer;171            if (!chosenServer || !chosenServer.machineId) {172                return;173            }174            chosenServer.clientSet.forEach((e) => {175                if (e !== undefined) {176                    $scope.remainingClientAddressList.push(e);177                }178            });179            if (chosenServer.belongToApp || chosenServer.machineId.indexOf('@') !== -1) {180                $scope.remainingClientAddressList.push(chosenServer.machineId);181            } else {182                alert('æç¤ºï¼éæ¬åºç¨å
æºå¨å°ä¸ä¼ç½®å空é²å表ä¸');183            }184            removeFromArr($scope.clusterMap, chosenServer);185            resetChosen();186            if ($scope.clusterMap.length > 0) {187                $scope.tmp.curChosenServer = $scope.clusterMap[0];188                $scope.onCurrentServerChange();189            } else {190                $scope.tmp.curChosenServer = {};191            }192        };193        function retrieveClusterAppInfo() {194            ClusterStateService.fetchClusterUniversalStateOfApp($scope.app).success(function (data) {195                if (data.code === 0 && data.data) {196                    $scope.loadError = undefined;197                    $scope.appClusterMachineList = data.data;198                    $scope.appClusterMachineList.forEach(processAppSingleData);199                    applyClusterMap($scope.appClusterMachineList);200                    if ($scope.clusterMap.length > 0) {201                        $scope.tmp.curChosenServer = $scope.clusterMap[0];202                        $scope.onCurrentServerChange();203                    }204                } else {205                    $scope.appClusterMachineList = {};206                    if (data.code === UNSUPPORTED_CODE) {207                        $scope.loadError = {message: '该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã'}208                    } else {209                        $scope.loadError = {message: data.msg};210                    }211                }212            }).error(() => {213                $scope.loadError = {message: 'æªç¥é误'};214            });215        }216        retrieveClusterAppInfo();217        $scope.saveAndApplyAssign = () => {218            let ok = confirm('æ¯å¦ç¡®è®¤æ§è¡åæ´ï¼');219            if (!ok) {220                return;221            }222            let cm = $scope.clusterMap;223            if (!cm) {224                cm = [];225            }226            cm.forEach((e) => {227                e.namespaceSet = convertStrToNamespaceSet(e.namespaceSetStr);228            });229            cm.namespaceSet = convertStrToNamespaceSet(cm.namespaceSetStr);230            let request = {231                clusterMap: cm,232                remainingList: $scope.remainingClientAddressList,233            };234            ClusterStateService.applyClusterFullAssignOfApp($scope.app, request).success((data) => {235                if (data.code === 0 && data.data) {236                    let failedServerSet = data.data.failedServerSet;237                    let failedClientSet = data.data.failedClientSet;238                    if (failedClientSet.length === 0 && failedServerSet.length === 0) {239                        alert('å
¨é¨æ¨éæå');240                    } else {241                        alert('æ¨é宿¯ãtoken server 失败å表ï¼' + JSON.stringify(failedServerSet) +242                            '; token client 失败å表ï¼' + JSON.stringify(failedClientSet));243                    }244                    retrieveClusterAppInfo();245                } else {246                    if (data.code === UNSUPPORTED_CODE) {247                        alert('该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã');248                    } else {249                        alert('æ¨é失败ï¼' + data.msg);250                    }251                }252            }).error(() => {253                alert('æªç¥é误');254            });255        };...cluster_app_server_manage.js
Source: cluster_app_server_manage.js 
1var app = angular.module('sentinelDashboardApp');2app.controller('SentinelClusterAppAssignManageController', ['$scope', '$stateParams', 'ngDialog',3    'MachineService', 'ClusterStateService',4    function ($scope, $stateParams, ngDialog, MachineService, ClusterStateService) {5        $scope.app = $stateParams.app;6        const UNSUPPORTED_CODE = 4041;7        const CLUSTER_MODE_CLIENT = 0;8        const CLUSTER_MODE_SERVER = 1;9        const DEFAULT_CLUSTER_SERVER_PORT = 18730;10        $scope.tmp = {11            curClientChosen: [],12            curRemainingClientChosen: [],13            curChosenServer: {},14        };15        function convertSetToString(set) {16            if (set === undefined) {17                return '';18            }19            let s = '';20            for (let i = 0; i < set.length; i++) {21                s = s + set[i];22                if (i < set.length - 1) {23                    s = s + ',';24                }25            }26            return s;27        }28        function convertStrToNamespaceSet(str) {29            if (str === undefined || str === '') {30                return [];31            }32            let arr = [];33            let spliced = str.split(',');34            spliced.forEach((v) => {35                arr.push(v.trim());36            });37            return arr;38        }39        function processAppSingleData(data) {40            if (data.state.server && data.state.server.namespaceSet) {41                data.state.server.namespaceSetStr = convertSetToString(data.state.server.namespaceSet);42                data.mode = data.state.stateInfo.mode;43            }44        }45        function removeFromArr(arr, v) {46            for (let i = 0; i < arr.length; i++) {47                if (arr[i] === v) {48                    arr.splice(i, 1);49                    break;50                }51            }52        }53        function resetChosen() {54            $scope.tmp.curClientChosen = [];55            $scope.tmp.curRemainingClientChosen = [];56        }57        function generateMachineId(e) {58            return e.ip + '@' + e.commandPort;59        }60        function applyClusterMap(appClusterMachineList) {61            if (!appClusterMachineList) {62                return;63            }64            let tmpMap = new Map();65            $scope.clusterMap = [];66            $scope.remainingClientAddressList = [];67            let tmpServerList = [];68            let tmpClientList = [];69            appClusterMachineList.forEach((e) => {70                if (e.mode === CLUSTER_MODE_CLIENT) {71                    tmpClientList.push(e);72                } else if (e.mode === CLUSTER_MODE_SERVER) {73                    tmpServerList.push(e);74                } else {75                    $scope.remainingClientAddressList.push(generateMachineId(e));76                }77            });78            tmpServerList.forEach((e) => {79                let ip = e.ip;80                let machineId = ip + '@' + e.commandPort;81                let group = {82                    ip: ip,83                    machineId: machineId,84                    port: e.state.server.port,85                    clientSet: [],86                    namespaceSetStr: e.state.server.namespaceSetStr,87                    belongToApp: true,88                };89                if (!tmpMap.has(ip)) {90                    tmpMap.set(ip, group);91                }92            });93            tmpClientList.forEach((e) => {94                let ip = e.ip;95                let machineId = ip + '@' + e.commandPort;96                let targetServer = e.state.client.clientConfig.serverHost;97                let targetPort = e.state.client.clientConfig.serverPort;98                if (targetServer === undefined || targetServer === '' ||99                    targetPort === undefined || targetPort <= 0) {100                    $scope.remainingClientAddressList.push(generateMachineId(e));101                    return;102                }103                if (!tmpMap.has(targetServer)) {104                    let group = {105                        ip: targetServer,106                        machineId: targetServer,107                        port: targetPort,108                        clientSet: [machineId],109                        belongToApp: false,110                    };111                    tmpMap.set(targetServer, group);112                } else {113                    let g = tmpMap.get(targetServer);114                    g.clientSet.push(machineId);115                }116            });117            tmpMap.forEach((v) => {118                if (v !== undefined) {119                    $scope.clusterMap.push(v);120                }121            });122        }123        $scope.onCurrentServerChange = () => {124            resetChosen();125        };126        $scope.remainingClientAddressList = [];127        $scope.moveToServerGroup = () => {128            let chosenServer = $scope.tmp.curChosenServer;129            if (!chosenServer || !chosenServer.machineId) {130                return;131            }132            $scope.tmp.curRemainingClientChosen.forEach(e => {133                chosenServer.clientSet.push(e);134                removeFromArr($scope.remainingClientAddressList, e);135            });136            resetChosen();137        };138        $scope.moveToRemainingSharePool = () => {139            $scope.tmp.curClientChosen.forEach(e => {140                $scope.remainingClientAddressList.push(e);141                removeFromArr($scope.tmp.curChosenServer.clientSet, e);142            });143            resetChosen();144        };145        function parseIpFromMachineId(machineId) {146            if (machineId.indexOf('@') === -1) {147                return machineId;148            }149            let arr = machineId.split('@');150            return arr[0];151        }152        $scope.addToServerList = () => {153            let group;154            $scope.tmp.curRemainingClientChosen.forEach(e => {155                group = {156                    machineId: e,157                    ip: parseIpFromMachineId(e),158                    port: DEFAULT_CLUSTER_SERVER_PORT,159                    clientSet: [],160                    namespaceSetStr: 'default,' + $scope.app,161                    belongToApp: true,162                };163                $scope.clusterMap.push(group);164                removeFromArr($scope.remainingClientAddressList, e);165                $scope.tmp.curChosenServer = group;166            });167            resetChosen();168        };169        $scope.removeFromServerList = () => {170            let chosenServer = $scope.tmp.curChosenServer;171            if (!chosenServer || !chosenServer.machineId) {172                return;173            }174            chosenServer.clientSet.forEach((e) => {175                if (e !== undefined) {176                    $scope.remainingClientAddressList.push(e);177                }178            });179            if (chosenServer.belongToApp || chosenServer.machineId.indexOf('@') !== -1) {180                $scope.remainingClientAddressList.push(chosenServer.machineId);181            } else {182                alert('æç¤ºï¼éæ¬åºç¨å
æºå¨å°ä¸ä¼ç½®å空é²å表ä¸');183            }184            removeFromArr($scope.clusterMap, chosenServer);185            resetChosen();186            if ($scope.clusterMap.length > 0) {187                $scope.tmp.curChosenServer = $scope.clusterMap[0];188                $scope.onCurrentServerChange();189            } else {190                $scope.tmp.curChosenServer = {};191            }192        };193        function retrieveClusterAppInfo() {194            ClusterStateService.fetchClusterUniversalStateOfApp($scope.app).success(function (data) {195                if (data.code === 0 && data.data) {196                    $scope.loadError = undefined;197                    $scope.appClusterMachineList = data.data;198                    $scope.appClusterMachineList.forEach(processAppSingleData);199                    applyClusterMap($scope.appClusterMachineList);200                    if ($scope.clusterMap.length > 0) {201                        $scope.tmp.curChosenServer = $scope.clusterMap[0];202                        $scope.onCurrentServerChange();203                    }204                } else {205                    $scope.appClusterMachineList = {};206                    if (data.code === UNSUPPORTED_CODE) {207                        $scope.loadError = {message: '该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã'}208                    } else {209                        $scope.loadError = {message: data.msg};210                    }211                }212            }).error(() => {213                $scope.loadError = {message: 'æªç¥é误'};214            });215        }216        retrieveClusterAppInfo();217        $scope.saveAndApplyAssign = () => {218            let ok = confirm('æ¯å¦ç¡®è®¤æ§è¡åæ´ï¼');219            if (!ok) {220                return;221            }222            let cm = $scope.clusterMap;223            if (!cm) {224                cm = [];225            }226            cm.forEach((e) => {227                e.namespaceSet = convertStrToNamespaceSet(e.namespaceSetStr);228            });229            cm.namespaceSet = convertStrToNamespaceSet(cm.namespaceSetStr);230            let request = {231                clusterMap: cm,232                remainingList: $scope.remainingClientAddressList,233            };234            ClusterStateService.applyClusterFullAssignOfApp($scope.app, request).success((data) => {235                if (data.code === 0 && data.data) {236                    let failedServerSet = data.data.failedServerSet;237                    let failedClientSet = data.data.failedClientSet;238                    if (failedClientSet.length === 0 && failedServerSet.length === 0) {239                        alert('å
¨é¨æ¨éæå');240                    } else {241                        alert('æ¨é宿¯ãtoken server 失败å表ï¼' + JSON.stringify(failedServerSet) +242                            '; token client 失败å表ï¼' + JSON.stringify(failedClientSet));243                    }244                    retrieveClusterAppInfo();245                } else {246                    if (data.code === UNSUPPORTED_CODE) {247                        alert('该åºç¨ç Sentinel 客æ·ç«¯ä¸æ¯æéç¾¤éæµï¼è¯·åçº§è³ 1.4.0 以ä¸çæ¬å¹¶å¼å
¥ç¸å
³ä¾èµã');248                    } else {249                        alert('æ¨é失败ï¼' + data.msg);250                    }251                }252            }).error(() => {253                alert('æªç¥é误');254            });255        };...machine-repository.js
Source: machine-repository.js 
1const {Machine, DailyRecord, DailyAnalysis, MonthlyAnalysis} = require('../models');2const { APIError, STATUS_CODES } = require('../../utils/app-errors');3class MachineRepository {4    async createMachine({machineId, machNo, label}){5        try{6            const newMachine = new Machine({7                machineId: machineId,8                machNo: machNo,9                label: label,10                dailyRecords: [],11                dailyAnalyses: [],12                monthlyAnalyses: [],13            })14            await newMachine.save();15            return newMachine;16        }catch(err){17            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Unable to Create Machine');18        }19    }20    async findMachineByNo({ machNo }){21        try{22            const machineData = await Machine.findOne({machNo: machNo});23            return machineData;24        }catch(err){25            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Finding Machine By Machine Number');26        }27    }28    async findMachineById({ machineId }){29        try{30            const machineData = await Machine.findOne({machineId: machineId});31            return machineData;32        }catch(err){33            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Finding Machine By Machine Id');34        }35    }36    async addMachineDailyRecords({machineId, day, month, year, historyRecords}){37        try{38            const selectedMachine = await Machine.findOne({machineId: machineId});39            if (selectedMachine){40                const newDailyRecord = new DailyRecord({41                    day: day,42                    month: month,43                    year: year,44                    machineId: machineId,45                    historyRecords: historyRecords46                })47                await newDailyRecord.save();48                selectedMachine.dailyRecords.push(newDailyRecord);49            }50            return await selectedMachine.save();51            52        }catch(err){53            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Add Machine Daily Records');54        }55    }56    async addMachineDailyAnalyses({machineId, day, month, year, machErrors, lineData}){57        try{58            const selectedMachine = await Machine.findOne({machineId: machineId});59            if (selectedMachine){60                const newDailyAnalysis = new DailyAnalysis({61                    day: day,62                    month: month,63                    year: year,64                    machineId: machineId,65                    machErrors: machErrors,66                    lineData: lineData67                })68                await newDailyAnalysis.save();69                selectedMachine.dailyAnalyses.push(newDailyAnalysis);70            }71            return await selectedMachine.save();72            73        }catch(err){74            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Add Machine Daily Analysis');75        }76    }77    async doesMonthlyAnalysisExists({month, year}){78        MonthlyAnalysis.findOne({month: month, year: year}, (err, doc) => {79            if (err){80                throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Does Monthly Analysis Exists');81            }82            if (doc){83                return true;84            } else {85                return false;86            }87        })88    }89    async addMachineMonthlyAnalyses({machineId, month, year, pieData}){90        try{91            const selectedMachine = await Machine.findOne({machineId: machineId});;92            if (selectedMachine){93                const newMonthlyAnalysis = new MonthlyAnalysis({94                    month: month,95                    year: year,96                    machineId: machineId,97                    pieData: pieData,98                })99                await newMonthlyAnalysis.save();100                selectedMachine.monthlyAnalyses.push(newMonthlyAnalysis);101            }102            return await selectedMachine.save();103            104        }catch(err){105            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Add Machine Monthly Analysis');106        }107    }108    async updateMachineMonthlyAnalyses({machineId, month, year, pieData}){   109        try{110            const selectedMonthlyAnalyses = await MonthlyAnalysis.findOne({machineId: machineId, month: month, year: year});111            if (selectedMonthlyAnalyses) {112                let oldPieData = selectedMonthlyAnalyses.pieData;113                let {offline, disabled, idle, running, diagnostic, deuplicate, error, firmwareDoesntExist, satellite, reader} = oldPieData;114                let newOffline = offline + pieData.offline;115                let newDisabled = disabled + pieData.disabled;116                let newIdle = idle + pieData.idle;117                let newRunning = running + pieData.running;118                let newDiagnostic = diagnostic + pieData.diagnostic;119                let newDeuplicate = deuplicate + pieData.deuplicate;120                let newError = error + pieData.error;121                let newFirmwareDoesntExist = firmwareDoesntExist + pieData.firmwareDoesntExist;122                let newSatellite = satellite + pieData.satellite;123                let newReader = reader + pieData.reader;124                let newData = {offline: newOffline, disabled: newDisabled, idle: newIdle, running: newRunning, diagnostic: newDiagnostic, deuplicate: newDeuplicate, error: newError, firmwareDoesntExist: newFirmwareDoesntExist, satellite: newSatellite, reader: newReader};125                const oldMonthlyAnalysis = await MonthlyAnalysis.findOneAndUpdate({machineId: machineId, month: month, year: year} , {pieData: newData});126                return oldMonthlyAnalysis;127            }128        }catch(err){129            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Update Machine Monthly Analyses');130        }131    }132    async findDailyRecordsByMonthAfterDay({machineId, day, month, year}){133        try{134            if(day == -1){135                const queryData = await DailyRecord.findOne({machineId: machineId, month: month, year: year}).populate('historyRecords');136                return queryData;137            } else{138                const queryData = await DailyRecord.findOne({machineId: machineId, month: month, year: year, day: { $gte: day}}).populate('historyRecords');139                return queryData;140            }141        } catch (err) {142            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Find Daily Records By Month After Day');143        }144    }145    async findDailyRecordsByDay({machineId, day, month, year}){146        try{147            const queryData = await DailyRecord.findOne({machineId: machineId, month: month, year: year, day: day}).populate('historyRecords');148            return queryData;149        } catch (err) {150            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Find Daily Records By Day');151        }152    }153    async findMonthAnalyses({machineId, month, year}){154        try{155            const queryData = await MonthlyAnalysis.findOne({machineId: machineId, month: month, year: year});156            return queryData;157        } catch (err) {158            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Find Monthly Analyses');159        }160    }161    async findDayAnalyses({machineId, day, month, year}){162        try{163            const queryData = await DailyAnalysis.findOne({machineId: machineId, day: day, month: month, year: year});164            return queryData;165        } catch (err) {166            throw new APIError('API Error', STATUS_CODES.INTERNAL_ERROR, 'Error on Find Daily Analyses');167        }168    }169}...machineManage.js
Source: machineManage.js 
1function removeMachine(id, ip) {2	var removeMachineBtn = document.getElementById(id);3	removeMachineBtn.disabled = true;4	$.get(5		'/manage/machine/checkMachineInstances.json',6		{7			ip: ip,8		},9        function(data){10			var machineHasInstance = data.machineHasInstance;11			var alertMsg;12			if (machineHasInstance == true) {13				alertMsg = "该æºå¨ip=" + ip + "è¿æè¿è¡ä¸çRedisèç¹,确认è¦å é¤åï¼";14			} else {15				alertMsg = "确认è¦å é¤ip=" + ip + "å?";16			}17			if (confirm(alertMsg)) {18				location.href = "/manage/machine/delete.do?machineIp="+ip;19			} else {20				removeMachineBtn.disabled = false;21			}22        }23     );24}25function saveOrUpdateMachine(machineId){26	var ip = document.getElementById("ip" + machineId);27	var room = document.getElementById("room" + machineId);28	var mem = document.getElementById("mem" + machineId);29	var cpu = document.getElementById("cpu" + machineId);30	var virtual = document.getElementById("virtual" + machineId);31    var realIp = document.getElementById("realIp" + machineId);32    var machineType = document.getElementById("machineType" + machineId);33    var extraDesc = document.getElementById("extraDesc" + machineId);34    var collect = document.getElementById("collect" + machineId);35	if(ip.value == ""){36    	alert("IPä¸è½ä¸ºç©º!");37        ip.focus();38		return false;39    }40    if(room.value == ""){41        alert("æºæ¿ä¸è½ä¸ºç©º!");42        room.focus();43        return false;44    }45    if(mem.value == ""){46        alert("å
åä¸è½ä¸ºç©º!");47        mem.focus();48        return false;49    }50    if(cpu.value == ""){51        alert("CPUä¸è½ä¸ºç©º!");52        cpu.focus();53        return false;54    }55    if(virtual.value == ""){56        alert("æ¯å¦èæºä¸ºç©º!");57        virtual.focus();58        return false;59    }60    var addMachineBtn = document.getElementById("addMachineBtn" + machineId);61    addMachineBtn.disabled = true;62    63	$.post(64		'/manage/machine/add.json',65		{66            ip: ip.value,67            room: room.value,68            mem: mem.value,69            cpu: cpu.value,70            virtual: virtual.value,71            realIp: realIp.value,72            id:machineId,73            machineType: machineType.value,74            extraDesc: extraDesc.value,75            collect: collect.value76		},77        function(data){78            if(data.result){79                $("#machineInfo" + machineId).html("<div class='alert alert-error' ><button class='close' data-dismiss='alert'>Ã</button><strong>Success!</strong>æ´æ°æåï¼çªå£ä¼èªå¨å
³é</div>");80                var targetId = "#addMachineModal" + machineId;81                setTimeout("$('" + targetId +"').modal('hide');window.location.reload();",1000);82            }else{83                addMachineBtn.disabled = false;84                $("#machineInfo" + machineId).html("<div class='alert alert-error' ><button class='close' data-dismiss='alert'>Ã</button><strong>Error!</strong>æ´æ°å¤±è´¥ï¼</div>");85            }86        }87     );...defect.js
Source: defect.js 
1const defectRepository = require('./repository/defect')2const machineRepository = require('./repository/machine')3const { InvalidError } = require('./errors')4const { DefectStatusEnum } = require('./enums')5const getDefect = async (machineId) => {6  await machineRepository.machineExists(machineId)7  const defect = defectRepository.find(machineId)8  return {9    data: { defect }10  }11}12const createDefect = async ({ personalNumber, description, machineId }) => {13  const defect = await defectRepository.createDefect({14    personalNumber,15    description,16    machineId17  })18  console.info(`Successfully set the defect for machine ${machineId} with ${description} by - ${personalNumber}`)19  return {20    data: {21      message: 'Successfully set the defect',22      defect23    }24  }25}26const getDefects = async (machineId) => {27  await machineRepository.machineExists(machineId)28  const defects = await defectRepository.getDefectsByMachineId(machineId)29  return {30    data: { defects }31  }32}33const setDefectStatus = async ({ machineId, defectTime, status }) => {34  if (!Object.values(DefectStatusEnum).some(v => v === status)) {35    throw new InvalidError(`Invalid defect status: ${status}`)36  }37  await machineRepository.machineExists(machineId)38  await defectRepository.setDefectStatusForMachineId(machineId)39  let successMessage = 'Successfully updated the status of defect'40  if (status === DefectStatusEnum.STUCK_HEADER) {41    await machineRepository.setMachineStatus({ machineId, status })42    successMessage = `Successfully updated and set the status of the machine ${machineId}`43  }44  console.info(successMessage)45  return {46    data: {47      message: successMessage48    }49  }50}51const getAll = async ({ limit, offset }) => {52  const defects = await defectRepository.getDefectsByStatuses({53    statuses: Object.values(DefectStatusEnum),54    pagination: {55      limit,56      offset57    }58  })59  return defects60}61module.exports = {62  getDefect,63  createDefect,64  getDefects,65  setDefectStatus,66  getAll...Using AI Code Generation
1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.machineId().then((machineId) => {4      console.log(machineId)5    })6  })7})8Cypress.Commands.add('machineId', () => {9  return cy.task('getMachineId')10})11module.exports = (on, config) => {12  on('task', {13    getMachineId() {14      return require('node-machine-id').machineIdSync()15    },16  })17}Using AI Code Generation
1const machineId = require('node-machine-id');2describe('My First Test', () => {3  it('Does not do much!', () => {4    expect(true).to.equal(true)5  })6})7it('machineId', () => {8  cy.log(machineId.machineIdSync());9})10it('machineId', () => {11  cy.log(machineId.machineIdSync());12})13it('machineId', () => {14  cy.log(machineId.machineIdSync());15})16it('machineId', () => {17  cy.log(machineId.machineIdSync());18})19it('machineId', () => {20  cy.log(machineId.machineIdSync());21})22it('machineId', () => {23  cy.log(machineId.machineIdSync());24})25it('machineId', () => {26  cy.log(machineId.machineIdSync());27})28it('machineId', () => {29  cy.log(machineId.machineIdSync());30})31it('machineId', () => {32  cy.log(machineId.machineIdSync());33})34it('machineId', () => {35  cy.log(machineId.machineIdSync());36})37it('machineId', () => {38  cy.log(machineId.machineIdSync());39})40it('machineId', () => {41  cy.log(machineId.machineIdSync());42})43it('machineId', () => {44  cy.log(machineId.machineIdSync());45})46it('machineId', () => {47  cy.log(machineId.machineIdSync());48})49it('machineId', () => {50  cy.log(machineId.machineIdSync());51})52it('machineId', () => {53  cy.log(machineId.machineIdSync());54})Using AI Code Generation
1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.machineId().then((machineId) => {4      cy.log(machineId);5    });6  });7});8describe('My First Test', function() {9  it('Does not do much!', function() {10    cy.machineId().then((machineId) => {11      cy.log(machineId);12    });13  });14});15describe('My First Test', function() {16  it('Does not do much!', function() {17    cy.machineId().then((machineId) => {18      cy.log(machineId);19    });20  });21});22describe('My First Test', function() {23  it('Does not do much!', function() {24    cy.machineId().then((machineId) => {25      cy.log(machineId);26    });27  });28});29describe('My First Test', function() {30  it('Does not do much!', function() {31    cy.machineId().then((machineId) => {32      cy.log(machineId);33    });34  });35});36describe('My First Test', function() {37  it('Does not do much!', function() {38    cy.machineId().then((machineId) => {39      cy.log(machineId);40    });41  });42});43describe('My First Test', function() {44  it('Does not do much!', function() {45    cy.machineId().then((machineId) => {46      cy.log(machineId);47    });48  });49});50describe('My First Test', function() {51  it('Does not do much!', function() {52    cy.machineId().then((machineId) => {53      cy.log(machineId);54    });55  });56});57describe('My First Test', function() {58  it('Does not do much!', function() {59    cy.machineId().then((machineId) => {60      cy.log(machineId);61    });62  });63});64describe('My First Test', function() {65  it('Does not do much!', function() {Using AI Code Generation
1import { machineId } from 'node-machine-id';2describe('My First Test', function () {3    it('Does not do much!', function () {4        cy.log(machineId(true));5        cy.contains('type').click();6        cy.url().should('include', '/commands/actions');7        cy.get('.action-email')8            .type('Using AI Code Generation
1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.machineId().then((machineId) => {4      console.log(machineId)5    })6  })7})Using AI Code Generation
1describe('Cypress Machine ID', () => {2    it('Get Machine ID', () => {3        cy.machineId().then((machineId) => {4            cy.log(machineId)5        })6    })7})8Cypress.Commands.add('machineId', () => {9    return cy.task('machineId')10})11module.exports = (on, config) => {12    on('task', {13        machineId() {14            return require('node-machine-id').machineIdSync()15        }16    })17}18{19}20{21}22module.exports = (on, config) => {23    on('task', {24        machineId() {25            return require('node-machine-id').machineIdSync()26        }27    })28}29Cypress.Commands.add('machineId', () => {30    return cy.task('machineId')31})32describe('Cypress Machine ID', () => {33    it('Get Machine ID', () => {34        cy.machineId().then((machineId) => {35            cy.log(machineId)36        })37    })38})Using AI Code Generation
1describe('My First Test', function() {2  it('Does not do much!', function() {3    cy.machineId().then((id) => {4      console.log(id);5    })6  })7})8module.exports = (on, config) => {9  require('cypress-machine-id')(on, config)10}11require('cypress-machine-id')12describe('My First Test', function() {13  it('Does not do much!', function() {14    cy.machineId().then((id) => {15      console.log(id);16    })17  })18})19const { machineId } = require('cypress-machine-id')20machineId().then((id) => {21  console.log(id);22})23describe('My First Test', function() {24  it('Does not do much!', function() {25    cy.machineId().then((id) => {26      console.log(id);27    })28  })29})30If you find any bugs or have any questions, please file an issue on [GitHub](Using AI Code Generation
1describe('Test Machine Id', () => {2  it('should return machine id', () => {3    cy.machineId()4      .then((id) => {5        console.log('Machine Id is', id);6      });7  });8});9describe('Test Machine Id', () => {10  it('should return machine id', () => {11    const id = cy.machineIdSync();12    console.log('Machine Id is', id);13  });14});15describe('Test Machine Id', () => {16  it('should return machine id', () => {17    cy.machineIdAsync()18      .then((id) => {19        console.log('Machine Id is', id);20      });21  });22});23describe('Test Machine Id', () => {24  it('should return machine id', async () => {25    const id = await cy.machineIdAsync();26    console.log('Machine Id is', id);27  });28});29describe('Test Machine Id', () => {30  it('should return machine id', async () => {31    const id = await cy.machineIdAsync();32    console.log('Machine Id is', id);33  });34});35describe('Test Machine Id', () => {36  it('should return machine id', async () => {37    try {38      const id = await cy.machineIdAsync();39      console.log('Machine Id is', id);40    } catch (e) {41      console.error('Error in getting machine id', e);42    }43  });44});45describe('Test Machine Id', () => {46  it('should return machine id', async () => {47    try {48      const id = await cy.machineIdAsync();49      console.log('Machine Id is', id);50      expect(id).to.be.a('string');51    } catch (e) {52      console.error('Error in getting machine id', e);53    }54  });55});56describe('Test Machine Id', () => {How to assert localStorage in Cypress
How to use then() and get the value in Cypress
Cypress load data from json - fixture before
Cypress custom find command is not chainable
Cypress - How to use response body in another request header
How can I use cookies across multiple Cypress tests?
Cypress-get value out of callback function
I can't open Cypress on Mac: Cypress not found
Add a variable to a response path
Is it possible to type inside the textbox displaying in a prompt in Cypress and click on ok button
Should you assert localStorage inside the should block? Yes, you should. Check out the official example from Cypress
For cy-commands (cy.put, cy.get ...), they're enqueued and runs one after another later by Cypress. On the other hand, non cy-commands (expect) are executed right away. Hence, your localStorage is not available if you leave expect outside should() because sign-in is not finished yet.
By moving expect inside should, that means it's run after cy.url() is done. Since cy.url is the last item in Cypress' internal queue, the other cy commands (cy.visit, cy.get, cy.findBy...) have been completed by this point.
Check out the latest blogs from LambdaTest on this topic:
Hey People! With the beginning of a new year, we are excited to announce a collection of new product updates! At LambdaTest, we’re committed to providing you with a comprehensive test execution platform to constantly improve the user experience and performance of your websites, web apps, and mobile apps. Our incredible team of developers came up with several new features and updates to spice up your workflow.
A woman’s success should be an inspiration to other women; we’re strongest when we cheer each other on. Every year we celebrate International Women’s Day on March 8th and acknowledge the contributions women have made in many industries. So, this Women’s Day, let’s celebrate women in software testing!
This article is a part of our Content Hub. For more in-depth resources, check out our content hub on Selenium JavaScript Tutorial.
2020 is finally winding down—and it’s been a challenging year for a lot of us. But we’re pretty sure at this point that when the new year begins, this year will just – vaporize.
Safari is the default browser on iPads, Macbooks, and iPhones. It lies second on browser preferences right after Chrome. Its 250+ features offer users striking benefits that set it apart from other most popular browsers like Chrome and Firefox. Building on that, iPhone’s popularity has resulted in a global smartphone market share of 53.6% for Safari.
Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.
You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.
Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.
Get 100 minutes of automation test minutes FREE!!
