Merge branch '2021.0' into feature/nacos-namespace

pull/1122/head
wenxuan70 2 years ago committed by GitHub
commit 48df1f8f7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,3 +15,7 @@
- [feat:add swagger report switch.](https://github.com/Tencent/spring-cloud-tencent/pull/1148)
- [fix:fix retry loadbalancer not working bug.](https://github.com/Tencent/spring-cloud-tencent/pull/1154)
- [feat: support nacos namespace mapping](https://github.com/Tencent/spring-cloud-tencent/pull/1122)
- [fix:fix header validation when using Chinese char.](https://github.com/Tencent/spring-cloud-tencent/pull/1166)
- [fix:remove bcprov-jdk15on dependency.](https://github.com/Tencent/spring-cloud-tencent/pull/1177)
- [feat:support configuration encryption.](https://github.com/Tencent/spring-cloud-tencent/pull/1181)
- [feat:optimize examples.](https://github.com/Tencent/spring-cloud-tencent/pull/1185)

@ -77,8 +77,7 @@ Spring Cloud Tencent 所有组件都已上传到 Maven 中央仓库,只需要
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<!--version number-->
<version>1.12.1-2021.0.8</version>
<version>${LATEST_VERSION_FROM_VERSION_MANAGEMENT_IN_WIKI}</version>
<type>pom</type>
<scope>import</scope>
</dependency>

@ -79,8 +79,7 @@ For example:
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<!--version number-->
<version>1.12.1-2021.0.8</version>
<version>${LATEST_VERSION_FROM_VERSION_MANAGEMENT_IN_WIKI}</version>
<type>pom</type>
<scope>import</scope>
</dependency>

@ -28,3 +28,4 @@
- [fix:upgrade spring version.](https://github.com/Tencent/spring-cloud-tencent/pull/1086)
- [fix:Update README-zh.md](https://github.com/Tencent/spring-cloud-tencent/pull/1090).
- [feature: support Polaris configuration center extension plugin interface and support dynamic modification of log levels.](https://github.com/Tencent/spring-cloud-tencent/pull/1103).
- fix:fix system env variable read bug.

@ -49,18 +49,6 @@
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
</dependency>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>

@ -47,7 +47,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT,
classes = EncodeTransferMedataFeignInterceptorTest.TestApplication.class,
properties = {"server.port=8081", "spring.config.location = classpath:application-test.yml"})
properties = {"server.port=48081", "spring.config.location = classpath:application-test.yml"})
public class EncodeTransferMedataFeignInterceptorTest {
@Autowired
@ -74,7 +74,7 @@ public class EncodeTransferMedataFeignInterceptorTest {
return MetadataContextHolder.get().getContext(MetadataContext.FRAGMENT_TRANSITIVE, "b");
}
@FeignClient(name = "test-feign", url = "http://localhost:8081")
@FeignClient(name = "test-feign", url = "http://localhost:48081")
public interface TestFeign {
@RequestMapping("/test")

@ -27,12 +27,14 @@ import com.google.protobuf.util.JsonFormat;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.context.ServiceRuleManager;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
/**
* Endpoint of polaris circuit breaker, include circuit breaker rules.
@ -51,25 +53,30 @@ public class PolarisCircuitBreakerEndpoint {
}
@ReadOperation
public Map<String, Object> circuitBreaker() {
CircuitBreakerProto.CircuitBreaker circuitBreaker = serviceRuleManager.getServiceCircuitBreakerRule(
public Map<String, Object> circuitBreaker(@Selector String dstService) {
List<CircuitBreakerProto.CircuitBreakerRule> rules = serviceRuleManager.getServiceCircuitBreakerRule(
MetadataContext.LOCAL_NAMESPACE,
MetadataContext.LOCAL_SERVICE
MetadataContext.LOCAL_SERVICE,
dstService
);
Map<String, Object> polarisCircuitBreakerInfo = new HashMap<>();
polarisCircuitBreakerInfo.put("namespace", MetadataContext.LOCAL_NAMESPACE);
polarisCircuitBreakerInfo.put("service", MetadataContext.LOCAL_SERVICE);
polarisCircuitBreakerInfo.put("circuitBreakerRules", parseCircuitBreakerRule(circuitBreaker));
List<Object> circuitBreakerRules = new ArrayList<>();
if (CollectionUtils.isNotEmpty(rules)) {
for (CircuitBreakerProto.CircuitBreakerRule rule : rules) {
circuitBreakerRules.add(parseCircuitBreakerRule(rule));
}
}
polarisCircuitBreakerInfo.put("circuitBreakerRules", circuitBreakerRules);
return polarisCircuitBreakerInfo;
}
private List<Object> parseCircuitBreakerRule(CircuitBreakerProto.CircuitBreaker circuitBreaker) {
List<Object> circuitBreakerRuleList = new ArrayList<>();
for (CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule : circuitBreaker.getRulesList()) {
private Object parseCircuitBreakerRule(CircuitBreakerProto.CircuitBreakerRule circuitBreakerRule) {
String ruleJson;
try {
ruleJson = JsonFormat.printer().print(circuitBreakerRule);
@ -78,9 +85,6 @@ public class PolarisCircuitBreakerEndpoint {
LOG.error("rule to Json failed. check rule {}.", circuitBreakerRule, e);
throw new RuntimeException("Json failed.", e);
}
circuitBreakerRuleList.add(JacksonUtils.deserialize2Map(ruleJson));
}
return circuitBreakerRuleList;
return JacksonUtils.deserialize2Map(ruleJson);
}
}

@ -0,0 +1,50 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.endpoint;
import com.tencent.cloud.polaris.circuitbreaker.config.PolarisCircuitBreakerAutoConfiguration;
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementAutoConfiguration;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test for {@link PolarisCircuitBreakerEndpointAutoConfiguration}.
*
* @author wenxuan70
*/
public class PolarisCircuitBreakerEndpointAutoConfigurationTest {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
PolarisContextAutoConfiguration.class,
RpcEnhancementAutoConfiguration.class,
PolarisCircuitBreakerAutoConfiguration.class,
PolarisCircuitBreakerEndpointAutoConfiguration.class
))
.withPropertyValues("management.endpoints.web.exposure.include=polaris-circuit-breaker");
@Test
public void testEndpointInitialization() {
contextRunner.run(context -> assertThat(context).hasSingleBean(PolarisCircuitBreakerEndpoint.class));
}
}

@ -56,7 +56,7 @@ public class PolarisCircuitBreakerEndpointTest {
@BeforeEach
void setUp() {
serviceRuleManager = mock(ServiceRuleManager.class);
when(serviceRuleManager.getServiceCircuitBreakerRule(anyString(), anyString())).thenAnswer(invocation -> {
when(serviceRuleManager.getServiceCircuitBreakerRule(anyString(), anyString(), anyString())).thenAnswer(invocation -> {
CircuitBreakerProto.CircuitBreakerRule.Builder ruleBuilder = CircuitBreakerProto.CircuitBreakerRule.newBuilder();
ruleBuilder.setName("test_for_circuit_breaker");
ruleBuilder.setEnable(true);
@ -66,7 +66,7 @@ public class PolarisCircuitBreakerEndpointTest {
ModelProto.MatchString.newBuilder().setValue(StringValue.newBuilder().setValue("*").build()).build()).build());
rmBuilder.setSource(CircuitBreakerProto.RuleMatcher.SourceService.newBuilder().setNamespace("*").setService("*").build());
ruleBuilder.setRuleMatcher(rmBuilder.build());
return CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(ruleBuilder.build()).build();
return CircuitBreakerProto.CircuitBreaker.newBuilder().addRules(ruleBuilder.build()).build().getRulesList();
});
}
@ -74,7 +74,7 @@ public class PolarisCircuitBreakerEndpointTest {
public void testPolarisCircuitBreaker() {
contextRunner.run(context -> {
PolarisCircuitBreakerEndpoint endpoint = new PolarisCircuitBreakerEndpoint(serviceRuleManager);
Map<String, Object> circuitBreakerInfo = endpoint.circuitBreaker();
Map<String, Object> circuitBreakerInfo = endpoint.circuitBreaker("test");
assertThat(circuitBreakerInfo).isNotNull();
assertThat(circuitBreakerInfo.get("namespace")).isNotNull();
assertThat(circuitBreakerInfo.get("service")).isNotNull();

@ -19,14 +19,17 @@
package com.tencent.cloud.polaris.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.tencent.cloud.common.constant.OrderConstant;
import com.tencent.cloud.common.util.AddressUtils;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.config.PolarisCryptoConfigProperties;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.polaris.factory.config.ConfigurationImpl;
import com.tencent.polaris.factory.config.configuration.ConfigFilterConfigImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -47,11 +50,15 @@ public class ConfigurationModifier implements PolarisConfigModifier {
private final PolarisConfigProperties polarisConfigProperties;
private final PolarisCryptoConfigProperties polarisCryptoConfigProperties;
private final PolarisContextProperties polarisContextProperties;
public ConfigurationModifier(PolarisConfigProperties polarisConfigProperties,
PolarisCryptoConfigProperties polarisCryptoConfigProperties,
PolarisContextProperties polarisContextProperties) {
this.polarisConfigProperties = polarisConfigProperties;
this.polarisCryptoConfigProperties = polarisCryptoConfigProperties;
this.polarisContextProperties = polarisContextProperties;
}
@ -66,6 +73,13 @@ public class ConfigurationModifier implements PolarisConfigModifier {
else {
throw new RuntimeException("Unsupported config data source");
}
ConfigFilterConfigImpl configFilterConfig = configuration.getConfigFile().getConfigFilterConfig();
configFilterConfig.setEnable(polarisCryptoConfigProperties.isEnabled());
if (polarisCryptoConfigProperties.isEnabled()) {
configFilterConfig.getChain().add("crypto");
configFilterConfig.getPlugin().put("crypto", Collections.singletonMap("type", "AES"));
}
}
private void initByLocalDataSource(ConfigurationImpl configuration) {

@ -23,6 +23,7 @@ import com.tencent.cloud.polaris.config.adapter.PolarisConfigFileLocator;
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager;
import com.tencent.cloud.polaris.config.condition.ConditionalOnReflectRefreshType;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.config.PolarisCryptoConfigProperties;
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
@ -53,6 +54,11 @@ public class PolarisConfigBootstrapAutoConfiguration {
return new PolarisConfigProperties();
}
@Bean
public PolarisCryptoConfigProperties polarisCryptoConfigProperties() {
return new PolarisCryptoConfigProperties();
}
@Bean
@ConditionalOnMissingBean
public PolarisPropertySourceManager polarisPropertySourceManager() {
@ -81,8 +87,9 @@ public class PolarisConfigBootstrapAutoConfiguration {
@Bean
@ConditionalOnConnectRemoteServerEnabled
public ConfigurationModifier configurationModifier(PolarisConfigProperties polarisConfigProperties,
PolarisCryptoConfigProperties polarisCryptoConfigProperties,
PolarisContextProperties polarisContextProperties) {
return new ConfigurationModifier(polarisConfigProperties, polarisContextProperties);
return new ConfigurationModifier(polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties);
}
@Bean

@ -13,22 +13,29 @@
* 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.config.config;
package com.tencent.cloud.polaris.config.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* example application starter.
* polaris config module bootstrap configs.
*
* @author lepdou 2022-03-10
*/
@SpringBootApplication
public class PolarisConfigExampleApplication {
@ConfigurationProperties("spring.cloud.polaris.config.crypto")
public class PolarisCryptoConfigProperties {
/**
* Whether to open the configuration crypto.
*/
private boolean enabled = true;
public boolean isEnabled() {
return enabled;
}
public static void main(String[] args) {
SpringApplication.run(PolarisConfigExampleApplication.class, args);
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

@ -25,6 +25,7 @@ import java.util.Objects;
import com.tencent.cloud.polaris.config.ConfigurationModifier;
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.config.PolarisCryptoConfigProperties;
import com.tencent.cloud.polaris.context.ModifyAddress;
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
@ -118,6 +119,15 @@ public class PolarisConfigDataLocationResolver implements
polarisConfigProperties = new PolarisConfigProperties();
}
PolarisCryptoConfigProperties polarisCryptoConfigProperties = loadPolarisConfigProperties(
resolverContext,
PolarisCryptoConfigProperties.class,
POLARIS_PREFIX + ".config.crypto"
);
if (Objects.isNull(polarisCryptoConfigProperties)) {
polarisCryptoConfigProperties = new PolarisCryptoConfigProperties();
}
PolarisContextProperties polarisContextProperties = loadPolarisConfigProperties(
resolverContext,
PolarisContextProperties.class,
@ -128,11 +138,14 @@ public class PolarisConfigDataLocationResolver implements
}
// prepare and init earlier Polaris SDKContext to pull config files from remote.
prepareAndInitEarlierPolarisSdkContext(resolverContext, polarisConfigProperties, polarisContextProperties);
prepareAndInitEarlierPolarisSdkContext(resolverContext, polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties);
bootstrapContext.registerIfAbsent(PolarisConfigProperties.class,
BootstrapRegistry.InstanceSupplier.of(polarisConfigProperties));
bootstrapContext.registerIfAbsent(PolarisCryptoConfigProperties.class,
BootstrapRegistry.InstanceSupplier.of(polarisCryptoConfigProperties));
bootstrapContext.registerIfAbsent(PolarisContextProperties.class,
BootstrapRegistry.InstanceSupplier.of(polarisContextProperties));
@ -152,7 +165,7 @@ public class PolarisConfigDataLocationResolver implements
);
return loadConfigDataResources(resolverContext,
location, profiles, polarisConfigProperties, polarisContextProperties);
location, profiles, polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties);
}
@Override
@ -189,6 +202,7 @@ public class PolarisConfigDataLocationResolver implements
ConfigDataLocation location,
Profiles profiles,
PolarisConfigProperties polarisConfigProperties,
PolarisCryptoConfigProperties polarisCryptoConfigProperties,
PolarisContextProperties polarisContextProperties) {
List<PolarisConfigDataResource> result = new ArrayList<>();
boolean optional = location.isOptional();
@ -209,6 +223,7 @@ public class PolarisConfigDataLocationResolver implements
}
PolarisConfigDataResource polarisConfigDataResource = new PolarisConfigDataResource(
polarisConfigProperties,
polarisCryptoConfigProperties,
polarisContextProperties,
profiles, optional,
fileName, groupName, serviceName
@ -246,12 +261,12 @@ public class PolarisConfigDataLocationResolver implements
}
private void prepareAndInitEarlierPolarisSdkContext(ConfigDataLocationResolverContext resolverContext,
PolarisConfigProperties polarisConfigProperties,
PolarisConfigProperties polarisConfigProperties, PolarisCryptoConfigProperties polarisCryptoConfigProperties,
PolarisContextProperties polarisContextProperties) {
ConfigurableBootstrapContext bootstrapContext = resolverContext.getBootstrapContext();
if (!bootstrapContext.isRegistered(SDKContext.class)) {
SDKContext sdkContext = sdkContext(resolverContext,
polarisConfigProperties, polarisContextProperties);
polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties);
sdkContext.init();
bootstrapContext.register(SDKContext.class, BootstrapRegistry.InstanceSupplier.of(sdkContext));
}
@ -259,9 +274,9 @@ public class PolarisConfigDataLocationResolver implements
}
private SDKContext sdkContext(ConfigDataLocationResolverContext resolverContext,
PolarisConfigProperties polarisConfigProperties,
PolarisConfigProperties polarisConfigProperties, PolarisCryptoConfigProperties polarisCryptoConfigProperties,
PolarisContextProperties polarisContextProperties) {
List<PolarisConfigModifier> modifierList = modifierList(polarisConfigProperties, polarisContextProperties);
List<PolarisConfigModifier> modifierList = modifierList(polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties);
return SDKContext.initContextByConfig(polarisContextProperties.configuration(modifierList, () -> {
return loadPolarisConfigProperties(resolverContext, String.class, "spring.cloud.client.ip-address");
}, () -> {
@ -270,13 +285,14 @@ public class PolarisConfigDataLocationResolver implements
}
private List<PolarisConfigModifier> modifierList(PolarisConfigProperties polarisConfigProperties,
PolarisCryptoConfigProperties polarisCryptoConfigProperties,
PolarisContextProperties polarisContextProperties) {
// add ModifyAddress and ConfigurationModifier to load SDKContext
List<PolarisConfigModifier> modifierList = new ArrayList<>();
ModifyAddress modifyAddress = new ModifyAddress(polarisContextProperties);
ConfigurationModifier configurationModifier = new ConfigurationModifier(polarisConfigProperties,
polarisContextProperties);
polarisCryptoConfigProperties, polarisContextProperties);
modifierList.add(modifyAddress);
modifierList.add(configurationModifier);
return modifierList;

@ -20,6 +20,7 @@ package com.tencent.cloud.polaris.config.configdata;
import java.util.Objects;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.config.PolarisCryptoConfigProperties;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import org.springframework.boot.context.config.ConfigData;
@ -35,6 +36,8 @@ public class PolarisConfigDataResource extends ConfigDataResource {
private final PolarisConfigProperties polarisConfigProperties;
private final PolarisCryptoConfigProperties polarisCryptoConfigProperties;
private final PolarisContextProperties polarisContextProperties;
private final Profiles profiles;
@ -48,10 +51,12 @@ public class PolarisConfigDataResource extends ConfigDataResource {
private final String serviceName;
public PolarisConfigDataResource(PolarisConfigProperties polarisConfigProperties,
PolarisCryptoConfigProperties polarisCryptoConfigProperties,
PolarisContextProperties polarisContextProperties,
Profiles profiles, boolean optional,
String fileName, String groupName, String serviceName) {
this.polarisConfigProperties = polarisConfigProperties;
this.polarisCryptoConfigProperties = polarisCryptoConfigProperties;
this.polarisContextProperties = polarisContextProperties;
this.profiles = profiles;
this.optional = optional;
@ -64,6 +69,10 @@ public class PolarisConfigDataResource extends ConfigDataResource {
return polarisConfigProperties;
}
public PolarisCryptoConfigProperties getPolarisCryptoConfigProperties() {
return polarisCryptoConfigProperties;
}
public PolarisContextProperties getPolarisContextProperties() {
return polarisContextProperties;
}
@ -99,6 +108,7 @@ public class PolarisConfigDataResource extends ConfigDataResource {
PolarisConfigDataResource that = (PolarisConfigDataResource) o;
return optional == that.optional &&
polarisConfigProperties.equals(that.polarisConfigProperties) &&
polarisCryptoConfigProperties.equals(that.polarisCryptoConfigProperties) &&
polarisContextProperties.equals(that.polarisContextProperties) &&
profiles.equals(that.profiles) &&
fileName.equals(that.fileName) &&
@ -108,6 +118,7 @@ public class PolarisConfigDataResource extends ConfigDataResource {
@Override
public int hashCode() {
return Objects.hash(polarisConfigProperties, polarisContextProperties, profiles, optional, fileName, groupName, serviceName);
return Objects.hash(polarisConfigProperties, polarisCryptoConfigProperties, polarisContextProperties, profiles,
optional, fileName, groupName, serviceName);
}
}

@ -26,6 +26,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.collect.Maps;
import com.tencent.cloud.polaris.config.spring.event.ConfigChangeSpringEvent;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
@ -37,6 +39,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.lang.NonNull;
import static com.tencent.cloud.polaris.config.listener.PolarisConfigListenerContext.fireConfigChange;
@ -50,6 +53,8 @@ import static com.tencent.cloud.polaris.config.listener.PolarisConfigListenerCon
*/
public final class PolarisConfigChangeEventListener implements ApplicationListener<ApplicationEvent>, ApplicationEventPublisherAware {
private static final Logger LOG = LoggerFactory.getLogger(PolarisConfigChangeEventListener.class);
private static final AtomicBoolean started = new AtomicBoolean();
private ApplicationEventPublisher eventPublisher;
@ -95,13 +100,24 @@ public final class PolarisConfigChangeEventListener implements ApplicationListen
Map<String, Object> ret = Maps.newHashMap();
MutablePropertySources sources = environment.getPropertySources();
sources.iterator().forEachRemaining(propertySource -> {
// Don't read system env variable.
if (StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME.equals(propertySource.getName())) {
return;
}
Object o = propertySource.getSource();
if (o instanceof Map) {
for (Map.Entry<String, Object> entry : ((Map<String, Object>) o).entrySet()) {
String key = entry.getKey();
try {
String value = environment.getProperty(key);
ret.put(key, value);
}
catch (Exception e) {
LOG.warn("Read property from {} with key {} failed.", propertySource.getName(), key, e);
}
}
}
else if (o instanceof Collection) {
int count = 0;

@ -77,6 +77,13 @@
"type": "java.lang.String",
"defaultValue": "./polaris/backup/config",
"description": "Where to load config file, polaris or local."
},
{
"name": "spring.cloud.polaris.config.crypto.enabled",
"type": "java.lang.Boolean",
"defaultValue": "true",
"description": "Whether to open the configuration crypto.",
"sourceType": "com.tencent.cloud.polaris.config.config.PolarisCryptoConfigProperties"
}
]
}

@ -47,7 +47,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT, classes = ConfigChangeListenerTest.TestApplication.class,
properties = {"server.port=8081", "spring.config.location = classpath:application-test.yml"})
properties = {"server.port=48081", "spring.config.location = classpath:application-test.yml"})
public class ConfigChangeListenerTest {
private static final CountDownLatch hits = new CountDownLatch(2);

@ -58,7 +58,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT, classes = PolarisConfigRefreshOptimizationListenerNotTriggeredTest.TestApplication.class,
properties = {
"server.port=8081",
"server.port=48081",
"spring.cloud.polaris.address=grpc://127.0.0.1:10081",
"spring.cloud.polaris.config.connect-remote-server=false",
"spring.cloud.polaris.config.refresh-type=reflect",

@ -59,7 +59,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT, classes = PolarisConfigRefreshOptimizationListenerTriggeredTest.TestApplication.class,
properties = {
"server.port=8081",
"server.port=48081",
"spring.cloud.polaris.address=grpc://127.0.0.1:10081",
"spring.cloud.polaris.config.connect-remote-server=false",
"spring.cloud.polaris.config.refresh-type=reflect",

@ -18,6 +18,8 @@
package com.tencent.cloud.polaris.ratelimit.filter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Objects;
@ -51,6 +53,8 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* Reactive filter to check quota.
*
@ -58,7 +62,7 @@ import org.springframework.web.server.WebFilterChain;
*/
public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
private static final Logger LOGGER = LoggerFactory.getLogger(QuotaCheckReactiveFilter.class);
private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckReactiveFilter.class);
private final LimitAPI limitAPI;
@ -122,22 +126,28 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
response.getHeaders()
.add(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc());
if (Objects.nonNull(quotaResponse.getActiveRule())) {
response.getHeaders()
.add(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, quotaResponse.getActiveRule().getName()
.getValue());
try {
String encodedActiveRuleName = URLEncoder.encode(
quotaResponse.getActiveRule().getName().getValue(), UTF_8);
response.getHeaders().add(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, encodedActiveRuleName);
}
catch (UnsupportedEncodingException e) {
LOG.error("Cannot encode {} for header internal-callee-activerule.",
quotaResponse.getActiveRule().getName().getValue(), e);
}
}
return response.writeWith(Mono.just(dataBuffer));
}
// Unirate
if (quotaResponse.getCode() == QuotaResultCode.QuotaResultOk && quotaResponse.getWaitMs() > 0) {
LOGGER.debug("The request of [{}] will waiting for {}ms.", path, quotaResponse.getWaitMs());
LOG.debug("The request of [{}] will waiting for {}ms.", path, quotaResponse.getWaitMs());
waitMs = quotaResponse.getWaitMs();
}
}
catch (Throwable t) {
// An exception occurs in the rate limiting API call,
// which should not affect the call of the business process.
LOGGER.error("fail to invoke getQuota, service is " + localService, t);
LOG.error("fail to invoke getQuota, service is " + localService, t);
}
if (waitMs > 0) {

@ -19,6 +19,8 @@
package com.tencent.cloud.polaris.ratelimit.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Objects;
import java.util.Set;
@ -50,6 +52,8 @@ import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.filter.OncePerRequestFilter;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* Servlet filter to check quota.
*
@ -115,8 +119,15 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
}
response.addHeader(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc());
if (Objects.nonNull(quotaResponse.getActiveRule())) {
response.addHeader(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, quotaResponse.getActiveRule().getName()
.getValue());
try {
String encodedActiveRuleName = URLEncoder.encode(
quotaResponse.getActiveRule().getName().getValue(), UTF_8);
response.addHeader(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, encodedActiveRuleName);
}
catch (UnsupportedEncodingException e) {
LOG.error("Cannot encode {} for header internal-callee-activerule.",
quotaResponse.getActiveRule().getName().getValue(), e);
}
}
return;
}

@ -81,7 +81,6 @@
<mocktio.version>4.5.1</mocktio.version>
<byte-buddy.version>1.12.10</byte-buddy.version>
<protobuf-java.version>3.21.7</protobuf-java.version>
<bcprov-jdk15on.version>1.69</bcprov-jdk15on.version>
<system-stubs-jupiter.version>2.0.2</system-stubs-jupiter.version>
<!-- Maven Plugin Versions -->
@ -244,12 +243,6 @@
<version>${protobuf-java.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>${bcprov-jdk15on.version}</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>

@ -15,7 +15,30 @@ spring:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# consul:
# port: 8500
# host: 127.0.0.1
# enabled: true
# discovery:
# enabled: true
# register: true
# health-check-path: /actuator/health
# health-check-interval: 10s
# instance-id: ${spring.application.name}:${server.port}
# service-name: ${spring.application.name}
# ip-address: localhost
# prefer-ip-address: true
# nacos:
# enabled: true
# password: nacos
# username: nacos
# context-path: /nacos
# discovery:
# enabled: true
# register-enabled: true
# group: polaris
# server-addr: 127.0.0.1:8848
# cluster-name: polaris
feign:
circuitbreaker:
enabled: true

@ -1,66 +0,0 @@
# Spring Cloud Polaris Circuitbreaker example
## 样例简介
本样例将介绍如何在Spring Cloud项目中使用```spring-cloud-starter-tencent-polaris-circuitbreaker```以使用其各项功能。
本样例包括被调方```polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-callee-service2```和主调方```polaris-circuitbreaker-feign-example```、```polaris-circuitbreaker-gateway-example```、```polaris-circuitbreaker-webclient-example```。
## 使用说明
### 修改配置
配置如下所示。其中,${ip}和${port}为Polaris后端服务的IP地址与端口号。
```yaml
spring:
application:
name: ${application.name}
cloud:
polaris:
address: ${ip}:${port}
```
### 启动样例
#### 启动Polaris后端服务
参考[Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)。
#### 启动被调应用
分别启动```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2```
#### 启动主调应用
##### 启动Feign并验证
启动```polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example```。
发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, 验证熔断和Polaris-server远程拉取降级。
发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, 验证熔断和代码降级。
##### 启动RestTemplate并验证
启动```polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example```。
发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, 验证熔断和Polaris-server远程拉取降级。
发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, 验证熔断和代码降级。
##### 启动WebClient并验证
启动```polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example```。
发送请求`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo'`, 验证熔断和代码降级。
##### 启动SCG并验证
启动```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example```。
发送请求`curl --location --request GET 'http://127.0.0.1:48080/polaris-circuitbreaker-callee-service/example/service/b/info'`, 验证熔断和代码降级。
修改```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/resources/bootstrap.yml```。删除本地fallback方法并重启验证熔断和Polaris-server远程拉取降级。

@ -1,66 +0,0 @@
# Spring Cloud Polaris Circuitbreaker example
## Example Introduction
This example shows how to use```spring-cloud-starter-tencent-polaris-circuitbreaker```in Spring Cloud project for its features.
This example contains callee-service```polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-callee-service2```and caller-service```polaris-circuitbreaker-feign-example```、```polaris-circuitbreaker-gateway-example```、```polaris-circuitbreaker-webclient-example```.
## Instruction
### Configuration
The configuration is as the following shows. ${ip} and ${port} are Polaris backend IP address and port number.
```yaml
spring:
application:
name: ${application.name}
cloud:
polaris:
address: ${ip}:${port}
```
### Launching Example
#### Launching Polaris Backend Service
Reference to [Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)
#### Launching callee service
Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service```、```polaris-circuitbreaker-example/polaris-circuitbreaker-callee-service2```
#### Launching caller service
##### Launching Feign and Verify
Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-feign-example```.
Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, Verify circuit breaker and fallback from Polaris-server.
Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, Verify circuit breaker and fallback from code.
##### Launching RestTemplate and Verify
Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-resttemplate-example```.
Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromPolaris'`, Verify circuit breaker and fallback from Polaris-server.
Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo/fallbackFromCode'`, Verify circuit breaker and fallback from code.
##### Launching WebClient and Verify
Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-webclient-example```。
Sending request`curl --location --request GET 'http://127.0.0.1:48080/example/service/a/getBServiceInfo'`, Verify circuit breaker and fallback from code.
##### Launching SCG and Verify
Launching```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example```。
Sending request`curl --location --request GET 'http://127.0.0.1:48080/polaris-circuitbreaker-callee-service/example/service/b/info'`, Verify circuit breaker and fallback from code.
Changing```polaris-circuitbreaker-example/polaris-circuitbreaker-gateway-example/resources/bootstrap.yml```, delete local fallback and restart, Verify circuit breaker and fallback from Polaris-server.

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-circuitbreaker-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-circuitbreaker-callee-service</artifactId>
<name>Polaris Circuit Breaker Callee Example</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Circuit breaker example callee application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
public class ServiceB {
public static void main(String[] args) {
SpringApplication.run(ServiceB.class, args);
}
}

@ -1,55 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.example;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Service B Controller.
*
* @author Haotian Zhang
*/
@RestController
@RequestMapping("/example/service/b")
public class ServiceBController {
/**
* Get service information.
*
* @return service information
*/
@GetMapping("/info")
public String info() {
return "hello world ! I'm a service B1";
}
@GetMapping("/health")
public String health() {
System.out.println("health check: 200 instance");
return "hello world ! I'm a service B1";
}
@GetMapping("/health-svc")
public String healthsvc() {
System.out.println("health-svc check: 200 instance");
return "hello world ! I'm a service B1";
}
}

@ -1,13 +0,0 @@
server:
port: 48081
spring:
application:
name: polaris-circuitbreaker-callee-service
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
stat:
enabled: true
port: 28082

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-circuitbreaker-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-circuitbreaker-callee-service2</artifactId>
<name>Polaris Circuit Breaker Callee Example 2</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,35 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.ciruitbreaker.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Circuit breaker example callee application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
public class ServiceB2 {
public static void main(String[] args) {
SpringApplication.run(ServiceB2.class, args);
}
}

@ -1,98 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.ciruitbreaker.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
/**
* Service B Controller.
*
* @author Haotian Zhang
*/
@RestController
@RequestMapping("/example/service/b")
public class ServiceBController {
private static final Logger LOG = LoggerFactory.getLogger(ServiceBController.class);
private boolean ifBadGateway = true;
private boolean ifDelay = true;
@GetMapping("/setBadGateway")
public void setBadGateway(@RequestParam boolean param) {
if (param) {
LOG.info("info is set to return HttpStatus.BAD_GATEWAY.");
}
else {
LOG.info("info is set to return HttpStatus.OK.");
}
this.ifBadGateway = param;
}
@GetMapping("/setDelay")
public void setDelay(@RequestParam boolean param) {
if (param) {
LOG.info("info is set to delay 100ms.");
}
else {
LOG.info("info is set to no delay.");
}
this.ifDelay = param;
}
/**
* Get service information.
*
* @return service information
*/
@GetMapping("/info")
public ResponseEntity<String> info() throws InterruptedException {
if (ifBadGateway) {
return new ResponseEntity<>("failed for call my service", HttpStatus.BAD_GATEWAY);
}
if (ifDelay) {
Thread.sleep(100);
}
return new ResponseEntity<>("hello world ! I'm a service B2", HttpStatus.OK);
}
@GetMapping("/health")
@ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service")
public String health() {
System.out.println("health check: 502 instance");
return "hello world ! I'm a service B1";
}
@GetMapping("/health-svc")
@ResponseStatus(value = HttpStatus.BAD_GATEWAY, reason = "failed for call my service")
public String healthsvc() {
System.out.println("health-svc check: 502 instance");
return "hello world ! I'm a service B1";
}
}

@ -1,13 +0,0 @@
server:
port: 48082
spring:
application:
name: polaris-circuitbreaker-callee-service
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
stat:
enabled: true
port: 28083

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-circuitbreaker-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-circuitbreaker-feign-example</artifactId>
<name>Polaris Circuit Breaker Feign Example</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,59 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.feign.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Circuit breaker example caller controller.
*
* @author sean yu
*/
@RestController
@RequestMapping("/example/service/a")
public class ServiceAController {
@Autowired
private ProviderB polarisServiceB;
@Autowired
private ProviderBWithFallback providerBWithFallback;
/**
* Get info of Service B by Feign.
* @return info of Service B
*/
@GetMapping("/getBServiceInfo/fallbackFromCode")
public String getBServiceInfoFallbackFromCode() {
return providerBWithFallback.info();
}
/**
* Get info of Service B by Feign.
* @return info of Service B
*/
@GetMapping("/getBServiceInfo/fallbackFromPolaris")
public String getBServiceInfoFallbackFromPolaris() {
return polarisServiceB.info();
}
}

@ -1,38 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.feign.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* Circuit breaker example caller application.
*
* @author sean yu
*/
@SpringBootApplication
@EnableFeignClients
public class ServiceAFeign {
public static void main(String[] args) {
SpringApplication.run(ServiceAFeign.class, args);
}
}

@ -1,24 +0,0 @@
server:
port: 48080
spring:
application:
name: polaris-circuitbreaker-feign-example
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
loadbalancer:
enabled: true
circuitbreaker:
enabled: true
feign:
circuitbreaker:
enabled: true
logging:
level:
root: info
com.tencent.cloud: debug

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-circuitbreaker-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-circuitbreaker-gateway-example</artifactId>
<name>Polaris Circuit Breaker Gateway Example</name>
<dependencies>
<dependency>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
<groupId>com.tencent.cloud</groupId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-router</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-gateway-plugin</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-featureenv-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,35 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.gateway.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* SCG application.
*
* @author sean yu
*/
@SpringBootApplication
public class GatewayScgApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayScgApplication.class, args);
}
}

@ -1,59 +0,0 @@
server:
session-timeout: 1800
port: 48080
spring:
application:
name: GatewayScgService
cloud:
tencent:
plugin:
scg:
staining:
enabled: true
rule-staining:
enabled: true
router:
feature-env:
enabled: true
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
gateway:
discovery:
locator:
enabled: true
'predicates[0]':
name: Path
args:
patterns: '''/'' + serviceId + ''/**'''
'filters[0]':
name: RewritePath
args:
regexp: '''/'' + serviceId + ''/(?<remaining>.*)'''
replacement: '''/$\{remaining}'''
'filters[1]':
name: CircuitBreaker
args:
# statusCodes 缺省时会自动识别 "5**" 为错误
# statusCodes: '''404,5**'''
# fallbackUri 缺省时会在熔断触发后拉取 plaris server 配置的降级作为 response
fallbackUri: '''forward:/polaris-fallback'''
# routes:
# - id: polaris-circuitbreaker-callee-service
# uri: lb://polaris-circuitbreaker-callee-service
# predicates:
# - Path=/polaris-circuitbreaker-callee-service/**
# filters:
# - StripPrefix=1
# - name: CircuitBreaker
# args:
# statusCodes: 502
# fallbackUri: forward:/polaris-fallback
logging:
level:
root: info
com.tencent.polaris.discovery.client.flow.RegisterFlow: off
com.tencent.polaris.plugins.registry: off
com.tencent.cloud: debug

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-circuitbreaker-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-circuitbreaker-resttemplate-example</artifactId>
<name>Polaris Circuit Breaker RestTemplate Example</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,74 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.resttemplate.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* Circuit breaker example caller controller.
*
* @author sean yu
*/
@RestController
@RequestMapping("/example/service/a")
public class ServiceAController {
@Autowired
@Qualifier("defaultRestTemplate")
private RestTemplate defaultRestTemplate;
@Autowired
@Qualifier("restTemplateFallbackFromPolaris")
private RestTemplate restTemplateFallbackFromPolaris;
@Autowired
@Qualifier("restTemplateFallbackFromCode")
private RestTemplate restTemplateFallbackFromCode;
@Autowired
private CircuitBreakerFactory circuitBreakerFactory;
@GetMapping("/getBServiceInfo")
public String getBServiceInfo() {
return circuitBreakerFactory
.create("polaris-circuitbreaker-callee-service#/example/service/b/info")
.run(() ->
defaultRestTemplate.getForObject("/example/service/b/info", String.class),
throwable -> "trigger the refuse for service b"
);
}
@GetMapping("/getBServiceInfo/fallbackFromPolaris")
public ResponseEntity<String> getBServiceInfoFallback() {
return restTemplateFallbackFromPolaris.getForEntity("/example/service/b/info", String.class);
}
@GetMapping("/getBServiceInfo/fallbackFromCode")
public ResponseEntity<String> getBServiceInfoFallbackClass() {
return restTemplateFallbackFromCode.getForEntity("/example/service/b/info", String.class);
}
}

@ -1,71 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.resttemplate.example;
import com.tencent.cloud.polaris.circuitbreaker.resttemplate.PolarisCircuitBreaker;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
/**
* Circuit breaker example caller application.
*
* @author sean yu
*/
@SpringBootApplication
public class ServiceAResTemplate {
public static void main(String[] args) {
SpringApplication.run(ServiceAResTemplate.class, args);
}
@Bean
@LoadBalanced
public RestTemplate defaultRestTemplate() {
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service");
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(uriBuilderFactory);
return restTemplate;
}
@Bean
@LoadBalanced
@PolarisCircuitBreaker
public RestTemplate restTemplateFallbackFromPolaris() {
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service");
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(uriBuilderFactory);
return restTemplate;
}
@Bean
@LoadBalanced
@PolarisCircuitBreaker(fallbackClass = CustomFallback.class)
public RestTemplate restTemplateFallbackFromCode() {
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory("http://polaris-circuitbreaker-callee-service");
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(uriBuilderFactory);
return restTemplate;
}
}

@ -1,20 +0,0 @@
server:
port: 48080
spring:
application:
name: polaris-circuitbreaker-resttemplate-example
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
loadbalancer:
enabled: true
circuitbreaker:
enabled: true
logging:
level:
root: info
com.tencent.cloud: debug

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-circuitbreaker-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-circuitbreaker-webclient-example</artifactId>
<name>Polaris Circuit Breaker WebClient Example</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-circuitbreaker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,59 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.webclient.example;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
/**
* Circuit breaker example caller controller.
*
* @author sean yu
*/
@RestController
@RequestMapping("/example/service/a")
public class ServiceAController {
@Autowired
private ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;
@Autowired
private WebClient.Builder webClientBuilder;
@GetMapping("/getBServiceInfo")
public Mono<String> getBServiceInfo() {
return webClientBuilder
.build()
.get()
.uri("/example/service/b/info")
.retrieve()
.bodyToMono(String.class)
.transform(it ->
reactiveCircuitBreakerFactory
.create("polaris-circuitbreaker-callee-service#/example/service/b/info")
.run(it, throwable -> Mono.just("fallback: trigger the refuse for service b"))
);
}
}

@ -1,45 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.circuitbreaker.webclient.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.reactive.function.client.WebClient;
/**
* Circuit breaker example caller application.
*
* @author sean yu
*/
@SpringBootApplication
public class ServiceAWebClient {
public static void main(String[] args) {
SpringApplication.run(ServiceAWebClient.class, args);
}
@LoadBalanced
@Bean
WebClient.Builder webClientBuilder() {
return WebClient.builder()
.baseUrl("http://polaris-circuitbreaker-callee-service");
}
}

@ -1,20 +0,0 @@
server:
port: 48080
spring:
application:
name: polaris-circuitbreaker-webclient-example
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
loadbalancer:
enabled: true
circuitbreaker:
enabled: true
logging:
level:
root: info
com.tencent.cloud: debug

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tencent-examples</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-circuitbreaker-example</artifactId>
<name>Polaris Circuit Breaker Example</name>
<packaging>pom</packaging>
<modules>
<module>polaris-circuitbreaker-feign-example</module>
<module>polaris-circuitbreaker-gateway-example</module>
<module>polaris-circuitbreaker-resttemplate-example</module>
<module>polaris-circuitbreaker-webclient-example</module>
<module>polaris-circuitbreaker-callee-service</module>
<module>polaris-circuitbreaker-callee-service2</module>
</modules>
</project>

@ -1,77 +0,0 @@
# Polaris Config Example 使用指南
## 1. bootstrap.yml 配置
修改 resources/bootstrap.yml ```spring.cloud.polaris.config.address``` 北极星服务端地址。
> 注意是在 bootstrap.yml 里配置,而不是在 application.yml 里配置。因为配置中心相关的配置是在 bootstrap 阶段依赖的配置。
```` yaml
spring:
application:
name: polaris-config-example
cloud:
polaris:
namespace: dev
config:
address: grpc://127.0.0.1:8093 # the address of polaris config server
auto-refresh: true # auto refresh when config file changed
groups:
- name: ${spring.application.name} # group name
files: [ "config/application.properties", "config/bootstrap.yml" ] # config/application.properties takes precedence over config/bootstrap.yml
````
## 2. 在北极星服务端创建配置文件
### 2.1 创建 namespace dev
### 2.2 创建配置文件分组polaris-config-example
北极星的配置文件分组概念为一组配置文件的集合,推荐应用名=分组名,例如在我们的示例中,新建一个 polaris-config-example 的分组。
把 polaris-config-example 应用的配置文件都放在 polaris-config-example 分组下,这样便于配置管理。
### 2.3 创建两个配置文件 config/application.properties 、config/bootstrap.yml
北极星配置中心的控制台,配置文件名可以通过 / 来按树状目录结构展示,通过树状结构可以清晰的管理配置文件。
#### 2.3.1 config/application.properties 文件内容
```` properties
timeout = 3000
````
#### 2.3.2 config/bootstrap.yml 文件内容
````yaml
teacher:
name : 张三
age: 38
````
页面样例如下图所示:
![](polaris-config-ui.png)
## 3. 运行 PolarisConfigExampleApplication
## 4. 访问接口
````
curl "http://localhost:48084/timeout"
curl "http://localhost:48084/person"
````
## 5. 动态推送能力
### 5.1 管控台动态修改并发布 config/application.properties
```` properties
timeout = 5000
````
### 5.2 再次访问接口
````
curl "http://localhost:48084/timeout"
````

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

@ -1,68 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tencent-examples</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-config-example</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Tencent dependency -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,52 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.config.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* the endpoint for get config.
*
* @author lepdou 2022-03-10
*/
@RestController
public class ConfigController {
@Value("${timeout:1000}")
private int timeout;
@Autowired
private Person person;
@Autowired
private Environment environment;
@GetMapping("/timeout")
public int timeout() {
environment.getProperty("timeout", "1000");
return timeout;
}
@GetMapping("/person")
public String person() {
return person.toString();
}
}

@ -1,68 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.config.example;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* example property object.
*
* @author lepdou 2022-03-28
*/
@Component
@ConfigurationProperties(prefix = "teacher")
public class Person {
private String name;
private int age;
private boolean isDirector;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isDirector() {
return isDirector;
}
public void setIsDirector(boolean isDirector) {
this.isDirector = isDirector;
}
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + ", age=" + age + ", isDirector=" + isDirector + '\'' + '}';
}
}

@ -1,66 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.config.example;
import java.util.Set;
import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener;
import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent;
import org.springframework.stereotype.Component;
/**
* Custom Config Listener Example .
*
* @author Palmer Xu 2022-06-06
*/
@Component
public final class PersonConfigChangeListener {
/**
* PolarisConfigKVFileChangeListener Example .
* @param event instance of {@link ConfigChangeEvent}
*/
@PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "teacher")
public void onChange(ConfigChangeEvent event) {
Set<String> changedKeys = event.changedKeys();
for (String changedKey : changedKeys) {
System.out.printf("%s = %s , ThreadId: %s\n", changedKey, event.getChange(changedKey), Thread.currentThread().getId());
}
}
@PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "teacher", async = false)
public void syncListen(ConfigChangeEvent event) {
Set<String> changedKeys = event.changedKeys();
for (String changedKey : changedKeys) {
System.out.printf("%s = %s , ThreadId: %s\n", changedKey, event.getChange(changedKey), Thread.currentThread().getId());
}
}
@PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "teacher", async = false)
public void syncListen2(ConfigChangeEvent event) {
Set<String> changedKeys = event.changedKeys();
for (String changedKey : changedKeys) {
System.out.printf("%s = %s , ThreadId: %s\n", changedKey, event.getChange(changedKey), Thread.currentThread().getId());
}
}
}

@ -1,24 +0,0 @@
server:
port: 48084
spring:
application:
name: polaris-config-example
profiles:
active: abc
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
config:
auto-refresh: true # auto refresh when config file changed
# data-source: local # config data source default is polaris.
# local-file-root-path: # set root path for reading config file, when in local data source
groups:
- name: ${spring.application.name} # group name
files: [ "config/application.properties", "config/bootstrap.yml" ] # config/application.properties takes precedence over config/bootstrap.yml
management:
endpoints:
web:
exposure:
include:
- polaris-config

@ -1,67 +0,0 @@
# Spring Cloud Polaris Discovery example
## 样例简介
本样例将介绍如何在Spring Cloud项目中使用```spring-cloud-starter-tencent-polaris-discovery```以使用其各项功能。
该样例分为两个微服务,即 ```discovery-caller-service``` 和 ```discovery-callee-service ```。
其中 ```discovery-caller-service``` 调用 ```discovery-callee-service```
## 使用说明
### 修改配置
修改 resource/bootstrap.yml 中北极星的服务端地址
```yaml
spring:
cloud:
polaris:
address: grpc://${ip}:8091
```
### 启动样例
#### 启动Polaris后端服务
参考[Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)。
#### 启动应用
- IDEA启动
分别启动
1. ```spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service```下的```DiscoveryCallerService```
2. ```spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service```下的```DiscoveryCalleeService```
### 验证
#### 调用 discovery-caller-service 暴露的接口
执行以下命令发起Feign调用其逻辑为```DiscoveryCalleeService```返回 value1+value2 的和
```shell
curl -L -X GET 'http://localhost:48080/discovery/service/caller/feign?value1=1&value2=2'
```
预期返回值
```
3
```
#### RestTemplate调用
执行以下命令发起RestTemplate调用其逻辑为```DiscoveryCalleeService```返回一段字符串
```shell
curl -L -X GET 'http://localhost:48080/discovery/service/caller/rest'
```
预期返回值
```
Discovery Service Callee
```

@ -1,81 +0,0 @@
# Spring Cloud Polaris Discovery example
## Example Introduction
This example shows how to use ```spring-cloud-starter-tencent-polaris-discovery`` in Spring Cloud project for its features.
This example is divided to two microservice, discovery-caller-service and discovery-callee-service. In these two microservices, discovery-caller-service invokes discovery-callee-service.
## Instruction
### Configuration
The configuration is as the following shows. ${ip} and ${port} are Polaris backend IP address and port number.
```yaml
spring:
application:
name: ${application.name}
cloud:
polaris:
address: ${ip}:${port}
```
### Launching Example
#### Launching Polaris Backend Service
Reference to [Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)
#### Launching Application
- IDEA Launching
Launching ```spring-cloud-tencent-examples/polaris-discovery-example/discovery-caller-service```'s ```DiscoveryCallerService``` and ```spring-cloud-tencent-examples/polaris-discovery-example/discovery-callee-service```'s ```DiscoveryCalleeService```
- Maven Package Launching
Execute under ```spring-cloud-tencent-examples/polaris-discovery-example```
```sh
mvn clean package
```
Then at ```discovery-caller-service``` and ```discovery-callee-service``` find the package that generates jar, and run it
```
java -jar ${app.jar}
```
Launch application, change ${app.jar} to jar's package name
### Verify
#### Feign Invoke
Execute the following orders to invoke Feign, ```DiscoveryCalleeService``` goes bank to the sum of value1+value2
```shell
curl -L -X GET 'http://localhost:48080/discovery/service/caller/feign?value1=1&value2=2'
```
Expected return rate
```
3
```
#### RestTemplate Invoke
Execute the following orders to invoke RestTemplate, ```DiscoveryCalleeService``` goes back to string characters
```shell
curl -L -X GET 'http://localhost:48080/discovery/service/caller/rest'
```
Expected return rate
```
Discovery Service Callee
```

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-discovery-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>discovery-callee-service</artifactId>
<name>Polaris Discovery Callee Service</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.tencent.polaris</groupId>-->
<!-- <artifactId>connector-consul</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.tencent.polaris</groupId>-->
<!-- <artifactId>connector-nacos</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,47 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.discovery.service.callee;
import java.util.HashMap;
import java.util.Map;
import com.tencent.cloud.common.spi.InstanceMetadataProvider;
import org.springframework.stereotype.Component;
/**
* custom metadata for instance.
*
* @author lepdou 2022-06-16
*/
@Component
public class CustomMetadata implements InstanceMetadataProvider {
@Override
public Map<String, String> getMetadata() {
Map<String, String> metadata = new HashMap<>();
metadata.put("k1", "v1");
return metadata;
}
@Override
public String getZone() {
return "shanghai-zone-1";
}
}

@ -1,69 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.discovery.service.callee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Discovery callee controller.
*
* @author Haotian Zhang
*/
@RestController
@RequestMapping("/discovery/service/callee")
public class DiscoveryCalleeController {
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryCalleeController.class);
@Value("${server.port:0}")
private int port;
@Value("${spring.cloud.client.ip-address:127.0.0.1}")
private String ip;
/**
* Get information of callee.
*
* @return information of callee
*/
@GetMapping("/info")
public String info() {
LOG.info("Discovery Service Callee [{}:{}] is called.", ip, port);
return String.format("Discovery Service Callee [%s:%s] is called.", ip, port);
}
/**
* Get sum of two value.
*
* @param value1 value 1
* @param value2 value 2
* @return sum
*/
@GetMapping("/sum")
public int sum(@RequestParam int value1, @RequestParam int value2) {
LOG.info("Discovery Service Callee [{}:{}] is called and sum is {}.", ip, port, value1 + value2);
return value1 + value2;
}
}

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.discovery.service.callee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Discovery callee application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
public class DiscoveryCalleeService {
public static void main(String[] args) {
SpringApplication.run(DiscoveryCalleeService.class, args);
}
}

@ -1,53 +0,0 @@
server:
port: ${random.int(7003,7005)}
spring:
application:
name: DiscoveryCalleeService
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
discovery:
enabled: true
register: true
contract:
exposure: true
stat:
enabled: true
port: 28082
# pushgateway:
# enabled: true
# address: 127.0.0.1:9091
tencent:
metadata:
content:
region: shanghai
rpc-enhancement:
reporter:
enabled: true
# consul:
# port: 8500
# host: 127.0.0.1
# enabled: true
# discovery:
# enabled: true
# register: true
# instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
# service-name: ${spring.application.name}
# ip-address: localhost
# prefer-ip-address: true
# nacos:
# enabled: true
# password: nacos
# username: nacos
# discovery:
# enabled: true
# register-enabled: true
# group: polaris
# server-addr: 127.0.0.1:8848
#eureka:
# client:
# serviceUrl:
# defaultZone: http://127.0.0.1:7654/eureka/

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-discovery-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>discovery-caller-service</artifactId>
<name>Polaris Discovery Caller Service</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-contract</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.retry</groupId>-->
<!-- <artifactId>spring-retry</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.tencent.polaris</groupId>-->
<!-- <artifactId>connector-consul</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.tencent.polaris</groupId>-->
<!-- <artifactId>connector-nacos</artifactId>-->
<!-- </dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,40 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.discovery.service.caller;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Discovery callee feign client.
*
* @author Haotian Zhang
*/
@FeignClient(value = "DiscoveryCalleeService", fallback = DiscoveryCalleeServiceFallback.class)
public interface DiscoveryCalleeService {
/**
* Get sum of two value.
* @param value1 value 1
* @param value2 value 2
* @return sum
*/
@GetMapping("/discovery/service/callee/sum")
int sum(@RequestParam("value1") int value1, @RequestParam("value2") int value2);
}

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.discovery.service.caller;
import org.springframework.stereotype.Component;
/**
* Discovery callee feign client fallback.
*
* @author Haotian Zhang
*/
@Component
public class DiscoveryCalleeServiceFallback implements DiscoveryCalleeService {
@Override
public int sum(int value1, int value2) {
return 0;
}
}

@ -1,70 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.discovery.service.caller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* Discovery caller controller.
*
* @author Haotian Zhang
*/
@RestController
@RequestMapping("/discovery/service/caller")
public class DiscoveryCallerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryCalleeService discoveryCalleeService;
/**
* Get sum of two value.
* @param value1 value 1
* @param value2 value 2
* @return sum
*/
@RequestMapping("/feign")
public int feign(@RequestParam int value1, @RequestParam int value2) {
return discoveryCalleeService.sum(value1, value2);
}
/**
* Get information of callee.
* @return information of callee
*/
@GetMapping("/rest")
public String rest() {
return restTemplate.getForObject("http://DiscoveryCalleeService/discovery/service/callee/info", String.class);
}
/**
* health check.
* @return health check info
*/
@GetMapping("/healthCheck")
public String healthCheck() {
return "pk ok";
}
}

@ -1,47 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.discovery.service.caller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* Discovery caller application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class DiscoveryCallerService {
public static void main(String[] args) {
SpringApplication.run(DiscoveryCallerService.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

@ -1,68 +0,0 @@
server:
session-timeout: 1800
port: 48080
spring:
application:
name: DiscoveryCallerService
cloud:
tencent:
metadata:
content:
region: shanghai
rpc-enhancement:
reporter:
enabled: true
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
discovery:
enabled: true
register: true
heartbeat:
enabled: true
health-check-url: /discovery/service/caller/healthCheck
contract:
exposure: true
report:
enabled: true
stat:
enabled: true
port: 28081
# pushgateway:
# enabled: true
# address: 127.0.0.1:9091
# consul:
# port: 8500
# host: 127.0.0.1
# enabled: true
# discovery:
# enabled: true
# register: true
# health-check-path: /actuator/health
# health-check-interval: 10s
# instance-id: ${spring.application.name}:${server.port}
# service-name: ${spring.application.name}
# ip-address: localhost
# prefer-ip-address: true
# nacos:
# enabled: true
# password: nacos
# username: nacos
# context-path: /nacos
# discovery:
# enabled: true
# register-enabled: true
# group: polaris
# server-addr: 127.0.0.1:8848
# cluster-name: polaris
#eureka:
# client:
# serviceUrl:
# defaultZone: http://127.0.0.1:7654/eureka/
management:
endpoints:
web:
exposure:
include:
- polaris-discovery

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tencent-examples</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-discovery-example</artifactId>
<packaging>pom</packaging>
<name>Spring Cloud Starter Tencent Polaris Discovery Example</name>
<modules>
<module>discovery-callee-service</module>
<module>discovery-caller-service</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
</project>

@ -1,68 +0,0 @@
# Spring Cloud Polaris Gateway example
## 样例简介
本样例将介绍如何在Spring Cloud项目中使用```spring-cloud-tencent-polaris-gateway```以使用其各项功能。
本样例包括 ```gateway-scg-service```和```gateway-callee-service```。```gateway-scg-service```调用```gateway-callee-service```。
## 使用说明
### 修改配置
配置如下所示。其中,${ip}和${port}为Polaris后端服务的IP地址与端口号。
```yaml
spring:
application:
name: ${application.name}
cloud:
polaris:
address: ${ip}:${port}
```
### 启动样例
#### 启动Polaris后端服务
参考[Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)。
#### 启动应用
- IDEA启动
分别启动```spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service```的```GatewayScgService```和```spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service```的```GatewayCalleeService```
- Maven打包启动
在```spring-cloud-tencent-examples/polaris-gateway-example```下执行
```sh
mvn clean package
```
然后在 ```gateway-scg-service```和```gateway-callee-service```下找到生成的jar包运行
```
java -jar ${app.jar}
```
启动应用,其中${app.jar}替换为对应的jar包名。
### 验证
#### Spring-Cloud-Gateway调用
```shell
curl -L -X GET 'http://localhost:48083/GatewayCalleeService/gateway/example/callee/echo' -H 'SCT-CUSTOM-METADATA: {"b": 2}'
```
预期返回值
```
{"a":"1","b":2}
```
#### 网关限流
参考[Polaris RateLimit Example](../polaris-ratelimit-example/README-zh.md)

@ -1,69 +0,0 @@
# Spring Cloud Polaris Gateway example
## Example Introduction
This example shows how to use ```spring-cloud-tencent-polaris-gateway``` in Spring Cloud project for its features.
This example contains ```gateway-scg-service``` and ```gateway-callee-service```. ```gateway-scg-service``` invoke ```gateway-callee-service```.
## Instruction
### Configuration
The configuration is as the following shows. ${ip} and ${port} are Polaris backend IP address and port number.
```yaml
spring:
application:
name: ${application.name}
cloud:
polaris:
address: ${ip}:${port}
```
### Launching Example
#### Launching Polaris Backend Service
Reference to [Polaris Getting Started](https://github.com/PolarisMesh/polaris#getting-started)
#### Launching Application
- IDEA Launching
Launching ```spring-cloud-tencent-examples/polaris-gateway-example/gateway-scg-service```'s ```GatewayScgService``` and ```spring-cloud-tencent-examples/polaris-gateway-example/gateway-callee-service```'s ```GatewayCalleeService```
- Maven Package Launching
Execute under ```spring-cloud-tencent-examples/polaris-gateway-example```
```sh
mvn clean package
```
Then find the jars under ```gateway-scg-service``` and ```gateway-callee-service```, and run it:
```
java -jar ${app.jar}
```
Launch application, change ${app.jar} to jar's package name.
### Verify
#### Spring-Cloud-Gateway Invoke
```shell
curl -L -X GET 'http://localhost:48083/GatewayCalleeService/gateway/example/callee/echo' -H 'SCT-CUSTOM-METADATA: {"b": 2}'
```
Expected return rate
```
{"a":"1","b":2}
```
#### Gateway Rate Limit
See [Polaris RateLimit Example](../polaris-ratelimit-example/README.md)

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-gateway-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway-callee-service</artifactId>
<name>Spring Cloud Starter Tencent Polaris Gateway Callee Example</name>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.gateway.example.callee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Gateway callee application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
public class GatewayCalleeApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayCalleeApplication.class, args);
}
}

@ -1,72 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.gateway.example.callee;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import com.tencent.cloud.common.constant.MetadataConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* Gateway callee controller.
*
* @author Haotian Zhang
*/
@RestController
@RequestMapping("/gateway/example/callee")
public class GatewayCalleeController {
private static Logger LOG = LoggerFactory.getLogger(GatewayCalleeController.class);
@Value("${server.port:0}")
private int port;
/**
* Get information of callee.
* @return information of callee
*/
@RequestMapping("/info")
public String info() {
LOG.info("Gateway Example Callee [{}] is called.", port);
return String.format("Gateway Example Callee [%s] is called.", port);
}
/**
* Get metadata in HTTP header.
*
* @param metadataStr metadata string
* @return metadata in HTTP header
* @throws UnsupportedEncodingException encoding exception
*/
@RequestMapping("/echo")
public String echoHeader(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String metadataStr)
throws UnsupportedEncodingException {
LOG.info(URLDecoder.decode(metadataStr, UTF_8));
metadataStr = URLDecoder.decode(metadataStr, UTF_8);
return metadataStr;
}
}

@ -1,14 +0,0 @@
server:
session-timeout: 1800
port: 48081
spring:
application:
name: GatewayCalleeService
cloud:
tencent:
metadata:
content:
env: blue
polaris:
address: grpc://119.91.66.223:8091
namespace: default

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-gateway-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway-callee-service2</artifactId>
<name>Spring Cloud Starter Tencent Polaris Gateway Callee Example</name>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.gateway.example.callee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Gateway callee application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
public class GatewayCalleeApplication2 {
public static void main(String[] args) {
SpringApplication.run(GatewayCalleeApplication2.class, args);
}
}

@ -1,72 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.gateway.example.callee;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import com.tencent.cloud.common.constant.MetadataConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* Gateway callee controller.
*
* @author Haotian Zhang
*/
@RestController
@RequestMapping("/gateway/example/callee")
public class GatewayCalleeController {
private static Logger LOG = LoggerFactory.getLogger(GatewayCalleeController.class);
@Value("${server.port:0}")
private int port;
/**
* Get information of callee.
* @return information of callee
*/
@RequestMapping("/info")
public String info() {
LOG.info("Gateway Example Callee [{}] is called.", port);
return String.format("Gateway Example Callee [%s] is called.", port);
}
/**
* Get metadata in HTTP header.
*
* @param metadataStr metadata string
* @return metadata in HTTP header
* @throws UnsupportedEncodingException encoding exception
*/
@RequestMapping("/echo")
public String echoHeader(@RequestHeader(MetadataConstant.HeaderName.CUSTOM_METADATA) String metadataStr)
throws UnsupportedEncodingException {
LOG.info(URLDecoder.decode(metadataStr, UTF_8));
metadataStr = URLDecoder.decode(metadataStr, UTF_8);
return metadataStr;
}
}

@ -1,14 +0,0 @@
server:
session-timeout: 1800
port: 48082
spring:
application:
name: GatewayCalleeService
cloud:
tencent:
metadata:
content:
env: green
polaris:
address: grpc://119.91.66.223:8091
namespace: default

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-gateway-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway-scg-service</artifactId>
<name>Spring Cloud Starter Tencent Polaris Gateway SCG Example</name>
<dependencies>
<dependency>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
<groupId>com.tencent.cloud</groupId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-router</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-gateway-plugin</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-metadata-transfer</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-featureenv-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>

@ -1,34 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.gateway.example.scg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* SCG application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
public class GatewayScgApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayScgApplication.class, args);
}
}

@ -1,68 +0,0 @@
server:
session-timeout: 1800
port: 48083
spring:
application:
name: GatewayScgService
cloud:
tencent:
plugin:
scg:
staining:
enabled: true
rule-staining:
enabled: true
router:
feature-env:
enabled: true
metadata:
content:
a: 1
transitive:
- a
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
gateway:
discovery:
locator:
enabled: true
'predicates[0]':
name: Path
args:
patterns: '''/'' + serviceId + ''/**'''
'filters[0]':
name: RewritePath
args:
regexp: '''/'' + serviceId + ''/(?<remaining>.*)'''
replacement: '''/$\{remaining}'''
'filters[1]':
name: Retry
args:
retries: 3
exceptions:
'[0]': '''java.net.ConnectException'''
'[1]': '''java.io.IOException'''
statuses:
'[0]': '''BAD_GATEWAY'''
'[1]': '''SERVICE_UNAVAILABLE'''
series:
'[0]': '''CLIENT_ERROR'''
methods:
'[0]': '''GET'''
'[1]': '''POST'''
'[2]': '''PUT'''
'[3]': '''DELETE'''
backoff:
firstBackoff: '''100ms'''
maxBackoff: '''500ms'''
factor: 2
basedOnPreviousValue: false
routes:
- id: GatewayCalleeService
uri: lb://GatewayCalleeService
predicates:
- Path=/GatewayCalleeService/**
filters:
- StripPrefix=1

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tencent-examples</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-gateway-example</artifactId>
<packaging>pom</packaging>
<name>Spring Cloud Starter Tencent Polaris Gateway Example</name>
<modules>
<module>gateway-scg-service</module>
<module>gateway-callee-service</module>
<module>gateway-callee-service2</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,64 +0,0 @@
# Spring Cloud Polaris RateLimit Example
## 项目说明
本项目演示如何使用 Polaris ratelimit starter 完成 Spring Cloud 应用的限流管理。
## 示例
### 如何接入
在启动示例进行演示之前,我们先了解一下如何接入 Polaris 限流组件。
> **注意:本章节只是为了便于您理解接入方式,本示例代码中已经完成接入工作,您无需再进行修改。**
1. 首先,修改 `pom.xml` 文件,引入 Polaris ratelimit starter。
```xml
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
</dependency>
```
2. 启动应用
北极星提供的example都支持在IDE中直接运行或者编译打包后通过命令行方式进行运行。
- 在本地启动Polaris服务端。
- 在北极星服务端可以通过控制台在命名空间Production下添加服务RateLimitCalleeService。
- 启动服务被调方:
1. IDE直接启动找到主类 `RateLimitCalleeService`,执行 main 方法启动应用。
2. 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包
- 执行 `java -jar ratelimit-callee-sevice-${verion}.jar`启动应用
- 执行 `java -jar ratelimit-caller-sevice-${verion}.jar`启动应用
- 启动后,可以在北极星控制台上看到注册上来的服务实例信息。
3. 调用服务
通过浏览器访问http://127.0.0.1:58080/business/invoke可以看到以下输出信息
````
hello world for ratelimit service 1
hello world for ratelimit service 2
hello world for ratelimit service 3
...
````
4. 配置限流规则并验证
北极星提供了三个方式进行限流规则的配置控制台、HTTP接口以及本地文件
- 使用的方式为通过HTTP接口进行配置。通过以下命令来配置
````
curl -X POST -H "Content-Type:application/json" 127.0.0.1:8090/naming/v1/ratelimits -d @rule.json
````
- 通过控制台进行配置,示例如下:
![](polaris-ratelimit-ui.png)
5. 验证限流效果
继续访问http://127.0.0.1:48081/business/invoke可以看到10次调用后就开始被限流
````
hello world for ratelimit service 1
hello world for ratelimit service 2
...
hello world for ratelimit service 10
request has been limited, service is RateLimitCalleeService, path is /business/invoke, 11
````

@ -1,71 +0,0 @@
# Spring Cloud Polaris RateLimit Example
## Project Explanation
This project shows how to use ratelimit feature of Polaris to complete Spring Cloud application's rate limit
## Example
### How to access
Before showcasing the project, let's get to know how to access Polaris rate limit component
> ** note: this chapter is to help you understand different ways to access, the codes in the example has been executed, you don't need to re-edit.**
1, first, change document `pom.xml`, introduce Polaris ratelimit starter
```xml
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
</dependency>
```
2. Launch Application
Examples provided by Polaris all support to run at IDE, or compile and run with orders
- Launch Polaris locally
- at Polaris end, through control panel, under namespace Product, add RateLimitCalleeService
- Launch callee server:
1. Launch IDE directly: First find `RateLimitCalleeService`, execute main then launch application
2. compile package then launch: first execute `mvn clean package` compile the package
- then execute `java -jar ratelimit-callee-sevice-${verion}.jar` execute the application
- then execute `java -jar ratelimit-caller-sevice-${verion}.jar` execute the application
- After launching, one can watch server instance from Polaris control panel
3. Invoke Service
After visiting http://127.0.0.1:58080/business/invoke, one can see the following information:
````
hello world for ratelimit service 1
hello world for ratelimit service 2
hello world for ratelimit service 3
...
````
4. Configuration rate limit and verification
Polaris provide three wats to conduct rate limit configuration (control panel, HTTP port and local files)
- HTTP configuration. One can figure with the following steps:
````
curl -X POST -H "Content-Type:application/json" 127.0.0.1:8090/naming/v1/ratelimits -d @rule.json
````
- Configuration is done through the console, example as follows.
![](polaris-ratelimit-ui.png)
5. Verify rate limit result
continue visit http://127.0.0.1:68080/business/invoke, one can see, after 10 invokes, rate limit will start:
````
hello world for ratelimit service 1
hello world for ratelimit service 2
````

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 KiB

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tencent-examples</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-ratelimit-example</artifactId>
<packaging>pom</packaging>
<name>Spring Cloud Starter Tencent Polaris RateLimit Example</name>
<modules>
<module>ratelimit-callee-service</module>
<module>ratelimit-caller-service</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
</project>

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-ratelimit-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ratelimit-callee-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -1,183 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.ratelimit.example.service.callee;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException.TooManyRequests;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
/**
* Rate limit controller.
*
* @author Haotian Zhang
*/
@Deprecated
@RestController
@RequestMapping("/business")
public class BusinessController {
private static final Logger LOG = LoggerFactory.getLogger(BusinessController.class);
private final AtomicInteger index = new AtomicInteger(0);
private final AtomicLong lastTimestamp = new AtomicLong(0);
@Autowired
private RestTemplate restTemplate;
@Autowired
private WebClient.Builder webClientBuilder;
@Value("${spring.application.name}")
private String appName;
@Value("${server.port:0}")
private int port;
@Value("${spring.cloud.client.ip-address:127.0.0.1}")
private String ip;
/**
* Get information.
* @return information
*/
@GetMapping("/info")
public String info() {
return String.format("hello world for ratelimit service %s [%s:%s] is called.", index.incrementAndGet(), ip, port);
}
@GetMapping("/info/webclient")
public Mono<String> infoWebClient() {
return Mono.just(String.format("hello world for ratelimit service %s [%s:%s] is called.", index.incrementAndGet(), ip, port));
}
@GetMapping("/invoke/webclient")
public String invokeInfoWebClient() throws InterruptedException, ExecutionException {
StringBuffer builder = new StringBuffer();
WebClient webClient = webClientBuilder.baseUrl("http://" + appName).build();
List<Mono<String>> monoList = new ArrayList<>();
for (int i = 0; i < 30; i++) {
Mono<String> response = webClient.get()
.uri(uriBuilder -> uriBuilder
.path("/business/info/webclient")
.queryParam("yyy", "yyy")
.build()
)
.header("xxx", "xxx")
.retrieve()
.bodyToMono(String.class)
.doOnSuccess(s -> builder.append(s).append("\n"))
.doOnError(e -> {
if (e instanceof WebClientResponseException) {
if (((WebClientResponseException) e).getRawStatusCode() == 429) {
builder.append("TooManyRequests ").append(index.incrementAndGet()).append("\n");
}
}
})
.onErrorReturn("");
monoList.add(response);
}
for (Mono<String> mono : monoList) {
mono.toFuture().get();
}
index.set(0);
return builder.toString();
}
/**
* Get information 30 times per 1 second.
*
* @return result of 30 calls.
* @throws InterruptedException exception
*/
@GetMapping("/invoke")
public String invokeInfo() throws InterruptedException {
StringBuffer builder = new StringBuffer();
CountDownLatch count = new CountDownLatch(30);
for (int i = 0; i < 30; i++) {
new Thread(() -> {
try {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("xxx", "xxx");
ResponseEntity<String> entity = restTemplate.exchange(
"http://" + appName + "/business/info?yyy={yyy}",
HttpMethod.GET,
new HttpEntity<>(httpHeaders),
String.class,
"yyy"
);
builder.append(entity.getBody()).append("\n");
}
catch (RestClientException e) {
if (e instanceof TooManyRequests) {
builder.append("TooManyRequests ").append(index.incrementAndGet()).append("\n");
}
else {
throw e;
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
count.countDown();
}
}).start();
}
count.await();
index.set(0);
return builder.toString();
}
/**
* Get information with unirate.
*
* @return information
*/
@GetMapping("/unirate")
public String unirate() {
long currentTimestamp = System.currentTimeMillis();
long lastTime = lastTimestamp.get();
if (lastTime != 0) {
LOG.info("Current timestamp:" + currentTimestamp + ", diff from last timestamp:" + (currentTimestamp - lastTime));
}
else {
LOG.info("Current timestamp:" + currentTimestamp);
}
lastTimestamp.set(currentTimestamp);
return "hello world for ratelimit service with diff from last request:" + (currentTimestamp - lastTime) + "ms.";
}
}

@ -1,51 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.ratelimit.example.service.callee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
/**
* Rate limit application.
*
* @author Haotian Zhang
*/
@SpringBootApplication
public class RateLimitCalleeService {
public static void main(String[] args) {
SpringApplication.run(RateLimitCalleeService.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@LoadBalanced
@Bean
WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}

@ -1,29 +0,0 @@
server:
port: 48081
spring:
application:
name: RateLimitCalleeService
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
ratelimit:
enabled: true
rejectRequestTipsFilePath: reject-tips.html
maxQueuingTime: 500
stat:
enabled: true
port: 28083
management:
endpoints:
web:
exposure:
include:
- polaris-ratelimit
logging:
level:
com.tencent.cloud.polaris: debug
label:
key-value: user:zhangsan, user2:lisi

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>polaris-ratelimit-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>ratelimit-caller-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-ratelimit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -1,185 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.ratelimit.example.service.caller;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException.TooManyRequests;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
@RestController
@RequestMapping("/business")
public class Controller {
private static final Logger LOG = LoggerFactory.getLogger(Controller.class);
private final AtomicInteger index = new AtomicInteger(0);
private final AtomicLong lastTimestamp = new AtomicLong(0);
@Autowired
private RestTemplate restTemplate;
@Autowired
private WebClient.Builder webClientBuilder;
private final String appName = "RateLimitCalleeService";
/**
* Get information.
* @return information
*/
@GetMapping("/info")
public String info() {
return "hello world for ratelimit service " + index.incrementAndGet();
}
@GetMapping("/info/webclient")
public Mono<String> infoWebClient() {
return Mono.just("hello world for ratelimit service " + index.incrementAndGet());
}
@GetMapping("/invoke/webclient")
public String invokeInfoWebClient(@RequestParam(defaultValue = "value1", required = false) String value1, @RequestParam(defaultValue = "value1", required = false) String value2, @RequestHeader Map<String, String> headers) throws InterruptedException, ExecutionException {
StringBuffer builder = new StringBuffer();
WebClient webClient = webClientBuilder.baseUrl("http://" + appName).build();
Consumer<HttpHeaders> headersConsumer = httpHeaders -> {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpHeaders.add(entry.getKey(), entry.getValue());
}
};
List<Mono<String>> monoList = new ArrayList<>();
for (int i = 0; i < 30; i++) {
Mono<String> response = webClient.get()
.uri(uriBuilder -> uriBuilder
.path("/business/info/webclient")
.queryParam("value1", value1)
.queryParam("value2", value2)
.build()
)
.headers(headersConsumer)
.retrieve()
.bodyToMono(String.class)
.doOnSuccess(s -> builder.append(s).append("\n"))
.doOnError(e -> {
if (e instanceof WebClientResponseException) {
if (((WebClientResponseException) e).getRawStatusCode() == 429) {
builder.append("TooManyRequests ").append(index.incrementAndGet()).append("\n");
}
}
})
.onErrorReturn("");
monoList.add(response);
}
for (Mono<String> mono : monoList) {
mono.toFuture().get();
}
index.set(0);
return builder.toString();
}
/**
* Get information 30 times per 1 second.
*
* @return result of 30 calls.
* @throws InterruptedException exception
*/
@GetMapping("/invoke")
public String invokeInfo(@RequestParam(defaultValue = "value1", required = false) String value1, @RequestParam(defaultValue = "value1", required = false) String value2, @RequestHeader Map<String, String> headers) throws InterruptedException {
StringBuffer builder = new StringBuffer();
CountDownLatch count = new CountDownLatch(30);
for (int i = 0; i < 30; i++) {
new Thread(() -> {
try {
HttpHeaders httpHeaders = new HttpHeaders();
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpHeaders.add(entry.getKey(), entry.getValue());
}
ResponseEntity<String> entity = restTemplate.exchange(
"http://" + appName + "/business/info?value1={value1}&value2={value2}",
HttpMethod.GET,
new HttpEntity<>(httpHeaders),
String.class,
value1, value2
);
builder.append(entity.getBody()).append("\n");
}
catch (RestClientException e) {
if (e instanceof TooManyRequests) {
builder.append("TooManyRequests ").append(index.incrementAndGet()).append("\n");
}
else {
throw e;
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
count.countDown();
}
}).start();
}
count.await();
index.set(0);
return builder.toString();
}
/**
* Get information with unirate.
*
* @return information
*/
@GetMapping("/unirate")
public String unirate() {
long currentTimestamp = System.currentTimeMillis();
long lastTime = lastTimestamp.get();
if (lastTime != 0) {
LOG.info("Current timestamp:" + currentTimestamp + ", diff from last timestamp:" + (currentTimestamp - lastTime));
}
else {
LOG.info("Current timestamp:" + currentTimestamp);
}
lastTimestamp.set(currentTimestamp);
return "hello world for ratelimit service with diff from last request:" + (currentTimestamp - lastTime) + "ms.";
}
}

@ -1,52 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.ratelimit.example.service.caller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
@SpringBootApplication
public class RateLimitCallerService {
private static final Logger LOG = LoggerFactory.getLogger(RateLimitCallerService.class);
public static void main(String[] args) {
SpringApplication.run(RateLimitCallerService.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@LoadBalanced
@Bean
WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}

@ -1,21 +0,0 @@
server:
port: 58080
spring:
application:
name: RateLimitCallerService
cloud:
polaris:
address: grpc://119.91.66.223:8091
namespace: default
enabled: true
management:
endpoints:
web:
exposure:
include:
- polaris-ratelimit
logging:
level:
com.tencent.cloud.polaris: debug

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-tencent-examples</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>polaris-router-example</artifactId>
<packaging>pom</packaging>
<modules>
<module>router-callee-service1</module>
<module>router-callee-service2</module>
<module>router-caller-service</module>
</modules>
</project>

@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>polaris-router-example</artifactId>
<groupId>com.tencent.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>router-callee-service1</artifactId>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,35 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.router.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Router callee application.
*
* @author lepdou 2022-04-06
*/
@SpringBootApplication
public class RouterCalleeApplication1 {
public static void main(String[] args) {
SpringApplication.run(RouterCalleeApplication1.class, args);
}
}

@ -1,53 +0,0 @@
/*
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. 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.router.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Discovery callee controller.
*
* @author lepdou 2022-04-06
*/
@RestController
@RequestMapping("/router/service/callee")
public class RouterCalleeController {
private static Logger LOG = LoggerFactory.getLogger(RouterCalleeController.class);
@Value("${server.port:0}")
private int port;
/**
* Get information of callee.
* @return information of callee
*/
@PostMapping("/info")
public String info(String name, @RequestBody User user) {
LOG.info("Discovery Service Callee [{}] is called.", port);
return String.format("Discovery Service Callee [%s] is called. user = %s", port, user);
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save