feat:add Tencent Cloud TSF support. (#1409)
Co-authored-by: Haotian Zhang <skyebefreeman@qq.com>pull/1410/head
parent
a3e35d6894
commit
1f05da13fe
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.tsf;
|
||||
|
||||
import com.tencent.cloud.polaris.config.ConditionalOnPolarisConfigEnabled;
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* @author juanyinyang
|
||||
* @Date Jul 23, 2023 3:52:48 PM
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty("spring.cloud.polaris.enabled")
|
||||
@ConditionalOnTsfEnabled
|
||||
@ConditionalOnPolarisConfigEnabled
|
||||
@Import(PolarisAdaptorTsfConfigAutoConfiguration.class)
|
||||
public class PolarisAdaptorTsfConfigBootstrapConfiguration {
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.tsf;
|
||||
|
||||
import com.tencent.cloud.common.constant.OrderConstant;
|
||||
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
|
||||
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
|
||||
import com.tencent.cloud.polaris.context.tsf.config.TsfCoreProperties;
|
||||
import com.tencent.polaris.factory.config.ConfigurationImpl;
|
||||
|
||||
/**
|
||||
* TSF config modifier.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class TsfConfigurationModifier implements PolarisConfigModifier {
|
||||
|
||||
|
||||
private final TsfCoreProperties tsfCoreProperties;
|
||||
|
||||
private final PolarisConfigProperties polarisConfigProperties;
|
||||
|
||||
public TsfConfigurationModifier(TsfCoreProperties tsfCoreProperties, PolarisConfigProperties polarisConfigProperties) {
|
||||
this.tsfCoreProperties = tsfCoreProperties;
|
||||
this.polarisConfigProperties = polarisConfigProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(ConfigurationImpl configuration) {
|
||||
if (polarisConfigProperties != null && tsfCoreProperties != null) {
|
||||
polarisConfigProperties.setEnabled(tsfCoreProperties.isTsePolarisEnable());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return OrderConstant.Modifier.CONFIG_ORDER - 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.tsf.cache;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* @author juanyinyang
|
||||
* @Date 2023年8月8日 下午4:56:18
|
||||
*/
|
||||
public final class PolarisPropertyCache {
|
||||
|
||||
private static final PolarisPropertyCache instance = new PolarisPropertyCache();
|
||||
|
||||
private final Set<String> cache = new HashSet<>();
|
||||
|
||||
private PolarisPropertyCache() {
|
||||
|
||||
}
|
||||
|
||||
public static PolarisPropertyCache getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Set<String> getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
cache.clear();
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.tsf.encrypt;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ConfigEncryptAESProvider extends ConfigEncryptProvider {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfigEncryptAESProvider.class);
|
||||
|
||||
@Override
|
||||
public String encrypt(String content, String password) {
|
||||
try {
|
||||
return EncryptAlgorithm.AES256.encrypt(content, password);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("[SCTT Config] Error on encrypting.", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String decrypt(String encryptedContent, String password) {
|
||||
try {
|
||||
return EncryptAlgorithm.AES256.decrypt(encryptedContent, password);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("[SCTT Config] Error on decrypting.", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.tsf.encrypt;
|
||||
|
||||
/**
|
||||
* TSF 配置加密提供器接口.
|
||||
*
|
||||
* @author hongweizhu
|
||||
*/
|
||||
public abstract class ConfigEncryptProvider {
|
||||
|
||||
/**
|
||||
* 加密.
|
||||
*
|
||||
* @param content 明文
|
||||
* @param password 密码
|
||||
* @return 密文
|
||||
*/
|
||||
public abstract String encrypt(String content, String password);
|
||||
|
||||
/**
|
||||
* 解密.
|
||||
*
|
||||
* @param encryptedContent 密文
|
||||
* @param password 密码
|
||||
* @return 明文
|
||||
*/
|
||||
public abstract String decrypt(String encryptedContent, String password);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.tsf.encrypt;
|
||||
|
||||
public final class ConfigEncryptProviderFactory {
|
||||
|
||||
private static ConfigEncryptProvider configEncryptProvider = null;
|
||||
|
||||
private ConfigEncryptProviderFactory() {
|
||||
}
|
||||
|
||||
public static ConfigEncryptProvider getInstance() {
|
||||
if (null == configEncryptProvider) {
|
||||
try {
|
||||
Class<?> providerClass = Class.forName(EncryptConfig.getProviderClass());
|
||||
configEncryptProvider = (ConfigEncryptProvider) providerClass.newInstance();
|
||||
}
|
||||
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return configEncryptProvider;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.tsf.consul.config.watch;
|
||||
|
||||
public interface ConfigChangeCallback {
|
||||
|
||||
/**
|
||||
* 配置变更回调函数.
|
||||
* @param lastConfigProperty 旧的配置属性
|
||||
* @param newConfigProperty 新的配置属性
|
||||
*/
|
||||
void callback(ConfigProperty lastConfigProperty, ConfigProperty newConfigProperty);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.tsf.consul.config.watch;
|
||||
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Component
|
||||
public @interface ConfigChangeListener {
|
||||
String prefix() default "";
|
||||
|
||||
String[] value() default {};
|
||||
|
||||
boolean async() default false;
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.tsf.consul.config.watch;
|
||||
|
||||
public class ConfigProperty {
|
||||
|
||||
private String key;
|
||||
|
||||
private Object value;
|
||||
|
||||
public ConfigProperty(String key, Object value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.tsf.consul.config.watch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent;
|
||||
import com.tencent.cloud.polaris.config.listener.PolarisConfigListenerContext;
|
||||
import com.tencent.cloud.polaris.config.listener.SyncConfigChangeListener;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.PriorityOrdered;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class TsfConsulConfigRefreshEventListener implements BeanPostProcessor, PriorityOrdered {
|
||||
private static final String DOT = ".";
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(@NonNull Object obj, @NonNull String beanName) throws BeansException {
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(@NonNull Object obj, @NonNull String beanName) throws BeansException {
|
||||
Class<?> clz = obj.getClass();
|
||||
if (!clz.isAnnotationPresent(ConfigChangeListener.class) || !ConfigChangeCallback.class.isAssignableFrom(clz)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
ConfigChangeListener targetAnno = clz.getAnnotation(ConfigChangeListener.class);
|
||||
String watchedPrefix = targetAnno.prefix();
|
||||
String[] watchedConfirmedValue = targetAnno.value();
|
||||
boolean isAsync = targetAnno.async();
|
||||
if (watchedConfirmedValue.length == 0 && StringUtils.isEmpty(watchedPrefix)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
ConfigChangeCallback bean = (ConfigChangeCallback) obj;
|
||||
com.tencent.cloud.polaris.config.listener.ConfigChangeListener listener = new SyncConfigChangeListener() {
|
||||
@Override
|
||||
public void onChange(ConfigChangeEvent changeEvent) {
|
||||
List<TsfCallbackParam> paramList = parseConfigChangeEventToTsfCallbackParam(changeEvent);
|
||||
for (TsfCallbackParam param : paramList) {
|
||||
if (isAsync()) {
|
||||
PolarisConfigListenerContext.executor()
|
||||
.execute(() -> bean.callback(param.oldValue, param.newValue));
|
||||
}
|
||||
else {
|
||||
bean.callback(param.oldValue, param.newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsync() {
|
||||
return isAsync;
|
||||
}
|
||||
};
|
||||
|
||||
Set<String> interestedKeys = new HashSet<>();
|
||||
Set<String> interestedKeyPrefixes = new HashSet<>();
|
||||
if (watchedConfirmedValue.length > 0) {
|
||||
for (String value : watchedConfirmedValue) {
|
||||
interestedKeys.add(StringUtils.isEmpty(watchedPrefix) ? value : watchedPrefix + DOT + value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
interestedKeyPrefixes.add(watchedPrefix);
|
||||
}
|
||||
|
||||
PolarisConfigListenerContext.addChangeListener(listener, interestedKeys, interestedKeyPrefixes);
|
||||
return bean;
|
||||
}
|
||||
|
||||
private List<TsfCallbackParam> parseConfigChangeEventToTsfCallbackParam(ConfigChangeEvent event) {
|
||||
List<TsfCallbackParam> result = new ArrayList<>();
|
||||
Set<String> changedKeys = event.changedKeys();
|
||||
for (String changedKey : changedKeys) {
|
||||
ConfigProperty oldValue = new ConfigProperty(changedKey, event.getChange(changedKey).getOldValue());
|
||||
ConfigProperty newValue = new ConfigProperty(changedKey, event.getChange(changedKey).getNewValue());
|
||||
TsfCallbackParam param = new TsfCallbackParam(oldValue, newValue);
|
||||
result.add(param);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static class TsfCallbackParam {
|
||||
ConfigProperty oldValue;
|
||||
ConfigProperty newValue;
|
||||
|
||||
TsfCallbackParam(ConfigProperty oldValue, ConfigProperty newValue) {
|
||||
this.oldValue = oldValue;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
com.tencent.cloud.polaris.config.tsf.adaptor.PolarisAdaptorTsfConfigExtensionLayer
|
@ -1,3 +1,4 @@
|
||||
com.tencent.cloud.polaris.config.PolarisConfigAutoConfiguration
|
||||
com.tencent.cloud.polaris.config.endpoint.PolarisConfigEndpointAutoConfiguration
|
||||
com.tencent.cloud.polaris.config.PolarisConfigBootstrapAutoConfiguration
|
||||
com.tencent.cloud.polaris.config.tsf.PolarisAdaptorTsfConfigAutoConfiguration
|
||||
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.contract.tsf;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.tencent.cloud.common.util.GzipUtil;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springdoc.api.AbstractOpenApiResource;
|
||||
import org.springdoc.api.AbstractOpenApiResourceUtil;
|
||||
import org.springdoc.core.providers.ObjectMapperProvider;
|
||||
import org.springdoc.webflux.api.OpenApiWebFluxUtil;
|
||||
import org.springdoc.webmvc.api.OpenApiWebMvcUtil;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
public class TsfApiMetadataGrapher implements SmartLifecycle {
|
||||
|
||||
private final AtomicBoolean isRunning = new AtomicBoolean(false);
|
||||
private final org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource;
|
||||
private final org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource;
|
||||
private final ObjectMapperProvider springdocObjectMapperProvider;
|
||||
private Logger logger = LoggerFactory.getLogger(TsfApiMetadataGrapher.class);
|
||||
private ApplicationContext applicationContext;
|
||||
private String groupName;
|
||||
|
||||
public TsfApiMetadataGrapher(org.springdoc.webmvc.api.MultipleOpenApiResource multipleOpenApiWebMvcResource,
|
||||
org.springdoc.webflux.api.MultipleOpenApiResource multipleOpenApiWebFluxResource,
|
||||
String groupName, ApplicationContext applicationContext, ObjectMapperProvider springdocObjectMapperProvider) {
|
||||
this.applicationContext = applicationContext;
|
||||
this.multipleOpenApiWebMvcResource = multipleOpenApiWebMvcResource;
|
||||
this.multipleOpenApiWebFluxResource = multipleOpenApiWebFluxResource;
|
||||
this.groupName = groupName;
|
||||
this.springdocObjectMapperProvider = springdocObjectMapperProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(Runnable runnable) {
|
||||
runnable.run();
|
||||
stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (!isRunning.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
AbstractOpenApiResource openApiResource = null;
|
||||
if (multipleOpenApiWebMvcResource != null) {
|
||||
openApiResource = OpenApiWebMvcUtil.getOpenApiResourceOrThrow(multipleOpenApiWebMvcResource, groupName);
|
||||
}
|
||||
else if (multipleOpenApiWebFluxResource != null) {
|
||||
openApiResource = OpenApiWebFluxUtil.getOpenApiResourceOrThrow(multipleOpenApiWebFluxResource, groupName);
|
||||
}
|
||||
OpenAPI openAPI = null;
|
||||
if (openApiResource != null) {
|
||||
openAPI = AbstractOpenApiResourceUtil.getOpenApi(openApiResource);
|
||||
}
|
||||
String jsonValue;
|
||||
if (springdocObjectMapperProvider != null && springdocObjectMapperProvider.jsonMapper() != null) {
|
||||
jsonValue = springdocObjectMapperProvider.jsonMapper().writeValueAsString(openAPI);
|
||||
}
|
||||
else {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
jsonValue = mapper.writeValueAsString(openAPI);
|
||||
}
|
||||
if (openAPI != null && !StringUtils.isEmpty(jsonValue)) {
|
||||
String serviceApiMeta = GzipUtil.compressBase64Encode(jsonValue, "utf-8");
|
||||
Environment environment = applicationContext.getEnvironment();
|
||||
String tsfToken = environment.getProperty("tsf_token");
|
||||
String tsfGroupId = environment.getProperty("tsf_group_id");
|
||||
if (StringUtils.isEmpty(tsfGroupId) || StringUtils.isEmpty(tsfToken)) {
|
||||
logger.info("[tsf-swagger] auto smart check application start with local consul, api registry not work");
|
||||
return;
|
||||
}
|
||||
logger.info("[tsf-swagger] api_meta len: {}", serviceApiMeta.length());
|
||||
String applicationName = environment.getProperty("spring.application.name");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("[tsf-swagger] service: {} openApi json data: {}", applicationName, jsonValue);
|
||||
logger.debug("[tsf-swagger] service: {} api_meta info: {}", applicationName, serviceApiMeta);
|
||||
}
|
||||
|
||||
System.setProperty(String.format("$%s", "api_metas"), serviceApiMeta);
|
||||
}
|
||||
else {
|
||||
logger.warn("[tsf-swagger] swagger or json is null, openApiResource keys:{}, group:{}", openApiResource, groupName);
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
logger.error("[tsf swagger] init TsfApiMetadataGrapher failed. occur exception: ", t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
isRunning.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return isRunning.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return -2;
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.contract.tsf;
|
||||
|
||||
import com.tencent.cloud.polaris.contract.config.ExtendedContractProperties;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Properties for TSF contract.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@ConfigurationProperties("tsf.swagger")
|
||||
public class TsfContractProperties implements ExtendedContractProperties {
|
||||
|
||||
@Value("${tsf.swagger.basePackage:}")
|
||||
private String basePackage;
|
||||
|
||||
@Value("${tsf.swagger.excludePath:}")
|
||||
private String excludePath;
|
||||
|
||||
@Value("${tsf.swagger.enabled:true}")
|
||||
private boolean enabled;
|
||||
|
||||
@Value("${tsf.swagger.group:default}")
|
||||
private String groupName;
|
||||
|
||||
@Value("${tsf.swagger.basePath:/**}")
|
||||
private String basePath;
|
||||
|
||||
@Value("${tsf.swagger.doc.auto-startup:true}")
|
||||
private boolean exposure;
|
||||
|
||||
/**
|
||||
* applicationId 应用Id.
|
||||
*/
|
||||
@Value("${tsf_application_id:}")
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBasePackage() {
|
||||
return basePackage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBasePackage(String basePackage) {
|
||||
this.basePackage = basePackage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExcludePath() {
|
||||
return excludePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExcludePath(String excludePath) {
|
||||
this.excludePath = excludePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroup() {
|
||||
return groupName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGroup(String group) {
|
||||
this.groupName = group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBasePath() {
|
||||
return basePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBasePath(String basePath) {
|
||||
this.basePath = basePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExposure() {
|
||||
return exposure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExposure(boolean exposure) {
|
||||
this.exposure = exposure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReportEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReportEnabled(boolean reportEnabled) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.contract.tsf;
|
||||
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto configuration for TSF contract properties.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnTsfEnabled
|
||||
public class TsfContractPropertiesAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfContractProperties tsfContractProperties() {
|
||||
return new TsfContractProperties();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.contract.tsf;
|
||||
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Bootstrap configuration for TSF contract properties.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnTsfEnabled
|
||||
@Import(TsfContractPropertiesAutoConfiguration.class)
|
||||
public class TsfContractPropertiesBootstrapConfiguration {
|
||||
|
||||
}
|
@ -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.contract.tsf;
|
||||
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
import com.tencent.cloud.polaris.contract.config.PolarisContractProperties;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import org.springdoc.core.providers.ObjectMapperProvider;
|
||||
import org.springdoc.webflux.api.MultipleOpenApiWebFluxResource;
|
||||
import org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
@ConditionalOnTsfEnabled
|
||||
@ConditionalOnClass(name = "org.springframework.web.servlet.config.annotation.EnableWebMvc")
|
||||
@ConditionalOnProperty(value = "tsf.swagger.enabled", havingValue = "true", matchIfMissing = true)
|
||||
public class TsfSwaggerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(OpenAPI.class)
|
||||
public TsfApiMetadataGrapher tsfApiMetadataGrapher(@Nullable MultipleOpenApiWebMvcResource multipleOpenApiWebMvcResource,
|
||||
@Nullable MultipleOpenApiWebFluxResource multipleOpenApiWebFluxResource, ApplicationContext context,
|
||||
PolarisContractProperties polarisContractProperties, ObjectMapperProvider springdocObjectMapperProvider) {
|
||||
return new TsfApiMetadataGrapher(multipleOpenApiWebMvcResource, multipleOpenApiWebFluxResource,
|
||||
polarisContractProperties.getGroup(), context, springdocObjectMapperProvider);
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesBootstrapConfiguration
|
||||
com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesBootstrapConfiguration,\
|
||||
com.tencent.cloud.polaris.contract.tsf.TsfContractPropertiesBootstrapConfiguration
|
||||
org.springframework.context.ApplicationListener=\
|
||||
com.tencent.cloud.polaris.contract.PolarisSwaggerApplicationListener
|
||||
|
@ -1,2 +1,4 @@
|
||||
com.tencent.cloud.polaris.contract.config.PolarisSwaggerAutoConfiguration
|
||||
com.tencent.cloud.polaris.contract.config.PolarisContractPropertiesAutoConfiguration
|
||||
com.tencent.cloud.polaris.contract.tsf.TsfContractPropertiesAutoConfiguration
|
||||
com.tencent.cloud.polaris.contract.tsf.TsfSwaggerAutoConfiguration
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.tsf;
|
||||
|
||||
import com.tencent.cloud.common.util.inet.PolarisInetUtils;
|
||||
import com.tencent.cloud.plugin.lossless.config.LosslessProperties;
|
||||
import com.tencent.cloud.polaris.PolarisDiscoveryProperties;
|
||||
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
import com.tencent.cloud.polaris.context.tsf.config.TsfCoreProperties;
|
||||
import com.tencent.cloud.polaris.context.tsf.consul.TsfConsulProperties;
|
||||
import com.tencent.cloud.polaris.tsf.lossless.TsfLosslessConfigModifier;
|
||||
import com.tencent.cloud.polaris.tsf.lossless.TsfLosslessProperties;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto configuration for TSF discovery.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnTsfEnabled
|
||||
public class TsfDiscoveryPropertiesAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfDiscoveryProperties tsfDiscoveryProperties(PolarisInetUtils polarisInetUtils) {
|
||||
return new TsfDiscoveryProperties(polarisInetUtils);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfHeartbeatProperties tsfHeartbeatProperties() {
|
||||
return new TsfHeartbeatProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfLosslessProperties tsfLosslessProperties() {
|
||||
return new TsfLosslessProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfDiscoveryConfigModifier tsfDiscoveryConfigModifier(TsfCoreProperties tsfCoreProperties,
|
||||
TsfConsulProperties tsfConsulProperties, TsfDiscoveryProperties tsfDiscoveryProperties,
|
||||
TsfHeartbeatProperties tsfHeartbeatProperties, PolarisDiscoveryProperties polarisDiscoveryProperties,
|
||||
PolarisContextProperties polarisContextProperties, ApplicationContext context) {
|
||||
return new TsfDiscoveryConfigModifier(tsfCoreProperties, tsfConsulProperties, tsfDiscoveryProperties,
|
||||
tsfHeartbeatProperties, polarisDiscoveryProperties, polarisContextProperties, context);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfZeroProtectionConfigModifier tsfZeroProtectionConfigModifier() {
|
||||
return new TsfZeroProtectionConfigModifier();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfLosslessConfigModifier tsfLosslessConfigModifier(LosslessProperties losslessProperties, TsfLosslessProperties tsfLosslessProperties) {
|
||||
return new TsfLosslessConfigModifier(losslessProperties, tsfLosslessProperties);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.tsf;
|
||||
|
||||
import com.tencent.cloud.polaris.DiscoveryPropertiesAutoConfiguration;
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Bootstrap configuration for TSF discovery.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnTsfEnabled
|
||||
@Import({TsfDiscoveryPropertiesAutoConfiguration.class,
|
||||
DiscoveryPropertiesAutoConfiguration.class,
|
||||
UtilAutoConfiguration.class})
|
||||
public class TsfDiscoveryPropertiesBootstrapConfiguration {
|
||||
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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.tsf;
|
||||
|
||||
import jakarta.validation.constraints.DecimalMax;
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.joda.time.Period;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@ConfigurationProperties(prefix = "tsf.discovery.heartbeat")
|
||||
@Validated
|
||||
public class TsfHeartbeatProperties {
|
||||
|
||||
private static final Log log = org.apache.commons.logging.LogFactory.getLog(TsfHeartbeatProperties.class);
|
||||
// TODO: change enabled to default to true when I stop seeing messages like
|
||||
// [WARN] agent: Check 'service:testConsulApp:xtest:8080' missed TTL, is now critical
|
||||
boolean enabled = true;
|
||||
|
||||
@Min(1)
|
||||
private int ttlValue = 30;
|
||||
|
||||
@NotNull
|
||||
private String ttlUnit = "s";
|
||||
|
||||
@DecimalMin("0.1")
|
||||
@DecimalMax("0.9")
|
||||
private double intervalRatio = 2.0 / 3.0;
|
||||
|
||||
//TODO: did heartbeatInterval need to be a field?
|
||||
|
||||
protected Period computeHearbeatInterval() {
|
||||
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
|
||||
// priority), no sooner than 1s from now
|
||||
double interval = ttlValue * intervalRatio;
|
||||
double max = Math.max(interval, 1);
|
||||
int ttlMinus1 = ttlValue - 1;
|
||||
double min = Math.min(ttlMinus1, max);
|
||||
Period heartbeatInterval = new Period(Math.round(1000 * min));
|
||||
log.debug("Computed heartbeatInterval: " + heartbeatInterval);
|
||||
return heartbeatInterval;
|
||||
}
|
||||
|
||||
public String getTtl() {
|
||||
return ttlValue + ttlUnit;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public @Min(1) int getTtlValue() {
|
||||
return this.ttlValue;
|
||||
}
|
||||
|
||||
public void setTtlValue(@Min(1) int ttlValue) {
|
||||
this.ttlValue = ttlValue;
|
||||
}
|
||||
|
||||
public @NotNull String getTtlUnit() {
|
||||
return this.ttlUnit;
|
||||
}
|
||||
|
||||
public void setTtlUnit(@NotNull String ttlUnit) {
|
||||
this.ttlUnit = ttlUnit;
|
||||
}
|
||||
|
||||
public @DecimalMin("0.1") @DecimalMax("0.9") double getIntervalRatio() {
|
||||
return this.intervalRatio;
|
||||
}
|
||||
|
||||
public void setIntervalRatio(@DecimalMin("0.1") @DecimalMax("0.9") double intervalRatio) {
|
||||
this.intervalRatio = intervalRatio;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this)
|
||||
.append("enabled", enabled)
|
||||
.append("ttlValue", ttlValue)
|
||||
.append("ttlUnit", ttlUnit)
|
||||
.append("intervalRatio", intervalRatio)
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.tsf;
|
||||
|
||||
import com.tencent.cloud.common.constant.OrderConstant;
|
||||
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
|
||||
import com.tencent.polaris.factory.config.ConfigurationImpl;
|
||||
|
||||
/**
|
||||
* Modifier for TSF discovery zero protection.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class TsfZeroProtectionConfigModifier implements PolarisConfigModifier {
|
||||
@Override
|
||||
public void modify(ConfigurationImpl configuration) {
|
||||
configuration.getConsumer().getZeroProtection().setEnable(true);
|
||||
configuration.getConsumer().getZeroProtection().setNeedTestConnectivity(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return OrderConstant.Modifier.DISCOVERY_ORDER + 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.tsf.consts;
|
||||
|
||||
/**
|
||||
* 预热所需枚举.
|
||||
* @author jiangfan
|
||||
*/
|
||||
public final class WarmupCons {
|
||||
|
||||
/**
|
||||
* 预热保护阈值.
|
||||
*/
|
||||
public static double DEFAULT_PROTECTION_THRESHOLD_KEY = 50;
|
||||
/**
|
||||
* TSF 启动时间。预热开始时间.
|
||||
*/
|
||||
public static String TSF_START_TIME = "TSF_START_TIME";
|
||||
|
||||
private WarmupCons() {
|
||||
|
||||
}
|
||||
}
|
@ -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.tsf.lossless;
|
||||
|
||||
import com.tencent.cloud.common.constant.OrderConstant;
|
||||
import com.tencent.cloud.plugin.lossless.config.LosslessProperties;
|
||||
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
|
||||
import com.tencent.polaris.factory.config.ConfigurationImpl;
|
||||
|
||||
/**
|
||||
* Modifier for TSF lossless online offline.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class TsfLosslessConfigModifier implements PolarisConfigModifier {
|
||||
|
||||
private final LosslessProperties losslessProperties;
|
||||
private final TsfLosslessProperties tsfLosslessProperties;
|
||||
|
||||
public TsfLosslessConfigModifier(LosslessProperties losslessProperties, TsfLosslessProperties tsfLosslessProperties) {
|
||||
this.losslessProperties = losslessProperties;
|
||||
this.tsfLosslessProperties = tsfLosslessProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modify(ConfigurationImpl configuration) {
|
||||
losslessProperties.setEnabled(true);
|
||||
losslessProperties.setPort(tsfLosslessProperties.getPort());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return OrderConstant.Modifier.LOSSLESS_ORDER - 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.tsf.lossless;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* 优雅上下线的配置.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@ConfigurationProperties("tsf.discovery.lossless")
|
||||
public class TsfLosslessProperties {
|
||||
|
||||
@Value("${tsf.discovery.lossless.port:${tsf_sctt_extensions_port:11134}}")
|
||||
private int port = 11134;
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TsfLosslessProperties{" +
|
||||
"port=" + port +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.tsf.registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistration;
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.tencent.polaris.api.config.plugin.DefaultPlugins.SERVER_CONNECTOR_CONSUL;
|
||||
|
||||
/**
|
||||
* Set API data to registration metadata.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class TsfApiPolarisRegistrationCustomizer implements PolarisRegistrationCustomizer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TsfApiPolarisRegistrationCustomizer.class);
|
||||
|
||||
private static final String API_META_KEY = "TSF_API_METAS";
|
||||
private final ApplicationContext context;
|
||||
|
||||
public TsfApiPolarisRegistrationCustomizer(ApplicationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(PolarisRegistration registration) {
|
||||
String apiMetaData = context.getEnvironment().getProperty("$api_metas");
|
||||
Map<String, Map<String, String>> metadata = registration.getExtendedMetadata();
|
||||
if (StringUtils.hasText(apiMetaData)) {
|
||||
if (!metadata.containsKey(SERVER_CONNECTOR_CONSUL)) {
|
||||
metadata.put(SERVER_CONNECTOR_CONSUL, new HashMap<>());
|
||||
}
|
||||
metadata.get(SERVER_CONNECTOR_CONSUL).put(API_META_KEY, apiMetaData);
|
||||
}
|
||||
else {
|
||||
LOG.warn("apiMetaData is null, service:{}", registration.getServiceId());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.tsf.registry;
|
||||
|
||||
import com.tencent.cloud.polaris.context.PolarisSDKContextManager;
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
import com.tencent.cloud.polaris.registry.PolarisServiceRegistryAutoConfiguration;
|
||||
import com.tencent.cloud.polaris.tsf.TsfDiscoveryProperties;
|
||||
import com.tencent.cloud.polaris.tsf.TsfHeartbeatProperties;
|
||||
import jakarta.servlet.ServletContext;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto configuration for TSF discovery.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnTsfEnabled
|
||||
@AutoConfigureBefore(PolarisServiceRegistryAutoConfiguration.class)
|
||||
public class TsfDiscoveryRegistryAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfMetadataPolarisRegistrationCustomizer tsfMetadataPolarisRegistrationCustomizer(TsfDiscoveryProperties tsfDiscoveryProperties) {
|
||||
return new TsfMetadataPolarisRegistrationCustomizer(tsfDiscoveryProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfPortPolarisRegistrationCustomizer tsfPortPolarisRegistrationCustomizer(
|
||||
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ApplicationContext context, TsfDiscoveryProperties tsfDiscoveryProperties,
|
||||
TsfHeartbeatProperties tsfHeartbeatProperties, PolarisSDKContextManager polarisSDKContextManager) {
|
||||
return new TsfPortPolarisRegistrationCustomizer(autoServiceRegistrationProperties, context,
|
||||
tsfDiscoveryProperties, tsfHeartbeatProperties, polarisSDKContextManager.getSDKContext());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
@ConditionalOnMissingBean
|
||||
public TsfServletRegistrationCustomizer tsfServletConsulCustomizer(ObjectProvider<ServletContext> servletContext) {
|
||||
return new TsfServletRegistrationCustomizer(servletContext);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(value = "tsf.swagger.enabled", havingValue = "true", matchIfMissing = true)
|
||||
public TsfApiPolarisRegistrationCustomizer tsfApiPolarisRegistrationCustomizer(ApplicationContext context) {
|
||||
return new TsfApiPolarisRegistrationCustomizer(context);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.tsf.registry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.tencent.cloud.common.constant.SdkVersion;
|
||||
import com.tencent.cloud.common.util.JacksonUtils;
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistration;
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
|
||||
import com.tencent.cloud.polaris.tsf.TsfDiscoveryProperties;
|
||||
import com.tencent.cloud.polaris.tsf.consts.WarmupCons;
|
||||
import com.tencent.cloud.polaris.tsf.util.RegistrationUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class TsfMetadataPolarisRegistrationCustomizer implements PolarisRegistrationCustomizer {
|
||||
|
||||
private final TsfDiscoveryProperties tsfDiscoveryProperties;
|
||||
|
||||
public TsfMetadataPolarisRegistrationCustomizer(TsfDiscoveryProperties tsfDiscoveryProperties) {
|
||||
this.tsfDiscoveryProperties = tsfDiscoveryProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(PolarisRegistration registration) {
|
||||
Map<String, String> metadata = registration.getMetadata();
|
||||
|
||||
metadata.put("TSF_APPLICATION_ID", tsfDiscoveryProperties.getTsfApplicationId());
|
||||
metadata.put("TSF_PROG_VERSION", tsfDiscoveryProperties.getTsfProgVersion());
|
||||
metadata.put("TSF_GROUP_ID", tsfDiscoveryProperties.getTsfGroupId());
|
||||
metadata.put("TSF_NAMESPACE_ID", tsfDiscoveryProperties.getTsfNamespaceId());
|
||||
metadata.put("TSF_INSTNACE_ID", tsfDiscoveryProperties.getInstanceId());
|
||||
metadata.put("TSF_REGION", tsfDiscoveryProperties.getTsfRegion());
|
||||
metadata.put("TSF_ZONE", tsfDiscoveryProperties.getTsfZone());
|
||||
// 处理预热相关的参数
|
||||
metadata.put(WarmupCons.TSF_START_TIME, String.valueOf(System.currentTimeMillis()));
|
||||
metadata.put("TSF_SDK_VERSION", SdkVersion.get());
|
||||
metadata.put("TSF_TAGS", JacksonUtils.serialize2Json(RegistrationUtil.createTags(tsfDiscoveryProperties)));
|
||||
RegistrationUtil.appendMetaIpAddress(metadata);
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.tsf.registry;
|
||||
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistration;
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
|
||||
import com.tencent.cloud.polaris.tsf.TsfDiscoveryProperties;
|
||||
import com.tencent.cloud.polaris.tsf.TsfHeartbeatProperties;
|
||||
import com.tencent.cloud.polaris.tsf.util.RegistrationUtil;
|
||||
import com.tencent.polaris.client.api.SDKContext;
|
||||
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* 服务注册时端口相关逻辑.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class TsfPortPolarisRegistrationCustomizer implements PolarisRegistrationCustomizer {
|
||||
|
||||
private final AutoServiceRegistrationProperties autoServiceRegistrationProperties;
|
||||
private final ApplicationContext context;
|
||||
private final TsfDiscoveryProperties tsfDiscoveryProperties;
|
||||
private final TsfHeartbeatProperties tsfHeartbeatProperties;
|
||||
private final SDKContext sdkContext;
|
||||
|
||||
public TsfPortPolarisRegistrationCustomizer(AutoServiceRegistrationProperties autoServiceRegistrationProperties,
|
||||
ApplicationContext context, TsfDiscoveryProperties tsfDiscoveryProperties,
|
||||
TsfHeartbeatProperties tsfHeartbeatProperties, SDKContext sdkContext) {
|
||||
this.autoServiceRegistrationProperties = autoServiceRegistrationProperties;
|
||||
this.context = context;
|
||||
this.tsfDiscoveryProperties = tsfDiscoveryProperties;
|
||||
this.tsfHeartbeatProperties = tsfHeartbeatProperties;
|
||||
this.sdkContext = sdkContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(PolarisRegistration registration) {
|
||||
if (tsfDiscoveryProperties.getPort() != null) {
|
||||
registration.setPort(tsfDiscoveryProperties.getPort());
|
||||
}
|
||||
// we know the port and can set the check
|
||||
RegistrationUtil.setCheck(autoServiceRegistrationProperties, tsfDiscoveryProperties, context,
|
||||
tsfHeartbeatProperties, registration, sdkContext.getConfig());
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.tsf.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.tencent.cloud.common.util.JacksonUtils;
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistration;
|
||||
import com.tencent.cloud.polaris.registry.PolarisRegistrationCustomizer;
|
||||
import com.tencent.polaris.plugins.connector.common.constant.ConsulConstant;
|
||||
import jakarta.servlet.ServletContext;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.tencent.polaris.plugins.connector.common.constant.ConsulConstant.MetadataMapKey.TAGS_KEY;
|
||||
|
||||
/**
|
||||
* @author Piotr Wielgolaski
|
||||
*/
|
||||
public class TsfServletRegistrationCustomizer implements PolarisRegistrationCustomizer {
|
||||
private final ObjectProvider<ServletContext> servletContext;
|
||||
|
||||
public TsfServletRegistrationCustomizer(ObjectProvider<ServletContext> servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(PolarisRegistration registration) {
|
||||
if (servletContext == null) {
|
||||
return;
|
||||
}
|
||||
ServletContext sc = servletContext.getIfAvailable();
|
||||
if (sc != null
|
||||
&& StringUtils.hasText(sc.getContextPath())
|
||||
&& StringUtils.hasText(sc.getContextPath().replaceAll("/", ""))) {
|
||||
Map<String, String> metadata = registration.getMetadata();
|
||||
|
||||
List<String> tags = Arrays.asList(JacksonUtils.deserialize(metadata.get(TAGS_KEY), String[].class));
|
||||
if (tags == null) {
|
||||
tags = new ArrayList<>();
|
||||
}
|
||||
tags.add("contextPath=" + sc.getContextPath());
|
||||
metadata.put(ConsulConstant.MetadataMapKey.TAGS_KEY, JacksonUtils.serialize2Json(tags));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
com.tencent.cloud.polaris.DiscoveryPropertiesBootstrapAutoConfiguration
|
||||
com.tencent.cloud.polaris.DiscoveryPropertiesBootstrapAutoConfiguration,\
|
||||
com.tencent.cloud.polaris.tsf.TsfDiscoveryPropertiesBootstrapConfiguration
|
||||
|
0
spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java → spring-cloud-starter-tencent-polaris-discovery/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java
0
spring-cloud-tencent-plugin-starters/spring-cloud-tencent-lossless-plugin/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java → spring-cloud-starter-tencent-polaris-discovery/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationUtils.java
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* 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.common.util.inet;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.tencent.cloud.common.util.AddressUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
|
||||
|
||||
/**
|
||||
* Extend from {@link InetUtils}.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class PolarisInetUtils implements Closeable {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PolarisInetUtils.class);
|
||||
// TODO: maybe shutdown the thread pool if it isn't being used?
|
||||
private final ExecutorService executorService;
|
||||
private final InetUtilsProperties properties;
|
||||
|
||||
public PolarisInetUtils(final InetUtilsProperties properties) {
|
||||
this.properties = properties;
|
||||
this.executorService = Executors
|
||||
.newSingleThreadExecutor(r -> {
|
||||
Thread thread = new Thread(r);
|
||||
thread.setName(InetUtilsProperties.PREFIX);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
|
||||
public static String getIpString(boolean _ipv6) {
|
||||
InetAddress result = null;
|
||||
try {
|
||||
int lowest = Integer.MAX_VALUE;
|
||||
for (Enumeration<NetworkInterface> nics = NetworkInterface
|
||||
.getNetworkInterfaces(); nics.hasMoreElements(); ) {
|
||||
NetworkInterface ifc = nics.nextElement();
|
||||
if (ifc.isUp()) {
|
||||
logger.trace("Testing interface: " + ifc.getDisplayName());
|
||||
if (ifc.getIndex() < lowest || result == null) {
|
||||
lowest = ifc.getIndex();
|
||||
}
|
||||
else if (result != null) {
|
||||
continue;
|
||||
}
|
||||
for (Enumeration<InetAddress> addrs = ifc
|
||||
.getInetAddresses(); addrs.hasMoreElements(); ) {
|
||||
InetAddress address = addrs.nextElement();
|
||||
if (_ipv6) {
|
||||
if (address instanceof Inet6Address
|
||||
&& !address.isLinkLocalAddress()
|
||||
&& !address.isLoopbackAddress()
|
||||
) {
|
||||
logger.trace("Found non-loopback interface: "
|
||||
+ ifc.getDisplayName());
|
||||
result = address;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (address instanceof Inet4Address
|
||||
&& !address.isLoopbackAddress()
|
||||
) {
|
||||
logger.trace("Found non-loopback interface: "
|
||||
+ ifc.getDisplayName());
|
||||
result = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.error("Cannot get first non-loopback address", ex);
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (result.getHostAddress().contains("%")) {
|
||||
return result.getHostAddress().split("%")[0];
|
||||
}
|
||||
else {
|
||||
return result.getHostAddress();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
public InetUtils.HostInfo findFirstNonLoopbackHostInfo() {
|
||||
InetAddress address = findFirstNonLoopbackAddress();
|
||||
if (address != null) {
|
||||
return convertAddress(address);
|
||||
}
|
||||
InetUtils.HostInfo hostInfo = new InetUtils.HostInfo();
|
||||
hostInfo.setHostname(this.properties.getDefaultHostname());
|
||||
hostInfo.setIpAddress(this.properties.getDefaultIpAddress());
|
||||
return hostInfo;
|
||||
}
|
||||
|
||||
public InetAddress findFirstNonLoopbackAddress() {
|
||||
boolean preferIpv6 = AddressUtils.preferIpv6();
|
||||
InetAddress result = findFirstNonLoopbackAddressByIpType(preferIpv6);
|
||||
logger.debug("ipv6 before, preferIpv6:{}, result:{}", preferIpv6, result);
|
||||
if (result == null) {
|
||||
result = findFirstNonLoopbackAddressByIpType(!preferIpv6);
|
||||
}
|
||||
logger.debug("ipv6 after, preferIpv6:{}, result:{}", preferIpv6, result);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
try {
|
||||
return InetAddress.getLocalHost();
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
logger.warn("Unable to retrieve localhost");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** for testing. */
|
||||
boolean isPreferredAddress(InetAddress address) {
|
||||
|
||||
if (this.properties.isUseOnlySiteLocalInterfaces()) {
|
||||
final boolean siteLocalAddress = address.isSiteLocalAddress();
|
||||
if (!siteLocalAddress) {
|
||||
logger.trace("Ignoring address: " + address.getHostAddress());
|
||||
}
|
||||
return siteLocalAddress;
|
||||
}
|
||||
final List<String> preferredNetworks = this.properties.getPreferredNetworks();
|
||||
if (preferredNetworks.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (String regex : preferredNetworks) {
|
||||
final String hostAddress = address.getHostAddress();
|
||||
if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
logger.trace("Ignoring address: " + address.getHostAddress());
|
||||
return false;
|
||||
}
|
||||
|
||||
/** for testing. */
|
||||
boolean ignoreInterface(String interfaceName) {
|
||||
for (String regex : this.properties.getIgnoredInterfaces()) {
|
||||
if (interfaceName.matches(regex)) {
|
||||
logger.trace("Ignoring interface: " + interfaceName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public InetUtils.HostInfo convertAddress(final InetAddress address) {
|
||||
InetUtils.HostInfo hostInfo = new InetUtils.HostInfo();
|
||||
Future<String> result = executorService.submit(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return address.getHostName();
|
||||
}
|
||||
});
|
||||
|
||||
String hostname;
|
||||
try {
|
||||
hostname = result.get(this.properties.getTimeoutSeconds(), TimeUnit.SECONDS);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.info("Cannot determine local hostname");
|
||||
hostname = "localhost";
|
||||
}
|
||||
if (hostname.contains("%")) {
|
||||
hostInfo.setHostname(hostname.split("%")[0]);
|
||||
}
|
||||
else {
|
||||
hostInfo.setHostname(hostname);
|
||||
}
|
||||
if (address.getHostAddress().contains("%")) {
|
||||
hostInfo.setIpAddress(address.getHostAddress().split("%")[0]);
|
||||
}
|
||||
else {
|
||||
hostInfo.setIpAddress(address.getHostAddress());
|
||||
}
|
||||
return hostInfo;
|
||||
}
|
||||
|
||||
public String findIpInterface() {
|
||||
InetAddress address = findFirstNonLoopbackAddress();
|
||||
if (address.getHostAddress().contains("%")) {
|
||||
return address.getHostAddress().split("%")[1];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String findIpAddress() {
|
||||
InetAddress address = findFirstNonLoopbackAddress();
|
||||
return address.getHostAddress().split("%")[0];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return "[ipv6]"
|
||||
*/
|
||||
public String findIpAddressWithBracket() {
|
||||
InetAddress address = findFirstNonLoopbackAddress();
|
||||
if (address.getHostAddress().contains("%")) {
|
||||
return address.getHostAddress().split("%")[0];
|
||||
}
|
||||
return address.getHostAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ipv6%eth0
|
||||
*
|
||||
*/
|
||||
public String findIpAddressAndInterface() {
|
||||
InetAddress address = findFirstNonLoopbackAddress();
|
||||
return address.getHostAddress();
|
||||
}
|
||||
|
||||
public InetAddress findFirstNonLoopbackAddressByIpType(boolean _ipv6) {
|
||||
InetAddress result = null;
|
||||
try {
|
||||
int lowest = Integer.MAX_VALUE;
|
||||
for (Enumeration<NetworkInterface> nics = NetworkInterface
|
||||
.getNetworkInterfaces(); nics.hasMoreElements(); ) {
|
||||
NetworkInterface ifc = nics.nextElement();
|
||||
if (ifc.isUp()) {
|
||||
logger.trace("Testing interface: " + ifc.getDisplayName());
|
||||
if (ifc.getIndex() < lowest || result == null) {
|
||||
lowest = ifc.getIndex();
|
||||
}
|
||||
else if (result != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
if (!ignoreInterface(ifc.getDisplayName())) {
|
||||
for (Enumeration<InetAddress> addrs = ifc
|
||||
.getInetAddresses(); addrs.hasMoreElements();) {
|
||||
InetAddress address = addrs.nextElement();
|
||||
if (_ipv6) {
|
||||
if (address instanceof Inet6Address
|
||||
&& !address.isLinkLocalAddress()
|
||||
&& !address.isLoopbackAddress()
|
||||
&& isPreferredAddress(address)) {
|
||||
logger.trace("Found non-loopback interface: "
|
||||
+ ifc.getDisplayName());
|
||||
result = address;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (address instanceof Inet4Address
|
||||
&& !address.isLoopbackAddress()
|
||||
&& isPreferredAddress(address)) {
|
||||
logger.trace("Found non-loopback interface: "
|
||||
+ ifc.getDisplayName());
|
||||
result = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.error("Cannot get first non-loopback address", ex);
|
||||
}
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.common.util.inet;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.commons.util.InetUtilsProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
/**
|
||||
* Auto configuration for PolarisInetUtils.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class PolarisInetUtilsAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public PolarisInetUtils polarisInetUtils(InetUtilsProperties properties) {
|
||||
return new PolarisInetUtils(properties);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.common.util.inet;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Auto configuration for PolarisInetUtils.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Import(PolarisInetUtilsAutoConfiguration.class)
|
||||
public class PolarisInetUtilsBootstrapConfiguration {
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
com.tencent.cloud.common.util.inet.PolarisInetUtilsBootstrapConfiguration
|
@ -1,3 +1,4 @@
|
||||
com.tencent.cloud.common.util.ApplicationContextAwareUtils
|
||||
com.tencent.cloud.common.metadata.config.MetadataAutoConfiguration
|
||||
com.tencent.cloud.common.metadata.endpoint.PolarisMetadataEndpointAutoConfiguration
|
||||
com.tencent.cloud.common.util.inet.PolarisInetUtilsAutoConfiguration
|
||||
|
@ -1,58 +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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" + "name='" + name + '\'' + ", age=" + age + '}';
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
server:
|
||||
port: 48085
|
||||
spring:
|
||||
application:
|
||||
name: polaris-config-data-example
|
||||
cloud:
|
||||
polaris:
|
||||
address: grpc://119.91.66.223:8091
|
||||
namespace: default
|
||||
config:
|
||||
auto-refresh: true # auto refresh when config file changed
|
||||
groups:
|
||||
- name: ${spring.application.name} # group name
|
||||
files: [ "config/application.properties", "config/bootstrap.yml" ]
|
||||
config:
|
||||
import:
|
||||
- optional:polaris
|
||||
- optional:polaris:test.yml
|
||||
- optional:polaris:configdataexample:test.yml
|
||||
- optional:polaris:config/bootstrap.yml
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include:
|
||||
- polaris-config
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.tsf.demo.consumer;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.tsf.annotation.EnableTsf;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableFeignClients // 使用Feign微服务调用时请启用
|
||||
@EnableTsf
|
||||
public class ConsumerApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ConsumerApplication.class, args);
|
||||
}
|
||||
|
||||
@LoadBalanced
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.tsf.demo.consumer.controller;
|
||||
|
||||
import com.tencent.cloud.tsf.demo.consumer.proxy.ProviderDemoService;
|
||||
import com.tencent.cloud.tsf.demo.consumer.proxy.ProviderService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@RestController
|
||||
public class ConsumerController {
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
@Autowired
|
||||
private ProviderService providerService;
|
||||
@Autowired
|
||||
private ProviderDemoService providerDemoService;
|
||||
|
||||
@RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
|
||||
public String restProvider(@PathVariable String str) {
|
||||
return restTemplate.getForObject("http://provider-demo/echo/" + str, String.class);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
|
||||
public String feignProvider(@PathVariable String str) {
|
||||
return providerDemoService.echo(str);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/echo-feign-url/{str}", method = RequestMethod.GET)
|
||||
public String feignUrlProvider(@PathVariable String str) {
|
||||
return providerService.echo(str);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.tsf.demo.consumer.entity;
|
||||
|
||||
/**
|
||||
* 用户自定义 Metadata.
|
||||
*/
|
||||
public class CustomMetadata {
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public CustomMetadata(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.tsf.demo.consumer.proxy;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@FeignClient(name = "provider-demo")
|
||||
public interface ProviderDemoService {
|
||||
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
|
||||
String echo(@PathVariable("str") String str);
|
||||
|
||||
@RequestMapping(value = "/echo/error/{str}", method = RequestMethod.GET)
|
||||
String echoError(@PathVariable("str") String str);
|
||||
|
||||
@RequestMapping(value = "/echo/slow/{str}", method = RequestMethod.GET)
|
||||
String echoSlow(@PathVariable("str") String str, @RequestParam("delay") int delay);
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
server:
|
||||
port: 18083
|
||||
spring:
|
||||
application:
|
||||
name: consumer-demo
|
||||
config:
|
||||
import: optional:polaris
|
||||
|
||||
feign:
|
||||
tsf:
|
||||
enabled: true
|
||||
|
||||
#本地测试时打开
|
||||
#tsf_namespace_id: default_namespace
|
||||
|
||||
logging:
|
||||
file:
|
||||
name: /tsf-demo-logs/${spring.application.name}/root.log
|
||||
level:
|
||||
root: INFO
|
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<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 https://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>tsf-example</artifactId>
|
||||
<name>Spring Cloud Tencent TSF Examples</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>provider-demo</module>
|
||||
<module>consumer-demo</module>
|
||||
</modules>
|
||||
</project>
|
@ -0,0 +1,54 @@
|
||||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>tsf-example</artifactId>
|
||||
<groupId>com.tencent.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>provider-demo</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.tencent.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-tencent-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</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>
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.tsf.demo.provider.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "provider.config")
|
||||
public class ProviderNameConfig {
|
||||
private String name = "echo-provider-default-name";
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.tsf.demo.provider.config;
|
||||
|
||||
import com.tencent.tsf.consul.config.watch.ConfigChangeCallback;
|
||||
import com.tencent.tsf.consul.config.watch.ConfigChangeListener;
|
||||
import com.tencent.tsf.consul.config.watch.ConfigProperty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigChangeListener(prefix = "provider.config", value = {"name"})
|
||||
public class ProviderNameConfigChangeListener implements ConfigChangeCallback {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ProviderNameConfigChangeListener.class);
|
||||
|
||||
@Override
|
||||
public void callback(ConfigProperty lastConfigProperty, ConfigProperty newConfigProperty) {
|
||||
log.info("[TSF SDK] Configuration Change Listener: key: {}, old value: {}, new value: {}",
|
||||
lastConfigProperty.getKey(), lastConfigProperty.getValue(), newConfigProperty.getValue());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.tsf.demo.provider.swagger.model;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "消息投递箱")
|
||||
public class MessageBox {
|
||||
|
||||
@Schema(title = "默认失效天数", required = false)
|
||||
private int expiredDays;
|
||||
|
||||
@Schema(title = "最大失效天数", required = false)
|
||||
private Integer maxExpiredDays;
|
||||
|
||||
@Schema(title = "容量大小", required = false)
|
||||
private Float capacity;
|
||||
|
||||
@Schema(title = "最大容量大小", required = false)
|
||||
private float maxCapacity;
|
||||
|
||||
@Schema(title = "接受的信息数量", required = false)
|
||||
private Double size;
|
||||
|
||||
@Schema(title = "最大接受的信息数量", required = false)
|
||||
private double maxSize;
|
||||
|
||||
@Schema(title = "消息(循环测试嵌套对象)", required = false)
|
||||
private MessageModel messageModel;
|
||||
|
||||
public int getExpiredDays() {
|
||||
return expiredDays;
|
||||
}
|
||||
|
||||
public void setExpiredDays(int expiredDays) {
|
||||
this.expiredDays = expiredDays;
|
||||
}
|
||||
|
||||
public Integer getMaxExpiredDays() {
|
||||
return maxExpiredDays;
|
||||
}
|
||||
|
||||
public void setMaxExpiredDays(Integer maxExpiredDays) {
|
||||
this.maxExpiredDays = maxExpiredDays;
|
||||
}
|
||||
|
||||
public Float getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public void setCapacity(Float capacity) {
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public float getMaxCapacity() {
|
||||
return maxCapacity;
|
||||
}
|
||||
|
||||
public void setMaxCapacity(float maxCapacity) {
|
||||
this.maxCapacity = maxCapacity;
|
||||
}
|
||||
|
||||
public Double getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Double size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public double getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
public void setMaxSize(double maxSize) {
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
public MessageModel getMessageModel() {
|
||||
return messageModel;
|
||||
}
|
||||
|
||||
public void setMessageModel(MessageModel messageModel) {
|
||||
this.messageModel = messageModel;
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.tsf.demo.provider.swagger.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "消息", title = "messageModel")
|
||||
public class MessageModel {
|
||||
|
||||
@Schema(name = "id", title = "消息ID", required = true, description = "消息ID notes")
|
||||
private String msgId;
|
||||
|
||||
@Schema(title = "消息内容", required = false)
|
||||
private String msgContent;
|
||||
|
||||
@Schema(title = "消息发送者", required = true)
|
||||
private MessageUser sendUser;
|
||||
|
||||
@Schema(title = "消息接收者", required = true)
|
||||
private List<MessageUser> receiveUsers;
|
||||
|
||||
@Schema(title = "消息发送时间", required = true)
|
||||
private long sendTime;
|
||||
|
||||
@Schema(title = "消息投递箱", required = false)
|
||||
private MessageBox messageBox;
|
||||
|
||||
public String getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public void setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
}
|
||||
|
||||
public String getMsgContent() {
|
||||
return msgContent;
|
||||
}
|
||||
|
||||
public void setMsgContent(String msgContent) {
|
||||
this.msgContent = msgContent;
|
||||
}
|
||||
|
||||
public MessageUser getSendUser() {
|
||||
return sendUser;
|
||||
}
|
||||
|
||||
public void setSendUser(MessageUser sendUser) {
|
||||
this.sendUser = sendUser;
|
||||
}
|
||||
|
||||
public List<MessageUser> getReceiveUsers() {
|
||||
return receiveUsers;
|
||||
}
|
||||
|
||||
public void setReceiveUsers(List<MessageUser> receiveUsers) {
|
||||
this.receiveUsers = receiveUsers;
|
||||
}
|
||||
|
||||
public long getSendTime() {
|
||||
return sendTime;
|
||||
}
|
||||
|
||||
public void setSendTime(long sendTime) {
|
||||
this.sendTime = sendTime;
|
||||
}
|
||||
|
||||
public MessageBox getMessageBox() {
|
||||
return messageBox;
|
||||
}
|
||||
|
||||
public void setMessageBox(MessageBox messageBox) {
|
||||
this.messageBox = messageBox;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.tsf.demo.provider.swagger.model;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "消息发送/接收者")
|
||||
public class MessageUser {
|
||||
|
||||
@Schema(title = "用户姓名", name = "name")
|
||||
private String name;
|
||||
|
||||
@Schema(title = "邮箱地址")
|
||||
private String email;
|
||||
|
||||
@Schema(title = "电话号码")
|
||||
private String phoneNum;
|
||||
|
||||
@Schema(title = "办公地址")
|
||||
private String officeAddress;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhoneNum() {
|
||||
return phoneNum;
|
||||
}
|
||||
|
||||
public void setPhoneNum(String phoneNum) {
|
||||
this.phoneNum = phoneNum;
|
||||
}
|
||||
|
||||
public String getOfficeAddress() {
|
||||
return officeAddress;
|
||||
}
|
||||
|
||||
public void setOfficeAddress(String officeAddress) {
|
||||
this.officeAddress = officeAddress;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
server:
|
||||
port: 18081
|
||||
spring:
|
||||
application:
|
||||
name: provider-demo
|
||||
config:
|
||||
import: optional:polaris
|
||||
cloud:
|
||||
polaris:
|
||||
namespace: default
|
||||
enabled: true
|
||||
stat:
|
||||
enabled: true
|
||||
port: 28081
|
||||
loadbalancer:
|
||||
strategy: polarisWeightedRandom
|
||||
tencent:
|
||||
rpc-enhancement:
|
||||
reporter:
|
||||
enabled: true
|
||||
|
||||
logging:
|
||||
file:
|
||||
name: /tsf-demo-logs/${spring.application.name}/root.log
|
||||
level:
|
||||
root: INFO
|
@ -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.context.tsf;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.tencent.polaris.api.utils.StringUtils;
|
||||
|
||||
import org.springframework.context.annotation.Condition;
|
||||
import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
|
||||
/**
|
||||
* Condition that if Polaris enabled.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Conditional(ConditionalOnTsfEnabled.OnTsfEnabledCondition.class)
|
||||
public @interface ConditionalOnTsfEnabled {
|
||||
|
||||
class OnTsfEnabledCondition implements Condition {
|
||||
|
||||
@Override
|
||||
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
|
||||
String tsfAppId = conditionContext.getEnvironment().getProperty("tsf_app_id", "");
|
||||
return StringUtils.isNotBlank(tsfAppId);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.context.tsf.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Core properties.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@ConfigurationProperties("tsf")
|
||||
public class TsfCoreProperties {
|
||||
|
||||
@Value("${tse_polaris_ip:}")
|
||||
private String tsePolarisIp = "";
|
||||
|
||||
@Value("${tsf_consul_enable:false}")
|
||||
private boolean tsfConsulEnable = false;
|
||||
|
||||
@Value("${tse_polaris_enable:false}")
|
||||
private boolean tsePolarisEnable = false;
|
||||
|
||||
public String getTsePolarisIp() {
|
||||
return tsePolarisIp;
|
||||
}
|
||||
|
||||
public void setTsePolarisIp(String tsePolarisIp) {
|
||||
this.tsePolarisIp = tsePolarisIp;
|
||||
}
|
||||
|
||||
public boolean isTsfConsulEnable() {
|
||||
return tsfConsulEnable;
|
||||
}
|
||||
|
||||
public void setTsfConsulEnable(boolean tsfConsulEnable) {
|
||||
this.tsfConsulEnable = tsfConsulEnable;
|
||||
}
|
||||
|
||||
public boolean isTsePolarisEnable() {
|
||||
return tsePolarisEnable;
|
||||
}
|
||||
|
||||
public void setTsePolarisEnable(boolean tsePolarisEnable) {
|
||||
this.tsePolarisEnable = tsePolarisEnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TsfCoreProperties{" +
|
||||
"tsePolarisIp='" + tsePolarisIp + '\'' +
|
||||
", tsfConsulEnable=" + tsfConsulEnable +
|
||||
", tsePolarisEnable=" + tsePolarisEnable +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.context.tsf.config;
|
||||
|
||||
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
|
||||
import com.tencent.cloud.polaris.context.tsf.ConditionalOnTsfEnabled;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Core properties auto configuration.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@AutoConfigureAfter(PolarisContextAutoConfiguration.class)
|
||||
@ConditionalOnTsfEnabled
|
||||
public class TsfCorePropertiesAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TsfCoreProperties tsfCoreProperties() {
|
||||
return new TsfCoreProperties();
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.context.tsf.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Core properties bootstrap configuration.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(TsfCorePropertiesAutoConfiguration.class)
|
||||
public class TsfCorePropertiesBootstrapConfiguration {
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.context.tsf.consul;
|
||||
|
||||
import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({PolarisContextAutoConfiguration.class, TsfConsulAutoConfiguration.class})
|
||||
public class TsfConsulBootstrapConfiguration {
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.context.tsf.consul;
|
||||
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Validated
|
||||
public class TsfConsulProperties {
|
||||
|
||||
/** Consul agent hostname. Defaults to '127.0.0.1'. */
|
||||
@Value("${tsf_consul_ip:${spring.cloud.consul.host:${SPRING_CLOUD_CONSUL_HOST:localhost}}}")
|
||||
@NotNull
|
||||
private String host = "localhost";
|
||||
|
||||
/**
|
||||
* Consul agent scheme (HTTP/HTTPS). If there is no scheme in address - client
|
||||
* will use HTTP.
|
||||
*/
|
||||
@Value("${spring.cloud.consul.scheme:${SPRING_CLOUD_CONSUL_SCHEME:}}")
|
||||
private String scheme;
|
||||
|
||||
/** Consul agent port. Defaults to '8500'. */
|
||||
@Value("${tsf_consul_port:${spring.cloud.consul.port:${SPRING_CLOUD_CONSUL_PORT:8500}}}")
|
||||
@NotNull
|
||||
private int port = 8500;
|
||||
|
||||
/** Is spring cloud consul enabled. */
|
||||
@Value("${spring.cloud.consul.enabled:${SPRING_CLOUD_CONSUL_ENABLED:true}}")
|
||||
private boolean enabled = true;
|
||||
|
||||
@Value("${tsf_consul_ttl_read_timeout:5000}")
|
||||
private int ttlReadTimeout = 5000; // default 5s
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public void setScheme(String scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
public int getTtlReadTimeout() {
|
||||
return ttlReadTimeout;
|
||||
}
|
||||
|
||||
public void setTtlReadTimeout(int ttlReadTimeout) {
|
||||
this.ttlReadTimeout = ttlReadTimeout;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConsulProperties{" +
|
||||
"host='" + host + '\'' +
|
||||
", scheme='" + scheme + '\'' +
|
||||
", port=" + port +
|
||||
", enabled=" + enabled +
|
||||
", ttlReadTimeout=" + ttlReadTimeout +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.context.tsf.env;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.tencent.polaris.api.utils.StringUtils;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
/**
|
||||
* Read TSF env.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class TsfCoreEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||
|
||||
/**
|
||||
* run before {@link ConfigDataEnvironmentPostProcessor}.
|
||||
*/
|
||||
public static final int ORDER = ConfigDataEnvironmentPostProcessor.ORDER - 1;
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
String tsfAppId = environment.getProperty("tsf_app_id");
|
||||
if (StringUtils.isNotBlank(tsfAppId)) {
|
||||
Map<String, Object> defaultProperties = new HashMap<>();
|
||||
|
||||
// TODO 接入consul配置后需要改动这个选项的判断
|
||||
// tse_polaris_enable
|
||||
defaultProperties.put("spring.cloud.polaris.config.enabled", environment.getProperty("tse_polaris_enable", "false"));
|
||||
|
||||
// tse_polaris_ip
|
||||
defaultProperties.put("spring.cloud.polaris.address", "grpc://" + environment.getProperty("tse_polaris_ip", "") + ":8091");
|
||||
|
||||
// tse_polaris_ip
|
||||
defaultProperties.put("spring.cloud.polaris.stat.port", environment.getProperty("tsf_sctt_extensions_port", "11134"));
|
||||
|
||||
MapPropertySource propertySource = new MapPropertySource("tsf-polaris-properties", defaultProperties);
|
||||
environment.getPropertySources().addFirst(propertySource);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 org.springframework.tsf.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* Compatible with old versions TSF SDK.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@EnableAutoConfiguration
|
||||
@EnableDiscoveryClient // 服务注册发现
|
||||
@EnableConfigurationProperties // 分布式配置
|
||||
public @interface EnableTsf {
|
||||
}
|
@ -1,4 +1,8 @@
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
com.tencent.cloud.polaris.context.config.PolarisContextBootstrapAutoConfiguration
|
||||
com.tencent.cloud.polaris.context.config.PolarisContextBootstrapAutoConfiguration,\
|
||||
com.tencent.cloud.polaris.context.tsf.config.TsfCorePropertiesBootstrapConfiguration,\
|
||||
com.tencent.cloud.polaris.context.tsf.consul.TsfConsulBootstrapConfiguration
|
||||
org.springframework.context.ApplicationListener=\
|
||||
com.tencent.cloud.polaris.context.logging.PolarisLoggingApplicationListener
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=\
|
||||
com.tencent.cloud.polaris.context.tsf.env.TsfCoreEnvironmentPostProcessor
|
||||
|
@ -1,2 +1,4 @@
|
||||
com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration
|
||||
com.tencent.cloud.polaris.context.config.PolarisContextPostConfiguration
|
||||
com.tencent.cloud.polaris.context.tsf.config.TsfCorePropertiesAutoConfiguration
|
||||
com.tencent.cloud.polaris.context.tsf.consul.TsfConsulAutoConfiguration
|
||||
|
Loading…
Reference in new issue