Skip to content

Commit

Permalink
Optimized some of the logic
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoxianhjy committed Sep 15, 2024
1 parent ea2f0c4 commit de2a396
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 185 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2024 Apollo Authors
*
* Licensed 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.
*
*/
package com.ctrip.framework.apollo.common.http;

import org.springframework.http.HttpStatus;

public class SearchResponseEntity<T> {

Check warning on line 21 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L21

Added line #L21 was not covered by tests

private T body;
private boolean hasMoreData;
private Object message;
private int code;

public static <T> SearchResponseEntity<T> ok(T body){
SearchResponseEntity<T> SearchResponseEntity = new SearchResponseEntity<>();
SearchResponseEntity.message = HttpStatus.OK.getReasonPhrase();
SearchResponseEntity.code = HttpStatus.OK.value();
SearchResponseEntity.body = body;
SearchResponseEntity.hasMoreData = false;
return SearchResponseEntity;

Check warning on line 34 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L29-L34

Added lines #L29 - L34 were not covered by tests
}

public static <T> SearchResponseEntity<T> okWithMessage(T body, Object message){
SearchResponseEntity<T> SearchResponseEntity = new SearchResponseEntity<>();
SearchResponseEntity.message = message;
SearchResponseEntity.code = HttpStatus.OK.value();
SearchResponseEntity.body = body;
SearchResponseEntity.hasMoreData = true;
return SearchResponseEntity;

Check warning on line 43 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L38-L43

Added lines #L38 - L43 were not covered by tests
}

public static <T> SearchResponseEntity<T> error(HttpStatus httpCode, Object message){
SearchResponseEntity<T> SearchResponseEntity = new SearchResponseEntity<>();
SearchResponseEntity.message = message;
SearchResponseEntity.code = httpCode.value();
return SearchResponseEntity;

Check warning on line 50 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L47-L50

Added lines #L47 - L50 were not covered by tests
}

public int getCode() {
return code;

Check warning on line 54 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L54

Added line #L54 was not covered by tests
}

public Object getMessage() {
return message;

Check warning on line 58 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L58

Added line #L58 was not covered by tests
}

public T getBody() {
return body;

Check warning on line 62 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L62

Added line #L62 was not covered by tests
}

public boolean isHasMoreData() {return hasMoreData;}

Check warning on line 65 in apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java

View check run for this annotation

Codecov / codecov/patch

apollo-common/src/main/java/com/ctrip/framework/apollo/common/http/SearchResponseEntity.java#L65

Added line #L65 was not covered by tests

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,95 +17,38 @@
package com.ctrip.framework.apollo.portal.controller;


import com.ctrip.framework.apollo.common.dto.PageDTO;
import com.ctrip.framework.apollo.portal.component.PortalSettings;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.http.SearchResponseEntity;
import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.ctrip.framework.apollo.portal.entity.vo.ItemInfo;
import com.ctrip.framework.apollo.portal.environment.Env;
import com.ctrip.framework.apollo.portal.service.GlobalSearchService;
import com.google.gson.Gson;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;


@RestController
public class GlobalSearchController {
private final PortalSettings portalSettings;
private final GlobalSearchService globalSearchService;
private final PortalConfig portalConfig;

public GlobalSearchController(final PortalSettings portalSettings, final GlobalSearchService globalSearchService, final PortalConfig portalConfig) {
this.portalSettings = portalSettings;
public GlobalSearchController(final GlobalSearchService globalSearchService, final PortalConfig portalConfig) {
this.globalSearchService = globalSearchService;
this.portalConfig = portalConfig;
}

@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@GetMapping("/global-search/item-info/by-key-or-value")
public ResponseEntity<?> getItemInfoBySearch(@RequestParam(value = "key", required = false, defaultValue = "") String key,
@RequestParam(value = "value", required = false , defaultValue = "") String value) {
public SearchResponseEntity<List<ItemInfo>> getItemInfoBySearch(@RequestParam(value = "key", required = false, defaultValue = "") String key,
@RequestParam(value = "value", required = false , defaultValue = "") String value) {

if(key.isEmpty() && value.isEmpty()) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON)
.body(new Gson().toJson("Please enter at least one search criterion in either key or value."));
}

List<Env> activeEnvs = portalSettings.getActiveEnvs();
if(activeEnvs.isEmpty()){
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.contentType(MediaType.APPLICATION_JSON)
.body(new Gson().toJson("Request accepted. Looking for available admin service."));

}

List<ItemInfo> allEnvItemInfos = new ArrayList<>();
List<String> envBeyondLimit = new ArrayList<>();
AtomicBoolean hasMoreData = new AtomicBoolean(false);
activeEnvs.forEach(env -> {
PageDTO<ItemInfo> perEnvItemInfos = globalSearchService.getPerEnvItemInfoBySearch(env, key, value,0, portalConfig.getPerEnvSearchMaxResults());
if (!perEnvItemInfos.hasContent()) {
return;
}
if(perEnvItemInfos.getTotal() > portalConfig.getPerEnvSearchMaxResults()){
envBeyondLimit.add(env.getName());
hasMoreData.set(true);
}
allEnvItemInfos.addAll(perEnvItemInfos.getContent());
});

Map<String, Object> body = new HashMap<>();
if(hasMoreData.get()){
body.put("data", allEnvItemInfos);
body.put("hasMoreData", true);
body.put("message", String.format(
"In %s , more than %d items found (Exceeded the maximum search quantity for a single environment). Please enter more precise criteria to narrow down the search scope.",
String.join(" , ", envBeyondLimit), portalConfig.getPerEnvSearchMaxResults()));
return ResponseEntity
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(body);
throw new BadRequestException("Please enter at least one search criterion in either key or value.");

Check warning on line 48 in apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/GlobalSearchController.java

View check run for this annotation

Codecov / codecov/patch

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/GlobalSearchController.java#L48

Added line #L48 was not covered by tests
}

body.put("data", allEnvItemInfos);
body.put("hasMoreData", false);
return ResponseEntity
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(body);
return globalSearchService.getAllEnvItemInfoBySearch(key, value, 0, portalConfig.getPerEnvSearchMaxResults());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,60 @@

import com.ctrip.framework.apollo.common.dto.ItemInfoDTO;
import com.ctrip.framework.apollo.common.dto.PageDTO;
import com.ctrip.framework.apollo.common.http.SearchResponseEntity;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.component.PortalSettings;
import com.ctrip.framework.apollo.portal.entity.vo.ItemInfo;
import com.ctrip.framework.apollo.portal.environment.Env;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@Service
public class GlobalSearchService {

private static final Logger LOGGER = LoggerFactory.getLogger(GlobalSearchService.class);
private final AdminServiceAPI.ItemAPI itemAPI;
private final PortalSettings portalSettings;

public GlobalSearchService(AdminServiceAPI.ItemAPI itemAPI) {
public GlobalSearchService(AdminServiceAPI.ItemAPI itemAPI, PortalSettings portalSettings) {
this.itemAPI = itemAPI;
this.portalSettings = portalSettings;
}

public PageDTO<ItemInfo> getPerEnvItemInfoBySearch(Env env, String key, String value, int page, int size) {
List<ItemInfo> perEnvItemInfos = new ArrayList<>();
PageDTO<ItemInfoDTO> perEnvItemInfoDTOs = itemAPI.getPerEnvItemInfoBySearch(env, key, value, page, size);
perEnvItemInfoDTOs.getContent().forEach(itemInfoDTO -> {
try {
ItemInfo itemInfo = new ItemInfo(itemInfoDTO.getAppId(),env.getName(),itemInfoDTO.getClusterName(),itemInfoDTO.getNamespaceName(),itemInfoDTO.getKey(),itemInfoDTO.getValue());
perEnvItemInfos.add(itemInfo);
} catch (Exception e) {
LOGGER.error("Error converting ItemInfoDTO to ItemInfo for item: {}", itemInfoDTO, e);
public SearchResponseEntity<List<ItemInfo>> getAllEnvItemInfoBySearch(String key, String value, int page, int size) {
List<Env> activeEnvs = portalSettings.getActiveEnvs();
List<String> envBeyondLimit = new ArrayList<>();
AtomicBoolean hasMoreData = new AtomicBoolean(false);
List<ItemInfo> allEnvItemInfos = new ArrayList<>();
activeEnvs.forEach(env -> {
PageDTO<ItemInfoDTO> perEnvItemInfoDTOs = itemAPI.getPerEnvItemInfoBySearch(env, key, value, page, size);
if (!perEnvItemInfoDTOs.hasContent()) {
return;
}
perEnvItemInfoDTOs.getContent().forEach(itemInfoDTO -> {
try {
ItemInfo itemInfo = new ItemInfo(itemInfoDTO.getAppId(),env.getName(),itemInfoDTO.getClusterName(),itemInfoDTO.getNamespaceName(),itemInfoDTO.getKey(),itemInfoDTO.getValue());
allEnvItemInfos.add(itemInfo);
} catch (Exception e) {
LOGGER.error("Error converting ItemInfoDTO to ItemInfo for item: {}", itemInfoDTO, e);

Check warning on line 61 in apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/GlobalSearchService.java

View check run for this annotation

Codecov / codecov/patch

apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/GlobalSearchService.java#L60-L61

Added lines #L60 - L61 were not covered by tests
}
});
if(perEnvItemInfoDTOs.getTotal() > size){
envBeyondLimit.add(env.getName());
hasMoreData.set(true);
}
});
return new PageDTO<>(perEnvItemInfos, PageRequest.of(page, size), perEnvItemInfoDTOs.getTotal());
if(hasMoreData.get()){
return SearchResponseEntity.okWithMessage(allEnvItemInfos,String.format(
"In %s , more than %d items found (Exceeded the maximum search quantity for a single environment). Please enter more precise criteria to narrow down the search scope.",
String.join(" , ", envBeyondLimit), size));
}
return SearchResponseEntity.ok(allEnvItemInfos);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function GlobalSearchValueController($scope, $window, $translate, toastr, AppUti
if(($scope.itemInfoSearchKey === '') && !($scope.itemInfoSearchValue === '')){
$scope.needToBeHighlightedValue = $scope.itemInfoSearchValue;
$scope.needToBeHighlightedKey = '';
result.data.forEach((itemInfo, index) => {
result.body.forEach((itemInfo, index) => {
allItemInfo.push(itemInfo);
isAllItemInfoDirectlyDisplayKeyWithoutShowHighlightKeyword[index] = '0';
isAllItemInfoDirectlyDisplayValueWithoutShowHighlightKeyword[index] = determineDisplayKeyOrValueWithoutShowHighlightKeyword(itemInfo.value, itemInfoSearchValue);
Expand All @@ -96,15 +96,15 @@ function GlobalSearchValueController($scope, $window, $translate, toastr, AppUti
}else if(!($scope.itemInfoSearchKey === '') && ($scope.itemInfoSearchValue === '')){
$scope.needToBeHighlightedKey = $scope.itemInfoSearchKey;
$scope.needToBeHighlightedValue = '';
result.data.forEach((itemInfo, index) => {
result.body.forEach((itemInfo, index) => {
allItemInfo.push(itemInfo);
isAllItemInfoDirectlyDisplayKeyWithoutShowHighlightKeyword[index] = determineDisplayKeyOrValueWithoutShowHighlightKeyword(itemInfo.key, itemInfoSearchKey);
isAllItemInfoDirectlyDisplayValueWithoutShowHighlightKeyword[index] = '0';
});
}else{
$scope.needToBeHighlightedKey = $scope.itemInfoSearchKey;
$scope.needToBeHighlightedValue = $scope.itemInfoSearchValue;
result.data.forEach((itemInfo, index) => {
result.body.forEach((itemInfo, index) => {
allItemInfo.push(itemInfo);
isAllItemInfoDirectlyDisplayValueWithoutShowHighlightKeyword[index] = determineDisplayKeyOrValueWithoutShowHighlightKeyword(itemInfo.value, itemInfoSearchValue);
isAllItemInfoDirectlyDisplayKeyWithoutShowHighlightKeyword[index] = determineDisplayKeyOrValueWithoutShowHighlightKeyword(itemInfo.key, itemInfoSearchKey);
Expand All @@ -131,14 +131,7 @@ function GlobalSearchValueController($scope, $window, $translate, toastr, AppUti

function handleError(error) {
$scope.itemInfo = [];
switch (error.status) {
case 400:
toastr.warning(error.data, $translate.instant('Item.GlobalSearch.Tips'));
break;
default:
toastr.error(AppUtil.errorMsg(error), $translate.instant('Item.GlobalSearchSystemError'));
break;
}
toastr.error(AppUtil.errorMsg(error), $translate.instant('Item.GlobalSearchSystemError'));
}
}

Expand Down
Loading

0 comments on commit de2a396

Please sign in to comment.