This is an automated email from the ASF dual-hosted git repository. hanahmily pushed a commit to branch 6.0.0/dev in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git
commit a204416a08164833b09257cee33c5575f62ceaf5 Author: Gao Hongtao <[email protected]> AuthorDate: Mon Sep 10 16:40:22 2018 +0800 Refactor topology page with v6 --- .roadhogrc.mock.js | 8 +- mock/service.js | 134 --------------------------------- mock/topology.js | 89 ++++++++++++++++++++++ src/components/Topology/AppTopology.js | 50 ++++-------- src/models/topology.js | 21 ++---- src/routes/Topology/Topology.js | 12 +-- 6 files changed, 118 insertions(+), 196 deletions(-) diff --git a/.roadhogrc.mock.js b/.roadhogrc.mock.js index 1021e7f..28819b2 100644 --- a/.roadhogrc.mock.js +++ b/.roadhogrc.mock.js @@ -1,10 +1,8 @@ -import mockjs from 'mockjs'; import fs from 'fs'; import { delay } from 'roadhog-api-doc'; -import { getTopology, getServiceTopology } from './mock/topology'; +import { getTopology, getGlobalTopology, getServiceTopology } from './mock/topology'; import { getAllApplication, getApplication } from './mock/application'; import { searchServer, getServer } from './mock/server'; -import { searchService, getService } from './mock/service'; import { Alarms, getNoticeAlarm, AlarmTrend } from './mock/alarm'; import { TraceBrief, Trace } from './mock/trace' import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools'; @@ -19,6 +17,7 @@ const resolvers = { Query: { getTopN, getAllServices, + getGlobalTopology, getServiceTopology, searchEndpoint, } @@ -60,9 +59,6 @@ const proxy = { 'POST /api/application': getApplication, 'POST /api/server/search': searchServer, 'POST /api/server': getServer, - 'POST /api/service/search': searchService, - 'POST /api/service': getService, - 'POST /api/service/options': getAllApplication, 'POST /api/notice': getNoticeAlarm, 'POST /api/login/account': (req, res) => { const { password, userName } = req.body; diff --git a/mock/service.js b/mock/service.js deleted file mode 100644 index a3a21f4..0000000 --- a/mock/service.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -import mockjs from 'mockjs'; - -export default { - searchService(req, res) { - res.json(mockjs.mock( - { - data: { - 'searchService|5': [ - { - 'key|+1': 3, - label: function() { return `service-${this.key}`; }, // eslint-disable-line - }, - ], - }, - } - )); - }, - getService(req, res) { - res.json(mockjs.mock( - { - data: { - queryBasicTraces: () => { - let offset = 0; - let duration = 2500; - return mockjs.mock( - { - 'traces|20': [{ - key: '@id', - operationNames: ['200://wgmb.ev/jcknolzq'], - duration: () => { - duration -= 100; - return duration; - }, - start: function() { // eslint-disable-line - offset = offset + 3600000; // eslint-disable-line - const now = new Date().getTime(); // eslint-disable-line - return `${now + offset}`; - },// eslint-disable-line - 'isError|1': true, - 'traceIds|1-3': ['@guid'], - }], - total: '@natural(20, 1000)', - }, - ); - }, - getServiceResponseTimeTrend: { - 'trendList|60': ['@natural(100, 1000)'], - }, - getServiceThroughputTrend: { - 'trendList|60': ['@natural(500, 10000)'], - }, - getServiceSLATrend: { - 'trendList|60': ['@natural(8000, 10000)'], - }, - getServiceTopology: () => { - const upNodes = mockjs.mock({ - 'nodes|1-5': [ - { - 'id|+1': 100, - name: '@url', - 'type|1': ['DUBBO', 'USER', 'SPRINGMVC'], - 'calls|1000-2000': 1, - 'sla|1-100.1-2': 1, - 'numOfServiceAlarm|1-100': 1, - }, - ], - }); - const centerNodes = mockjs.mock({ - nodes: [ - { - 'id|+1': 1, - name: '@url', - 'type|1': ['DUBBO', 'tomcat', 'SPRINGMVC'], - 'calls|1000-2000': 1, - 'sla|1-100.1-2': 1, - 'numOfServiceAlarm|1-100': 1, - }, - ], - }); - const downNodes = mockjs.mock({ - 'nodes|2-5': [ - { - 'id|+1': 200, - name: '@url', - 'type|1': ['Oracle', 'MYSQL', 'REDIS'], - }, - ], - }); - downNodes.nodes.push({ id: -111 }); - const nodes = upNodes.nodes.concat(centerNodes.nodes, downNodes.nodes); - const calls = upNodes.nodes.map(node => (mockjs.mock({ - source: node.id, - target: 1, - 'isAlert|1': true, - 'callType|1': ['rpc', 'http', 'dubbo'], - 'cpm|0-1000': 1, - 'avgResponseTime|500-5000': 0, - }))).concat(downNodes.nodes.map(node => (mockjs.mock({ - source: 1, - target: node.id, - 'isAlert|1': true, - 'callType|1': ['rpc', 'http', 'dubbo'], - 'cpm|0-2000': 1, - 'avgResponseTime|500-5000': 1, - })))); - calls.push({ source: '-175', target: 1, isAlert: false, callType: 'GRPC', cpm: 0, avgResponseTime: 52 }); - return { - nodes, - calls, - }; - }, - }, - } - )); - }, -}; diff --git a/mock/topology.js b/mock/topology.js index 5480589..fd1fe86 100644 --- a/mock/topology.js +++ b/mock/topology.js @@ -68,6 +68,95 @@ export default { calls, }; }, + getGlobalTopology: () => { + const application = mockjs.mock({ + 'nodes|2-3': [ + { + 'id|+1': 2, + name: '@name', + 'type|1': ['DUBBO', 'tomcat', 'SPRINGMVC'], + isReal: true, + }, + ], + }); + const users = mockjs.mock({ + nodes: [ + { + id: 1, + name: 'User', + type: 'USER', + isReal: false, + }, + ], + }); + const resources = mockjs.mock({ + 'nodes|5': [ + { + 'id|+1': 200, + name: '@name', + 'type|1': ['Oracle', 'MYSQL', 'REDIS'], + isReal: false, + }, + ], + }); + const nodes = users.nodes.concat(application.nodes, resources.nodes); + const userConnectApplication = mockjs.mock({ + calls: [ + { + source: 1, + target: 2, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + { + source: 2, + target: 3, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + { + source: 3, + target: 2, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + { + source: 2, + target: 200, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + { + source: 2, + target: 201, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + { + source: 3, + target: 202, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + { + source: 3, + target: 203, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + { + source: 3, + target: 204, + 'callType|1': ['rpc', 'http', 'dubbo'], + 'cpm|100-2000': 1, + }, + ], + }); + return { + nodes, + calls: userConnectApplication.calls, + }; + }, getTopology(req, res) { res.json(mockjs.mock( { diff --git a/src/components/Topology/AppTopology.js b/src/components/Topology/AppTopology.js index a0f5332..4f51d64 100644 --- a/src/components/Topology/AppTopology.js +++ b/src/components/Topology/AppTopology.js @@ -28,23 +28,10 @@ const conf = { export default class AppTopology extends Base { setUp = (elements) => { const { nodes } = elements; - const cpmArray = nodes.filter(_ => _.data && _.data.cpm).map(_ => _.data.cpm); - const minCPM = Math.min(...cpmArray); - const maxCPM = Math.max(...cpmArray); - const { nodeSize: { min, max } } = conf; - const scale = maxCPM > minCPM ? (max - min) / (maxCPM - minCPM) : 0; const eleWithNewUsers = this.supplyUserNode(elements.edges); return { edges: eleWithNewUsers.edges, - nodes: nodes.filter(_ => !_.data || _.data.id !== '1').map((_) => { - return { - ..._, - data: { - ..._.data, - size: (_.data && _.data.cpm && scale > 0) ? (scale * (_.data.cpm - minCPM)) + min : min, - }, - }; - }).concat(eleWithNewUsers.nodes), + nodes: nodes.filter(_ => !_.data || _.data.id !== '1').concat(eleWithNewUsers.nodes), }; } @@ -81,11 +68,11 @@ export default class AppTopology extends Base { bindEvent = (cy) => { const { onSelectedApplication } = this.props; if (onSelectedApplication) { - cy.on('select', 'node[sla]', (evt) => { + cy.on('select', 'node[?isReal]', (evt) => { const node = evt.target; onSelectedApplication(node.data()); }); - cy.on('unselect', 'node[sla]', () => { + cy.on('unselect', 'node[?isReal]', () => { onSelectedApplication(); }); } @@ -93,37 +80,32 @@ export default class AppTopology extends Base { getStyle = () => { return cytoscape.stylesheet() - .selector('node[sla]') + .selector('node[?isReal]') .css({ - width: 'data(size)', - height: 'data(size)', + width: 60, + height: 60, 'text-valign': 'bottom', 'text-halign': 'center', 'font-family': 'Microsoft YaHei', content: 'data(name)', 'text-margin-y': 10, - 'border-width': ele => (ele.data('isAlarm') ? 10 : 0), + 'border-width': 0, 'border-color': '#A8071A', - 'pie-1-background-color': '#2FC25B', - 'pie-1-background-size': 'data(sla)', - 'pie-1-background-opacity': 0.8, - 'pie-2-background-color': '#F04864', - 'pie-2-background-size': '100 - data(sla)', - 'pie-2-background-opacity': 0.8, + 'background-image': ele => `img/node/${ele.data('type') ? ele.data('type').toUpperCase() : 'UNDEFINED'}.png`, + 'background-width': '60%', + 'background-height': '60%', + 'background-color': '#fff', }) .selector(':selected') .css({ - 'pie-size': '80%', - 'background-color': ele => (ele.data('isAlarm') ? '#A8071A' : '#1890FF'), - 'pie-1-background-opacity': 1, - 'pie-2-background-opacity': 1, + 'border-width': 4, }) .selector('.faded') .css({ opacity: 0.25, 'text-opacity': 0, }) - .selector('node[!sla]') + .selector('node[!isReal]') .css({ width: 60, height: 60, @@ -144,10 +126,10 @@ export default class AppTopology extends Base { 'control-point-step-size': 100, 'target-arrow-shape': 'triangle', 'arrow-scale': 1.7, - 'target-arrow-color': ele => (ele.data('isAlert') ? 'rgb(204, 0, 51)' : 'rgb(147, 198, 174)'), - 'line-color': ele => (ele.data('isAlert') ? 'rgb(204, 0, 51)' : 'rgb(147, 198, 174)'), + 'target-arrow-color': 'rgb(147, 198, 174)', + 'line-color': 'rgb(147, 198, 174)', width: 3, - label: ele => `${ele.data('callType')} \n ${ele.data('cpm')} cpm / ${ele.data('avgResponseTime')} ms`, + label: ele => `${ele.data('callType')} \n ${ele.data('cpm')} cpm`, 'text-wrap': 'wrap', color: 'rgb(110, 112, 116)', 'text-rotation': 'autorotate', diff --git a/src/models/topology.js b/src/models/topology.js index 9ae1643..760f1fa 100644 --- a/src/models/topology.js +++ b/src/models/topology.js @@ -16,41 +16,30 @@ */ -import { generateModal } from '../utils/models'; +import { base } from '../utils/models'; -export default generateModal({ +export default base({ namespace: 'topology', state: { - getClusterTopology: { + getGlobalTopology: { nodes: [], calls: [], }, }, dataQuery: ` query Topology($duration: Duration!) { - getClusterTopology(duration: $duration) { + getGlobalTopology(duration: $duration) { nodes { id name type - ... on ApplicationNode { - sla - cpm - avgResponseTime - apdex - isAlarm - numOfServer - numOfServerAlarm - numOfServiceAlarm - } + isReal } calls { source target - isAlert callType cpm - avgResponseTime } } } diff --git a/src/routes/Topology/Topology.js b/src/routes/Topology/Topology.js index bcd6a26..ff56a81 100644 --- a/src/routes/Topology/Topology.js +++ b/src/routes/Topology/Topology.js @@ -109,16 +109,16 @@ export default class Topology extends PureComponent { } filter = () => { - const { topology: { variables: { appRegExps }, data: { getClusterTopology } } } = this.props; + const { topology: { variables: { appRegExps }, data: { getGlobalTopology } } } = this.props; if (!appRegExps) { - return getClusterTopology; + return getGlobalTopology; } - const nn = getClusterTopology.nodes.filter(_ => appRegExps + const nn = getGlobalTopology.nodes.filter(_ => appRegExps .findIndex(r => _.name.match(r)) > -1); - const cc = getClusterTopology.calls.filter(_ => nn + const cc = getGlobalTopology.calls.filter(_ => nn .findIndex(n => n.id === _.source || n.id === _.target) > -1); return { - nodes: getClusterTopology.nodes.filter(_ => cc + nodes: getGlobalTopology.nodes.filter(_ => cc .findIndex(c => c.source === _.id || c.target === _.id) > -1), calls: cc, }; @@ -206,7 +206,7 @@ export default class Topology extends PureComponent { tokenSeparators={[',']} value={appFilters} > - {data.getClusterTopology.nodes.filter(_ => _.sla) + {data.getGlobalTopology.nodes.filter(_ => _.sla) .map(_ => <Option key={_.name}>{_.name}</Option>)} </Select> <DescriptionList layout="vertical">
