VYPR
High severityNVD Advisory· Published Jan 25, 2022· Updated Aug 3, 2024

Apache ShenYu missing authentication allows gateway registration

CVE-2022-23945

Description

Apache ShenYu Admin 2.4.0-2.4.1 lacks authentication on HTTP gateway registration, enabling unauthorized gateway registration and potential traffic manipulation.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Apache ShenYu Admin 2.4.0-2.4.1 lacks authentication on HTTP gateway registration, enabling unauthorized gateway registration and potential traffic manipulation.

Vulnerability

Apache ShenYu Admin versions 2.4.0 and 2.4.1 [2] lack authentication for HTTP-based gateway registration. The /register endpoint does not verify the identity of the registering gateway, allowing any client to register as a gateway.

Exploitation

If ShenYu Admin is exposed to the internet [4], an attacker can send a crafted HTTP request to the registration endpoint without any authentication. No user interaction or special privileges are required.

Impact

Successful exploitation allows an attacker to register as a gateway, potentially intercepting or manipulating traffic [1]. This could lead to data disclosure or unauthorized API governance actions.

Mitigation

Upgrade to Apache ShenYu 2.4.2 or apply the patch from commit 9a02215 [3] [4]. If upgrade is not possible, restrict network access to ShenYu Admin.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.shenyu:shenyu-commonMaven
>= 2.4.0, < 2.4.22.4.2

Affected products

2

Patches

1
9a0221501303

