Skip to content

Commit

Permalink
Merge pull request #912 from ctripcorp/feature/keeper_rdb_release_ui
Browse files Browse the repository at this point in the history
add keeper rdb release ui
  • Loading branch information
LanternLee authored Nov 20, 2024
2 parents b63181b + ea9ed98 commit 2b336d5
Show file tree
Hide file tree
Showing 13 changed files with 131 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.ctrip.xpipe.redis.checker;

import com.ctrip.xpipe.redis.core.entity.KeeperDiskInfo;
import com.ctrip.xpipe.redis.core.entity.KeeperInstanceMeta;
import org.springframework.web.client.RestClientException;

import java.util.List;

public interface KeeperContainerService {

KeeperDiskInfo getKeeperDiskInfo(String keeperContainerIp) throws RestClientException;

boolean setKeeperContainerDiskIOLimit(String keeperContainerIp, int keeperContainerPort, int limitInByte);

List<KeeperInstanceMeta> getAllKeepers(String keeperContainerIp);

void resetKeeper(String activeKeeperIp, Long replId);

void releaseRdb(String ip, int port, Long replId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@

import com.ctrip.xpipe.redis.checker.KeeperContainerService;
import com.ctrip.xpipe.redis.core.entity.KeeperDiskInfo;
import com.ctrip.xpipe.redis.core.entity.KeeperInstanceMeta;
import com.ctrip.xpipe.redis.core.entity.KeeperTransMeta;
import com.ctrip.xpipe.redis.core.service.AbstractService;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;

import java.util.List;

@Service
public class DefaultKeeperContainerService extends AbstractService implements KeeperContainerService {

Expand All @@ -27,4 +35,33 @@ public boolean setKeeperContainerDiskIOLimit(String keeperContainerIp, int keepe
null, Boolean.class, keeperContainerIp, keeperContainerPort, limitInByte);
return null != rst && rst;
}

@Override
public List<KeeperInstanceMeta> getAllKeepers(String keeperContainerIp) {
return restTemplate.exchange(String.format("http://%s:8080/keepers", keeperContainerIp), HttpMethod.GET, null,
new ParameterizedTypeReference<List<KeeperInstanceMeta>>() {}).getBody();
}

@Override
public void resetKeeper(String activeKeeperIp, Long replId) {
KeeperTransMeta keeperInstanceMeta = new KeeperTransMeta();
keeperInstanceMeta.setReplId(replId);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<KeeperTransMeta> requestEntity = new HttpEntity<>(keeperInstanceMeta, headers);
restTemplate.exchange(String.format("http://%s:8080/keepers/election/reset", activeKeeperIp),
HttpMethod.POST, requestEntity, Void.class);
}

@Override
public void releaseRdb(String ip, int port, Long replId) {
KeeperTransMeta keeperInstanceMeta = new KeeperTransMeta();
keeperInstanceMeta.setReplId(replId);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<KeeperTransMeta> requestEntity = new HttpEntity<>(keeperInstanceMeta, headers);
restTemplate.exchange(String.format("http://%s:8080/keepers/rdb/release", ip),
HttpMethod.DELETE, requestEntity, Void.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import com.ctrip.xpipe.redis.console.model.KeeperRestElectionModel;
import com.ctrip.xpipe.redis.console.model.MigrationKeeperContainerDetailModel;
import com.ctrip.xpipe.redis.console.service.ConfigService;
import com.ctrip.xpipe.redis.console.service.KeeperContainerService;
import com.ctrip.xpipe.redis.checker.KeeperContainerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -104,4 +104,14 @@ public RetMessage resetElection(@RequestBody KeeperRestElectionModel model){
}
}

@RequestMapping(value = "/keepers/release/rdb", method = RequestMethod.POST)
public RetMessage releaseRdb(@RequestBody KeeperRestElectionModel model){
try {
keeperContainerService.releaseRdb(model.getIp(), Integer.parseInt(model.getPort()), Long.parseLong(model.getShardId()));
return RetMessage.createSuccessMessage();
} catch (Exception e) {
return RetMessage.createFailMessage(e.getMessage());
}
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.ctrip.xpipe.redis.console.keeper.command;

import com.ctrip.xpipe.command.AbstractCommand;
import com.ctrip.xpipe.redis.console.service.KeeperContainerService;
import com.ctrip.xpipe.redis.checker.KeeperContainerService;

public class KeeperResetCommand<T> extends AbstractCommand<T> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,5 @@ public interface KeeperContainerService {

void updateKeeperContainerByInfoModel(KeeperContainerInfoModel keeperContainerInfoModel);

List<KeeperInstanceMeta> getAllKeepers(String keeperContainerIp);

void resetKeeper(String activeKeeperIp, Long replId);

Map<Long, Long> keeperContainerIdDcMap();
}
Original file line number Diff line number Diff line change
Expand Up @@ -460,25 +460,6 @@ public Integer doQuery() throws DalException {
});
}

@Override
public List<KeeperInstanceMeta> getAllKeepers(String keeperContainerIp) {
getOrCreateRestTemplate();
return restTemplate.exchange(String.format("http://%s:8080/keepers", keeperContainerIp), HttpMethod.GET, null,
new ParameterizedTypeReference<List<KeeperInstanceMeta>>() {}).getBody();
}

@Override
public void resetKeeper(String activeKeeperIp, Long replId) {
KeeperTransMeta keeperInstanceMeta = new KeeperTransMeta();
keeperInstanceMeta.setReplId(replId);
getOrCreateRestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<KeeperTransMeta> requestEntity = new HttpEntity<>(keeperInstanceMeta, headers);
restTemplate.exchange(String.format("http://%s:8080/keepers/election/reset", activeKeeperIp),
HttpMethod.POST, requestEntity, Void.class);
}

@Override
public Map<Long, Long> keeperContainerIdDcMap() {
Map<Long, Long> keeperContainerIdDcMap = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,22 +181,6 @@ public void updateKeeperContainerByInfoModel(KeeperContainerInfoModel keeperCont
throw new UnsupportedOperationException();
}

@Override
public List<KeeperInstanceMeta> getAllKeepers(String keeperContainerIp) {
throw new UnsupportedOperationException();
}

@Override
public void resetKeeper(String activeKeeperIp, Long replId) {
KeeperTransMeta keeperInstanceMeta = new KeeperTransMeta();
keeperInstanceMeta.setReplId(replId);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<KeeperTransMeta> requestEntity = new HttpEntity<>(keeperInstanceMeta, headers);
restTemplate.exchange(String.format("http://%s:8080/keepers/election/reset", activeKeeperIp),
HttpMethod.POST, requestEntity, Void.class);
}

@Override
public Map<Long, Long> keeperContainerIdDcMap() {
Map<Long, Long> keeperContainerIdDcMap = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.ctrip.xpipe.redis.console.model.*;
import com.ctrip.xpipe.redis.console.repository.AzGroupClusterRepository;
import com.ctrip.xpipe.redis.console.service.*;
import com.ctrip.xpipe.redis.console.service.impl.KeeperContainerServiceImpl;
import com.ctrip.xpipe.redis.console.service.model.ShardModelService;
import com.ctrip.xpipe.utils.ObjectUtils;
import com.ctrip.xpipe.utils.VisibleForTesting;
Expand All @@ -26,6 +27,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ctrip.xpipe.redis.checker.KeeperContainerService;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
Expand Down Expand Up @@ -55,7 +57,9 @@ public class ShardModelServiceImpl implements ShardModelService{
@Autowired
private ReplDirectionService replDirectionService;
@Autowired
private KeeperContainerService keeperContainerService;
private KeeperContainerServiceImpl keeperContainerServiceImpl;
@Autowired
private KeeperContainerService keeperContainerService;
@Autowired
private AzGroupClusterRepository azGroupClusterRepository;
@Autowired
Expand Down Expand Up @@ -124,7 +128,7 @@ public List<ShardModel> getMultiShardModel(final String dcName, final String clu
return shardModels;
}

Map<Long, Long> containerIdDcMap = keeperContainerService.keeperContainerIdDcMap();
Map<Long, Long> containerIdDcMap = keeperContainerServiceImpl.keeperContainerIdDcMap();
for (int i = 0; i < shards.size(); i++) {
ShardTbl shardInfo = shards.get(i);
Future<DcClusterShardTbl> dcClusterShardFuture = dcClusterShardFutures.get(i);
Expand Down
4 changes: 2 additions & 2 deletions redis/redis-console/src/main/resources/static/dist/bundle.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ function FullLinkHealthCheckCtl($rootScope, $scope, $window, $stateParams, Healt
$scope.doShowActions = doShowActions;
$scope.getShardAllMeta = getShardAllMeta;
$scope.getShardKeeperState = getShardKeeperState;
$scope.releaseRdb = releaseRdb;
$scope.resetElection = resetElection;
$scope.disableResetElection = false;
$scope.disableReleaseRdb = false;
$scope.getDisableResetElection = getDisableResetElection;
$scope.getDisableReleaseRdb = getDisableReleaseRdb;
$scope.resetElectionErr = null;
$scope.releaseRdbErr = null;
$scope.getResetElectionErr = getResetElectionErr;
$scope.getReleaseRdbErr = getReleaseRdbErr;

redisRoleHealthCheck();
shardCheckerGroupHealthCheck();
Expand Down Expand Up @@ -78,6 +83,30 @@ function FullLinkHealthCheckCtl($rootScope, $scope, $window, $stateParams, Healt
})
}

let rdbTimer = null;
function releaseRdb(ip, port) {
$scope.disableReleaseRdb = true;
KeeperContainerService.releaseRdb(ip, port, $stateParams.shardId).then(function (response) {
if (response.state != 0) {
$scope.disableReleaseRdb = false;
$scope.releaseRdbErr = response.message;
$('#releaseRdbErr').modal('show');
} else {
if (!rdbTimer) {
rdbTimer = setTimeout(() => {
clearTimeout(rdbTimer);
rdbTimer = null;
$scope.disableReleaseRdb = false;
}, 3000);
}
}
}).catch(function (error){
$scope.disableReleaseRdb = false;
$scope.releaseRdbErr = "Status Code:" + error.status + " " + error.statusText + "\n" + error.data.exception;
$('#releaseRdbErr').modal('show');
})
}

let timer = null;
function resetElection(ip, port) {
$scope.disableResetElection = true;
Expand Down Expand Up @@ -106,6 +135,10 @@ function FullLinkHealthCheckCtl($rootScope, $scope, $window, $stateParams, Healt
return $scope.resetElectionErr;
}

function getReleaseRdbErr() {
return $scope.releaseRdbErr;
}

function doShowActions() {
$scope.showActions = !$scope.showActions;
}
Expand All @@ -114,4 +147,8 @@ function FullLinkHealthCheckCtl($rootScope, $scope, $window, $stateParams, Healt
return $scope.disableResetElection;
}

function getDisableReleaseRdb() {
return $scope.disableReleaseRdb;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ angular
reset_election:{
method:'POST',
url:'/api/keepers/election/reset/:ip/:port/:shardId'
},
release_rdb:{
method:'POST',
url:'/api/keepers/release/rdb/:ip/:port/:shardId'
}
});

Expand Down Expand Up @@ -304,6 +308,21 @@ angular
return d.promise;
}

function releaseRdb(ip, port, shardId) {
var d = $q.defer();
resource.release_rdb({
ip:ip,
port:port,
shardId:shardId
},
function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}

return {
findAvailableKeepersByDc : findAvailableKeepersByDc,
findAvailableKeepersByDcAndCluster : findAvailableKeepersByDcAndCluster,
Expand All @@ -320,6 +339,7 @@ angular
getOverloadKeeperContainerMigrationProcess : getOverloadKeeperContainerMigrationProcess,
beginToMigrateOverloadKeeperContainers : beginToMigrateOverloadKeeperContainers,
migrateKeeperTaskTerminate : migrateKeeperTaskTerminate,
resetElection: resetElection
resetElection: resetElection,
releaseRdb: releaseRdb
}
}]);
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@
<md-card-actions layout="row" layout-align="end center">
<md-button class="md-raised" ng-disabled="getDisableResetElection()" ng-click="resetElection(keeper.host, keeper.port)">reset Election</md-button>
</md-card-actions>
<md-card-actions layout="row" layout-align="end center">
<md-button class="md-raised" ng-disabled="getDisableReleaseRdb()" ng-click="releaseRdb(keeper.host, keeper.port)">release rdb</md-button>
</md-card-actions>
</md-card-title>
<md-card-content>
<div style="white-space: nowrap;">
Expand Down Expand Up @@ -147,6 +150,10 @@
xpipe-detail="getResetElectionErr()"
xpipe-show-cancel-btn="true"></xpipeconfirmdialog>

<xpipeconfirmdialog xpipe-dialog-id="'releaseRdbErr'" xpipe-title="'releaseRdb Err'"
xpipe-detail="getReleaseRdbErr()"
xpipe-show-cancel-btn="true"></xpipeconfirmdialog>

<div flex-xs flex-gt-xs="50" layout="column">
<!--Checker-->
<md-card md-theme="{{shardCheckerHealthCheckResult != [] ? 'default' : 'red'}}" md-theme-watch>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,34 +300,6 @@ public void testUpdateKeeperContainerByInfoModel() {

}

@Test
public void getAllKeepersTest() {
RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
keeperContainerService.setRestTemplate(restTemplate);
ResponseEntity<List<KeeperInstanceMeta>> response = Mockito.mock(ResponseEntity.class);
List<KeeperInstanceMeta> list = new ArrayList<>();
Mockito.when(response.getBody()).thenReturn(list);
Mockito.when(restTemplate.exchange(anyString(), eq(HttpMethod.GET), Mockito.isNull(), Mockito.any(ParameterizedTypeReference.class))).thenReturn(response);
List<KeeperInstanceMeta> allKeepers = keeperContainerService.getAllKeepers("keeperContainerIp");
Assert.assertEquals(list, allKeepers);
}

@Test
public void resetKeepersTest() {
KeeperTransMeta keeperInstanceMeta = new KeeperInstanceMeta();
KeeperMeta meta = new KeeperMeta();
meta.setIp("");
keeperInstanceMeta.setKeeperMeta(meta);
RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
keeperContainerService.setRestTemplate(restTemplate);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<KeeperTransMeta> requestEntity = new HttpEntity<>(keeperInstanceMeta, headers);
Mockito.when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), eq(requestEntity), eq(Void.class))).thenReturn(null);
keeperContainerService.resetKeeper(keeperInstanceMeta.getKeeperMeta().getIp(), keeperInstanceMeta.getReplId());
}

@Test
public void testUpdateKeeperContainerByInfoModelFail() {
KeeperContainerInfoModel keeper = keeperContainerService.findKeeperContainerInfoModelById(30);
Expand Down

0 comments on commit 2b336d5

Please sign in to comment.