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


The following commit(s) were added to refs/heads/6.0.0/dev by this push:
     new 3c29300  Refactor service page with v6
3c29300 is described below

commit 3c293009b56f6ef904fc442d06fe4d1f4dccb2be
Author: Gao Hongtao <[email protected]>
AuthorDate: Tue Sep 11 17:28:35 2018 +0800

    Refactor service page with v6
---
 .roadhogrc.mock.js                                 |  12 +-
 mock/aggregation.js                                |   2 +
 mock/metadata.js                                   |  31 +-
 mock/topology.js                                   |  13 +-
 src/common/menu.js                                 |   4 +-
 src/common/router.js                               |   4 +-
 .../index.js                                       |  39 +--
 src/models/application.js                          | 238 ---------------
 src/models/service.js                              | 333 +++++++++++++++++++++
 .../Application.js => Service/Service.js}          | 125 ++++----
 .../Application.less => Service/Service.less}      |   0
 .../Server.js => Service/ServiceInstance.js}       |  53 ++--
 src/utils/utils.js                                 |  23 +-
 13 files changed, 499 insertions(+), 378 deletions(-)

diff --git a/.roadhogrc.mock.js b/.roadhogrc.mock.js
index 28819b2..c415afe 100644
--- a/.roadhogrc.mock.js
+++ b/.roadhogrc.mock.js
@@ -1,13 +1,11 @@
 import fs from 'fs';
 import { delay } from 'roadhog-api-doc';
-import { getTopology, getGlobalTopology, getServiceTopology } from 
'./mock/topology';
-import { getAllApplication, getApplication } from './mock/application';
-import { searchServer, getServer } from './mock/server';
+import { getGlobalTopology, getServiceTopology } from './mock/topology';
 import { Alarms, getNoticeAlarm, AlarmTrend } from './mock/alarm';
 import { TraceBrief, Trace } from './mock/trace'
 import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
 import { graphql } from 'graphql';
-import { ClusterBrief, getAllServices, searchEndpoint } from './mock/metadata';
+import { ClusterBrief, getServiceInstances, getAllServices, searchEndpoint } 
from './mock/metadata';
 import { IntValues, Thermodynamic } from './mock/metric';
 import { getTopN } from './mock/aggregation';
 
@@ -17,6 +15,7 @@ const resolvers = {
   Query: {
     getTopN,
     getAllServices,
+    getServiceInstances,
     getGlobalTopology,
     getServiceTopology,
     searchEndpoint,
@@ -54,11 +53,6 @@ const proxy = {
     const { query: source, variables: variableValues } = req.body;
     graphql({ schema, source, variableValues }).then((result) => 
res.send(result));
   },
-  'POST /api/topology': getTopology,
-  'POST /api/application/options': getAllApplication,
-  'POST /api/application': getApplication,
-  'POST /api/server/search': searchServer,
-  'POST /api/server': getServer,
   'POST /api/notice': getNoticeAlarm,
   'POST /api/login/account': (req, res) => {
     const { password, userName } = req.body;
diff --git a/mock/aggregation.js b/mock/aggregation.js
index e03c16a..3047ce3 100644
--- a/mock/aggregation.js
+++ b/mock/aggregation.js
@@ -24,6 +24,8 @@ export default {
       array = mockjs.mock({ 'array|10': [{ 'id|+1': 1, name: '@url', 
'value|200-1000': 1 }]});
     } else if (args.condition.filterScope === 'SERVICE') {
       array = mockjs.mock({ 'array|10': [{ 'id|+1': 1, name: '@name', 
'value|100-10000': 1 }]});
+    } else if (args.condition.filterScope === 'SERVICE_INSTANCE') {
+      array = mockjs.mock({ 'array|10': [{ 'id|+1': 1, name: '@name', 
'value|100-10000': 1 }]});
     }
     return array.array;
   },
diff --git a/mock/metadata.js b/mock/metadata.js
index 12fe2c3..4fdf8d4 100644
--- a/mock/metadata.js
+++ b/mock/metadata.js
@@ -24,8 +24,35 @@ export default {
       'numOfDatabase|1-100': 1,
       'numOfCache|1-100': 1,
       'numOfMQ|1-100': 1,
-    })
-  ,
+  }),
+  getServiceInstances: () => {
+    const data = mockjs.mock({
+      'id|1-10': [{
+        'id|+1': 3,
+        name: '@natural(4, 20)',
+        attributes: [
+          {
+            name: 'os',
+            value: 'LINUX',
+          },
+          {
+            name: 'host',
+            value: 'WORKSAPCE-@name',
+          },
+          {
+            name: 'pid',
+            value: '@natural(4, 20)',
+          },
+          {
+            name: 'ipv4',
+            value: '@ip',
+          },
+        ],
+        'language|1': ['JAVA', 'RUBY', 'DOTNET'],
+    }], // eslint-disable-line
+    });
+    return data.id;
+  },
   getAllServices: () => {
     const data = mockjs.mock({
       'serviceId|20-50': [{ 'id|+1': 3, name: function() { return 
`service-${this.id}`; } }], // eslint-disable-line
diff --git a/mock/topology.js b/mock/topology.js
index fd1fe86..7a82c64 100644
--- a/mock/topology.js
+++ b/mock/topology.js
@@ -26,15 +26,17 @@ export default {
           'id|+1': 100,
           name: '@url',
           'type|1': ['DUBBO', 'USER', 'SPRINGMVC'],
+          isReal: true,
         },
       ],
     });
     const centerNodes = mockjs.mock({
       nodes: [
         {
-          'id|+1': 1,
+          'id|+1': 10,
           name: '@url',
           'type|1': ['DUBBO', 'tomcat', 'SPRINGMVC'],
+          isReal: true,
         },
       ],
     });
