Proxy Support And ConsumerGroup Enhancement (#207)

* Support dashboard v4-v5 switch And query for v5 topic

* Modify tag name

* Support proxy-module And Fix the problem of showing wrong consumerGroup-info

---------

Co-authored-by: yuanziwei <yuanziwei@xiaomi.com>
This commit is contained in:
Akai
2024-06-12 09:12:19 +08:00
committed by GitHub
parent e7cb315050
commit d58e13da95
22 changed files with 516 additions and 48 deletions

View File

@@ -59,6 +59,9 @@ rocketmq:
# must create userInfo file: ${rocketmq.config.dataPath}/users.properties if the login is required
loginRequired: false
useTLS: false
proxyAddr: 127.0.0.1:8080
proxyAddrs:
- 127.0.0.1:8080
# set the accessKey and secretKey if you used acl
# accessKey: rocketmq2
# secretKey: 12345678

View File

@@ -104,6 +104,7 @@
<script type="text/javascript" src="src/tools/tools.js?v=201703171710"></script>
<script type="text/javascript" src="src/cluster.js?timestamp=4"></script>
<script type="text/javascript" src="src/topic.js"></script>
<script type="text/javascript" src="src/proxy.js"></script>
<script type="text/javascript" src="src/consumer.js?timestamp=6"></script>
<script type="text/javascript" src="src/producer.js"></script>
<script type="text/javascript" src="src/message.js"></script>

View File

@@ -213,6 +213,9 @@ app.config(['$routeProvider', '$httpProvider','$cookiesProvider','getDictNamePro
}).when('/ops', {
templateUrl: 'view/pages/ops.html',
controller:'opsController'
}).when('/proxy', {
templateUrl: 'view/pages/proxy.html',
controller:'proxyController'
}).when('/acl', {
templateUrl: 'view/pages/acl.html',
controller: 'aclController'

View File

@@ -79,6 +79,7 @@ module.controller('consumerController', ['$scope', 'ngDialog', '$http', 'Notific
url: "consumer/groupList.query",
params: {
skipSysGroup: false,
address: localStorage.getItem('isV5') ? localStorage.getItem('proxyAddr') : null
}
}).success(function (resp) {
if (resp.status == 0) {
@@ -243,11 +244,11 @@ module.controller('consumerController', ['$scope', 'ngDialog', '$http', 'Notific
}
});
};
$scope.detail = function (consumerGroupName) {
$scope.detail = function (consumerGroupName, address) {
$http({
method: "GET",
url: "consumer/queryTopicByConsumer.query",
params: {consumerGroup: consumerGroupName}
params: {consumerGroup: consumerGroupName, address: address}
}).success(function (resp) {
if (resp.status == 0) {
console.log(resp);
@@ -262,11 +263,11 @@ module.controller('consumerController', ['$scope', 'ngDialog', '$http', 'Notific
});
};
$scope.client = function (consumerGroupName) {
$scope.client = function (consumerGroupName, address) {
$http({
method: "GET",
url: "consumer/consumerConnection.query",
params: {consumerGroup: consumerGroupName}
params: {consumerGroup: consumerGroupName, address: address}
}).success(function (resp) {
if (resp.status == 0) {
console.log(resp);

View File

@@ -100,6 +100,7 @@ var en = {
"RESET_OFFSET":"resetOffset",
"CLUSTER_NAME":"clusterName",
"OPS":"OPS",
"PROXY":"Proxy",
"AUTO_REFRESH":"AUTO_REFRESH",
"REFRESH":"REFRESH",
"LOGOUT":"Logout",

View File

@@ -101,6 +101,7 @@ var zh = {
"RESET_OFFSET":"重置位点",
"CLUSTER_NAME":"集群名",
"OPS":"运维",
"PROXY":"代理",
"AUTO_REFRESH":"自动刷新",
"REFRESH":"刷新",
"LOGOUT":"退出",

View File

@@ -0,0 +1,97 @@
/*
* 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.
*/
var module = app;
module.controller('proxyController', ['$scope', '$location', '$http', 'Notification', 'remoteApi', 'tools', '$window',
function ($scope, $location, $http, Notification, remoteApi, tools, $window) {
$scope.proxyAddrList = [];
$scope.userRole = $window.sessionStorage.getItem("userrole");
$scope.writeOperationEnabled = $scope.userRole == null ? true : ($scope.userRole == 1 ? true : false);
$scope.inputReadonly = !$scope.writeOperationEnabled;
$scope.newProxyAddr = "";
$scope.allProxyConfig = {};
$http({
method: "GET",
url: "proxy/homePage.query"
}).success(function (resp) {
if (resp.status == 0) {
$scope.proxyAddrList = resp.data.proxyAddrList;
$scope.selectedProxy = resp.data.currentProxyAddr;
$scope.showProxyDetailConfig($scope.selectedProxy);
localStorage.setItem('proxyAddr',$scope.selectedProxy);
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
$scope.eleChange = function (data) {
$scope.proxyAddrList = data;
}
$scope.showDetailConf = function () {
$(".proxyModal").modal();
}
$scope.showProxyDetailConfig = function (proxyAddr) {
$http({
method: "GET",
url: "proxy/proxyDetailConfig.query",
params: {proxyAddress: proxyAddr}
}).success(function (resp) {
if (resp.status == 0) {
$scope.allProxyConfig = resp.data;
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
};
$scope.updateProxyAddr = function () {
$http({
method: "POST",
url: "proxy/updateProxyAddr.do",
params: {proxyAddr: $scope.selectedProxy}
}).success(function (resp) {
if (resp.status == 0) {
localStorage.setItem('proxyAddr', $scope.selectedProxy);
Notification.info({message: "SUCCESS", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
$scope.showProxyDetailConfig($scope.selectedProxy);
};
$scope.addProxyAddr = function () {
$http({
method: "POST",
url: "proxy/addProxyAddr.do",
params: {newProxyAddr: $scope.newProxyAddr}
}).success(function (resp) {
if (resp.status == 0) {
if ($scope.proxyAddrList.indexOf($scope.newProxyAddr) == -1) {
$scope.proxyAddrList.push($scope.newProxyAddr);
}
$("#proxyAddr").val("");
$scope.newProxyAddr = "";
Notification.info({message: "SUCCESS", delay: 2000});
} else {
Notification.error({message: resp.errMsg, delay: 2000});
}
});
};
}])

View File

@@ -28,6 +28,7 @@
<div class="navbar-collapse collapse navbar-warning-collapse">
<ul class="nav navbar-nav">
<li ng-class="path =='ops' ? 'active':''"><a ng-href="#/ops">{{'OPS' | translate}}</a></li>
<li ng-show="rmqVersion" ng-class="path =='proxy' ? 'active':''"><a ng-href="#/proxy">{{'PROXY' | translate}}</a></li>
<li ng-class="path =='dashboard' || path ==''? 'active':''"><a ng-href="#/">{{'DASHBOARD' | translate}}</a></li>
<li ng-class="path =='cluster' ? 'active':''"><a ng-href="#/cluster">{{'CLUSTER' | translate}}</a></li>
<li ng-class="path =='topic' ? 'active':''"><a ng-href="#/topic">{{'TOPIC' | translate}}</a></li>

View File

@@ -66,11 +66,11 @@
<td class="text-center">{{consumerGroup.consumeTps}}</td>
<td class="text-center">{{consumerGroup.diffTotal}}</td>
<td class="text-left">
<button name="client" ng-click="client(consumerGroup.group)"
<button name="client" ng-click="client(consumerGroup.group, consumerGroup.address)"
class="btn btn-raised btn-sm btn-primary"
type="button">{{'CLIENT' | translate}}
</button>
<button name="client" ng-click="detail(consumerGroup.group)"
<button name="client" ng-click="detail(consumerGroup.group, consumerGroup.address)"
class="btn btn-raised btn-sm btn-primary"
type="button">{{'CONSUME_DETAIL' | translate}}
</button>

View File

@@ -0,0 +1,67 @@
<!--
~ 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.
-->
<div class="container-fluid" id="deployHistoryList">
<div class="page-content">
<h2 class="md-title">ProxyServerAddressList</h2>
<div class="pull-left" style="min-width: 400px; max-width: 500px; padding: 10px 10px 10px 0">
<select ng-model="selectedProxy" chosen
ng-options="x for x in proxyAddrList"
ng-change="updateProxyAddr()"
required></select>
</div>
<div class="pull-left">
<button class="btn btn-raised btn-sm btn-primary" type="button" ng-show="{{writeOperationEnabled}}"
ng-click="updateProxyAddr()">{{'UPDATE' | translate}}
</button>
</div>
<form class="form-inline pull-left" style="margin-left: 20px" ng-show="{{writeOperationEnabled}}">
<div class="form-group" style="margin: 0">
<label for="proxyAddr">ProxyAddr:</label>
<input id="proxyAddr" class="form-control" style="width: 300px; margin: 0 10px 0 10px" type="text" ng-model="newProxyAddr" required/>
<button class="btn btn-raised btn-sm btn-primary" type="button"
ng-click="addProxyAddr()"> {{ 'ADD' | translate}}
</button>
</div>
</form>
</div>
</div>
<div class="modal proxyModal fade" role="dialog" tabindex="-1" aria-hidden="true" aria-labelledby="config-modal-label">
<div class="modal-dialog modal-lg">
<div class="modal-content" >
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal">&times;</button>
<h4 id="config-modal-label" class="modal-title">
[{{selectedProxy}}]
</h4>
</div>
<div class="modal-body limit_height">
<table class="table table-bordered">
<tr ng-repeat="(key, value) in allProxyConfig">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</table>
</div>
<div class="modal-footer">
<div class="col-md-12 text-center">
<button type="button" class="btn btn-raised" data-dismiss="modal">{{ 'CLOSE' | translate }}</button>
</div>
</div>
</div>
</div>
</div>