mirror of
https://gitee.com/dromara/Raincat.git
synced 2024-12-03 12:29:08 +08:00
调用注册中心获取应用列表
This commit is contained in:
parent
5c93aac62f
commit
1b8856bf11
@ -0,0 +1,28 @@
|
||||
package com.raincat.admin.service.apps;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chaoshen
|
||||
* @date 2018/7/6
|
||||
* @description
|
||||
*/
|
||||
@Component
|
||||
public class AcceptApplicationNameExecutor {
|
||||
|
||||
@Autowired
|
||||
AcceptApplicationNameFactory acceptApplicationNameFactory;
|
||||
|
||||
/**
|
||||
* 执行任务
|
||||
*
|
||||
* @param apps
|
||||
*/
|
||||
public void execute(List<String> apps) {
|
||||
List<AcceptApplicationNameService> services = acceptApplicationNameFactory.getBeans();
|
||||
services.forEach(service -> service.acceptAppNameList(apps));
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package com.raincat.admin.service.apps;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.raincat.admin.service.apps.enums.AcceptApplicationNameEnum;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 客户端从注册中心获取应用名称-工厂类
|
||||
*
|
||||
* @author chaoshen
|
||||
* @date 2018/7/6
|
||||
* @description
|
||||
*/
|
||||
@Component
|
||||
public class AcceptApplicationNameFactory implements ApplicationContextAware {
|
||||
|
||||
//@Value("${accept.apps.server.type}")
|
||||
private String acceptType;
|
||||
|
||||
private static AppsType types;
|
||||
|
||||
|
||||
private static Map<AcceptApplicationNameEnum, AcceptApplicationNameService> beanMap;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
Map<String, AcceptApplicationNameService> map = applicationContext.getBeansOfType(AcceptApplicationNameService.class);
|
||||
beanMap = new HashMap<>();
|
||||
map.forEach((k, v) -> beanMap.put(v.code(), v));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据不同的类型获取bean
|
||||
*
|
||||
* @param code
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public <T extends AcceptApplicationNameService> T getBean(AcceptApplicationNameEnum code) {
|
||||
return (T) beanMap.get(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置文件来获取bean
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public <T extends AcceptApplicationNameService> T getBean(String code) {
|
||||
return getBean(AcceptApplicationNameEnum.getAcceptApplicationNameEnum(code));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据单一配置文件来获取bean
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public <T extends AcceptApplicationNameService> T getBean() {
|
||||
return getBean(acceptType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置文件来获取beans
|
||||
* accept.apps.server.type=eureka,dubbo...
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public List getBeans0() {
|
||||
return Arrays.asList(acceptType.split(","))
|
||||
.stream()
|
||||
.distinct()
|
||||
.map(v -> getBean(v))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置文件来获取beans
|
||||
* accept.apps.server.type[0]=eureka
|
||||
* ...
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public List getBeans() {
|
||||
return types.getType()
|
||||
.stream()
|
||||
.distinct()
|
||||
.map(v -> getBean(v))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@EnableConfigurationProperties
|
||||
@ConfigurationProperties(prefix = "accept.apps.server")
|
||||
public static class AppsType {
|
||||
|
||||
private List<AcceptApplicationNameEnum> type;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
types = this;
|
||||
}
|
||||
|
||||
public AppsType() {
|
||||
this.type = Lists.newArrayList();
|
||||
}
|
||||
|
||||
public List<AcceptApplicationNameEnum> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(List<AcceptApplicationNameEnum> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.raincat.admin.service.apps;
|
||||
|
||||
import com.raincat.admin.service.apps.enums.AcceptApplicationNameEnum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chaoshen
|
||||
* @date 2018/7/5
|
||||
* @description 从注册中心获取参与分布式事务应用名称列表
|
||||
*/
|
||||
public interface AcceptApplicationNameService {
|
||||
|
||||
String APP_URL = "/apps";
|
||||
|
||||
/***
|
||||
* 获取注册中心所有应用列表
|
||||
* @param apps 已有的应用列表
|
||||
* @return 去重后的注册中心应用列表
|
||||
*/
|
||||
<T> List<T> acceptAppNameList(List<T> apps);
|
||||
|
||||
/**
|
||||
* 注册中心方式
|
||||
*
|
||||
* @return 注册中心枚举类
|
||||
*/
|
||||
AcceptApplicationNameEnum code();
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.raincat.admin.service.apps.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author chaoshen
|
||||
* @date 2018/7/5
|
||||
* @description
|
||||
*/
|
||||
public enum AcceptApplicationNameEnum {
|
||||
EUREKA("eureka"),
|
||||
ZOOKEEPER("zookeeper"),
|
||||
DUBBO("dubbo"),
|
||||
UNACCEPT("no");
|
||||
|
||||
@Getter
|
||||
private String name;
|
||||
|
||||
AcceptApplicationNameEnum(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static AcceptApplicationNameEnum getAcceptApplicationNameEnum(String name) {
|
||||
for (AcceptApplicationNameEnum acceptApplicationNameEnum : AcceptApplicationNameEnum.values()) {
|
||||
if (acceptApplicationNameEnum.name.equals(name)) {
|
||||
return acceptApplicationNameEnum;
|
||||
}
|
||||
}
|
||||
return UNACCEPT;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.raincat.admin.service.apps.impl;
|
||||
|
||||
import com.raincat.admin.service.apps.AcceptApplicationNameService;
|
||||
import com.raincat.admin.service.apps.enums.AcceptApplicationNameEnum;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chaoshen
|
||||
* @date 2018/7/6
|
||||
* @description
|
||||
*/
|
||||
@Service
|
||||
public class AcceptDefaultApplicationNameService implements AcceptApplicationNameService {
|
||||
|
||||
@Override
|
||||
public <T> List<T> acceptAppNameList(List<T> apps) {
|
||||
return apps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AcceptApplicationNameEnum code() {
|
||||
return AcceptApplicationNameEnum.UNACCEPT;
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package com.raincat.admin.service.apps.impl;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.raincat.admin.service.apps.AcceptApplicationNameService;
|
||||
import com.raincat.admin.service.apps.enums.AcceptApplicationNameEnum;
|
||||
import com.raincat.common.holder.httpclient.OkHttpTools;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.Request;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author chaoshen
|
||||
* @date 2018/7/5
|
||||
* @description
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AcceptEurekaApplicationNameService implements AcceptApplicationNameService {
|
||||
|
||||
@Value("${accept.apps.eureka.url}")
|
||||
private String eurekaServerUrl;
|
||||
|
||||
@Value("${accept.apps.eureka.intervalTime}")
|
||||
private String appIntervalTime;
|
||||
|
||||
private static volatile ConcurrentHashMap<String, Object> CACHE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
private static String UPDATE_TIME_KEY = "ADMIN_UPDATE_TIME";
|
||||
|
||||
|
||||
@Override
|
||||
public <T> List<T> acceptAppNameList(List<T> apps) {
|
||||
Object updateTime = CACHE_MAP.get(UPDATE_TIME_KEY);
|
||||
if (updateTime == null) {
|
||||
//CACHE_MAP.clear();
|
||||
log.info("首次加入 [参与分布式事务项目的应用名称] 缓存数据!");
|
||||
getEurekaAppList().stream().forEach(appName -> CACHE_MAP.put(appName, appName));
|
||||
} else {
|
||||
long dValue = System.currentTimeMillis() - (Long) updateTime;
|
||||
if (dValue > Long.valueOf(appIntervalTime) * 1000) {
|
||||
//若在eureka里能获取到应用信息,说明已经用到分布式事务,所以不用删除旧的缓存数据?
|
||||
//CACHE_MAP.clear();
|
||||
log.info("刷新 [参与分布式事务项目的应用名称] 缓存数据!");
|
||||
getEurekaAppList().stream().forEach(appName -> CACHE_MAP.put(appName, appName));
|
||||
}
|
||||
}
|
||||
CACHE_MAP.forEach((s, o) -> {
|
||||
if (!UPDATE_TIME_KEY.equals(s) && !apps.contains(s)) {
|
||||
apps.add((T) s);
|
||||
}
|
||||
});
|
||||
return apps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AcceptApplicationNameEnum code() {
|
||||
return AcceptApplicationNameEnum.EUREKA;
|
||||
}
|
||||
|
||||
private Set<String> getEurekaAppList() {
|
||||
Set<String> set = Sets.newHashSet();
|
||||
try {
|
||||
JsonObject response = OkHttpTools.getInstance().execute(buildRequest(eurekaServerUrl + APP_URL), JsonObject.class);
|
||||
log.debug("Eureka server response: [{}]", response);
|
||||
if (response == null) {
|
||||
return set;
|
||||
}
|
||||
JsonArray jsonArray = response.getAsJsonObject("applications").getAsJsonArray("application");
|
||||
if (jsonArray != null) {
|
||||
jsonArray.forEach(jsonObject -> {
|
||||
JsonObject application = jsonObject.getAsJsonObject();
|
||||
//每个实例信息
|
||||
application.getAsJsonArray("instance").forEach(jsonObj -> {
|
||||
JsonObject instance = jsonObj.getAsJsonObject();
|
||||
//是否使用tx
|
||||
JsonElement jsonElement = instance.getAsJsonObject("metadata").get("tx-metadata");
|
||||
Optional<String> optional = Optional
|
||||
.ofNullable(jsonElement)
|
||||
.map(r -> jsonElement.getAsBoolean() ? "true" : null);
|
||||
optional.ifPresent(r -> set.add(instance.get("app").getAsString().toLowerCase()));
|
||||
});
|
||||
});
|
||||
}
|
||||
CACHE_MAP.put(UPDATE_TIME_KEY, System.currentTimeMillis());
|
||||
} catch (IOException e) {
|
||||
log.error("Eureka server response analysis error!", e);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
private static Request buildRequest(String url) {
|
||||
return new Request.Builder()
|
||||
.url(url)
|
||||
.addHeader("Content-Type", "application/json")
|
||||
.addHeader("Accept", "application/json")
|
||||
//.addHeader("Authorization", Credentials.basic("user", "password"))
|
||||
.build();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user