You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2019/08/10 07:50:12 UTC
[servicecomb-pack] 07/36: SCB-1411 Implement dashboard transaction
statistics
This is an automated email from the ASF dual-hosted git repository.
ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-pack.git
commit fdda5ba927ef4c0de84044dbfca85db6811e2c89
Author: Lei Zhang <co...@gmail.com>
AuthorDate: Wed Aug 7 19:23:18 2019 +0800
SCB-1411 Implement dashboard transaction statistics
---
.../fsm/repository/NoneTransactionRepository.java | 6 ++++
.../fsm/repository/TransactionRepository.java | 3 ++
.../ElasticsearchTransactionRepository.java | 25 ++++++++++++--
.../pack/alpha/server/api/APIControllerV1.java | 7 ++++
.../pack/alpha/ui/TransactionController.java | 24 ++++++++++++++
.../alpha/ui/vo/TransactionStatisticsDTO.java} | 38 +++++++++++++++++-----
.../main/resources/static/js/alpha-dashboard.js | 30 +++++++++++++++++
.../resources/templates/fragments/main_layout.html | 1 -
.../src/main/resources/templates/index.html | 32 ++++++++++--------
9 files changed, 140 insertions(+), 26 deletions(-)
diff --git a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/NoneTransactionRepository.java b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/NoneTransactionRepository.java
index 5ebc21c..a376f25 100644
--- a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/NoneTransactionRepository.java
+++ b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/NoneTransactionRepository.java
@@ -18,6 +18,7 @@
package org.apache.servicecomb.pack.alpha.fsm.repository;
import java.lang.invoke.MethodHandles;
+import java.util.Map;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.GlobalTransaction;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.PagingGlobalTransactions;
import org.slf4j.Logger;
@@ -41,4 +42,9 @@ public class NoneTransactionRepository implements TransactionRepository {
public PagingGlobalTransactions getGlobalTransactions(int page, int size) throws Exception {
throw new UnsupportedOperationException("NoneTransactionRepository Unsupported!");
}
+
+ @Override
+ public Map<String,Long> getTransactionStatistics() {
+ throw new UnsupportedOperationException("NoneTransactionRepository Unsupported!");
+ }
}
diff --git a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/TransactionRepository.java b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/TransactionRepository.java
index fd303d4..0b3bbb1 100644
--- a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/TransactionRepository.java
+++ b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/TransactionRepository.java
@@ -17,6 +17,7 @@
package org.apache.servicecomb.pack.alpha.fsm.repository;
+import java.util.Map;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.GlobalTransaction;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.PagingGlobalTransactions;
@@ -29,4 +30,6 @@ public interface TransactionRepository {
PagingGlobalTransactions getGlobalTransactions(int page, int size)
throws Exception;
+
+ Map<String,Long> getTransactionStatistics();
}
diff --git a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/elasticsearch/ElasticsearchTransactionRepository.java b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/elasticsearch/ElasticsearchTransactionRepository.java
index 4ccc5c4..e0aa41a 100644
--- a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/elasticsearch/ElasticsearchTransactionRepository.java
+++ b/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/elasticsearch/ElasticsearchTransactionRepository.java
@@ -24,13 +24,19 @@ import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import org.apache.servicecomb.pack.alpha.fsm.metrics.MetricsService;
-import org.apache.servicecomb.pack.alpha.fsm.repository.TransactionRepository;
+import java.util.Map;
+import java.util.stream.Collectors;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.GlobalTransaction;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.PagingGlobalTransactions;
+import org.apache.servicecomb.pack.alpha.fsm.metrics.MetricsService;
+import org.apache.servicecomb.pack.alpha.fsm.repository.TransactionRepository;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.aggregations.AggregationBuilders;
+import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
+import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
+import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
@@ -132,6 +138,21 @@ public class ElasticsearchTransactionRepository implements TransactionRepository
.globalTransactions(globalTransactions).elapsed(System.currentTimeMillis() - start).build();
}
+ public Map<String, Long> getTransactionStatistics() {
+ TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders
+ .terms("count_group_by_state").field("state.keyword");
+ SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .addAggregation(termsAggregationBuilder)
+ .build();
+ return this.template.query(searchQuery, response -> {
+ final StringTerms groupState = response.getAggregations().get("count_group_by_state");
+ return groupState.getBuckets()
+ .stream()
+ .collect(Collectors.toMap(MultiBucketsAggregation.Bucket::getKeyAsString,
+ MultiBucketsAggregation.Bucket::getDocCount));
+ });
+ }
+
private final SearchResultMapper searchResultMapper = new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> aClass,
diff --git a/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIControllerV1.java b/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIControllerV1.java
index 88148db..4609821 100644
--- a/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIControllerV1.java
+++ b/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIControllerV1.java
@@ -17,6 +17,7 @@
package org.apache.servicecomb.pack.alpha.server.api;
+import java.util.Map;
import org.apache.servicecomb.pack.alpha.fsm.repository.TransactionRepository;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.GlobalTransaction;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.PagingGlobalTransactions;
@@ -60,4 +61,10 @@ public class APIControllerV1 {
.getGlobalTransactions(page, size);
return ResponseEntity.ok(pagingGlobalTransactions);
}
+
+ @GetMapping(value = "/transaction/statistics")
+ ResponseEntity<Map<String,Long>> getTransactions() {
+ return ResponseEntity.ok(transactionRepository.getTransactionStatistics());
+ }
+
}
diff --git a/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/TransactionController.java b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/TransactionController.java
index 10ab5a3..ff47ec7 100644
--- a/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/TransactionController.java
+++ b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/TransactionController.java
@@ -20,6 +20,7 @@ package org.apache.servicecomb.pack.alpha.ui;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.GlobalTransaction;
import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.PagingGlobalTransactions;
@@ -28,6 +29,7 @@ import org.apache.servicecomb.pack.alpha.ui.vo.DataTablesResponseDTO;
import org.apache.servicecomb.pack.alpha.ui.vo.EventDTO;
import org.apache.servicecomb.pack.alpha.ui.vo.SubTransactionDTO;
import org.apache.servicecomb.pack.alpha.ui.vo.TransactionRowDTO;
+import org.apache.servicecomb.pack.alpha.ui.vo.TransactionStatisticsDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
@@ -172,6 +174,28 @@ public class TransactionController implements ApplicationListener<WebServerIniti
return "transaction_details";
}
+ @GetMapping("/ui/transaction/statistics")
+ @ResponseBody
+ public TransactionStatisticsDTO getGlobalTransactionStatistics() {
+ TransactionStatisticsDTO statisticsDTO = new TransactionStatisticsDTO();
+ UriComponents uriComponents = UriComponentsBuilder
+ .fromUriString("http://localhost:" + serverPort + "/alpha/api/v1/transaction/statistics")
+ .build();
+ ResponseEntity<Map> entity = restTemplate
+ .getForEntity(uriComponents.toUriString(), Map.class);
+ Map<String,Number> statistics = entity.getBody();
+ if(statistics.containsKey("COMMITTED")){
+ statisticsDTO.setSuccessful(statistics.get("COMMITTED").longValue());
+ }
+ if(statistics.containsKey("SUSPENDED")){
+ statisticsDTO.setFailed(statistics.get("SUSPENDED").longValue());
+ }
+ if(statistics.containsKey("COMPENSATED")){
+ statisticsDTO.setCompensated(statistics.get("COMPENSATED").longValue());
+ }
+ return statisticsDTO;
+ }
+
private GlobalTransaction findGlobalTransactionByGlobalTxId(String globalTxId){
UriComponents uriComponents = UriComponentsBuilder
.fromUriString("http://localhost:" + serverPort + "/alpha/api/v1/transaction/"+globalTxId)
diff --git a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/TransactionRepository.java b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/vo/TransactionStatisticsDTO.java
similarity index 55%
copy from alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/TransactionRepository.java
copy to alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/vo/TransactionStatisticsDTO.java
index fd303d4..df3cb3a 100644
--- a/alpha/alpha-fsm/src/main/java/org/apache/servicecomb/pack/alpha/fsm/repository/TransactionRepository.java
+++ b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/vo/TransactionStatisticsDTO.java
@@ -15,18 +15,38 @@
* limitations under the License.
*/
-package org.apache.servicecomb.pack.alpha.fsm.repository;
+package org.apache.servicecomb.pack.alpha.ui.vo;
-import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.GlobalTransaction;
-import org.apache.servicecomb.pack.alpha.core.fsm.repository.model.PagingGlobalTransactions;
+public class TransactionStatisticsDTO {
+ private long successful;
+ private long compensated;
+ private long failed;
-public interface TransactionRepository {
+ public long getTotal() {
+ return successful + compensated + failed;
+ }
- void send(GlobalTransaction transaction) throws Exception;
+ public long getSuccessful() {
+ return successful;
+ }
- GlobalTransaction getGlobalTransactionByGlobalTxId(String globalTxId)
- throws Exception;
+ public void setSuccessful(long successful) {
+ this.successful = successful;
+ }
- PagingGlobalTransactions getGlobalTransactions(int page, int size)
- throws Exception;
+ public long getFailed() {
+ return failed;
+ }
+
+ public void setFailed(long failed) {
+ this.failed = failed;
+ }
+
+ public long getCompensated() {
+ return compensated;
+ }
+
+ public void setCompensated(long compensated) {
+ this.compensated = compensated;
+ }
}
diff --git a/alpha/alpha-ui/src/main/resources/static/js/alpha-dashboard.js b/alpha/alpha-ui/src/main/resources/static/js/alpha-dashboard.js
new file mode 100644
index 0000000..e292e7a
--- /dev/null
+++ b/alpha/alpha-ui/src/main/resources/static/js/alpha-dashboard.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+$(document).ready(function () {
+ $.ajax('/ui/transaction/statistics', {
+ success: function (data) {
+ $('#statistics-total').text(data.total)
+ $('#statistics-successful').text(data.successful)
+ $('#statistics-compensated').text(data.compensated)
+ $('#statistics-failed').text(data.failed)
+ },
+ error: function (state) {
+ // TODO show message
+ }
+ });
+});
\ No newline at end of file
diff --git a/alpha/alpha-ui/src/main/resources/templates/fragments/main_layout.html b/alpha/alpha-ui/src/main/resources/templates/fragments/main_layout.html
index 467074e..a632f70 100644
--- a/alpha/alpha-ui/src/main/resources/templates/fragments/main_layout.html
+++ b/alpha/alpha-ui/src/main/resources/templates/fragments/main_layout.html
@@ -64,7 +64,6 @@
</div>
<!-- End of Content Wrapper -->
-
</div>
<!-- End of Page Wrapper -->
diff --git a/alpha/alpha-ui/src/main/resources/templates/index.html b/alpha/alpha-ui/src/main/resources/templates/index.html
index f79afde..bc13638 100644
--- a/alpha/alpha-ui/src/main/resources/templates/index.html
+++ b/alpha/alpha-ui/src/main/resources/templates/index.html
@@ -16,7 +16,7 @@
-->
<!DOCTYPE html>
-<html xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorate="~{fragments/main_layout}">
+<html xmlns:layout="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml" layout:decorate="~{fragments/main_layout}">
<head>
<title>Alpha Admin - Dashboard</title>
</head>
@@ -27,31 +27,32 @@
<!-- Content Row -->
<div class="row">
- <!-- Cluster Card -->
+
+ <!-- Total Transaction Card -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
- <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Cluster</div>
- <div class="h5 mb-0 font-weight-bold text-gray-800">2</div>
+ <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Total Transaction</div>
+ <div class="h5 mb-0 font-weight-bold text-gray-800" id="statistics-total">0</div>
</div>
<div class="col-auto">
- <i class="fas fa-calendar fa-2x text-gray-300"></i>
+ <i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
- <!-- Total Transaction Card -->
+ <!-- Successful Transaction Card -->
<div class="col-xl-3 col-md-6 mb-4">
- <div class="card border-left-primary shadow h-100 py-2">
+ <div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
- <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Total Transaction</div>
- <div class="h5 mb-0 font-weight-bold text-gray-800">215,00</div>
+ <div class="text-xs font-weight-bold text-success text-uppercase mb-1">Successful Transactions</div>
+ <div class="h5 mb-0 font-weight-bold text-gray-800" id="statistics-successful">0</div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
@@ -61,14 +62,14 @@
</div>
</div>
- <!-- Successful Transaction Card -->
+ <!-- Compensated Transaction Card -->
<div class="col-xl-3 col-md-6 mb-4">
- <div class="card border-left-success shadow h-100 py-2">
+ <div class="card border-left-warning shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
- <div class="text-xs font-weight-bold text-success text-uppercase mb-1">Successful Transactions</div>
- <div class="h5 mb-0 font-weight-bold text-gray-800">215,00</div>
+ <div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Compensated Transaction</div>
+ <div class="h5 mb-0 font-weight-bold text-gray-800" id="statistics-compensated">0</div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
@@ -85,7 +86,7 @@
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-danger text-uppercase mb-1">Failed Transactions</div>
- <div class="h5 mb-0 font-weight-bold text-gray-800">0</div>
+ <div class="h5 mb-0 font-weight-bold text-gray-800" id="statistics-failed">0</div>
</div>
<div class="col-auto">
<i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
@@ -129,5 +130,8 @@
</div>
</div>
</div>
+ <div layout:fragment="scripts">
+ <script th:src="@{/js/alpha-dashboard.js}"></script>
+ </div>
</body>
</html>