This is an automated email from the ASF dual-hosted git repository. hefengen pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push: new 7bc5b2cf09 [type:fix] fixing e2e chunk header error (#5593) 7bc5b2cf09 is described below commit 7bc5b2cf09f0940a0696c8586a6d0fa186415b21 Author: aias00 <rok...@163.com> AuthorDate: Wed Jul 10 18:48:10 2024 +0800 [type:fix] fixing e2e chunk header error (#5593) * debug for fixing e2e chunck header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * debug for fixing e2e chunk header error * ShenYu Admin Cluster, add ignore list properties * ShenYu Admin Cluster, add ignore list properties * debug for fixing e2e chunk header error * fix cluster e2e failure * fix cluster e2e failure * fix cluster e2e failure * fix cluster e2e failure * fix cluster e2e failure * fix cluster e2e failure * fix cluster e2e failure * fix cluster e2e failure * fix cluster e2e failure * Update ClusterProperties.java * add restTemplate bean name * add comment --------- Co-authored-by: moremind <hefen...@apache.org> --- .../shenyu/admin/config/ClusterConfiguration.java | 10 +- .../admin/config/properties/ClusterProperties.java | 72 +++++++++- .../listener/websocket/WebsocketCollector.java | 4 +- .../mode/cluster/filter/ClusterForwardFilter.java | 50 +++++-- .../jdbc/ClusterSelectMasterServiceJdbcImpl.java | 10 +- .../mode/cluster/service/ShenyuClusterService.java | 4 +- shenyu-admin/src/main/resources/application.yml | 7 + .../shenyu/alert/config/RestTemplateConfig.java | 2 +- .../alert/strategy/AbstractAlertNotifyHandler.java | 2 +- .../e2e/testcase/cluster/DividePluginCases.java | 3 + .../e2e/testcase/cluster/DividePluginTest.java | 3 + .../shenyu/e2e/client/admin/AdminClient.java | 160 +++++++++++---------- .../apache/shenyu/e2e/engine/ShenYuExtension.java | 2 +- .../springcloud/cache/ServiceInstanceCache.java | 3 + .../listener/SpringCloudHeartBeatListener.java | 3 + .../websocket/client/ShenyuWebsocketClient.java | 6 +- 16 files changed, 240 insertions(+), 101 deletions(-) diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/ClusterConfiguration.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/ClusterConfiguration.java index 9768c5cb3c..bcb7b1b982 100644 --- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/ClusterConfiguration.java +++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/ClusterConfiguration.java @@ -32,6 +32,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; /** * The type Cluster configuration. @@ -69,11 +71,15 @@ public class ClusterConfiguration { /** * Shenyu cluster forward filter. * + * @param clusterProperties cluster properties * @return the Shenyu cluster forward filter */ @Bean - public ClusterForwardFilter clusterForwardFilter() { - return new ClusterForwardFilter(); + public ClusterForwardFilter clusterForwardFilter(final ClusterProperties clusterProperties) { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(clusterProperties.getConnectionTimeout()); + factory.setReadTimeout(clusterProperties.getReadTimeout()); + return new ClusterForwardFilter(new RestTemplate(factory)); } } diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/properties/ClusterProperties.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/properties/ClusterProperties.java index 589b72d181..cc38863f3b 100644 --- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/properties/ClusterProperties.java +++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/properties/ClusterProperties.java @@ -17,6 +17,7 @@ package org.apache.shenyu.admin.config.properties; +import com.google.common.collect.Lists; import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.List; @@ -42,10 +43,25 @@ public class ClusterProperties { */ private String schema = "http"; + /** + * the connectionTimeout. + */ + private int connectionTimeout = 6000; + + /** + * the readTimeout. + */ + private int readTimeout = 6000; + /** * cluster forward uri list. */ - private List<String> forwardList; + private List<String> forwardList = Lists.newArrayList(); + + /** + * cluster forward ignore uri list. + */ + private List<String> ignoredList = Lists.newArrayList(); /** * cluster select master task period. @@ -111,6 +127,42 @@ public class ClusterProperties { this.schema = schema; } + /** + * Get connection timeout. + * + * @return connectionTimeout + */ + public int getConnectionTimeout() { + return connectionTimeout; + } + + /** + * Set connection timeout. + * + * @param connectionTimeout connectionTimeout + */ + public void setConnectionTimeout(final int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + /** + * Get readTimeout. + * + * @return readTimeout + */ + public int getReadTimeout() { + return readTimeout; + } + + /** + * Set readTimeout. + * + * @param readTimeout readTimeout + */ + public void setReadTimeout(final int readTimeout) { + this.readTimeout = readTimeout; + } + /** * Gets the value of forwardList. * @@ -129,6 +181,24 @@ public class ClusterProperties { this.forwardList = forwardList; } + /** + * Get the ignore list. + * + * @return the ignore list + */ + public List<String> getIgnoredList() { + return ignoredList; + } + + /** + * Set the ignore list. + * + * @param ignoredList the ignore list + */ + public void setIgnoredList(final List<String> ignoredList) { + this.ignoredList = ignoredList; + } + /** * Gets the select master task period. * diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketCollector.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketCollector.java index a5a54bc841..ab21de5d17 100644 --- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketCollector.java +++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/websocket/WebsocketCollector.java @@ -99,7 +99,9 @@ public class WebsocketCollector { } if (Objects.equals(message, DataEventTypeEnum.RUNNING_MODE.name())) { - LOG.info("websocket fetching running mode info..."); + if (LOG.isDebugEnabled()) { + LOG.debug("websocket fetching running mode info..."); + } // check if this node is master boolean isMaster = true; String runningMode = RunningModeEnum.STANDALONE.name(); diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/filter/ClusterForwardFilter.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/filter/ClusterForwardFilter.java index 48c6dc1423..4a20722b58 100644 --- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/filter/ClusterForwardFilter.java +++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/filter/ClusterForwardFilter.java @@ -57,8 +57,7 @@ public class ClusterForwardFilter extends OncePerRequestFilter { private static final PathMatcher PATH_MATCHER = new AntPathMatcher(); - @Resource - private RestTemplate restTemplate; + private final RestTemplate restTemplate; @Resource private ClusterSelectMasterService clusterSelectMasterService; @@ -66,30 +65,59 @@ public class ClusterForwardFilter extends OncePerRequestFilter { @Resource private ClusterProperties clusterProperties; + public ClusterForwardFilter(final RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + @Override protected void doFilterInternal(@NotNull final HttpServletRequest request, @NotNull final HttpServletResponse response, @NotNull final FilterChain filterChain) throws ServletException, IOException { String method = request.getMethod(); + + String uri = request.getRequestURI(); + String requestContextPath = request.getContextPath(); + String simpleUri = uri.replaceAll(requestContextPath, ""); + if (StringUtils.equals(HttpMethod.OPTIONS.name(), method)) { + if (LOG.isDebugEnabled()) { + LOG.debug("method is OPTIONS or GET, no forward :{}", simpleUri); + } filterChain.doFilter(request, response); return; } if (clusterSelectMasterService.isMaster()) { + if (LOG.isDebugEnabled()) { + LOG.debug("this node is master, no forward :{}", simpleUri); + } filterChain.doFilter(request, response); return; } // this node is not master - String uri = request.getRequestURI(); - String requestContextPath = request.getContextPath(); - String replaced = uri.replaceAll(requestContextPath, ""); - boolean anyMatch = clusterProperties.getForwardList() - .stream().anyMatch(x -> PATH_MATCHER.match(x, replaced)); - if (!anyMatch) { + + // check whether the uri should be ignored + boolean shouldIgnore = clusterProperties.getIgnoredList() + .stream().anyMatch(x -> PATH_MATCHER.match(x, simpleUri)); + if (shouldIgnore) { + if (LOG.isDebugEnabled()) { + LOG.debug("shouldIgnore, no forward :{}", simpleUri); + } filterChain.doFilter(request, response); return; } + + // check whether the uri should be forwarded + boolean shouldForward = clusterProperties.getForwardList() + .stream().anyMatch(x -> PATH_MATCHER.match(x, simpleUri)); + if (!shouldForward) { + if (LOG.isDebugEnabled()) { + LOG.debug("!shouldForward, no forward :{}", simpleUri); + } + filterChain.doFilter(request, response); + return; + } + // cluster forward request to master forwardRequest(request, response); } @@ -98,7 +126,9 @@ public class ClusterForwardFilter extends OncePerRequestFilter { final HttpServletResponse response) throws IOException { String targetUrl = getForwardingUrl(request); - LOG.info("forwarding current uri: {} method: {} request to target url: {}", request.getRequestURI(), request.getMethod(), targetUrl); + if (LOG.isDebugEnabled()) { + LOG.debug("forwarding current uri: {} method: {} request to target url: {}", request.getRequestURI(), request.getMethod(), targetUrl); + } // Create request entity HttpHeaders headers = new HttpHeaders(); // Copy request headers @@ -106,7 +136,7 @@ public class ClusterForwardFilter extends OncePerRequestFilter { HttpEntity<byte[]> requestEntity = new HttpEntity<>(getBody(request), headers); // Send request ResponseEntity<byte[]> responseEntity = restTemplate.exchange(targetUrl, HttpMethod.valueOf(request.getMethod()), requestEntity, byte[].class); - + // Set response status and headers response.setStatus(responseEntity.getStatusCodeValue()); // Copy response headers diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/impl/jdbc/ClusterSelectMasterServiceJdbcImpl.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/impl/jdbc/ClusterSelectMasterServiceJdbcImpl.java index 02854d6cf0..67ccece4c3 100644 --- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/impl/jdbc/ClusterSelectMasterServiceJdbcImpl.java +++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/impl/jdbc/ClusterSelectMasterServiceJdbcImpl.java @@ -33,6 +33,9 @@ import java.time.LocalDateTime; import java.util.Objects; import java.util.concurrent.locks.Lock; +/** + * The cluster select master service jdbc impl. + */ public class ClusterSelectMasterServiceJdbcImpl implements ClusterSelectMasterService { private static final Logger LOG = LoggerFactory.getLogger(ClusterSelectMasterServiceJdbcImpl.class); @@ -92,7 +95,12 @@ public class ClusterSelectMasterServiceJdbcImpl implements ClusterSelectMasterSe @Override public boolean checkMasterStatus() throws IllegalStateException { if (masterFlag) { - jdbcLockRegistry.renewLock(MASTER_LOCK_KEY); + try { + jdbcLockRegistry.renewLock(MASTER_LOCK_KEY); + } catch (IllegalStateException e) { + masterFlag = false; + throw e; + } } return masterFlag; } diff --git a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/service/ShenyuClusterService.java b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/service/ShenyuClusterService.java index c009d9e35b..0430202159 100644 --- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/service/ShenyuClusterService.java +++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mode/cluster/service/ShenyuClusterService.java @@ -97,7 +97,9 @@ public class ShenyuClusterService implements ShenyuRunningModeService { renewed = shenyuClusterSelectMasterService.checkMasterStatus(); if (renewed) { - LOG.info("renew master success"); + if (LOG.isDebugEnabled()) { + LOG.debug("renew master success"); + } } } } catch (Exception e) { diff --git a/shenyu-admin/src/main/resources/application.yml b/shenyu-admin/src/main/resources/application.yml index 5201bc1f8f..dd8bbdef7b 100755 --- a/shenyu-admin/src/main/resources/application.yml +++ b/shenyu-admin/src/main/resources/application.yml @@ -115,6 +115,13 @@ shenyu: cluster: enabled: false type: jdbc + connectionTimeout: 15000 + readTimeout: 15000 + ignored-list: + - /selector/list/** + - /appAuth/list/** + - /plugin/list/** + - /rule/list/** forward-list: - /shenyu-client/** - /configs/** diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/config/RestTemplateConfig.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/config/RestTemplateConfig.java index 1fb10db2d5..00cf7cf320 100644 --- a/shenyu-alert/src/main/java/org/apache/shenyu/alert/config/RestTemplateConfig.java +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/config/RestTemplateConfig.java @@ -36,7 +36,7 @@ public class RestTemplateConfig { * @param factory ClientHttpRequestFactory * @return RestTemplate */ - @Bean + @Bean(name = "alterRestTemplate") public RestTemplate restTemplate(final ClientHttpRequestFactory factory) { RestTemplate restTemplate = new RestTemplate(factory); restTemplate.setInterceptors(Collections.singletonList(new HeaderRequestInterceptor())); diff --git a/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/AbstractAlertNotifyHandler.java b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/AbstractAlertNotifyHandler.java index 67a43d4d2c..29e6f387a1 100644 --- a/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/AbstractAlertNotifyHandler.java +++ b/shenyu-alert/src/main/java/org/apache/shenyu/alert/strategy/AbstractAlertNotifyHandler.java @@ -38,7 +38,7 @@ abstract class AbstractAlertNotifyHandler implements AlertNotifyHandler { @Resource private TemplateEngine templateEngine; - @Resource + @Resource(name = "alterRestTemplate") private RestTemplate restTemplate; protected String renderContent(final AlarmContent alert) { diff --git a/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginCases.java b/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginCases.java index e91ab95dc8..6c040abc86 100644 --- a/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginCases.java +++ b/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginCases.java @@ -42,6 +42,9 @@ import static org.apache.shenyu.e2e.template.ResourceDataTemplate.newSelectorBui import static org.apache.shenyu.e2e.template.ResourceDataTemplate.newUpstreamsBuilder; import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString; +/** + * Testing Cluster Divide plugin testcases. + */ public class DividePluginCases implements ShenYuScenarioProvider { private static final String ANYTHING = "/anything"; diff --git a/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginTest.java b/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginTest.java index d40b23815d..82ec02eb56 100644 --- a/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginTest.java +++ b/shenyu-e2e/shenyu-e2e-case/shenyu-e2e-case-cluster/src/test/java/org/apache/shenyue/e2e/testcase/cluster/DividePluginTest.java @@ -38,6 +38,9 @@ import org.junit.jupiter.api.BeforeEach; import java.util.List; import java.util.Objects; +/** + * Testing Cluster Divide plugin. + */ @ShenYuTest(environments = { @ShenYuTest.Environment( serviceName = "shenyu-e2e-admin", diff --git a/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/AdminClient.java b/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/AdminClient.java index 97e4c1f16f..32db0cd87d 100644 --- a/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/AdminClient.java +++ b/shenyu-e2e/shenyu-e2e-client/src/main/java/org/apache/shenyu/e2e/client/admin/AdminClient.java @@ -55,8 +55,8 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; @@ -71,38 +71,38 @@ import static org.apache.shenyu.e2e.model.data.SearchCondition.QUERY_ALL; */ @ShenYuAdminClient public class AdminClient extends BaseClient { - + private static final Logger log = LoggerFactory.getLogger(AdminClient.class); - + private static final TypeReference<PaginatedResources<PluginDTO>> PAGINATED_PLUGINS_TYPE_REFERENCE = new TypeReference<PaginatedResources<PluginDTO>>() { }; - + private static final TypeReference<SearchedResources<SelectorDTO>> SEARCHED_SELECTORS_TYPE_REFERENCE = new TypeReference<SearchedResources<SelectorDTO>>() { }; - + private static final TypeReference<SearchedResources<RuleDTO>> SEARCHED_RULES_TYPE_REFERENCE = new TypeReference<SearchedResources<RuleDTO>>() { }; - + private static final TypeReference<SearchedResources<FakeResourceDTO>> FAKE_VALUE_TYPE = new TypeReference<SearchedResources<FakeResourceDTO>>() { }; - + private static final TypeReference<List<MetaDataDTO>> SEARCHED_METADATAS_TYPE_REFERENCE = new TypeReference<List<MetaDataDTO>>() { }; - + private final MultiValueMap<String, String> basicAuth = new HttpHeaders(); - + private final RestTemplate template = new RestTemplate(); - + private final ObjectMapper mapper = new ObjectMapper(); - + private final String scenarioId; - + private final String baseURL; - + private String serviceName; - + private final ImmutableMap<String, String> loginInfo; - + public AdminClient(final String scenarioId, final String serviceName, final String baseURL, final Properties properties) { super(serviceName); Preconditions.checkArgument(properties.containsKey("username"), "Property username does not exist"); @@ -115,20 +115,19 @@ public class AdminClient extends BaseClient { .put("password", properties.getProperty("password")) .build(); } - + /** * Login to ShenYu Admin and cache the token. */ public void login() { final String url = baseURL + "/platform/login?userName={username}&password={password}"; - log.info("login, url:{}", url); ResponseEntity<ShenYuResult> response = template.getForEntity( url, ShenYuResult.class, loginInfo ); ShenYuResult rst = assertAndGet(response, "login dashboard user success"); - + String token = Assertions.assertDoesNotThrow(() -> rst.toObject(LoginInfo.class).getToken(), "checking to cast common"); Assertions.assertNotNull(token, "checking token not null"); Assertions.assertNotEquals("", token, "checking token not empty"); @@ -136,7 +135,7 @@ public class AdminClient extends BaseClient { Plugin.check(listPlugins()); } - + /** * List all plugins. * @@ -144,7 +143,7 @@ public class AdminClient extends BaseClient { */ public List<PluginDTO> listPlugins() { List<PluginDTO> result = Lists.newArrayList(); - + int cur = 1; int total; do { @@ -157,18 +156,18 @@ public class AdminClient extends BaseClient { 30 ); ShenYuResult rst = assertAndGet(response, "query success"); - + PaginatedResources<PluginDTO> pagination = Assertions.assertDoesNotThrow( () -> mapper.readValue(rst.getData().traverse(), PAGINATED_PLUGINS_TYPE_REFERENCE), - "checking cast to PaginatedResources<T>" + "checking cast to PaginatedResources<T>" ); result.addAll(pagination.getDataList()); - + total = pagination.getPage().getTotalPage(); } while (++cur < total); return result; } - + /** * List all existence selectors. * @@ -180,7 +179,7 @@ public class AdminClient extends BaseClient { .build(); return list("/selector/list/search", condition, SEARCHED_SELECTORS_TYPE_REFERENCE, v -> v); } - + /** * List all existence rules. * @@ -192,21 +191,22 @@ public class AdminClient extends BaseClient { .build(); return list("/rule/list/search", condition, SEARCHED_RULES_TYPE_REFERENCE, v -> v); } - + /** * all meta data list. + * * @return List */ public List<MetaDataDTO> listAllMetaData() { return getMetaDataList("/meta-data/findAll", SEARCHED_METADATAS_TYPE_REFERENCE, v -> v); } - + private <T extends ResourceDTO, OUT> List<OUT> list(final String uri, final QueryCondition condition, final TypeReference<SearchedResources<T>> valueType, final Mapper<T, OUT> mapper) { List<OUT> result = Lists.newArrayList(); - + int curPage = 1; int total; - + do { SearchedResources<T> resources = search(uri, curPage, 20, condition, valueType); resources.getList().stream() @@ -214,10 +214,10 @@ public class AdminClient extends BaseClient { .forEach(result::add); total = resources.getPages(); } while (++curPage <= total); - + return result; } - + private <T extends ResourceDTO, OUT> List<OUT> getMetaDataList(final String uri, final TypeReference<List<T>> valueType, final Mapper<T, OUT> mapper) { List<OUT> result = Lists.newArrayList(); List<T> resources = getSearch(uri, valueType); @@ -226,9 +226,10 @@ public class AdminClient extends BaseClient { .forEach(result::add); return result; } - + /** * Fetch the selectors by the given conditions. + * * @param keyword expected selectors included the word. return all if absent. * @param plugins expected selectors under specified plugins. return all if absent. * @return paginated info with list of {@link SelectorDTO}s @@ -241,9 +242,10 @@ public class AdminClient extends BaseClient { .build(); return search("/selector/list/search", condition, SEARCHED_SELECTORS_TYPE_REFERENCE); } - + /** * Fetch the selectors by the given conditions. + * * @param keyword expected selectors included the word. return all if absent. * @param page page. * @param pageSize size. @@ -258,11 +260,11 @@ public class AdminClient extends BaseClient { .build(); return search("/selector/list/search", page, pageSize, condition, SEARCHED_SELECTORS_TYPE_REFERENCE); } - + /** * Fetch the rules by the given conditions. * - * @param keyword expected selectors included the word. return all if absent. + * @param keyword expected selectors included the word. return all if absent. * @param selectors expected selectors under specified plugins. return all if absent. * @return paginated info with list of {@link RuleDTO}s */ @@ -274,40 +276,41 @@ public class AdminClient extends BaseClient { .build(); return search("/rule/list/search", condition, SEARCHED_RULES_TYPE_REFERENCE); } - + private <T extends ResourceDTO> SearchedResources<T> search(final String uri, final QueryCondition condition, final TypeReference<SearchedResources<T>> valueType) { return search(uri, 1, 10, condition, valueType); } - + private <T extends ResourceDTO> SearchedResources<T> search(final String uri, final int pageNum, final int pageSize, final QueryCondition condition, final TypeReference<SearchedResources<T>> valueType) { SearchCondition searchCondition = SearchCondition.builder() - .pageNum(pageNum) - .pageSize(pageSize) - .condition(condition) - .build(); - + .pageNum(pageNum) + .pageSize(pageSize) + .condition(condition) + .build(); + HttpEntity<SearchCondition> entity = new HttpEntity<>(searchCondition, basicAuth); ResponseEntity<ShenYuResult> response = template.postForEntity(baseURL + uri, entity, ShenYuResult.class); ShenYuResult rst = assertAndGet(response, "query success"); - + return Assertions.assertDoesNotThrow( () -> mapper.readValue(rst.getData().traverse(), valueType), - "checking cast to SearchedResources<T>" + "checking cast to SearchedResources<T>" ); } - + private <T extends ResourceDTO> List<T> getSearch(final String uri, final TypeReference<List<T>> valueType) { ResponseEntity<ShenYuResult> response = template.exchange(baseURL + uri, HttpMethod.GET, new HttpEntity<>(basicAuth), ShenYuResult.class); ShenYuResult rst = assertAndGet(response, "query success"); return Assertions.assertDoesNotThrow( () -> mapper.readValue(rst.getData().traverse(), valueType), - "checking cast to SearchedResources<T>" + "checking cast to SearchedResources<T>" ); } - + /** * create selectorDTO. + * * @param selector selector * @return SelectorDTO */ @@ -316,9 +319,10 @@ public class AdminClient extends BaseClient { Selectors.INSTANCE.put(selector.getName(), dto.getId()); return dto; } - + /** * Create Rule. + * * @param rule rule * @return RuleDTO */ @@ -327,7 +331,7 @@ public class AdminClient extends BaseClient { Rules.INSTANCE.put(rule.getName(), dto.getId()); return dto; } - + @SuppressWarnings("unchecked") private <T extends ResourceData, R extends ResourceDTO> R create(final String uri, final T data) { log.info("trying to create resource({}) name: {}", data.getClass().getSimpleName(), data.getName()); @@ -351,16 +355,17 @@ public class AdminClient extends BaseClient { } Assertions.assertNotNull(searchedResources, "checking searchedResources object is non-null"); Assertions.assertEquals(1, searchedResources.getTotal(), "checking the total hits of searching"); - + ResourceDTO created = searchedResources.getList().get(0); Assertions.assertNotNull(created, "checking created object is non-null"); log.info("create resource({}) successful. name: {}, id: {}", data.getClass().getSimpleName(), data.getName(), created.getId()); return (R) created; } - + /** * bindingData. + * * @param bindingData bindingData */ public void bindingData(final BindingData bindingData) { @@ -377,7 +382,7 @@ public class AdminClient extends BaseClient { public void deleteSelectors(final List<String> ids) { delete("/selector/batch", ids); } - + /** * Delete selectors in batch. * @@ -386,7 +391,7 @@ public class AdminClient extends BaseClient { public void deleteSelectors(final String... ids) { delete("/selector/batch", Lists.newArrayList(ids)); } - + /** * Delete rules in batch. * @@ -395,14 +400,14 @@ public class AdminClient extends BaseClient { public void deleteRules(final String... ids) { delete("/rule/batch", Lists.newArrayList(ids)); } - + /** * Delete all selectors. */ public void deleteAllSelectors() { deleteAll("/selector/batch"); } - + /** * Delete all rules under given id of selector. * @@ -412,70 +417,71 @@ public class AdminClient extends BaseClient { List<String> ids = searchRules(null, selectorId).getList().stream().map(RuleDTO::getId).collect(Collectors.toList()); deleteRules(ids.toArray(new String[]{})); } - + private void deleteAll(final String uri) { Preconditions.checkArgument(uri.endsWith("/batch"), "uri[{}] must be end with '/batch'", uri); - + String listAllResourcesUrl = uri.replace("/batch", "") + "/list/search"; List<String> ids = list(listAllResourcesUrl, QUERY_ALL, FAKE_VALUE_TYPE, FakeResourceDTO::getId); - + delete(uri, ids); List<FakeResourceDTO> result = list(listAllResourcesUrl, QUERY_ALL, FAKE_VALUE_TYPE, v -> v); Assertions.assertEquals(0, result.size(), "resource list is empty after deleted"); } - + private void delete(final String uri, final List<String> ids) { if (ids.isEmpty()) { log.info("delete resources, effected size: 0, cause by: there is not resources in ShenYuAdmin"); return; } - + HttpEntity<List<String>> entity = new HttpEntity<>(ids, basicAuth); ResponseEntity<ShenYuResult> response = template.exchange(baseURL + uri, HttpMethod.DELETE, entity, ShenYuResult.class); ShenYuResult rst = assertAndGet(response, "delete success"); Integer deleted = Assertions.assertDoesNotThrow(() -> rst.toObject(Integer.class), "checking to cast object"); Assertions.assertEquals(ids.size(), deleted, "checking deleted records"); - + log.info("delete resources, effected size: {}, effected rows: {}", ids.size(), ids); } - + /** * Fetch Selector by given id. + * * @param id of selector that needs to fetch * @return {@link SelectorDTO} */ public SelectorDTO getSelector(final String id) { return getResource("/selector", id, SelectorDTO.class); } - + private <T extends ResourceDTO> T getResource(final String uri, final String id, final Class<T> valueType) { ResponseEntity<ShenYuResult> response = template.exchange(baseURL + uri + "/{id}", HttpMethod.GET, new HttpEntity<>(basicAuth), ShenYuResult.class, id); Assertions.assertEquals(HttpStatus.OK, response.getStatusCode(), "checking http status"); - + ShenYuResult rst = response.getBody(); Assertions.assertNotNull(rst, "checking http response body"); - + if (rst.getCode() == 500) { Assertions.assertTrue(rst.getMessage().contains("selector is not existed"), "checking shenyu result message"); return null; } - + Assertions.assertEquals("detail success", rst.getMessage(), "checking shenyu result message"); Assertions.assertEquals(200, rst.getCode(), "checking shenyu result code"); return Assertions.assertDoesNotThrow(() -> rst.toObject(valueType), "checking cast data to " + valueType.getSimpleName()); } - + private ShenYuResult assertAndGet(final ResponseEntity<ShenYuResult> response, final String message) { Assertions.assertEquals(HttpStatus.OK, response.getStatusCode(), "checking http status"); - + ShenYuResult rst = response.getBody(); Assertions.assertNotNull(rst, "checking http response body"); Assertions.assertEquals(200, rst.getCode(), "checking shenyu result code"); Assertions.assertEquals(message, rst.getMessage(), "checking shenyu result message"); - + return rst; } - + /** * change plugin status. * @@ -485,7 +491,7 @@ public class AdminClient extends BaseClient { public void changePluginStatus(final String id, final MultiValueMap<String, String> formData) { putResource("/plugin", id, PluginDTO.class, formData); } - + private <T extends ResourceDTO> T putResource(final String uri, final String id, final Class<T> valueType, final MultiValueMap<String, String> formData) { HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, basicAuth); ResponseEntity<ShenYuResult> response = template.exchange(baseURL + uri + "/" + id, HttpMethod.PUT, requestEntity, ShenYuResult.class); @@ -494,7 +500,7 @@ public class AdminClient extends BaseClient { Assertions.assertNotNull(rst, "checking http response body"); return Assertions.assertDoesNotThrow(() -> rst.toObject(valueType), "checking cast data to " + valueType.getSimpleName()); } - + /** * change plugin status. * @@ -509,7 +515,7 @@ public class AdminClient extends BaseClient { throw new RuntimeException(e); } } - + private void putResourceByJson(final String uri, final String id, final String json) { basicAuth.add("Content-Type", MediaType.APPLICATION_JSON_VALUE); HttpEntity<String> requestEntity = new HttpEntity<>(json, basicAuth); @@ -519,7 +525,7 @@ public class AdminClient extends BaseClient { Assertions.assertNotNull(rst, "checking http response body"); basicAuth.remove("Content-Type"); } - + /** * sync all plugin. */ @@ -528,10 +534,10 @@ public class AdminClient extends BaseClient { template.postForEntity(baseURL + "/plugin/syncPluginAll", entity, ShenYuResult.class); log.warn("admin syncPluginAll"); } - + @FunctionalInterface interface Mapper<I, O> extends Function<I, O> { - + } - + } diff --git a/shenyu-e2e/shenyu-e2e-engine/src/main/java/org/apache/shenyu/e2e/engine/ShenYuExtension.java b/shenyu-e2e/shenyu-e2e-engine/src/main/java/org/apache/shenyu/e2e/engine/ShenYuExtension.java index 0d6055ee05..e6e43d3c56 100644 --- a/shenyu-e2e/shenyu-e2e-engine/src/main/java/org/apache/shenyu/e2e/engine/ShenYuExtension.java +++ b/shenyu-e2e/shenyu-e2e-engine/src/main/java/org/apache/shenyu/e2e/engine/ShenYuExtension.java @@ -77,7 +77,7 @@ public class ShenYuExtension implements BeforeAllCallback, ExecutionCondition, A }); // FIXME check service is available for (ShenYuTest.Environment environment : environments) { - if (!SocketUtils.checkUrl(environment.service().baseUrl(), 10000)) { + if (!SocketUtils.checkUrl(environment.service().baseUrl(), 15000)) { throw new AssertionFailedError(environment.serviceName() + ":" + environment.service().baseUrl() + " is not available"); //return ConditionEvaluationResult.disabled(environment.serviceName() + ":" + environment.service().baseUrl() + " is not available"); } diff --git a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/cache/ServiceInstanceCache.java b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/cache/ServiceInstanceCache.java index 1f3e40f680..4fb502e331 100644 --- a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/cache/ServiceInstanceCache.java +++ b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/cache/ServiceInstanceCache.java @@ -26,6 +26,9 @@ import java.util.List; import java.util.Map; import java.util.Optional; +/** + * the Service Instance Cache. + */ public class ServiceInstanceCache { private static final Map<String, List<ServiceInstance>> SERVICE_INSTANCE_MAP = Maps.newConcurrentMap(); diff --git a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/listener/SpringCloudHeartBeatListener.java b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/listener/SpringCloudHeartBeatListener.java index 57af0027b3..551521af5c 100644 --- a/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/listener/SpringCloudHeartBeatListener.java +++ b/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-springcloud/src/main/java/org/apache/shenyu/plugin/springcloud/listener/SpringCloudHeartBeatListener.java @@ -33,6 +33,9 @@ import org.springframework.context.ApplicationListener; import java.util.List; import java.util.Map; +/** + * SpringCloud HeartBeat Listener. + */ public class SpringCloudHeartBeatListener implements ApplicationListener<HeartbeatEvent> { private static final Logger LOG = LoggerFactory.getLogger(SpringCloudHeartBeatListener.class); diff --git a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/client/ShenyuWebsocketClient.java b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/client/ShenyuWebsocketClient.java index 13b04e8ef1..bf77c30325 100644 --- a/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/client/ShenyuWebsocketClient.java +++ b/shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/client/ShenyuWebsocketClient.java @@ -166,10 +166,6 @@ public final class ShenyuWebsocketClient extends WebSocketClient { } this.masterUrl = String.valueOf(jsonToMap.get(RunningModeConstants.MASTER_URL)); this.isConnectedToMaster = Boolean.TRUE.equals(jsonToMap.get(RunningModeConstants.IS_MASTER)); - if (!isConnectedToMaster) { - LOG.info("not connected to master, close now, master url:[{}], current url:[{}]", masterUrl, this.getURI().toString()); - this.nowClose(); - } } else { handleResult(result); } @@ -210,7 +206,7 @@ public final class ShenyuWebsocketClient extends WebSocketClient { this.reconnectBlocking(); } else { this.sendPing(); - send(DataEventTypeEnum.RUNNING_MODE.name()); +// send(DataEventTypeEnum.RUNNING_MODE.name()); LOG.debug("websocket send to [{}] ping message successful", this.getURI()); } } catch (Exception e) {