[type:refactor] add an authentication on shenyu admin when register by http (#2723)

https://github.com/apache/shenyuSaberSolaJan 7, 2022via ghsa
40 files changed · +627 56
  • shenyu-admin/src/main/java/org/apache/shenyu/admin/shiro/bean/StatelessAuthFilter.java+2 3 modified
    @@ -20,6 +20,7 @@
     import org.apache.commons.lang3.StringUtils;
     import org.apache.shenyu.admin.model.result.ShenyuAdminResult;
     import org.apache.shenyu.admin.utils.ShenyuResultMessage;
    +import org.apache.shenyu.common.constant.Constants;
     import org.apache.shenyu.common.exception.CommonErrorCode;
     import org.apache.shenyu.common.utils.GsonUtils;
     import org.apache.shiro.subject.Subject;
    @@ -41,8 +42,6 @@ public class StatelessAuthFilter extends AccessControlFilter {
     
         private static final Logger LOG = LoggerFactory.getLogger(StatelessAuthFilter.class);
     
    -    private static final String HEAD_TOKEN = "X-Access-Token";
    -
         @Override
         protected boolean isAccessAllowed(final ServletRequest servletRequest,
                                           final ServletResponse servletResponse,
    @@ -58,7 +57,7 @@ protected boolean onAccessDenied(final ServletRequest servletRequest,
                 return true;
             }
     
    -        String tokenValue = httpServletRequest.getHeader(HEAD_TOKEN);
    +        String tokenValue = httpServletRequest.getHeader(Constants.X_ACCESS_TOKEN);
             if (StringUtils.isBlank(tokenValue)) {
                 LOG.error("token is null.");
                 unionFailResponse(servletResponse);
    
  • shenyu-admin/src/main/resources/application.yml+0 2 modified
    @@ -88,8 +88,6 @@ shenyu:
           - /index**
           - /platform/login
           - /websocket
    -      - /configs/**
    -      - /shenyu-client/**
           - /error
           - /actuator/health
           - /swagger-ui.html
    
  • shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/shutdown/ShenyuClientShutdownHook.java+7 4 modified
    @@ -25,6 +25,7 @@
     import java.util.concurrent.TimeUnit;
     import java.util.concurrent.atomic.AtomicBoolean;
     import java.util.concurrent.atomic.AtomicInteger;
    +
     import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
     import org.apache.shenyu.register.common.config.ShenyuRegisterCenterConfig;
     import org.slf4j.Logger;
    @@ -49,10 +50,11 @@ public class ShenyuClientShutdownHook {
     
         private static IdentityHashMap<Thread, Thread> delayedHooks = new IdentityHashMap<>();
     
    -    public ShenyuClientShutdownHook() { }
    +    public ShenyuClientShutdownHook() {
    +    }
     
         public ShenyuClientShutdownHook(final ShenyuClientRegisterRepository repository, final ShenyuRegisterCenterConfig config) {
    -        String name = hookNamePrefix + "-" + hookId.incrementAndGet();
    +        String name = String.join("-", hookNamePrefix, String.valueOf(hookId.incrementAndGet()));
             Runtime.getRuntime().addShutdownHook(new Thread(repository::close, name));
             LOG.info("Add hook {}", name);
             ShenyuClientShutdownHook.props = config.getProps();
    @@ -65,7 +67,7 @@ public ShenyuClientShutdownHook(final ShenyuClientRegisterRepository repository,
          * @param props  Properties
          */
         public static void set(final ShenyuClientRegisterRepository result, final Properties props) {
    -        String name = hookNamePrefix + "-" + hookId.incrementAndGet();
    +        String name = String.join("-", hookNamePrefix, String.valueOf(hookId.incrementAndGet()));
             Runtime.getRuntime().addShutdownHook(new Thread(result::close, name));
             LOG.info("Add hook {}", name);
             ShenyuClientShutdownHook.props = props;
    @@ -113,7 +115,8 @@ public void run() {
                             LOG.info("sleep {}ms", shutdownWaitTime);
                             try {
                                 TimeUnit.MILLISECONDS.sleep(shutdownWaitTime);
    -                        } catch (InterruptedException ignore) { }
    +                        } catch (InterruptedException ignore) {
    +                        }
                             hook.run();
                         }, hook.getName());
                         delayHooks.put(delayHook, delayHook);
    
  • shenyu-client/shenyu-client-http/shenyu-client-springcloud/src/test/java/org/apache/shenyu/client/springcloud/init/SpringCloudClientBeanPostProcessorTest.java+17 6 modified
    @@ -37,6 +37,7 @@
     import org.springframework.web.bind.annotation.RequestMapping;
     import org.springframework.web.bind.annotation.RestController;
     
    +import java.util.Optional;
     import java.util.Properties;
     
     import static org.hamcrest.Matchers.equalTo;
    @@ -51,9 +52,12 @@
     @RunWith(MockitoJUnitRunner.class)
     @FixMethodOrder(MethodSorters.NAME_ASCENDING)
     public final class SpringCloudClientBeanPostProcessorTest {
    +
         @Mock
         private static Environment env;
     
    +    private MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +
         private final SpringCloudClientTestBean springCloudClientTestBean = new SpringCloudClientTestBean();
     
         @Before
    @@ -63,27 +67,31 @@ public void init() {
     
         @Test
         public void testShenyuBeanProcess() {
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.of("token"));
             // config with full
             SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor = buildSpringCloudClientBeanPostProcessor(true);
             assertThat(springCloudClientTestBean, equalTo(springCloudClientBeanPostProcessor.postProcessAfterInitialization(springCloudClientTestBean, "springCloudClientTestBean")));
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testNormalBeanProcess() {
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.of("token"));
             SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor = buildSpringCloudClientBeanPostProcessor(false);
             Object normalBean = new Object();
     
             assertThat(normalBean, equalTo(springCloudClientBeanPostProcessor.postProcessAfterInitialization(normalBean, "normalBean")));
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testWithShenyuClientAnnotation() {
    -        try (MockedStatic mocked = mockStatic(RegisterUtils.class)) {
    -            mocked.when(() -> RegisterUtils.doRegister(any(), any(), any()))
    -                    .thenAnswer((Answer<Void>) invocation -> null);
    -            SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor = buildSpringCloudClientBeanPostProcessor(false);
    -            assertThat(springCloudClientTestBean, equalTo(springCloudClientBeanPostProcessor.postProcessAfterInitialization(springCloudClientTestBean, "normalBean")));
    -        }
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.of("token"));
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doRegister(any(), any(), any()))
    +                .thenAnswer((Answer<Void>) invocation -> null);
    +        SpringCloudClientBeanPostProcessor springCloudClientBeanPostProcessor = buildSpringCloudClientBeanPostProcessor(false);
    +        assertThat(springCloudClientTestBean, equalTo(springCloudClientBeanPostProcessor.postProcessAfterInitialization(springCloudClientTestBean, "normalBean")));
    +        registerUtilsMockedStatic.close();
         }
     
         private SpringCloudClientBeanPostProcessor buildSpringCloudClientBeanPostProcessor(final boolean full) {
    @@ -92,11 +100,14 @@ private SpringCloudClientBeanPostProcessor buildSpringCloudClientBeanPostProcess
             properties.setProperty("isFull", full + "");
             properties.setProperty("ip", "127.0.0.1");
             properties.setProperty("port", "8081");
    +        properties.setProperty("username", "admin");
    +        properties.setProperty("password", "123456");
             PropertiesConfig config = new PropertiesConfig();
             config.setProps(properties);
             ShenyuRegisterCenterConfig mockRegisterCenter = new ShenyuRegisterCenterConfig();
             mockRegisterCenter.setServerLists("http://127.0.0.1:8080");
             mockRegisterCenter.setRegisterType("http");
    +        mockRegisterCenter.setProps(properties);
             return new SpringCloudClientBeanPostProcessor(config, ShenyuClientRegisterRepositoryFactory.newInstance(mockRegisterCenter), env);
         }
     
    
  • shenyu-client/shenyu-client-tars/src/test/java/org/apache/shenyu/client/tars/TarsServiceBeanPostProcessorTest.java+12 0 modified
    @@ -21,17 +21,23 @@
     import org.apache.shenyu.client.core.register.ShenyuClientRegisterRepositoryFactory;
     import org.apache.shenyu.client.tars.common.annotation.ShenyuTarsClient;
     import org.apache.shenyu.client.tars.common.annotation.ShenyuTarsService;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.apache.shenyu.register.common.config.PropertiesConfig;
     import org.apache.shenyu.register.common.config.ShenyuRegisterCenterConfig;
     import org.junit.BeforeClass;
     import org.junit.FixMethodOrder;
     import org.junit.Test;
     import org.junit.runner.RunWith;
     import org.junit.runners.MethodSorters;
    +import org.mockito.MockedStatic;
     import org.mockito.junit.MockitoJUnitRunner;
     
    +import java.util.Optional;
     import java.util.Properties;
     
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
    +
     /**
      * Test case for {@link TarsServiceBeanPostProcessor}.
      */
    @@ -46,14 +52,20 @@ public static void init() {
             properties.setProperty("contextPath", "/tars");
             properties.setProperty("port", "8080");
             properties.setProperty("host", "localhost");
    +        properties.setProperty("username", "admin");
    +        properties.setProperty("password", "123456");
     
             PropertiesConfig config = new PropertiesConfig();
             config.setProps(properties);
     
             ShenyuRegisterCenterConfig mockRegisterCenter = new ShenyuRegisterCenterConfig();
             mockRegisterCenter.setServerLists("http://localhost:58080");
             mockRegisterCenter.setRegisterType("http");
    +        mockRegisterCenter.setProps(properties);
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.of("token"));
             tarsServiceBeanPostProcessor = new TarsServiceBeanPostProcessor(config, ShenyuClientRegisterRepositoryFactory.newInstance(mockRegisterCenter));
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
    
  • shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java+75 0 modified
    @@ -487,6 +487,81 @@ public interface Constants {
          */
         String TRANSMIT_HEADER_TO_GENERAL_CONTEXT_TYPE = "transmitHeaderToGeneralContext";
     
    +    /**
    +     * When register by http, the meta register path.
    +     */
    +    String META_PATH = "/shenyu-client/register-metadata";
    +
    +    /**
    +     * When register by http, the meta type.
    +     */
    +    String META_TYPE = "metadata";
    +
    +    /**
    +     * When register by http, the uri path.
    +     */
    +    String URI_PATH = "/shenyu-client/register-uri";
    +
    +    /**
    +     * When register by http, the login path.
    +     */
    +    String LOGIN_PATH = "/platform/login";
    +
    +    /**
    +     * When register by http, admin username.
    +     */
    +    String USER_NAME = "username";
    +
    +    /**
    +     * Login name.
    +     */
    +    String LOGIN_NAME = "userName";
    +
    +    /**
    +     * When register by http, admin password.
    +     */
    +    String PASS_WORD = "password";
    +
    +    /**
    +     * X-Access-Token.
    +     */
    +    String X_ACCESS_TOKEN = "X-Access-Token";
    +
    +    /**
    +     * The admin return result code.
    +     */
    +    String ADMIN_RESULT_CODE = "code";
    +
    +    /**
    +     * The admin return result data.
    +     */
    +    String ADMIN_RESULT_DATA = "data";
    +
    +    /**
    +     * The admin return result token.
    +     */
    +    String ADMIN_RESULT_TOKEN = "token";
    +
    +    /**
    +     * The admin userName.
    +     */
    +    String ADMIN_RESULT_USERNAME = "userName";
    +
    +    /**
    +     * The admin password.
    +     */
    +    String ADMIN_RESULT_PASSWORD = "password";
    +
    +    /**
    +     * shenyu admin path configs fetch.
    +     */
    +    String SHENYU_ADMIN_PATH_CONFIGS_FETCH = "/configs/fetch";
    +
    +    /**
    +     * shenyu admin path configs listener.
    +     */
    +    String SHENYU_ADMIN_PATH_CONFIGS_LISTENER = "/configs/listener";
    +
         /**
          * String q.
          */
    
  • shenyu-common/src/main/java/org/apache/shenyu/common/utils/FreshBeanHolder.java+73 0 added
    @@ -0,0 +1,73 @@
    +/*
    + * 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.
    + */
    +
    +package org.apache.shenyu.common.utils;
    +
    +import java.util.function.Function;
    +
    +public class FreshBeanHolder<E, O> implements Function<E, O> {
    +
    +    private final Function<E, O> function;
    +
    +    private volatile O o;
    +
    +    public FreshBeanHolder(final Function<E, O> function) {
    +        this.function = function;
    +    }
    +
    +    /**
    +     * Apply.
    +     *
    +     * @param e e
    +     * @return O o
    +     */
    +    @Override
    +    public O apply(final E e) {
    +        if (o != null) {
    +            return o;
    +        }
    +        return init(e);
    +    }
    +
    +    /**
    +     * Init.
    +     *
    +     * @return bean
    +     */
    +    synchronized O init(final E e) {
    +        if (o != null) {
    +            return o;
    +        }
    +        O res = function.apply(e);
    +        o = res;
    +        return res;
    +    }
    +
    +    /**
    +     * Fresh.
    +     *
    +     * @param e e
    +     */
    +    public void doFresh(final E e) {
    +        O fresh = function.apply(e);
    +        if (fresh != null) {
    +            synchronized (this) {
    +                this.o = fresh;
    +            }
    +        }
    +    }
    +}
    
  • shenyu-examples/shenyu-examples-dubbo/shenyu-examples-alibaba-dubbo-service-annotation/src/main/resources/application.yml+2 0 modified
    @@ -27,6 +27,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
         dubbo:
           props:
    
  • shenyu-examples/shenyu-examples-dubbo/shenyu-examples-alibaba-dubbo-service/src/main/resources/application.yml+2 0 modified
    @@ -29,6 +29,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
         dubbo:
           props:
    
  • shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service-annotation/src/main/resources/application.yml+3 0 modified
    @@ -26,6 +26,9 @@ shenyu:
       register:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
    +    props:
    +      username: admin
    +      password: 123456
       client:
         dubbo:
           props:
    
  • shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service/src/main/resources/application.yml+3 0 modified
    @@ -29,6 +29,9 @@ shenyu:
       register:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
    +    props:
    +      username: admin
    +      password: 123456
       client:
         dubbo:
           props:
    
  • shenyu-examples/shenyu-examples-dubbo/shenyu-examples-apache-dubbo-service-xml/src/main/resources/shenyu.xml+6 0 modified
    @@ -28,6 +28,12 @@
         <bean id="shenyuRegisterCenterConfig" class="org.apache.shenyu.register.common.config.ShenyuRegisterCenterConfig">
             <property name="registerType" value="http"/>
             <property name="serverLists" value="http://localhost:9095"/>
    +        <property name="props">
    +            <props>
    +                <prop key="username">admin</prop>
    +                <prop key="password">123456</prop>
    +            </props>
    +        </property>
         </bean>
     
         <!-- ClientPropertiesConfig -->
    
  • shenyu-examples/shenyu-examples-dubbo/shenyu-examples-spring-cloud-alibaba-dubbo-service-annotation/src/main/resources/application.yml+3 0 modified
    @@ -28,6 +28,9 @@ shenyu:
       register:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
    +    props:
    +      username: admin
    +      password: 123456
       client:
         dubbo:
           props:
    
  • shenyu-examples/shenyu-examples-grpc/src/main/resources/application.yml+2 0 modified
    @@ -29,6 +29,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
         grpc:
           props:
    
  • shenyu-examples/shenyu-examples-http/src/main/resources/application.yml+2 0 modified
    @@ -22,6 +22,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
           http:
             props:
    
  • shenyu-examples/shenyu-examples-https/src/main/resources/application.yml+2 0 modified
    @@ -28,6 +28,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://shenyu-admin:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
           http:
             props:
    
  • shenyu-examples/shenyu-examples-motan/shenyu-examples-motan-service/src/main/resources/application.yml+2 0 modified
    @@ -28,6 +28,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
         motan:
           props:
    
  • shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/src/main/resources/application.yml+2 0 modified
    @@ -35,6 +35,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
         sofa:
           props:
    
  • shenyu-examples/shenyu-examples-springcloud/src/main/resources/application.yml+2 0 modified
    @@ -41,6 +41,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
         springCloud:
           props:
    
  • shenyu-examples/shenyu-examples-tars/src/main/resources/application.yml+2 0 modified
    @@ -33,6 +33,8 @@ shenyu:
         registerType: http #zookeeper #etcd #nacos #consul
         serverLists: http://localhost:9095 #localhost:2181 #http://localhost:2379 #localhost:8848
         props:
    +      username: admin
    +      password: 123456
       client:
         tars:
           props:
    
  • shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java+2 2 modified
    @@ -128,13 +128,13 @@ private Boolean filterRule(final RuleData ruleData, final ServerWebExchange exch
         }
     
         private void selectorLog(final SelectorData selectorData, final String pluginName) {
    -        if (Boolean.TRUE.equals(selectorData.getLogged())) {
    +        if (selectorData.getLogged()) {
                 LOG.info("{} selector success match , selector name :{}", pluginName, selectorData.getName());
             }
         }
     
         private void ruleLog(final RuleData ruleData, final String pluginName) {
    -        if (Boolean.TRUE.equals(ruleData.getLoged())) {
    +        if (ruleData.getLoged()) {
                 LOG.info("{} rule success match , rule name :{}", pluginName, ruleData.getName());
             }
         }
    
  • shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/HttpClientRegisterRepository.java+28 12 modified
    @@ -29,8 +29,8 @@
     import org.apache.shenyu.spi.Join;
     import org.slf4j.Logger;
     import org.slf4j.LoggerFactory;
    -
     import java.util.List;
    +import java.util.Optional;
     
     /**
      * The type Http client register repository.
    @@ -39,45 +39,61 @@
     public class HttpClientRegisterRepository implements ShenyuClientRegisterRepository {
     
         private static final Logger LOGGER = LoggerFactory.getLogger(RegisterUtils.class);
    -    
    -    private static final String META_PATH = "/shenyu-client/register-metadata";
     
    -    private static final String META_TYPE = "metadata";
    +    private String username;
     
    -    private static final String URI_PATH = "/shenyu-client/register-uri";
    +    private String password;
     
         private List<String> serverList;
     
    -    public HttpClientRegisterRepository() { }
    +    private String accessToken;
    +
    +    public HttpClientRegisterRepository() {
    +    }
     
         public HttpClientRegisterRepository(final ShenyuRegisterCenterConfig config) {
             init(config);
         }
     
         @Override
         public void init(final ShenyuRegisterCenterConfig config) {
    +        this.username = config.getProps().getProperty(Constants.USER_NAME);
    +        this.password = config.getProps().getProperty(Constants.PASS_WORD);
             this.serverList = Lists.newArrayList(Splitter.on(",").split(config.getServerLists()));
    +        this.getAccessToken().ifPresent(V -> this.accessToken = String.valueOf(V));
         }
    -    
    +
         /**
          * Persist uri.
          *
          * @param registerDTO the register dto
          */
         @Override
         public void persistURI(final URIRegisterDTO registerDTO) {
    -        doRegister(registerDTO, URI_PATH, Constants.URI);
    +        doRegister(registerDTO, Constants.URI_PATH, Constants.URI);
         }
    -    
    +
         @Override
         public void persistInterface(final MetaDataRegisterDTO metadata) {
    -        doRegister(metadata, META_PATH, META_TYPE);
    +        doRegister(metadata, Constants.META_PATH, Constants.META_TYPE);
         }
    -    
    +
    +    private Optional getAccessToken() {
    +        for (String server : serverList) {
    +            try {
    +                Optional login = RegisterUtils.doLogin(username, password, server.concat(Constants.LOGIN_PATH));
    +                return login;
    +            } catch (Exception e) {
    +                LOGGER.error("login admin url :{} is fail, will retry, ex is :{}", server, e);
    +            }
    +        }
    +        return Optional.empty();
    +    }
    +
         private <T> void doRegister(final T t, final String path, final String type) {
             for (String server : serverList) {
                 try {
    -                RegisterUtils.doRegister(GsonUtils.getInstance().toJson(t), server + path, type);
    +                RegisterUtils.doRegister(GsonUtils.getInstance().toJson(t), server.concat(path), type, accessToken);
                     return;
                 } catch (Exception e) {
                     LOGGER.error("register admin url :{} is fail, will retry, ex is :{}", server, e);
    
  • shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/utils/OkHttpTools.java+39 0 modified
    @@ -21,8 +21,11 @@
     import okhttp3.OkHttpClient;
     import okhttp3.Request;
     import okhttp3.RequestBody;
    +import okhttp3.Headers;
    +import okhttp3.HttpUrl;
     
     import java.io.IOException;
    +import java.util.Map;
     import java.util.concurrent.TimeUnit;
     
     /**
    @@ -72,4 +75,40 @@ public String post(final String url, final String json) throws IOException {
                     .build();
             return client.newCall(request).execute().body().string();
         }
    +
    +    /**
    +     * Post string.
    +     *
    +     * @param url     the url
    +     * @param json    the json
    +     * @param headers the headers
    +     * @return the string
    +     * @throws IOException the io exception
    +     */
    +    public String post(final String url, final String json, final Headers headers) throws IOException {
    +        RequestBody body = RequestBody.create(JSON, json);
    +        Request request = new Request.Builder()
    +                .headers(headers)
    +                .url(url)
    +                .post(body)
    +                .build();
    +        return client.newCall(request).execute().body().string();
    +    }
    +
    +    /**
    +     * Get string.
    +     *
    +     * @param url   the url
    +     * @param query the query
    +     * @return the http result
    +     * @throws IOException the io exception
    +     */
    +    public String get(final String url, final Map<String, Object> query) throws IOException {
    +        Request.Builder reqBuild = new Request.Builder();
    +        HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
    +        query.forEach((K, V) -> urlBuilder.addQueryParameter(K, String.valueOf(V)));
    +        reqBuild.url(urlBuilder.build());
    +        Request request = reqBuild.build();
    +        return client.newCall(request).execute().body().string();
    +    }
     }
    
  • shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/main/java/org/apache/shenyu/register/client/http/utils/RegisterUtils.java+57 2 modified
    @@ -17,11 +17,19 @@
     
     package org.apache.shenyu.register.client.http.utils;
     
    +import okhttp3.Headers;
    +import org.apache.shenyu.common.constant.Constants;
    +import org.apache.shenyu.common.exception.CommonErrorCode;
    +import org.apache.shenyu.common.utils.GsonUtils;
     import org.slf4j.Logger;
     import org.slf4j.LoggerFactory;
    +import org.springframework.util.StringUtils;
     
     import java.io.IOException;
    +import java.util.HashMap;
    +import java.util.Map;
     import java.util.Objects;
    +import java.util.Optional;
     
     import static org.apache.shenyu.common.constant.Constants.SUCCESS;
     
    @@ -34,12 +42,35 @@ public final class RegisterUtils {
     
         private RegisterUtils() {
         }
    -    
    +
    +    /**
    +     * Do register.
    +     *
    +     * @param json        the json
    +     * @param url         the url
    +     * @param type        the type
    +     * @param accessToken the token
    +     * @throws IOException the io exception
    +     */
    +    public static void doRegister(final String json, final String url, final String type, final String accessToken) throws IOException {
    +        if (StringUtils.isEmpty(accessToken)) {
    +            LOGGER.error("{} client register error accessToken is null, please check the config : {} ", type, json);
    +            return;
    +        }
    +        Headers headers = new Headers.Builder().add(Constants.X_ACCESS_TOKEN, accessToken).build();
    +        String result = OkHttpTools.getInstance().post(url, json, headers);
    +        if (Objects.equals(SUCCESS, result)) {
    +            LOGGER.info("{} client register success: {} ", type, json);
    +        } else {
    +            LOGGER.error("{} client register error: {} ", type, json);
    +        }
    +    }
    +
         /**
          * Do register.
          *
          * @param json the json
    -     * @param url the url
    +     * @param url  the url
          * @param type the type
          * @throws IOException the io exception
          */
    @@ -51,4 +82,28 @@ public static void doRegister(final String json, final String url, final String
                 LOGGER.error("{} client register error: {} ", type, json);
             }
         }
    +
    +    /**
    +     * Do login.
    +     *
    +     * @param username the username
    +     * @param password the password
    +     * @param url      the ulr
    +     * @return Optional token
    +     * @throws IOException the io exception
    +     */
    +    public static Optional doLogin(final String username, final String password, final String url) throws IOException {
    +        Map<String, Object> loginMap = new HashMap<>(2);
    +        loginMap.put(Constants.LOGIN_NAME, username);
    +        loginMap.put(Constants.PASS_WORD, password);
    +        String result = OkHttpTools.getInstance().get(url, loginMap);
    +        Map<String, Object> resultMap = GsonUtils.getInstance().convertToMap(result);
    +        if (!String.valueOf(CommonErrorCode.SUCCESSFUL).equals(String.valueOf(resultMap.get(Constants.ADMIN_RESULT_CODE)))) {
    +            return Optional.empty();
    +        }
    +        String tokenJson = GsonUtils.getInstance().toJson(resultMap.get(Constants.ADMIN_RESULT_DATA));
    +        LOGGER.info("login success: {} ", tokenJson);
    +        Map<String, Object> tokenMap = GsonUtils.getInstance().convertToMap(tokenJson);
    +        return Optional.ofNullable(tokenMap.get(Constants.ADMIN_RESULT_TOKEN));
    +    }
     }
    
  • shenyu-register-center/shenyu-register-client/shenyu-register-client-http/src/test/java/org/apache/shenyu/register/client/http/RegisterUtilsTest.java+11 9 modified
    @@ -18,9 +18,11 @@
     package org.apache.shenyu.register.client.http;
     
     import com.google.gson.Gson;
    +
     import java.io.IOException;
     import java.util.HashMap;
     import java.util.Map;
    +
     import org.apache.shenyu.register.client.http.utils.OkHttpTools;
     import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.apache.shenyu.register.common.enums.RegisterTypeEnum;
    @@ -39,15 +41,15 @@
      * Test case for {@link RegisterUtils}.
      */
     public final class RegisterUtilsTest {
    -    
    +
         private Gson gson = new Gson();
    -    
    +
         private OkHttpTools okHttpTools;
    -    
    +
         private String json;
    -    
    +
         private String url;
    -    
    +
         @Before
         public void setUp() {
             okHttpTools = mock(OkHttpTools.class);
    @@ -64,18 +66,18 @@ public void setUp() {
             json = gson.toJson(jsonMap);
             url = "http://localhost:9095/shenyu-client/dubbo-register";
         }
    -    
    +
         @Test
         public void testDoRegisterWhenSuccess() throws IOException {
             when(okHttpTools.post(url, json)).thenReturn("success");
    -        
    +
             try (MockedStatic<OkHttpTools> okHttpToolsMockedStatic = mockStatic(OkHttpTools.class)) {
                 okHttpToolsMockedStatic.when(OkHttpTools::getInstance).thenReturn(okHttpTools);
                 RegisterUtils.doRegister(json, url, RegisterTypeEnum.DUBBO.getName());
                 verify(okHttpTools, times(1)).post(eq(url), eq(json));
             }
         }
    -    
    +
         @Test
         public void testDoRegisterWhenError() throws IOException {
             when(okHttpTools.post(url, json)).thenReturn("Error parameter!");
    @@ -85,7 +87,7 @@ public void testDoRegisterWhenError() throws IOException {
                 verify(okHttpTools, times(1)).post(eq(url), eq(json));
             }
         }
    -    
    +
         @Test(expected = IOException.class)
         public void testDoRegisterWhenThrowException() throws IOException {
             when(okHttpTools.post(url, json)).thenThrow(IOException.class);
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-alibaba-dubbo/src/test/java/org/apache/shenyu/springboot/starter/client/alibaba/dubbo/ShenyuAlibabaDubboClientConfigurationTest.java+9 0 modified
    @@ -18,14 +18,20 @@
     package org.apache.shenyu.springboot.starter.client.alibaba.dubbo;
     
     import org.apache.shenyu.client.alibaba.dubbo.AlibabaDubboServiceBeanListener;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     import org.springframework.context.annotation.PropertySource;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuAlibabaDubboClientConfiguration}.
    @@ -37,6 +43,8 @@ public class ShenyuAlibabaDubboClientConfigurationTest {
     
         @Test
         public void testShenyuAlibabaDubboClientConfiguration() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             new ApplicationContextRunner()
                 .withConfiguration(AutoConfigurations.of(ShenyuAlibabaDubboClientConfiguration.class))
                 .withBean(ShenyuAlibabaDubboClientConfigurationTest.class)
    @@ -47,5 +55,6 @@ public void testShenyuAlibabaDubboClientConfiguration() {
                         assertNotNull(listener);
                     }
                 );
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-alibaba-dubbo/src/test/resources/application.properties+2 0 modified
    @@ -18,6 +18,8 @@ dubbo.registry.address=zookeeper://localhost:2181
     # more see shenyu-register-center module
     shenyu.register.register-type=http
     shenyu.register.serverLists=http://localhost:9095
    +shenyu.register.props.username=admin
    +shenyu.register.props.password=123456
     
     # more see org.apache.shenyu.client.core.shutdown.ShenyuClientShutdownHook.TakeoverOtherHooksThread.class
     shenyu.register.props[shutdownWaitTime]=3000
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-apache-dubbo/src/test/java/org/apache/shenyu/springboot/starter/client/apache/dubbo/ShenyuApacheDubboClientConfigurationTest.java+9 0 modified
    @@ -18,14 +18,20 @@
     package org.apache.shenyu.springboot.starter.client.apache.dubbo;
     
     import org.apache.shenyu.client.apache.dubbo.ApacheDubboServiceBeanListener;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     import org.springframework.context.annotation.PropertySource;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuApacheDubboClientConfiguration}.
    @@ -37,6 +43,8 @@ public class ShenyuApacheDubboClientConfigurationTest {
     
         @Test
         public void testShenyuApacheDubboClientConfiguration() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             new ApplicationContextRunner()
                 .withConfiguration(AutoConfigurations.of(ShenyuApacheDubboClientConfiguration.class))
                 .withBean(ShenyuApacheDubboClientConfigurationTest.class)
    @@ -47,5 +55,6 @@ public void testShenyuApacheDubboClientConfiguration() {
                         assertNotNull(listener);
                     }
                 );
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-apache-dubbo/src/test/resources/application.properties+2 0 modified
    @@ -18,6 +18,8 @@ dubbo.registry.address=zookeeper://localhost:2181
     # more see shenyu-register-center module
     shenyu.register.register-type=http
     shenyu.register.serverLists=http://localhost:9095
    +shenyu.register.props.username=admin
    +shenyu.register.props.password=123456
     
     # more see org.apache.shenyu.client.core.shutdown.ShenyuClientShutdownHook.TakeoverOtherHooksThread.class
     shenyu.register.props[shutdownWaitTime]=3000
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-common/src/test/java/org/apache/shenyu/springboot/starter/client/common/config/ShenyuClientCommonBeanConfigurationTest.java+17 0 modified
    @@ -18,18 +18,24 @@
     package org.apache.shenyu.springboot.starter.client.common.config;
     
     import org.apache.shenyu.register.client.api.ShenyuClientRegisterRepository;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.apache.shenyu.register.common.config.ShenyuClientConfig;
     import org.apache.shenyu.register.common.config.ShenyuRegisterCenterConfig;
     import org.apache.shenyu.register.common.enums.RegisterTypeEnum;
     import org.junit.Before;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     
    +import java.util.Optional;
    +
     import static org.assertj.core.api.Assertions.assertThat;
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuClientCommonBeanConfiguration}.
    @@ -49,6 +55,8 @@ public void before() {
                             "debug=true",
                             "shenyu.register.registerType=http",
                             "shenyu.register.serverLists=http://localhost:9095",
    +                        "shenyu.register.props.username=admin",
    +                        "shenyu.register.props.password=123456",
                             "shenyu.client.dubbo.props[contextPath]=/common",
                             "shenyu.client.dubbo.props[appName]=common",
                             "shenyu.client.dubbo.props[host]=localhost",
    @@ -58,27 +66,36 @@ public void before() {
     
         @Test
         public void testShenyuClientRegisterRepository() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 ShenyuClientRegisterRepository repository = context.getBean("shenyuClientRegisterRepository", ShenyuClientRegisterRepository.class);
                 assertNotNull(repository);
             });
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testShenyuRegisterCenterConfig() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 ShenyuRegisterCenterConfig config = context.getBean("shenyuRegisterCenterConfig", ShenyuRegisterCenterConfig.class);
                 assertNotNull(config);
                 assertThat(config.getRegisterType()).isEqualTo(RegisterTypeEnum.HTTP.getName());
             });
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testShenyuClientConfig() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 ShenyuClientConfig config = context.getBean("shenyuClientConfig", ShenyuClientConfig.class);
                 assertNotNull(config);
                 assertThat(config.getClient()).containsKey("dubbo");
             });
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-grpc/src/test/java/org/apache/dromara/springboot/starter/client/grpc/ShenyuGrpcClientConfigurationTest.java+17 0 modified
    @@ -21,15 +21,21 @@
     import org.apache.shenyu.client.grpc.GrpcClientBeanPostProcessor;
     import org.apache.shenyu.client.grpc.GrpcContextRefreshedEventListener;
     import org.apache.shenyu.client.grpc.server.GrpcServerRunner;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Before;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.ComponentScan;
     import org.springframework.context.annotation.Configuration;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuGrpcClientConfiguration}.
    @@ -50,6 +56,8 @@ public void before() {
                     "debug=true",
                     "shenyu.register.registerType=http",
                     "shenyu.register.serverLists=http://localhost:9095",
    +                "shenyu.register.props.username=admin",
    +                "shenyu.register.props.password=123456",
                     "shenyu.client.grpc.props[contextPath]=/grpc",
                     "shenyu.client.grpc.props[appName]=grpc",
                     "shenyu.client.grpc.props[ipAndPort]=127.0.0.1:8080",
    @@ -59,25 +67,34 @@ public void before() {
     
         @Test
         public void testGrpcClientBeanPostProcessor() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 GrpcClientBeanPostProcessor processor = context.getBean("grpcServiceBeanPostProcessor", GrpcClientBeanPostProcessor.class);
                 assertNotNull(processor);
             });
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testGrpcContextRefreshedEventListener() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 GrpcContextRefreshedEventListener listener = context.getBean("grpcContextRefreshedEventListener", GrpcContextRefreshedEventListener.class);
                 assertNotNull(listener);
             });
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testGrpcServerRunner() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 GrpcServerRunner runner = context.getBean("grpcServer", GrpcServerRunner.class);
                 assertNotNull(runner);
             });
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-motan/src/test/java/org/apache/shenyu/springboot/starter/client/motan/ShenyuMotanClientConfigurationTest.java+11 0 modified
    @@ -19,13 +19,19 @@
     package org.apache.shenyu.springboot.starter.client.motan;
     
     import org.apache.shenyu.client.motan.MotanServiceBeanPostProcessor;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuMotanClientConfiguration}.
    @@ -36,13 +42,17 @@ public class ShenyuMotanClientConfigurationTest {
     
         @Test
         public void testMotanServiceBeanPostProcessor() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             new ApplicationContextRunner()
                 .withConfiguration(AutoConfigurations.of(ShenyuMotanClientConfiguration.class))
                 .withBean(ShenyuMotanClientConfigurationTest.class)
                 .withPropertyValues(
                     "debug=true",
                     "shenyu.register.registerType=http",
                     "shenyu.register.serverLists=http://localhost:9095",
    +                "shenyu.register.props.username=admin",
    +                "shenyu.register.props.password=123456",
                     "shenyu.client.motan.props[contextPath]=/motan",
                     "shenyu.client.motan.props[appName]=motan",
                     "shenyu.client.motan.props[host]=127.0.0.1",
    @@ -52,5 +62,6 @@ public void testMotanServiceBeanPostProcessor() {
                     MotanServiceBeanPostProcessor processor = context.getBean("tarsServiceBeanPostProcessor", MotanServiceBeanPostProcessor.class);
                     assertNotNull(processor);
                 });
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-sofa/src/test/java/org/apache/shenyu/springboot/starter/client/sofa/ShenyuSofaClientConfigurationTest.java+11 0 modified
    @@ -19,13 +19,19 @@
     package org.apache.shenyu.springboot.starter.client.sofa;
     
     import org.apache.shenyu.client.sofa.SofaServiceBeanPostProcessor;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuSofaClientConfiguration}.
    @@ -36,13 +42,17 @@ public class ShenyuSofaClientConfigurationTest {
     
         @Test
         public void testSofaServiceBeanPostProcessor() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             new ApplicationContextRunner()
                 .withConfiguration(AutoConfigurations.of(ShenyuSofaClientConfiguration.class))
                 .withBean(ShenyuSofaClientConfigurationTest.class)
                 .withPropertyValues(
                     "debug=true",
                     "shenyu.register.registerType=http",
                     "shenyu.register.serverLists=http://localhost:9095",
    +                "shenyu.register.props.username=admin",
    +                "shenyu.register.props.password=123456",
                     "shenyu.client.sofa.props[contextPath]=/sofa",
                     "shenyu.client.sofa.props[appName]=sofa",
                     "shenyu.client.sofa.props[host]=127.0.0.1",
    @@ -53,5 +63,6 @@ public void testSofaServiceBeanPostProcessor() {
                             assertNotNull(processor);
                         }
                 );
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springcloud/src/test/java/org/apache/shenyu/springboot/starter/client/springcloud/ShenyuSpringCloudClientConfigurationTest.java+14 0 modified
    @@ -19,14 +19,20 @@
     
     import org.apache.shenyu.client.springcloud.init.ContextRegisterListener;
     import org.apache.shenyu.client.springcloud.init.SpringCloudClientBeanPostProcessor;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Before;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuSpringCloudClientConfiguration}.
    @@ -46,6 +52,8 @@ public void before() {
                     "debug=true",
                     "shenyu.register.registerType=http",
                     "shenyu.register.serverLists=http://localhost:9095",
    +                "shenyu.register.props.username=admin",
    +                "shenyu.register.props.password=123456",
                     "spring.application.name=springcloud",
                     "shenyu.client.springCloud.props[contextPath]=/springcloud",
                     "shenyu.client.springCloud.props[port]=8884"
    @@ -54,17 +62,23 @@ public void before() {
     
         @Test
         public void testSpringCloudClientBeanPostProcessor() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 SpringCloudClientBeanPostProcessor repository = context.getBean("springCloudClientBeanPostProcessor", SpringCloudClientBeanPostProcessor.class);
                 assertNotNull(repository);
             });
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testContextRegisterListener() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 ContextRegisterListener listener = context.getBean("contextRegisterListener", ContextRegisterListener.class);
                 assertNotNull(listener);
             });
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-springmvc/src/test/java/org/apache/shenyu/springboot/starter/client/springmvc/ShenyuSpringMvcClientConfigurationTest.java+14 0 modified
    @@ -19,14 +19,20 @@
     
     import org.apache.shenyu.client.springmvc.init.ContextRegisterListener;
     import org.apache.shenyu.client.springmvc.init.SpringMvcClientBeanPostProcessor;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Before;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuSpringMvcClientConfiguration}.
    @@ -46,6 +52,8 @@ public void before() {
                     "debug=true",
                     "shenyu.register.registerType=http",
                     "shenyu.register.serverLists=http://localhost:9095",
    +                "shenyu.register.props.username=admin",
    +                "shenyu.register.props.password=123456",
                     "shenyu.client.http.props[contextPath]=/http",
                     "shenyu.client.http.props[appName]=http",
                     "shenyu.client.http.props[port]=8189"
    @@ -54,17 +62,23 @@ public void before() {
     
         @Test
         public void testSpringMvcClientBeanPostProcessor() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 SpringMvcClientBeanPostProcessor processor = context.getBean("springHttpClientBeanPostProcessor", SpringMvcClientBeanPostProcessor.class);
                 assertNotNull(processor);
             });
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testContextRegisterListener() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 ContextRegisterListener listener = context.getBean("contextRegisterListener", ContextRegisterListener.class);
                 assertNotNull(listener);
             });
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-client/shenyu-spring-boot-starter-client-tars/src/test/java/org/apache/shenyu/springboot/starter/client/tars/ShenyuTarsClientConfigurationTest.java+14 0 modified
    @@ -20,14 +20,20 @@
     
     import org.apache.shenyu.client.tars.TarsContextRefreshedEventListener;
     import org.apache.shenyu.client.tars.TarsServiceBeanPostProcessor;
    +import org.apache.shenyu.register.client.http.utils.RegisterUtils;
     import org.junit.Before;
     import org.junit.Test;
    +import org.mockito.MockedStatic;
     import org.springframework.boot.autoconfigure.AutoConfigurations;
     import org.springframework.boot.context.properties.EnableConfigurationProperties;
     import org.springframework.boot.test.context.runner.ApplicationContextRunner;
     import org.springframework.context.annotation.Configuration;
     
    +import java.util.Optional;
    +
     import static org.junit.Assert.assertNotNull;
    +import static org.mockito.ArgumentMatchers.any;
    +import static org.mockito.Mockito.mockStatic;
     
     /**
      * Test case for {@link ShenyuTarsClientConfiguration}.
    @@ -47,6 +53,8 @@ public void before() {
                     "debug=true",
                     "shenyu.register.registerType=http",
                     "shenyu.register.serverLists=http://localhost:9095",
    +                "shenyu.register.props.username=admin",
    +                "shenyu.register.props.password=123456",
                     "shenyu.client.tars.props[contextPath]=/tars",
                     "shenyu.client.tars.props[appName]=tars",
                     "shenyu.client.tars.props[host]=127.0.0.1",
    @@ -56,17 +64,23 @@ public void before() {
     
         @Test
         public void testTarsServiceBeanPostProcessor() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 TarsServiceBeanPostProcessor processor = context.getBean("tarsServiceBeanPostProcessor", TarsServiceBeanPostProcessor.class);
                 assertNotNull(processor);
             });
    +        registerUtilsMockedStatic.close();
         }
     
         @Test
         public void testTarsContextRefreshedEventListener() {
    +        MockedStatic<RegisterUtils> registerUtilsMockedStatic = mockStatic(RegisterUtils.class);
    +        registerUtilsMockedStatic.when(() -> RegisterUtils.doLogin(any(), any(), any())).thenReturn(Optional.ofNullable("token"));
             applicationContextRunner.run(context -> {
                 TarsContextRefreshedEventListener listener = context.getBean("tarsContextRefreshedEventListener", TarsContextRefreshedEventListener.class);
                 assertNotNull(listener);
             });
    +        registerUtilsMockedStatic.close();
         }
     }
    
  • shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-http/src/test/java/org/apache/shenyu/springboot/starter/sync/data/http/HttpClientPluginConfigurationTest.java+23 0 modified
    @@ -18,6 +18,8 @@
     package org.apache.shenyu.springboot.starter.sync.data.http;
     
     import com.github.tomakehurst.wiremock.WireMockServer;
    +import org.apache.shenyu.common.exception.CommonErrorCode;
    +import org.apache.shenyu.common.utils.GsonUtils;
     import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
     import org.apache.shenyu.sync.data.http.HttpSyncDataService;
     import org.apache.shenyu.sync.data.http.config.HttpConfig;
    @@ -35,6 +37,8 @@
     
     import java.nio.file.Files;
     import java.nio.file.Paths;
    +import java.util.HashMap;
    +import java.util.Map;
     import java.util.Objects;
     
     import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
    @@ -58,6 +62,8 @@
             properties = {
                     "shenyu.sync.http.url=http://localhost:18848",
                     "shenyu.sync.http.delayTime=3",
    +                "shenyu.sync.http.username=admin",
    +                "shenyu.sync.http.password=123456",
                     "shenyu.sync.http.connectionTimeout=5"
             })
     @EnableAutoConfiguration
    @@ -74,6 +80,13 @@ public final class HttpClientPluginConfigurationTest {
         public static void setUpWireMock() throws Exception {
             WireMockServer wireMockServer = new WireMockServer(options().port(18848));
     
    +        wireMockServer.stubFor(get(urlPathEqualTo("/platform/login"))
    +                .willReturn(aResponse()
    +                        .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
    +                        .withBody(mockLoginResponseJson())
    +                        .withStatus(200))
    +        );
    +
             wireMockServer.stubFor(get(urlPathEqualTo("/configs/fetch"))
                     .willReturn(aResponse()
                             .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
    @@ -113,4 +126,14 @@ private static String mockConfigsFetchResponseJson() throws Exception {
                     Paths.get(Objects.requireNonNull(HttpClientPluginConfigurationTest.class.getClassLoader()
                             .getResource("mock_configs_fetch_response.json")).toURI())));
         }
    +
    +    // mock configs fetch api response
    +    private static String mockLoginResponseJson() {
    +        Map<String, Object> result = new HashMap<>();
    +        Map<String, Object> data = new HashMap<>();
    +        data.put("token", "token");
    +        result.put("data", data);
    +        result.put("code", CommonErrorCode.SUCCESSFUL);
    +        return GsonUtils.getInstance().toJson(result);
    +    }
     }
    
  • shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/config/HttpConfig.java+40 0 modified
    @@ -30,6 +30,46 @@ public class HttpConfig {
     
         private Integer connectionTimeout;
     
    +    private String username;
    +
    +    private String password;
    +
    +    /**
    +     * get username.
    +     *
    +     * @return username
    +     */
    +    public String getUsername() {
    +        return username;
    +    }
    +
    +    /**
    +     * set username.
    +     *
    +     * @param username username
    +     */
    +    public void setUsername(final String username) {
    +        this.username = username;
    +    }
    +
    +    /**
    +     * get password.
    +     *
    +     * @return password
    +     */
    +    public String getPassword() {
    +        return password;
    +    }
    +
    +    /**
    +     * set password.
    +     *
    +     * @param password password
    +     */
    +    public void setPassword(final String password) {
    +        this.password = password;
    +    }
    +
         /**
          * get url.
          *
    
  • shenyu-sync-data-center/shenyu-sync-data-http/src/main/java/org/apache/shenyu/sync/data/http/HttpSyncDataService.java+67 14 modified
    @@ -25,10 +25,14 @@
     import org.apache.commons.lang3.ArrayUtils;
     import org.apache.commons.lang3.StringUtils;
     import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
    +import org.apache.shenyu.common.constant.Constants;
     import org.apache.shenyu.common.constant.HttpConstants;
     import org.apache.shenyu.common.dto.ConfigData;
     import org.apache.shenyu.common.enums.ConfigGroupEnum;
    +import org.apache.shenyu.common.exception.CommonErrorCode;
     import org.apache.shenyu.common.exception.ShenyuException;
    +import org.apache.shenyu.common.utils.FreshBeanHolder;
    +import org.apache.shenyu.common.utils.GsonUtils;
     import org.apache.shenyu.common.utils.ThreadUtils;
     import org.apache.shenyu.sync.data.api.AuthDataSubscriber;
     import org.apache.shenyu.sync.data.api.MetaDataSubscriber;
    @@ -40,6 +44,7 @@
     import org.slf4j.LoggerFactory;
     import org.springframework.http.HttpEntity;
     import org.springframework.http.HttpHeaders;
    +import org.springframework.http.HttpMethod;
     import org.springframework.http.MediaType;
     import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
     import org.springframework.util.LinkedMultiValueMap;
    @@ -51,6 +56,10 @@
     import java.util.Arrays;
     import java.util.List;
     import java.util.Objects;
    +import java.util.Map;
    +import java.util.HashMap;
    +import java.util.Optional;
    +import java.util.Iterator;
     import java.util.concurrent.ExecutorService;
     import java.util.concurrent.LinkedBlockingQueue;
     import java.util.concurrent.ThreadPoolExecutor;
    @@ -67,19 +76,9 @@ public class HttpSyncDataService implements SyncDataService, AutoCloseable {
          */
         private static final Logger LOG = LoggerFactory.getLogger(HttpSyncDataService.class);
     
    -    private static final AtomicBoolean RUNNING = new AtomicBoolean(false);
    -
         private static final Gson GSON = new Gson();
     
    -    /**
    -     * shenyu admin path configs fetch.
    -     */
    -    private static final String SHENYU_ADMIN_PATH_CONFIGS_FETCH = "/configs/fetch";
    -
    -    /**
    -     * shenyu admin path configs listener.
    -     */
    -    private static final String SHENYU_ADMIN_PATH_CONFIGS_LISTENER = "/configs/listener";
    +    private static final AtomicBoolean RUNNING = new AtomicBoolean(false);
     
         /**
          * default: 10s.
    @@ -93,15 +92,21 @@ public class HttpSyncDataService implements SyncDataService, AutoCloseable {
     
         private ExecutorService executor;
     
    +    private final HttpConfig httpConfig;
    +
         private final List<String> serverList;
     
         private final DataRefreshFactory factory;
     
    +    private final FreshBeanHolder<String, Optional<Object>> accessToken;
    +
         public HttpSyncDataService(final HttpConfig httpConfig, final PluginDataSubscriber pluginDataSubscriber,
                                    final List<MetaDataSubscriber> metaDataSubscribers, final List<AuthDataSubscriber> authDataSubscribers) {
    +        this.httpConfig = httpConfig;
             this.factory = new DataRefreshFactory(pluginDataSubscriber, metaDataSubscribers, authDataSubscribers);
             this.serverList = Lists.newArrayList(Splitter.on(",").split(httpConfig.getUrl()));
             this.httpClient = createRestTemplate();
    +        this.accessToken = new FreshBeanHolder<>(this::doLogin);
             this.start();
         }
     
    @@ -149,11 +154,18 @@ private void doFetchGroupConfig(final String server, final ConfigGroupEnum... gr
             for (ConfigGroupEnum groupKey : groups) {
                 params.append("groupKeys").append("=").append(groupKey.name()).append("&");
             }
    -        String url = server + SHENYU_ADMIN_PATH_CONFIGS_FETCH + "?" + StringUtils.removeEnd(params.toString(), "&");
    +        String url = server + Constants.SHENYU_ADMIN_PATH_CONFIGS_FETCH + "?" + StringUtils.removeEnd(params.toString(), "&");
             LOG.info("request configs: [{}]", url);
             String json;
             try {
    -            json = this.httpClient.getForObject(url, String.class);
    +            Optional<Object> token = accessToken.apply(server);
    +            if (!token.isPresent()) {
    +                throw new ShenyuException("get token from server : [" + server + " ] error");
    +            }
    +            HttpHeaders headers = new HttpHeaders();
    +            headers.set(Constants.X_ACCESS_TOKEN, String.valueOf(token.get()));
    +            HttpEntity<String> httpEntity = new HttpEntity<>(headers);
    +            json = this.httpClient.exchange(url, HttpMethod.GET, httpEntity, String.class).getBody();
             } catch (RestClientException e) {
                 String message = String.format("fetch config fail from server[%s], %s", url, e.getMessage());
                 LOG.warn(message);
    @@ -184,6 +196,10 @@ private boolean updateCacheWithJson(final String json) {
         }
     
         private void doLongPolling(final String server) {
    +        Optional<Object> token = accessToken.apply(server);
    +        if (!token.isPresent()) {
    +            throw new ShenyuException("get token from server : [" + server + " ] error");
    +        }
             MultiValueMap<String, String> params = new LinkedMultiValueMap<>(8);
             for (ConfigGroupEnum group : ConfigGroupEnum.values()) {
                 ConfigData<?> cacheConfig = factory.cacheConfigData(group);
    @@ -194,8 +210,9 @@ private void doLongPolling(final String server) {
             }
             HttpHeaders headers = new HttpHeaders();
             headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    +        headers.set(Constants.X_ACCESS_TOKEN, String.valueOf(token.get()));
             HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, headers);
    -        String listenerUrl = server + SHENYU_ADMIN_PATH_CONFIGS_LISTENER;
    +        String listenerUrl = server + Constants.SHENYU_ADMIN_PATH_CONFIGS_LISTENER;
             LOG.debug("request listener configs: [{}]", listenerUrl);
     
             JsonArray groupJson;
    @@ -228,6 +245,40 @@ public void close() {
             }
         }
     
    +    private Optional<Object> doLogin(final String server) {
    +        Map<String, Object> loginMap = new HashMap<>(2);
    +        loginMap.put(Constants.LOGIN_NAME, httpConfig.getUsername());
    +        loginMap.put(Constants.PASS_WORD, httpConfig.getPassword());
    +        String param = toQuery(loginMap);
    +        String url = String.join("?", server + Constants.LOGIN_PATH, param);
    +        String result = this.httpClient.getForObject(url, String.class);
    +        Map<String, Object> resultMap = GsonUtils.getInstance().convertToMap(result);
    +        if (!String.valueOf(CommonErrorCode.SUCCESSFUL).equals(String.valueOf(resultMap.get(Constants.ADMIN_RESULT_CODE)))) {
    +            return Optional.empty();
    +        }
    +        String tokenJson = GsonUtils.getInstance().toJson(resultMap.get(Constants.ADMIN_RESULT_DATA));
    +        LOG.info("login success: {} ", tokenJson);
    +        Map<String, Object> tokenMap = GsonUtils.getInstance().convertToMap(tokenJson);
    +        return Optional.ofNullable(tokenMap.get(Constants.ADMIN_RESULT_TOKEN));
    +    }
    +
    +    private String toQuery(final Object o) {
    +        Map<String, Object> map = null;
    +        if (o instanceof Map) {
    +            map = (Map) o;
    +        } else {
    +            map = GsonUtils.getInstance().convertToMap(GsonUtils.getInstance().toJson(o));
    +        }
    +        String[] list = new String[((Map) map).size()];
    +        int i = 0;
    +
    +        Map.Entry e;
    +        for (Iterator var = ((Map) map).entrySet().iterator(); var.hasNext(); list[i++] = (String) e.getKey() + "=" + e.getValue().toString()) {
    +            e = (Map.Entry) var.next();
    +        }
    +        return StringUtils.join(list, '&');
    +    }
    +
         class HttpLongPollingTask implements Runnable {
     
             private final String server;
    @@ -242,6 +293,8 @@ public void run() {
                     int retryTimes = 3;
                     for (int time = 1; time <= retryTimes; time++) {
                         try {
    +                        //refresh the admin token
    +                        accessToken.doFresh(server);
                             doLongPolling(server);
                         } catch (Exception e) {
                             // print warnning LOG.
    
  • shenyu-sync-data-center/shenyu-sync-data-http/src/test/java/org/apache/shenyu/sync/data/http/HttpSyncDataServiceTest.java+21 2 modified
    @@ -22,6 +22,7 @@
     import org.apache.shenyu.common.dto.ConfigData;
     import org.apache.shenyu.common.dto.PluginData;
     import org.apache.shenyu.common.enums.ConfigGroupEnum;
    +import org.apache.shenyu.common.exception.CommonErrorCode;
     import org.apache.shenyu.common.utils.GsonUtils;
     import org.apache.shenyu.sync.data.api.AuthDataSubscriber;
     import org.apache.shenyu.sync.data.api.MetaDataSubscriber;
    @@ -40,9 +41,9 @@
     import wiremock.org.apache.http.entity.ContentType;
     
     import java.util.Collections;
    -import java.util.HashMap;
    -import java.util.Map;
     import java.util.Objects;
    +import java.util.Map;
    +import java.util.HashMap;
     import java.util.concurrent.atomic.AtomicBoolean;
     
     import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
    @@ -76,6 +77,12 @@ public final class HttpSyncDataServiceTest {
     
         @Before
         public void before() {
    +        wireMockRule.stubFor(get(urlPathEqualTo("/platform/login"))
    +                .willReturn(aResponse()
    +                        .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
    +                        .withBody(this.mockLoginResponseJson())
    +                        .withStatus(200))
    +        );
             wireMockRule.stubFor(get(urlPathEqualTo("/configs/fetch"))
                     .willReturn(aResponse()
                             .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
    @@ -95,6 +102,8 @@ public void before() {
             httpConfig.setConnectionTimeout(3000);
             // set delay time
             httpConfig.setDelayTime(3);
    +        httpConfig.setPassword("123456");
    +        httpConfig.setUsername("admin");
             this.pluginDataSubscriber = mock(PluginDataSubscriber.class);
             this.metaDataSubscriber = mock(MetaDataSubscriber.class);
             this.authDataSubscriber = mock(AuthDataSubscriber.class);
    @@ -157,4 +166,14 @@ private String mockConfigsFetchResponseJson() {
             response.put("code", 200);
             return GsonUtils.getInstance().toJson(response);
         }
    +
    +    // mock configs fetch api response
    +    private String mockLoginResponseJson() {
    +        Map<String, Object> result = new HashMap<>();
    +        Map<String, Object> data = new HashMap<>();
    +        data.put("token", "token");
    +        result.put("data", data);
    +        result.put("code", CommonErrorCode.SUCCESSFUL);
    +        return GsonUtils.getInstance().toJson(result);
    +    }
     }
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.