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 <[email protected]> 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>