@@ -44,6 +46,7 @@ export default {
           'id|+1': 200,
           name: '@url',
           'type|1': ['Oracle', 'MYSQL', 'REDIS'],
+          isReal: false,
         },
       ],
     });
@@ -51,18 +54,16 @@ export default {
     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,
+      target: 10,
       'callType|1': ['rpc', 'http', 'dubbo'],
       'cpm|0-1000': 1,
     }))).concat(downNodes.nodes.map(node => (mockjs.mock({
-      source: 1,
+      source: 10,
       target: node.id,
-      'isAlert|1': true,
       'callType|1': ['rpc', 'http', 'dubbo'],
       'cpm|0-2000': 1,
     }))));
-    calls.push({ source: '-175', target: 1, isAlert: false, callType: 'GRPC', 
cpm: 0, avgResponseTime: 52 });
+    calls.push({ source: '-175', target: 10, callType: 'GRPC', cpm: 0 });
     return {
       nodes,
       calls,
diff --git a/src/common/menu.js b/src/common/menu.js
index bc98328..eb64c7c 100644
--- a/src/common/menu.js
+++ b/src/common/menu.js
@@ -31,8 +31,8 @@ const menuData = [{
       name: 'Topology',
       path: 'topology',
     }, {
-      name: 'Application',
-      path: 'application',
+      name: 'Service',
+      path: 'service',
     }, {
       name: 'Endpoint',
       path: 'endpoint',
diff --git a/src/common/router.js b/src/common/router.js
index db30edd..6cbbf87 100644
--- a/src/common/router.js
+++ b/src/common/router.js
@@ -97,8 +97,8 @@ export const getRouterData = (app) => {
     '/monitor/topology': {
       component: dynamicWrapper(app, ['topology'], () => 
import('../routes/Topology/Topology')),
     },
-    '/monitor/application': {
-      component: dynamicWrapper(app, ['application'], () => 
import('../routes/Application/Application')),
+    '/monitor/service': {
+      component: dynamicWrapper(app, ['service'], () => 
import('../routes/Service/Service')),
     },
     '/monitor/endpoint': {
       component: dynamicWrapper(app, ['endpoint'], () => 
import('../routes/Endpoint/Endpoint')),
diff --git a/src/components/ServerLitePanel/index.js 
b/src/components/ServiceInstanceLitePanel/index.js
similarity index 59%
rename from src/components/ServerLitePanel/index.js
rename to src/components/ServiceInstanceLitePanel/index.js
index a3d896c..dbe64ee 100644
--- a/src/components/ServerLitePanel/index.js
+++ b/src/components/ServiceInstanceLitePanel/index.js
@@ -22,55 +22,56 @@ import {
   ChartCard, MiniArea, MiniBar,
 } from "../Charts";
 import DescriptionList from "../DescriptionList";
-import { axis } from '../../utils/time';
-import { avgTimeSeries, getServerId } from '../../utils/utils';
+import { axisY } from '../../utils/time';
+import { avgTS, getAttributes, getServiceInstanceId } from '../../utils/utils';
 
 const { Option } = Select;
 const { Description } = DescriptionList;
 
-export default class ServerLitePanel extends PureComponent {
+export default class ServiceInstanceLitePanel extends PureComponent {
   bytesToMB = list => list.map(_ => parseFloat((_ / (1024 ** 2)).toFixed(2)))
 
   render() {
-    const { serverList, duration, data, onSelectServer, onMoreServer } = 
this.props;
-    if (serverList.length < 1) {
+    const { serviceInstanceList, duration, data, onSelectServiceInstance, 
onMoreServiceInstance } = this.props;
+    if (serviceInstanceList.length < 1) {
       return null;
     }
-    const { serverInfo, getServerResponseTimeTrend, getServerThroughputTrend } 
= data;
-    if (!serverInfo.key) {
-      onSelectServer(serverList[0].key, serverList[0]);
+    const { serviceInstanceInfo, getServiceInstanceResponseTimeTrend, 
getServiceInstanceThroughputTrend } = data;
+    if (!serviceInstanceInfo.key) {
+      onSelectServiceInstance(serviceInstanceList[0].key, 
serviceInstanceList[0]);
     }
+    const { attributes } = serviceInstanceInfo;
     return (
       <div>
         <Row gutter={0}>
           <Col span={24}>
             <Select
               size="small"
-              value={serverInfo.key}
-              onChange={value => onSelectServer(value, serverList.find(_ => 
_.key === value))}
+              value={serviceInstanceInfo.key}
+              onChange={value => onSelectServiceInstance(value, 
serviceInstanceList.find(_ => _.key === value))}
               style={{ width: '100%' }}
             >
-              {serverList.map(_ => <Option key={_.key} 
value={_.key}>{getServerId(_)}</Option>)}
+              {serviceInstanceList.map(_ => <Option key={_.key} 
value={_.key}>{getServiceInstanceId(_)}</Option>)}
             </Select>
           </Col>
           <Col span={24}>
             <Card bordered={false} bodyStyle={{ padding: 5 }}>
               <DescriptionList col={1} gutter={0} size="small">
-                <Description term="Host">{serverInfo.host}</Description>
-                <Description term="OS">{serverInfo.osName}</Description>
+                <Description term="Host">{getAttributes(attributes, 
'host')}</Description>
+                <Description term="OS">{getAttributes(attributes, 
'os')}</Description>
               </DescriptionList>
             </Card>
           </Col>
           <Col span={24}>
             <ChartCard
               title="Avg Throughput"
-              total={`${avgTimeSeries(getServerThroughputTrend.trendList)} 
cpm`}
+              total={`${avgTS(getServiceInstanceThroughputTrend.values)} cpm`}
               contentHeight={46}
               bordered={false}
               bodyStyle={{ padding: 5 }}
             >
               <MiniBar
-                data={axis(duration, getServerThroughputTrend.trendList)}
+                data={axisY(duration, 
getServiceInstanceThroughputTrend.values)}
                 color="#975FE4"
               />
             </ChartCard>
@@ -78,22 +79,22 @@ export default class ServerLitePanel extends PureComponent {
           <Col span={24}>
             <ChartCard
               title="Avg Response Time"
-              total={`${avgTimeSeries(getServerResponseTimeTrend.trendList)} 
ms`}
+              total={`${avgTS(getServiceInstanceResponseTimeTrend.values)} ms`}
               contentHeight={46}
               bordered={false}
               bodyStyle={{ padding: 5 }}
             >
-              {getServerResponseTimeTrend.trendList.length > 0 ? (
+              {getServiceInstanceResponseTimeTrend.values.length > 0 ? (
                 <MiniArea
                   animate={false}
                   color="#87cefa"
-                  data={axis(duration, getServerResponseTimeTrend.trendList)}
+                  data={axisY(duration, 
getServiceInstanceResponseTimeTrend.values)}
                 />
               ) : (<span style={{ display: 'none' }} />)}
             </ChartCard>
           </Col>
         </Row>
-        {serverInfo.key ? <a style={{ float: 'right' }} 
onClick={onMoreServer}> More Server Details<Icon type="ellipsis" /> </a> : null}
+        {serviceInstanceInfo.key ? <a style={{ float: 'right' }} 
onClick={onMoreServiceInstance}> More Server Details<Icon type="ellipsis" /> 
</a> : null}
       </div>
     );
   }
diff --git a/src/models/application.js b/src/models/application.js
deleted file mode 100644
index cd40b39..0000000
--- a/src/models/application.js
+++ /dev/null
@@ -1,238 +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 { generateModal } from '../utils/models';
-import { query as queryService } from '../services/graphql';
-
-const optionsQuery = `
-  query ApplicationOption($duration: Duration!) {
-    applicationId: getAllApplication(duration: $duration) {
-      key: id
-      label: name
-    }
-  }
-`;
-
-const dataQuery = `
-  query Application($applicationId: ID!, $duration: Duration!) {
-    getSlowService(applicationId: $applicationId, duration: $duration, topN: 
10) {
-      service {
-        key: id
-        label: name
-        applicationId
-        applicationName
-      }
-      value: avgResponseTime
-    }
-    getServerThroughput(applicationId: $applicationId, duration: $duration, 
topN: 999999) {
-      key: id
-      osName
-      host
-      pid
-      ipv4
-      value: cpm
-    }
-    getApplicationTopology(applicationId: $applicationId, duration: $duration) 
{
-      nodes {
-        id
-        name
-        type
-        ... on ApplicationNode {
-          sla
-          cpm
-          avgResponseTime
-          apdex
-          isAlarm
-          numOfServer
-          numOfServerAlarm
-          numOfServiceAlarm
-        }
-      }
-      calls {
-        source
-        target
-        isAlert
-        callType
-        cpm
-        avgResponseTime
-      }
-    }
-  }
-`;
-
-const serverQuery = `
-query Application($serverId: ID!, $duration: Duration!) {
-  getServerResponseTimeTrend(serverId: $serverId, duration: $duration) {
-    trendList
-  }
-  getServerThroughputTrend(serverId: $serverId, duration: $duration) {
-    trendList
-  }
-  getCPUTrend(serverId: $serverId, duration: $duration) {
-    cost
-  }
-  getGCTrend(serverId: $serverId, duration: $duration) {
-    youngGCCount
-    oldGCount
-    youngGCTime
-    oldGCTime
-  }
-  getMemoryTrend(serverId: $serverId, duration: $duration) {
-    heap
-    maxHeap
-    noheap
-    maxNoheap
-  }
-}
-`;
-
-export default generateModal({
-  namespace: 'application',
-  state: {
-    allApplication: [],
-    getSlowService: [],
-    getServerThroughput: [],
-    getApplicationTopology: {
-      nodes: [],
-      calls: [],
-    },
-    showServer: false,
-    serverInfo: {},
-    getServerResponseTimeTrend: {
-      trendList: [],
-    },
-    getServerThroughputTrend: {
-      trendList: [],
-    },
-    getCPUTrend: {
-      cost: [],
-    },
-    getMemoryTrend: {
-      heap: [],
-      maxHeap: [],
-      noheap: [],
-      maxNoheap: [],
-    },
-    getGCTrend: {
-      youngGCCount: [],
-      oldGCount: [],
-      youngGCTime: [],
-      oldGCTime: [],
-    },
-  },
-  optionsQuery,
-  dataQuery,
-  effects: {
-    *fetchServer({ payload }, { call, put }) {
-      const { variables, serverInfo } = payload;
-      const response = yield call(queryService, 'server', { variables, query: 
serverQuery });
-      if (!response.data) {
-        return;
-      }
-      yield put({
-        type: 'saveServer',
-        payload: response.data,
-        serverInfo,
-      });
-    },
-  },
-  reducers: {
-    saveApplication(preState, { payload }) {
-      const { data } = preState;
-      return {
-        ...preState,
-        data: {
-          ...data,
-          ...payload,
-          serverInfo: {},
-          getServerResponseTimeTrend: {
-            trendList: [],
-          },
-          getServerThroughputTrend: {
-            trendList: [],
-          },
-          getCPUTrend: {
-            cost: [],
-          },
-          getMemoryTrend: {
-            heap: [],
-            maxHeap: [],
-            noheap: [],
-            maxNoheap: [],
-          },
-          getGCTrend: {
-            youngGCCount: [],
-            oldGCount: [],
-            youngGCTime: [],
-            oldGCTime: [],
-          },
-        },
-      };
-    },
-    saveServer(preState, { payload, serverInfo }) {
-      const { data } = preState;
-      return {
-        ...preState,
-        data: {
-          ...data,
-          serverInfo,
-          ...payload,
-        },
-      };
-    },
-    showServer(preState) {
-      const { data } = preState;
-      return {
-        ...preState,
-        data: {
-          ...data,
-          showServer: true,
-        },
-      };
-    },
-    hideServer(preState) {
-      const { data } = preState;
-      return {
-        ...preState,
-        data: {
-          ...data,
-          showServer: false,
-        },
-      };
-    },
-  },
-  subscriptions: {
-    setup({ history, dispatch }) {
-      return history.listen(({ pathname, state }) => {
-        if (pathname === '/monitor/application' && state) {
-          dispatch({
-            type: 'saveVariables',
-            payload: {
-              values: {
-                applicationId: `${state.key}`,
-              },
-              labels: {
-                applicationId: state.label,
-              },
-            },
-          });
-        }
-      });
-    },
-  },
-});
diff --git a/src/models/service.js b/src/models/service.js
new file mode 100644
index 0000000..6cb391b
--- /dev/null
+++ b/src/models/service.js
@@ -0,0 +1,333 @@
+/**
+ * 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 { base } from '../utils/models';
+import { exec } from '../services/graphql';
+
+const optionsQuery = `
+  query ServiceOption($duration: Duration!) {
+    serviceId: getAllServices(duration: $duration) {
+      key: id
+      label: name
+    }
+  }
+`;
+
+const dataQuery = `
+  query Service($serviceId: ID!, $duration: Duration!) {
+    getSlowEndpoint: getTopN(duration: $duration, condition: {
+      name: "slowEndpoint",
+      topN: 10,
+      order: DES,
+      filterScope: ENDPOINT,
+      filterId: $serviceId
+    }) {
+      key: id
+      label: name
+      value
+    }
+    getServiceInstanceThroughput: getTopN(duration: $duration, condition: {
+      name: "serviceInstanceThroughtput",
+      topN: 10,
+      order: DES,
+      filterScope: SERVICE_INSTANCE,
+      filterId: $serviceId
+    }) {
+      key: id
+      label: name
+      value
+    }
+    getServiceInstances(duration: $duration, id: $serviceId) {
+      key: id
+      name
+      attributes {
+        name
+        value
+      }
+      language
+    }
+    getServiceTopology(serviceId: $serviceId, duration: $duration) {
+      nodes {
+        id
+        name
+        type
+        isReal
+      }
+      calls {
+        source
+        target
+        callType
+        cpm
+      }
+    }
+  }
+`;
+
+const serviceInstanceQuery = `
+query ServiceInstance($serviceInstanceId: ID!, $duration: Duration!) {
+  getServiceInstanceResponseTimeTrend: getLinearIntValues(metric: {
+    name: "serviceInstanceResponseTimeTrend"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  getServiceInstanceThroughputTrend: getLinearIntValues(metric: {
+    name: "serviceInstanceThroughputTrend"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  getCPUTrend: getLinearIntValues(metric: {
+    name: "CPUTrend"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  youngGCCount: getLinearIntValues(metric: {
+    name: "youngGCCount"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  oldGCCount: getLinearIntValues(metric: {
+    name: "oldGCCount"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  youngGCTime: getLinearIntValues(metric: {
+    name: "youngGCTime"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  oldGCTime: getLinearIntValues(metric: {
+    name: "oldGCTime"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  heap: getLinearIntValues(metric: {
+    name: "heap"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  maxHeap: getLinearIntValues(metric: {
+    name: "maxHeap"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  noheap: getLinearIntValues(metric: {
+    name: "noheap"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+  maxNoheap: getLinearIntValues(metric: {
+    name: "maxNoheap"
+    id: $serviceInstanceId
+  }, duration: $duration) {
+    values {
+      value
+    }
+  }
+}
+`;
+
+export default base({
+  namespace: 'service',
+  state: {
+    allService: [],
+    getSlowEndpoint: [],
+    getServiceInstanceThroughput: [],
+    getServiceTopology: {
+      nodes: [],
+      calls: [],
+    },
+    getServiceInstances: [],
+    showServiceInstance: false,
+    serviceInstanceInfo: {},
+    getServiceInstanceResponseTimeTrend: {
+      values: [],
+    },
+    getServiceInstanceThroughputTrend: {
+      values: [],
+    },
+    getCPUTrend: {
+      values: [],
+    },
+    heap: {
+      values: [],
+    },
+    maxHeap: {
+      values: [],
+    },
+    noheap: {
+      values: [],
+    },
+    maxNoheap: {
+      values: [],
+    },
+    youngGCCount: {
+      values: [],
+    },
+    oldGCCount: {
+      values: [],
+    },
+    youngGCTime: {
+      values: [],
+    },
+    oldGCTime: {
+      values: [],
+    },
+  },
+  optionsQuery,
+  dataQuery,
+  effects: {
+    *fetchServiceInstance({ payload }, { call, put }) {
+      const { variables, serviceInstanceInfo } = payload;
+      const response = yield call(exec, { variables, query: 
serviceInstanceQuery });
+      if (!response.data) {
+        return;
+      }
+      yield put({
+        type: 'saveServiceInstance',
+        payload: response.data,
+        serviceInstanceInfo,
+      });
+    },
+  },
+  reducers: {
+    saveService(preState, { payload }) {
+      const { data } = preState;
+      return {
+        ...preState,
+        data: {
+          ...data,
+          ...payload,
+          serviceInstanceInfo: {},
+          getServiceInstanceResponseTimeTrend: {
+            values: [],
+          },
+          getServiceInstanceThroughputTrend: {
+            values: [],
+          },
+          getCPUTrend: {
+            values: [],
+          },
+          heap: {
+            values: [],
+          },
+          maxHeap: {
+            values: [],
+          },
+          noheap: {
+            values: [],
+          },
+          maxNoheap: {
+            values: [],
+          },
+          youngGCCount: {
+            values: [],
+          },
+          oldGCCount: {
+            values: [],
+          },
+          youngGCTime: {
+            values: [],
+          },
+          oldGCTime: {
+            values: [],
+          },
+        },
+      };
+    },
+    saveServiceInstance(preState, { payload, serviceInstanceInfo }) {
+      const { data } = preState;
+      return {
+        ...preState,
+        data: {
+          ...data,
+          serviceInstanceInfo,
+          ...payload,
+        },
+      };
+    },
+    showServiceInstance(preState) {
+      const { data } = preState;
+      return {
+        ...preState,
+        data: {
+          ...data,
+          showServiceInstance: true,
+        },
+      };
+    },
+    hideServiceInstance(preState) {
+      const { data } = preState;
+      return {
+        ...preState,
+        data: {
+          ...data,
+          showServiceInstance: false,
+        },
+      };
+    },
+  },
+  subscriptions: {
+    setup({ history, dispatch }) {
+      return history.listen(({ pathname, state }) => {
+        if (pathname === '/monitor/service' && state) {
+          dispatch({
+            type: 'saveVariables',
+            payload: {
+              values: {
+                serviceId: `${state.key}`,
+              },
+              labels: {
+                serviceId: state.label,
+              },
+            },
+          });
+        }
+      });
+    },
+  },
+});
diff --git a/src/routes/Application/Application.js 
b/src/routes/Service/Service.js
similarity index 60%
rename from src/routes/Application/Application.js
rename to src/routes/Service/Service.js
index 5281f54..07985b9 100644
--- a/src/routes/Application/Application.js
+++ b/src/routes/Service/Service.js
@@ -19,12 +19,12 @@
 import React, { PureComponent } from 'react';
 import { connect } from 'dva';
 import { Row, Col, Select, Card, Form, Breadcrumb } from 'antd';
-import Server from './Server';
-import { AppTopology } from '../../components/Topology';
-import { Panel } from '../../components/Page';
-import RankList from '../../components/RankList';
-import ServerLitePanel from '../../components/ServerLitePanel';
-import { getServerId, redirect } from '../../utils/utils';
+import { AppTopology } from 'components/Topology';
+import { Panel } from 'components/Page';
+import RankList from 'components/RankList';
+import ServiceInstanceLitePanel from 'components/ServiceInstanceLitePanel';
+import ServiceInstance from './ServiceInstance';
+import { getServiceInstanceId, redirect } from '../../utils/utils';
 
 const { Option } = Select;
 const { Item: FormItem } = Form;
@@ -39,24 +39,24 @@ const middleColResponsiveProps = {
 };
 
 @connect(state => ({
-  application: state.application,
+  service: state.service,
   duration: state.global.duration,
   globalVariables: state.global.globalVariables,
 }))
 @Form.create({
   mapPropsToFields(props) {
-    const { variables: { values, labels } } = props.application;
+    const { variables: { values, labels } } = props.service;
     return {
-      applicationId: Form.createFormField({
-        value: { key: values.applicationId ? values.applicationId : '', label: 
labels.applicationId ? labels.applicationId : '' },
+      serviceId: Form.createFormField({
+        value: { key: values.serviceId ? values.serviceId : '', label: 
labels.serviceId ? labels.serviceId : '' },
       }),
     };
   },
 })
-export default class Application extends PureComponent {
+export default class Service extends PureComponent {
   componentDidMount() {
     this.props.dispatch({
-      type: 'application/initOptions',
+      type: 'service/initOptions',
       payload: { variables: this.props.globalVariables },
     });
   }
@@ -66,71 +66,71 @@ export default class Application extends PureComponent {
       return;
     }
     this.props.dispatch({
-      type: 'application/initOptions',
+      type: 'service/initOptions',
       payload: { variables: nextProps.globalVariables },
     });
   }
 
   handleSelect = (selected) => {
     this.props.dispatch({
-      type: 'application/saveVariables',
+      type: 'service/saveVariables',
       payload: {
-        values: { applicationId: selected.key },
-        labels: { applicationId: selected.label },
+        values: { serviceId: selected.key },
+        labels: { serviceId: selected.label },
       },
     });
   }
 
   handleChange = (variables) => {
-    const { data: { serverInfo, showServer } } = this.props.application;
-    if (showServer) {
-      this.handleSelectServer(serverInfo.key, serverInfo);
+    const { data: { serviceInstanceInfo, showServiceInstance } } = 
this.props.service;
+    if (showServiceInstance) {
+      this.handleSelectServiceInstance(serviceInstanceInfo.key, 
serviceInstanceInfo);
     } else {
       this.props.dispatch({
-        type: 'application/fetchData',
-        payload: { variables, reducer: 'saveApplication' },
+        type: 'service/fetchData',
+        payload: { variables, reducer: 'saveService' },
       });
     }
   }
 
-  handleGoApplication = () => {
+  handleGoService = () => {
     this.props.dispatch({
-      type: 'application/hideServer',
+      type: 'service/hideServiceInstance',
     });
   }
 
-  handleGoServer = () => {
+  handleGoServiceInstance = () => {
     this.props.dispatch({
-      type: 'application/showServer',
+      type: 'service/showServiceInstance',
     });
   }
 
-  handleSelectServer = (serverId, serverInfo) => {
+  handleSelectServiceInstance = (serviceInstanceId, serviceInstanceInfo) => {
     const { globalVariables: { duration } } = this.props;
     this.props.dispatch({
-      type: 'application/fetchServer',
-      payload: { variables: { duration, serverId }, serverInfo },
+      type: 'service/fetchServiceInstance',
+      payload: { variables: { duration, serviceInstanceId }, 
serviceInstanceInfo },
     });
   }
 
   renderApp = () => {
     const { getFieldDecorator } = this.props.form;
-    const { variables: { values, options }, data } = this.props.application;
+    const { variables: { values, options, labels }, data } = 
this.props.service;
     return (
       <div>
         <Form layout="inline">
           <FormItem>
-            {getFieldDecorator('applicationId')(
+            {getFieldDecorator('serviceId')(
               <Select
                 showSearch
                 optionFilterProp="children"
                 style={{ width: 200 }}
-                placeholder="Select a application"
+                placeholder="Select a service"
                 labelInValue
                 onSelect={this.handleSelect.bind(this)}
               >
-                {options.applicationId && options.applicationId.map(app =>
-                  <Option key={app.key} value={app.key}>{app.label}</Option>)}
+                {options.serviceId && options.serviceId.map(service =>
+                  <Option key={service.key} 
value={service.key}>{service.label}</Option>)}
               </Select>
             )}
           </FormItem>
@@ -143,12 +143,12 @@ export default class Application extends PureComponent {
           <Row gutter={0}>
             <Col {...{ ...middleColResponsiveProps, xl: 16, lg: 12, md: 24 }}>
               <Card
-                title="Application Map"
+                title="Service Map"
                 bordered={false}
                 bodyStyle={{ padding: 0 }}
               >
                 <AppTopology
-                  elements={data.getApplicationTopology}
+                  elements={data.getServiceTopology}
                   height={335}
                   layout={{
                     name: 'dagre',
@@ -163,12 +163,12 @@ export default class Application extends PureComponent {
                 bordered={false}
                 bodyStyle={{ padding: '10px 10px', height: 391 }}
               >
-                <ServerLitePanel
+                <ServiceInstanceLitePanel
                   data={data}
-                  serverList={data.getServerThroughput}
+                  serviceInstanceList={data.getServiceInstances}
                   duration={this.props.duration}
-                  onSelectServer={this.handleSelectServer}
-                  onMoreServer={this.handleGoServer}
+                  onSelectServiceInstance={this.handleSelectServiceInstance}
+                  onMoreServiceInstance={this.handleGoServiceInstance}
                 />
               </Card>
             </Col>
@@ -176,43 +176,30 @@ export default class Application extends PureComponent {
           <Row gutter={8}>
             <Col {...{ ...middleColResponsiveProps, xl: 12, lg: 12, md: 24 }}>
               <Card
-                title="Running Server"
+                title="Running ServiceInstance"
                 bordered={false}
                 bodyStyle={{ padding: 5 }}
               >
                 <RankList
-                  data={data.getServerThroughput}
-                  renderLabel={getServerId}
+                  data={data.getServiceInstanceThroughput}
                   renderValue={_ => `${_.value} cpm`}
-                  renderBadge={_ => ([
-                    {
-                      key: 'host',
-                      label: 'Host',
-                      value: _.host,
-                    },
-                    {
-                      key: 'os',
-                      label: 'OS',
-                      value: _.osName,
-                    },
-                  ])}
                   color="#965fe466"
                 />
               </Card>
             </Col>
             <Col {...{ ...middleColResponsiveProps, xl: 12, lg: 12, md: 24 }}>
               <Card
-                title="Slow Service"
+                title="Slow Endpoint"
                 bordered={false}
                 bodyStyle={{ padding: '0px 10px' }}
               >
                 <RankList
-                  data={data.getSlowService.map(_ => ({ ..._.service, value: 
_.value }))}
+                  data={data.getSlowEndpoint}
                   renderValue={_ => `${_.value} ms`}
-                  onClick={(key, item) => redirect(this.props.history, 
'/monitor/service', { key,
+                  onClick={(key, item) => redirect(this.props.history, 
'/monitor/endpoint', { key,
                     label: item.label,
-                    applicationId: item.applicationId,
-                    applicationName: item.applicationName })}
+                    serviceId: values.serviceId,
+                    serviceName: labels.serviceId })}
                 />
               </Card>
             </Col>
@@ -223,32 +210,32 @@ export default class Application extends PureComponent {
   }
 
   render() {
-    const { application, duration } = this.props;
-    const { variables, data } = application;
-    const { showServer, serverInfo } = data;
+    const { service, duration } = this.props;
+    const { variables, data } = service;
+    const { showServiceInstance, serviceInstanceInfo } = data;
     return (
       <Row type="flex" justify="start">
-        {showServer ? (
-          <Col span={showServer ? 24 : 0}>
+        {showServiceInstance ? (
+          <Col span={showServiceInstance ? 24 : 0}>
             <Breadcrumb>
               <Breadcrumb.Item>
-                Application
+                Service
               </Breadcrumb.Item>
               <Breadcrumb.Item>
-                <a 
onClick={this.handleGoApplication}>{variables.labels.applicationId}</a>
+                <a 
onClick={this.handleGoService}>{variables.labels.serviceId}</a>
               </Breadcrumb.Item>
-              <Breadcrumb.Item>{getServerId(serverInfo)}</Breadcrumb.Item>
+              
<Breadcrumb.Item>{getServiceInstanceId(serviceInstanceInfo)}</Breadcrumb.Item>
             </Breadcrumb>
             <Panel
               variables={variables.values}
               globalVariables={this.props.globalVariables}
               onChange={this.handleChange}
             >
-              <Server data={data} duration={duration} />
+              <ServiceInstance data={data} duration={duration} />
             </Panel>
           </Col>
          ) : null}
-        <Col span={showServer ? 0 : 24}>
+        <Col span={showServiceInstance ? 0 : 24}>
           {this.renderApp()}
         </Col>
       </Row>
diff --git a/src/routes/Application/Application.less 
b/src/routes/Service/Service.less
similarity index 100%
rename from src/routes/Application/Application.less
rename to src/routes/Service/Service.less
diff --git a/src/routes/Application/Server.js 
b/src/routes/Service/ServiceInstance.js
similarity index 64%
rename from src/routes/Application/Server.js
rename to src/routes/Service/ServiceInstance.js
index f3945ce..fa1cdd2 100644
--- a/src/routes/Application/Server.js
+++ b/src/routes/Service/ServiceInstance.js
@@ -20,31 +20,32 @@ import React, { PureComponent } from 'react';
 import { Row, Col, Card, Tag } from 'antd';
 import {
   ChartCard, MiniArea, MiniBar, Line, Area, StackBar,
-} from '../../components/Charts';
-import DescriptionList from '../../components/DescriptionList';
-import { axis } from '../../utils/time';
-import { avgTimeSeries } from '../../utils/utils';
+} from 'components/Charts';
+import DescriptionList from 'components/DescriptionList';
+import { axisY } from '../../utils/time';
+import { avgTS, getAttributes } from '../../utils/utils';
 
 const { Description } = DescriptionList;
 
 
-export default class Server extends PureComponent {
-  bytesToMB = list => list.map(_ => parseFloat((_ / (1024 ** 2)).toFixed(2)))
+export default class ServiceInstance extends PureComponent {
+  bytesToMB = list => list.map(_ => ({ value: parseFloat((_.value / (1024 ** 
2)).toFixed(2))}))
 
   render() {
     const { duration, data } = this.props;
-    const { serverInfo, getServerResponseTimeTrend, getServerThroughputTrend,
-      getCPUTrend, getMemoryTrend, getGCTrend } = data;
+    const { serviceInstanceInfo, getServiceInstanceResponseTimeTrend, 
getServiceInstanceThroughputTrend,
+      getCPUTrend, heap, maxHeap, noheap, maxNoheap, youngGCCount, oldGCCount, 
youngGCTime, oldGCTime } = data;
+    const { attributes } = serviceInstanceInfo;
     return (
       <div>
         <Row gutter={8}>
           <Col xs={24} sm={24} md={24} lg={6} xl={6} style={{ marginTop: 8 }}>
             <Card style={{ marginTop: 8 }} bordered={false}>
               <DescriptionList col={1} layout="vertical">
-                <Description term="Host">{serverInfo.host}</Description>
-                <Description term="IPv4">{serverInfo.ipv4 ? 
serverInfo.ipv4.join() : ''}</Description>
-                <Description term="Pid">{serverInfo.pid}</Description>
-                <Description term="OS">{serverInfo.osName}</Description>
+                <Description term="Host">{getAttributes(attributes, 
'host')}</Description>
+                <Description term="IPv4">{getAttributes(attributes, 
'ipv4')}</Description>
+                <Description term="Pid">{getAttributes(attributes, 
'pid')}</Description>
+                <Description term="OS">{getAttributes(attributes, 
'os')}</Description>
               </DescriptionList>
             </Card>
           </Col>
@@ -53,24 +54,24 @@ export default class Server extends PureComponent {
               <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 
8 }}>
                 <ChartCard
                   title="Avg Throughput"
-                  total={`${avgTimeSeries(getServerThroughputTrend.trendList)} 
cpm`}
+                  total={`${avgTS(getServiceInstanceThroughputTrend.values)} 
cpm`}
                   contentHeight={46}
                 >
                   <MiniBar
                     color="#975FE4"
-                    data={axis(duration, getServerThroughputTrend.trendList)}
+                    data={axisY(duration, 
getServiceInstanceThroughputTrend.values)}
                   />
                 </ChartCard>
               </Col>
               <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 
8 }}>
                 <ChartCard
                   title="Avg Response Time"
-                  
total={`${avgTimeSeries(getServerResponseTimeTrend.trendList)} ms`}
+                  total={`${avgTS(getServiceInstanceResponseTimeTrend.values)} 
ms`}
                   contentHeight={46}
                 >
-                  {getServerResponseTimeTrend.trendList.length > 0 ? (
+                  {getServiceInstanceResponseTimeTrend.values.length > 0 ? (
                     <MiniArea
-                      data={axis(duration, 
getServerResponseTimeTrend.trendList)}
+                      data={axisY(duration, 
getServiceInstanceResponseTimeTrend.values)}
                     />
                   ) : (<span style={{ display: 'none' }} />)}
                 </ChartCard>
@@ -83,7 +84,7 @@ export default class Server extends PureComponent {
                   contentHeight={150}
                 >
                   <Line
-                    data={axis(duration, getCPUTrend.cost)}
+                    data={axisY(duration, getCPUTrend.values)}
                   />
                 </ChartCard>
               </Col>
@@ -95,8 +96,8 @@ export default class Server extends PureComponent {
                   contentHeight={150}
                 >
                   <Area
-                    data={axis(duration, this.bytesToMB(getMemoryTrend.heap), 
({ x, y }) => ({ x, y, type: 'value' }))
-                      .concat(axis(duration, 
this.bytesToMB(getMemoryTrend.maxHeap), ({ x, y }) => ({ x, y, type: 'free' 
})))}
+                    data={axisY(duration, this.bytesToMB(heap.values), ({ x, y 
}) => ({ x, y, type: 'value' }))
+                      .concat(axisY(duration, this.bytesToMB(maxHeap.values), 
({ x, y }) => ({ x, y, type: 'free' })))}
                   />
                 </ChartCard>
               </Col>
@@ -106,8 +107,8 @@ export default class Server extends PureComponent {
                   contentHeight={150}
                 >
                   <Area
-                    data={axis(duration, 
this.bytesToMB(getMemoryTrend.noheap), ({ x, y }) => ({ x, y, type: 'value' }))
-                    .concat(axis(duration, 
this.bytesToMB(getMemoryTrend.maxNoheap), ({ x, y }) => ({ x, y, type: 'free' 
})))}
+                    data={axisY(duration, this.bytesToMB(noheap.values), ({ x, 
y }) => ({ x, y, type: 'value' }))
+                    .concat(axisY(duration, this.bytesToMB(maxNoheap.values), 
({ x, y }) => ({ x, y, type: 'free' })))}
                   />
                 </ChartCard>
               </Col>
@@ -122,14 +123,14 @@ export default class Server extends PureComponent {
                       <div style={{ marginBottom: 10 }}>
                         <span style={{ marginRight: 10 }}>Young GC</span>
                         <Tag color="#66b5ff">
-                          {getGCTrend.youngGCCount.reduce((sum, v) => sum + v)}
+                          {youngGCCount.values.map(_ => _.value).reduce((sum, 
v) => sum + v)}
                         </Tag>
                         <span>collections</span>
                       </div>
                       <div>
                         <span style={{ marginRight: 10 }}>Old GC</span>
                         <Tag color="#ffb566">
-                          {getGCTrend.oldGCount.reduce((sum, v) => sum + v)}
+                          {oldGCCount.values.map(_ => _.value).reduce((sum, v) 
=> sum + v)}
                         </Tag>
                         <span>collections</span>
                       </div>
@@ -137,8 +138,8 @@ export default class Server extends PureComponent {
                   }
                 >
                   <StackBar
-                    data={axis(duration, getGCTrend.youngGCTime, ({ x, y }) => 
({ x, y, type: 'youngGCTime' }))
-                    .concat(axis(duration, getGCTrend.oldGCTime, ({ x, y }) => 
({ x, y, type: 'oldGCTime' })))}
+                    data={axisY(duration, youngGCTime.values, ({ x, y }) => ({ 
x, y, type: 'youngGCTime' }))
+                    .concat(axisY(duration, oldGCTime.values, ({ x, y }) => ({ 
x, y, type: 'oldGCTime' })))}
                   />
                 </ChartCard>
               </Col>
diff --git a/src/utils/utils.js b/src/utils/utils.js
index d6c4e3b..130dd1c 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -114,12 +114,25 @@ export function isUrl(path) {
   return reg.test(path);
 }
 
-export function getServerId(serverInfo) {
-  let { host } = serverInfo;
-  if (serverInfo.ipv4 && serverInfo.ipv4.length > 0) {
-    [host] = serverInfo.ipv4;
+export function getServiceInstanceId(serviceInstanceInfo) {
+  const { attributes } = serviceInstanceInfo;
+  if (!attributes || attributes.length < 1) {
+    return '';
   }
-  return `${serverInfo.pid}@${host}`;
+  let host = getAttributes(attributes, 'host');
+  const ipv4 = getAttributes(attributes, 'ipv4');
+  if (ipv4 && ipv4.length > 0) {
+    [host] = ipv4;
+  }
+  return `${getAttributes(attributes, 'pid')}@${host}`;
+}
+
+export function getAttributes(attributes, name) {
+  if (!attributes || attributes.length < 1) {
+    return '';
+  }
+  const a = attributes.find(_ => _.name === name);
+  return a ? a.value : '';
 }
 
 export function redirect(history, pathname, param) {

Reply via email to