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 636f1e1cd9ee6b864052ba21df373e7970240ede Author: Lei Zhang <[email protected]> AuthorDate: Fri Aug 9 01:33:08 2019 +0800 SCB-1411 Transaction query list page adds status selection --- .../servicecomb/pack/alpha/core/api/APIv1.java | 3 + .../fsm/repository/NoneTransactionRepository.java | 5 ++ .../fsm/repository/TransactionRepository.java | 3 + .../ElasticsearchTransactionRepository.java | 19 ++++++- .../pack/alpha/server/api/APIv1Controller.java | 2 +- .../pack/alpha/server/api/APIv1Impl.java | 7 ++- .../alpha/ui/controller/TransactionController.java | 26 +++++++-- .../pack/alpha/ui/vo/DataTablesRequestDTO.java | 9 +++ .../main/resources/static/js/alpha-transaction.js | 65 +++++++++++++--------- .../resources/templates/transaction_details.html | 8 +-- 10 files changed, 106 insertions(+), 41 deletions(-) diff --git a/alpha/alpha-core/src/main/java/org/apache/servicecomb/pack/alpha/core/api/APIv1.java b/alpha/alpha-core/src/main/java/org/apache/servicecomb/pack/alpha/core/api/APIv1.java index de9cf64..d35bb9f 100644 --- a/alpha/alpha-core/src/main/java/org/apache/servicecomb/pack/alpha/core/api/APIv1.java +++ b/alpha/alpha-core/src/main/java/org/apache/servicecomb/pack/alpha/core/api/APIv1.java @@ -30,6 +30,9 @@ public interface APIv1 { GlobalTransaction getTransactionByGlobalTxId(String globalTxId) throws Exception; + PagingGlobalTransactions getTransactions(String state, int page, int size) + throws Exception; + PagingGlobalTransactions getTransactions(int page, int size) throws Exception; 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 cd6b02f..900256e 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 @@ -40,6 +40,11 @@ public class NoneTransactionRepository implements TransactionRepository { } @Override + public PagingGlobalTransactions getGlobalTransactions(String state, int page, int size) throws Exception { + throw new UnsupportedOperationException("NoneTransactionRepository Unsupported!"); + } + + @Override public PagingGlobalTransactions getGlobalTransactions(int page, int size) throws Exception { 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 c2d81b9..825f1fc 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 @@ -29,6 +29,9 @@ public interface TransactionRepository { GlobalTransaction getGlobalTransactionByGlobalTxId(String globalTxId) throws Exception; + PagingGlobalTransactions getGlobalTransactions(String state, int page, int size) + throws Exception; + PagingGlobalTransactions getGlobalTransactions(int page, int size) throws Exception; 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 903b223..8a5b644 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 @@ -32,6 +32,7 @@ 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.action.search.SearchType; +import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.aggregations.AggregationBuilders; @@ -109,15 +110,25 @@ public class ElasticsearchTransactionRepository implements TransactionRepository @Override public PagingGlobalTransactions getGlobalTransactions(int page, int size) { + return getGlobalTransactions(null, page, size); + } + + @Override + public PagingGlobalTransactions getGlobalTransactions(String state, int page, int size) { long start = System.currentTimeMillis(); List<GlobalTransaction> globalTransactions = new ArrayList(); + QueryBuilder query; + if (state != null && state.trim().length() > 0) { + query = QueryBuilders.termQuery("state.keyword", state); + } else { + query = QueryBuilders.matchAllQuery(); + } SearchQuery searchQuery = new NativeSearchQueryBuilder() .withIndices(INDEX_NAME) .withTypes(INDEX_TYPE) - .withQuery(QueryBuilders.matchAllQuery()) + .withQuery(query) .withPageable(PageRequest.of(page, size)) .build(); - ScrolledPage<GlobalTransactionDocument> scroll = (ScrolledPage<GlobalTransactionDocument>) this.template .startScroll(SCROLL_TIMEOUT, searchQuery, GlobalTransactionDocument.class, searchResultMapper); @@ -223,7 +234,9 @@ public class ElasticsearchTransactionRepository implements TransactionRepository long end = System.currentTimeMillis(); metricsService.metrics().doRepositoryAvgTime((end - begin) / queries.size()); queries.clear(); - LOG.info("save queries={}, received={}, accepted={}",queries.size(),metricsService.metrics().getRepositoryReceived(),metricsService.metrics().getRepositoryAccepted()); + LOG.info("save queries={}, received={}, accepted={}", queries.size(), + metricsService.metrics().getRepositoryReceived(), + metricsService.metrics().getRepositoryAccepted()); } class RefreshTimer implements Runnable { diff --git a/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Controller.java b/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Controller.java index f071884..8d6f466 100644 --- a/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Controller.java +++ b/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Controller.java @@ -52,7 +52,7 @@ public class APIv1Controller { ResponseEntity<PagingGlobalTransactions> getTransactions(@RequestParam(value = "page", required = false, defaultValue = "0") int page, @RequestParam(value = "size", required = false, defaultValue = "50") int size) throws Exception { - return ResponseEntity.ok(APIv1Impl.getTransactions(page,size)); + return ResponseEntity.ok(APIv1Impl.getTransactions(null,page,size)); } @GetMapping(value = "/transaction/statistics") diff --git a/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Impl.java b/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Impl.java index 371f0ea..2138906 100644 --- a/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Impl.java +++ b/alpha/alpha-server/src/main/java/org/apache/servicecomb/pack/alpha/server/api/APIv1Impl.java @@ -53,8 +53,13 @@ public class APIv1Impl implements APIv1 { public PagingGlobalTransactions getTransactions(int page, int size) throws Exception { + return getTransactions(null, page, size); + } + + public PagingGlobalTransactions getTransactions(String state, int page, int size) + throws Exception { PagingGlobalTransactions pagingGlobalTransactions = transactionRepository - .getGlobalTransactions(page, size); + .getGlobalTransactions(state, page, size); return pagingGlobalTransactions; } diff --git a/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/controller/TransactionController.java b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/controller/TransactionController.java index 0ef8530..6ea5d52 100644 --- a/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/controller/TransactionController.java +++ b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/controller/TransactionController.java @@ -17,6 +17,8 @@ package org.apache.servicecomb.pack.alpha.ui.controller; +import java.io.IOException; +import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -31,6 +33,8 @@ 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.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; @@ -44,11 +48,12 @@ import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; +import sun.misc.BASE64Decoder; @Controller @EnableScheduling public class TransactionController { - + private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final String WEBSOCKET_BROKER_METRICES_TOPIC = "/topic/metrics"; @Autowired @@ -65,7 +70,8 @@ public class TransactionController { throws Exception { List<TransactionRowDTO> data = new ArrayList<>(); PagingGlobalTransactions pagingGlobalTransactions = apiv1 - .getTransactions(dataTablesRequestDTO.getStart() / dataTablesRequestDTO.getLength(), + .getTransactions(dataTablesRequestDTO.getState(), + dataTablesRequestDTO.getStart() / dataTablesRequestDTO.getLength(), dataTablesRequestDTO.getLength()); pagingGlobalTransactions.getGlobalTransactions().forEach(globalTransaction -> { data.add(TransactionRowDTO.builder() @@ -140,8 +146,8 @@ public class TransactionController { .serviceName(event.get("serviceName").toString()) .instanceId(event.get("instanceId").toString()) .globalTxId(event.get("globalTxId").toString()) - .parentTxId(event.get("parentTxId").toString()) - .localTxId(event.get("localTxId").toString()) + .parentTxId(event.get("parentTxId") != null ? event.get("parentTxId").toString() : null) + .localTxId(event.get("localTxId") != null ? event.get("localTxId").toString() : null) .createTime(new Date(Long.valueOf(event.get("createTime").toString()))) .build(); if (eventDTO.getType().equals("TxStartedEvent")) { @@ -156,10 +162,18 @@ public class TransactionController { eventDTO.setTimeout(Long.valueOf(event.get("timeout").toString())); } } - if (eventDTO.getType().equals("TxAbortedEvent")) { + if (eventDTO.getType().equals("TxAbortedEvent") || eventDTO.getType().equals("SagaAbortedEvent")) { // TxAbortedEvent properties if (event.containsKey("payloads")) { - eventDTO.setException(event.get("payloads").toString()); + BASE64Decoder decoder = new BASE64Decoder(); + String exception; + try { + exception = new String(decoder.decodeBuffer(event.get("payloads").toString()), "UTF-8"); + } catch (IOException e) { + exception = "BASE64Decoder error"; + LOG.error(e.getMessage(),e); + } + eventDTO.setException(exception); } } events.add(eventDTO); diff --git a/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/vo/DataTablesRequestDTO.java b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/vo/DataTablesRequestDTO.java index 0048f57..a679c08 100644 --- a/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/vo/DataTablesRequestDTO.java +++ b/alpha/alpha-ui/src/main/java/org/apache/servicecomb/pack/alpha/ui/vo/DataTablesRequestDTO.java @@ -28,6 +28,7 @@ public class DataTablesRequestDTO { private int start; private int length; private String query; + private String state; public int getDraw() { return draw; @@ -76,4 +77,12 @@ public class DataTablesRequestDTO { public void setQuery(String query) { this.query = query; } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } } diff --git a/alpha/alpha-ui/src/main/resources/static/js/alpha-transaction.js b/alpha/alpha-ui/src/main/resources/static/js/alpha-transaction.js index 47cbbaa..fad1a75 100644 --- a/alpha/alpha-ui/src/main/resources/static/js/alpha-transaction.js +++ b/alpha/alpha-ui/src/main/resources/static/js/alpha-transaction.js @@ -22,7 +22,7 @@ $(document).ready(function () { column = data.columns[i]; column.searchRegex = column.search.regex; column.searchValue = column.search.value; - delete(column.search); + delete (column.search); } // set query parameters @@ -30,6 +30,10 @@ $(document).ready(function () { if (typeof queryValue !== typeof undefined && queryValue !== false) { data.query = queryValue; } + + if($('select[name="state_select"]').find('option:selected').text() != 'ALL'){ + data.state = $('select[name="state_select"]').find('option:selected').text() + } } var transaction_table = $('#dataTable').DataTable({ @@ -39,11 +43,11 @@ $(document).ready(function () { lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]], processing: true, serverSide: true, - order: [[ 4, "desc" ]], + order: [[4, "desc"]], ajax: { - url : $('#transaction_config').attr('ajax'), + url: $('#transaction_config').attr('ajax'), type: 'POST', - data: function(data) { + data: function (data) { datatablesRequest(data); } }, @@ -51,51 +55,60 @@ $(document).ready(function () { lengthMenu: "_MENU_", }, columns: [ - { "data": "serviceName" }, - { "data": "instanceId" }, - { "data": "globalTxId" }, - { "data": "subTxSize" }, - { "data": "beginTime" }, - { "data": "durationTime" }, - { "data": "state" }, - { "data": "" } + {"data": "serviceName"}, + {"data": "instanceId"}, + {"data": "globalTxId"}, + {"data": "subTxSize"}, + {"data": "beginTime"}, + {"data": "durationTime"}, + {"data": "state"}, + {"data": ""} ], columnDefs: [ { render: function (data, type, row) { - return '<i class="fas fa-fw fa-bullseye row-transaction" style="cursor:pointer" globalTxId='+row.globalTxId+'></i>'; + return '<i class="fas fa-fw fa-bullseye row-transaction" style="cursor:pointer" globalTxId=' + + row.globalTxId + '></i>'; }, width: "50px", targets: -1 }, { render: function (data, type, row) { - if(data == 'COMMITTED'){ - return '<span class="text-success">'+data+'</span>' - }else if(data == 'SUSPENDED'){ - return '<span class="text-danger">'+data+'</span>' - }else if(data == 'COMPENSATED'){ - return '<span class="text-warning">'+data+'</span>' - }else{ + if (data == 'COMMITTED') { + return '<span class="text-success">' + data + '</span>' + } else if (data == 'SUSPENDED') { + return '<span class="text-danger">' + data + '</span>' + } else if (data == 'COMPENSATED') { + return '<span class="text-warning">' + data + '</span>' + } else { return data; } }, width: "50px", targets: 6 }, - { "visible": false, "targets": [ 4 ] } + {"visible": false, "targets": [4]} ] }); - $('#dataTable tbody').on("click","tr", function(_event){ - var data = transaction_table.row( this ).data(); - window.location.href = "/ui/transaction/"+data.globalTxId + $('#dataTable tbody').on("click", "tr", function (_event) { + var data = transaction_table.row(this).data(); + window.location.href = "/ui/transaction/" + data.globalTxId }); // table toolbar add state select & custom layout - $('#dataTable_wrapper .row:first div:first').removeClass("col-sm-12 col-md-6"); + $('#dataTable_wrapper .row:first div:first').removeClass( + "col-sm-12 col-md-6"); $('#dataTable_wrapper .row:first div:last').removeClass("col-sm-12 col-md-6"); $('#dataTable_wrapper .row:first div:first').addClass("col-sm-18 col-md-9"); $('#dataTable_wrapper .row:first div:last').addClass("col-sm-6 col-md-3"); - $('#dataTable_wrapper .row:first div:last').append('<select name="state_select" class="custom-select custom-select-sm form-control form-control-sm"><option value="ALL">ALL</option><option value="COMMITTED">COMMITTED</option><option value="COMPENSATED">COMPENSATED</option><option value="SUSPENDED">SUSPENDED</option></select>') + var stateSelect = $('#dataTable_wrapper .row:first div:last').append( + '<select name="state_select" class="custom-select custom-select-sm form-control form-control-sm">' + + '<option value="ALL">ALL</option><option value="COMMITTED">COMMITTED</option>' + + '<option value="COMPENSATED">COMPENSATED</option>' + + '<option value="SUSPENDED">SUSPENDED</option></select>'); + stateSelect.on('change',function(){ + transaction_table.ajax.reload(); + }) }); \ No newline at end of file diff --git a/alpha/alpha-ui/src/main/resources/templates/transaction_details.html b/alpha/alpha-ui/src/main/resources/templates/transaction_details.html index ccac9aa..697febc 100644 --- a/alpha/alpha-ui/src/main/resources/templates/transaction_details.html +++ b/alpha/alpha-ui/src/main/resources/templates/transaction_details.html @@ -32,9 +32,9 @@ </div> <div class="card-body"> <div class="events" th:each="event,stat : ${events}"> - <div th:class="${event.type}=='TxAbortedEvent' ? 'row text-danger' : 'row'"> + <div th:class="${event.type}=='TxAbortedEvent' or ${event.type}=='SagaAbortedEvent' ? 'row text-danger' : 'row'"> <div class="col-xl-6 col-lg-6"> - <div><i class="fas fa-envelope"></i> <span th:class="${event.type}=='TxAbortedEvent' ? 'small text-danger' : 'small text-success'" th:text="${event.type}"></span></div> + <div><i class="fas fa-envelope"></i> <span th:class="${event.type}=='TxAbortedEvent' or ${event.type}=='SagaAbortedEvent' ? 'small text-danger' : 'small text-success'" th:text="${event.type}"></span></div> <div><i class="fas fa-bell"></i> <span class="small" th:text="${event.serviceName} + '(' + ${event.instanceId} + ')'"></span></div> <div><i class="fas fa-mars-stroke"></i> <span class="small" th:text="${event.parentTxId}"></span></div> <div><i class="fas fa-transgender"></i> <span class="small" th:text="${event.localTxId}"></span></div> @@ -43,7 +43,7 @@ <div><i class="fas fa-calendar"></i> <span class="small" th:text="${event.createTime}"></span></div> <div><i class="fas fa-clock"></i> <span class="small" th:text="${event.timeout}+' ms'"></span></div> <div th:if="${event.type}==TxStartedEvent"><i class="fas fa-undo"></i> <span class="small" th:text="${event.retries}"></span></div> - <div th:if="${event.type}==TxStartedEvent or ${event.type}==TxAbortedEvent" class="position-absolute" style="bottom: 0px; right: 15px;"> + <div th:if="${event.type}==TxStartedEvent or ${event.type}==TxAbortedEvent or ${event.type}=='SagaAbortedEvent'" class="position-absolute" style="bottom: 0px; right: 15px;"> <i name="event_more" class="fas fa-caret-square-down" style="cursor:pointer" th:target="'div-more-'+${stat.index}"></i> </div> </div> @@ -60,7 +60,7 @@ </div> <!-- TxAbortedEvent more --> - <div th:id="'div-more-'+${stat.index}" th:if="${event.type}==TxAbortedEvent" class="d-none" style="padding-top: 10px"> + <div th:id="'div-more-'+${stat.index}" th:if="${event.type}==TxAbortedEvent or ${event.type}==SagaAbortedEvent" class="d-none" style="padding-top: 10px"> <div class="card border-danger"> <div class="card-header small border-danger bg-danger text-white">Exception Stack</div> <div class="card-body">
