feat: support enable/disable cloud location provider via configuration. (#1799)
Signed-off-by: Haotian Zhang <928016560@qq.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>2024
parent
0b9d8cdadd
commit
0f2d7073a4
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.tencent.cloud.polaris.context.config.location;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.tencent.cloud.common.constant.OrderConstant;
|
||||
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
|
||||
import com.tencent.polaris.api.plugin.location.LocationProvider;
|
||||
import com.tencent.polaris.factory.config.ConfigurationImpl;
|
||||
import com.tencent.polaris.factory.config.global.LocationConfigImpl;
|
||||
import com.tencent.polaris.factory.config.global.LocationProviderConfigImpl;
|
||||
|
||||
/**
|
||||
* Config modifier for Polaris location providers.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class PolarisLocationConfigModifier implements PolarisConfigModifier {
|
||||
|
||||
private final PolarisLocationProperties properties;
|
||||
|
||||
public PolarisLocationConfigModifier(PolarisLocationProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(ConfigurationImpl configuration) {
|
||||
LocationConfigImpl locationConfig = (LocationConfigImpl) configuration.getGlobal().getLocation();
|
||||
List<LocationProviderConfigImpl> providers = locationConfig.getProviders();
|
||||
if (providers == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String cloudTypeName = LocationProvider.ProviderType.CLOUD.getName();
|
||||
|
||||
if (!properties.getCloud().isEnabled()) {
|
||||
// Remove cloud provider if disabled
|
||||
providers.removeIf(p -> cloudTypeName.equals(p.getType()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Only add the cloud provider entry if it does not already exist
|
||||
boolean cloudProviderExists = providers.stream()
|
||||
.anyMatch(p -> cloudTypeName.equals(p.getType()));
|
||||
if (!cloudProviderExists) {
|
||||
LocationProviderConfigImpl cloudProviderConfig = new LocationProviderConfigImpl();
|
||||
cloudProviderConfig.setType(cloudTypeName);
|
||||
providers.add(cloudProviderConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return OrderConstant.Modifier.LOCATION_ORDER;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.tencent.cloud.polaris.context.config.location;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Properties for Polaris location provider configuration.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.cloud.polaris.location")
|
||||
public class PolarisLocationProperties {
|
||||
|
||||
/**
|
||||
* Cloud location provider configuration.
|
||||
*/
|
||||
private Cloud cloud = new Cloud();
|
||||
|
||||
public Cloud getCloud() {
|
||||
return cloud;
|
||||
}
|
||||
|
||||
public void setCloud(Cloud cloud) {
|
||||
this.cloud = cloud;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PolarisLocationProperties{" +
|
||||
"cloud=" + cloud +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties for cloud location provider.
|
||||
*/
|
||||
public static class Cloud {
|
||||
|
||||
/**
|
||||
* Whether to enable the cloud location provider. Default is true.
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Cloud{" +
|
||||
"enabled=" + enabled +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.tencent.cloud.polaris.context.config.location;
|
||||
|
||||
import com.tencent.cloud.common.constant.OrderConstant;
|
||||
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
|
||||
import com.tencent.polaris.api.plugin.location.LocationProvider;
|
||||
import com.tencent.polaris.factory.config.global.LocationConfigImpl;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link PolarisLocationConfigModifier}.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@DisplayName("PolarisLocationConfigModifier")
|
||||
class PolarisLocationConfigModifierTest {
|
||||
|
||||
private final ApplicationContextRunner enabledContextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(TestApplication.class)
|
||||
.withPropertyValues("spring.cloud.polaris.enabled=true")
|
||||
.withPropertyValues("spring.cloud.polaris.location.cloud.enabled=true")
|
||||
.withPropertyValues("spring.application.name=test")
|
||||
.withPropertyValues("spring.cloud.gateway.enabled=false");
|
||||
|
||||
private final ApplicationContextRunner disabledContextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(TestApplication.class)
|
||||
.withPropertyValues("spring.cloud.polaris.enabled=true")
|
||||
.withPropertyValues("spring.cloud.polaris.location.cloud.enabled=false")
|
||||
.withPropertyValues("spring.application.name=test")
|
||||
.withPropertyValues("spring.cloud.gateway.enabled=false");
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
PolarisSDKContextManager.innerDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test purpose: verify that cloud location provider is added by default.
|
||||
* Test scenario: no explicit location config, cloud.enabled defaults to true.
|
||||
* Verification: providers list contains one entry with type "cloud".
|
||||
*/
|
||||
@DisplayName("cloud provider is added when enabled by default")
|
||||
@Test
|
||||
void testModify_cloudEnabledByDefault() {
|
||||
enabledContextRunner.run(context -> {
|
||||
PolarisSDKContextManager manager = context.getBean(PolarisSDKContextManager.class);
|
||||
LocationConfigImpl locationConfig = (LocationConfigImpl) manager.getSDKContext()
|
||||
.getConfig().getGlobal().getLocation();
|
||||
boolean hasCloudProvider = locationConfig.getProviders().stream()
|
||||
.anyMatch(p -> LocationProvider.ProviderType.CLOUD.getName().equals(p.getType()));
|
||||
assertThat(hasCloudProvider).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test purpose: verify that cloud location provider is removed when disabled.
|
||||
* Test scenario: spring.cloud.polaris.location.cloud.enabled=false.
|
||||
* Verification: providers list contains no entry with type "cloud".
|
||||
*/
|
||||
@DisplayName("cloud provider is removed when disabled")
|
||||
@Test
|
||||
void testModify_cloudDisabled() {
|
||||
disabledContextRunner.run(context -> {
|
||||
PolarisSDKContextManager manager = context.getBean(PolarisSDKContextManager.class);
|
||||
LocationConfigImpl locationConfig = (LocationConfigImpl) manager.getSDKContext()
|
||||
.getConfig().getGlobal().getLocation();
|
||||
boolean hasCloudProvider = locationConfig.getProviders().stream()
|
||||
.anyMatch(p -> LocationProvider.ProviderType.CLOUD.getName().equals(p.getType()));
|
||||
assertThat(hasCloudProvider).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test purpose: verify that no duplicate cloud provider entry is added.
|
||||
* Test scenario: cloud is enabled (default), Spring context is loaded once.
|
||||
* Verification: providers list contains exactly one entry with type "cloud".
|
||||
*/
|
||||
@DisplayName("no duplicate cloud provider entry is added")
|
||||
@Test
|
||||
void testModify_noDuplicateCloudProvider() {
|
||||
enabledContextRunner.run(context -> {
|
||||
PolarisSDKContextManager manager = context.getBean(PolarisSDKContextManager.class);
|
||||
LocationConfigImpl locationConfig = (LocationConfigImpl) manager.getSDKContext()
|
||||
.getConfig().getGlobal().getLocation();
|
||||
long cloudProviderCount = locationConfig.getProviders().stream()
|
||||
.filter(p -> LocationProvider.ProviderType.CLOUD.getName().equals(p.getType()))
|
||||
.count();
|
||||
assertThat(cloudProviderCount).isEqualTo(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test purpose: verify getOrder returns the location order constant.
|
||||
* Test scenario: obtain modifier bean from context and call getOrder.
|
||||
* Verification: order equals OrderConstant.Modifier.LOCATION_ORDER.
|
||||
*/
|
||||
@DisplayName("getOrder returns LOCATION_ORDER")
|
||||
@Test
|
||||
void testGetOrder() {
|
||||
enabledContextRunner.run(context -> {
|
||||
PolarisLocationConfigModifier modifier = context.getBean(PolarisLocationConfigModifier.class);
|
||||
assertThat(modifier.getOrder()).isEqualTo(OrderConstant.Modifier.LOCATION_ORDER);
|
||||
});
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
protected static class TestApplication {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.tencent.cloud.polaris.context.config.location;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link PolarisLocationProperties}.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@DisplayName("PolarisLocationProperties")
|
||||
class PolarisLocationPropertiesTest {
|
||||
|
||||
/**
|
||||
* Test purpose: verify PolarisLocationProperties default values.
|
||||
* Test scenario: no configuration provided, use default constructor.
|
||||
* Verification: cloud.enabled is true by default.
|
||||
*/
|
||||
@DisplayName("cloud.enabled defaults to true")
|
||||
@Test
|
||||
void testDefaultCloudEnabled() {
|
||||
// Arrange
|
||||
PolarisLocationProperties properties = new PolarisLocationProperties();
|
||||
|
||||
// Act & Assert
|
||||
assertThat(properties.getCloud().isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test purpose: verify PolarisLocationProperties.Cloud setter and getter.
|
||||
* Test scenario: set cloud.enabled to false via setter.
|
||||
* Verification: getter returns false.
|
||||
*/
|
||||
@DisplayName("Cloud enabled can be set to false")
|
||||
@Test
|
||||
void testSetCloudEnabled() {
|
||||
// Arrange
|
||||
PolarisLocationProperties properties = new PolarisLocationProperties();
|
||||
PolarisLocationProperties.Cloud cloud = new PolarisLocationProperties.Cloud();
|
||||
cloud.setEnabled(false);
|
||||
|
||||
// Act
|
||||
properties.setCloud(cloud);
|
||||
|
||||
// Assert
|
||||
assertThat(properties.getCloud().isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test purpose: verify PolarisLocationProperties toString output.
|
||||
* Test scenario: default properties instance.
|
||||
* Verification: toString contains cloud and enabled info.
|
||||
*/
|
||||
@DisplayName("toString contains cloud info")
|
||||
@Test
|
||||
void testToString() {
|
||||
// Arrange
|
||||
PolarisLocationProperties properties = new PolarisLocationProperties();
|
||||
|
||||
// Act
|
||||
String result = properties.toString();
|
||||
|
||||
// Assert
|
||||
assertThat(result).contains("cloud=");
|
||||
assertThat(result).contains("enabled=true");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test purpose: verify PolarisLocationProperties.Cloud toString output.
|
||||
* Test scenario: default Cloud instance.
|
||||
* Verification: toString contains enabled=true.
|
||||
*/
|
||||
@DisplayName("Cloud toString contains enabled info")
|
||||
@Test
|
||||
void testCloudToString() {
|
||||
// Arrange
|
||||
PolarisLocationProperties.Cloud cloud = new PolarisLocationProperties.Cloud();
|
||||
|
||||
// Act
|
||||
String result = cloud.toString();
|
||||
|
||||
// Assert
|
||||
assertThat(result).contains("enabled=true");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue