nacos加入到项目当中

This commit is contained in:
dengqichen 2024-08-22 15:30:55 +08:00
parent c4838bb415
commit 016280fe4d
35 changed files with 712 additions and 335 deletions

2
.gitignore vendored
View File

@ -27,3 +27,5 @@ hs_err_pid*
/bin/nacos-server-2.3.0/data/protocol/raft/*/log/ /bin/nacos-server-2.3.0/data/protocol/raft/*/log/
/bin/nacos/nacos-server-2.3.0/logs/ /bin/nacos/nacos-server-2.3.0/logs/
/bin/nacos/nacos-server-2.3.0/data/protocol/raft/*/log/ /bin/nacos/nacos-server-2.3.0/data/protocol/raft/*/log/
/*/target/generated-sources/annotations/*
/.idea/*

View File

@ -1,40 +0,0 @@
package com.qc.soft.framework.basic.redis;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.Filter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Redis使用FastJson序列化
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter("com");
@Override
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, Object.class, AUTO_TYPE_FILTER);
}
}

View File

@ -9,8 +9,8 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration //@Configuration
@ConditionalOnProperty(name = "spring.redis.host", havingValue = "true") //@ConditionalOnProperty(name = "spring.redis", havingValue = "true")
@Slf4j @Slf4j
public class RedisAutoConfiguration { public class RedisAutoConfiguration {
@ -18,18 +18,43 @@ public class RedisAutoConfiguration {
log.info("Framework redis template registered successfully!!!"); log.info("Framework redis template registered successfully!!!");
} }
@Bean // @Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>(); // RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory); // template.setConnectionFactory(redisConnectionFactory);
FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(); // FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>();
template.setDefaultSerializer(serializer); // template.setDefaultSerializer(new StringRedisSerializer());
template.setValueSerializer(serializer); // template.setValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer()); // template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer()); // template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer); // template.setHashValueSerializer(serializer);
template.afterPropertiesSet(); // template.afterPropertiesSet();
return template; // return template;
return new RedisTemplate<>();
} }
// @Bean
// public DefaultRedisScript<Long> limitScript()
// {
// DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
// redisScript.setScriptText(limitScriptText());
// redisScript.setResultType(Long.class);
// return redisScript;
// }
//
// private String limitScriptText()
// {
// return "local key = KEYS[1]\n" +
// "local count = tonumber(ARGV[1])\n" +
// "local time = tonumber(ARGV[2])\n" +
// "local current = redis.call('get', key);\n" +
// "if current and tonumber(current) > count then\n" +
// " return tonumber(current);\n" +
// "end\n" +
// "current = redis.call('incr', key)\n" +
// "if tonumber(current) == 1 then\n" +
// " redis.call('expire', key, time)\n" +
// "end\n" +
// "return tonumber(current);";
// }
} }

View File

@ -9,12 +9,14 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootConfiguration @SpringBootConfiguration
@EnableAutoConfiguration @EnableAutoConfiguration
@ComponentScan("com.qc.soft.deploy.ease.*") @ComponentScan("com.qc.soft.deploy.ease.*")
@EnableFeignClients @EnableFeignClients
@EnableDiscoveryClient @EnableDiscoveryClient
@EnableScheduling
public class DeployEaseTenantAdapterApplication { public class DeployEaseTenantAdapterApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -1,10 +1,7 @@
package com.qc.soft.deploy.ease.adapter; package com.qc.soft.deploy.ease.adapter;
import com.qc.soft.deploy.ease.adapter.config.AppConfig;
import com.qc.soft.framework.basic.context.ApplicationContextProvider; import com.qc.soft.framework.basic.context.ApplicationContextProvider;
import com.qc.soft.framework.basic.context.SpringContext;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;

View File

@ -0,0 +1,18 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
public abstract class IJenkinsDataProvider {
public abstract ThirdPartyJenkinsResponse views();
public abstract ThirdPartyJenkinsViewDetailResponse viewDetail(String viewName);
public abstract ThirdPartyJenkinsJobDetailResponse job(String viewName, String jobName);
public abstract ThirdPartyJenkinsBuildResponse build(String viewName, String jobName, Long buildNumber);
}

View File

@ -0,0 +1,67 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.Optional;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_BUILD;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL;
@Component
@Slf4j
public class JenkinsBusinessProvider {
@Resource
private JenkinsRealTimeDataProvider realTimeDataProvider;
@Resource
private JenkinsCacheDataProvider cacheDataProvider;
@Resource
private RedisTemplate<String, Object> redisTemplate;
public ThirdPartyJenkinsResponse views() {
ThirdPartyJenkinsResponse redisValue = cacheDataProvider.views();
if (redisValue == null) {
return realTimeDataProvider.views();
}
return redisValue;
}
public ThirdPartyJenkinsViewDetailResponse viewDetail(String viewName) {
ThirdPartyJenkinsViewDetailResponse redisValue = cacheDataProvider.viewDetail(viewName);
if (redisValue == null) {
return realTimeDataProvider.viewDetail(viewName);
}
return redisValue;
}
public ThirdPartyJenkinsJobDetailResponse job(String viewName, String jobName) {
ThirdPartyJenkinsJobDetailResponse redisValue = cacheDataProvider.job(viewName, jobName);
if (redisValue == null) {
return realTimeDataProvider.job(viewName, jobName);
}
return redisValue;
}
public ThirdPartyJenkinsBuildResponse build(String viewName, String jobName, Long buildNumber) {
ThirdPartyJenkinsBuildResponse redisValue = cacheDataProvider.build(viewName, jobName, buildNumber);
if (redisValue == null) {
return realTimeDataProvider.build(viewName, jobName, buildNumber);
}
return redisValue;
}
}

View File

@ -0,0 +1,44 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_BUILD;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL;
@Component
@Slf4j
public class JenkinsCacheDataProvider extends IJenkinsDataProvider {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
public ThirdPartyJenkinsResponse views() {
return (ThirdPartyJenkinsResponse) redisTemplate.opsForValue().get(REDIS_JENKINS_ORIGINAL_VIEW);
}
@Override
public ThirdPartyJenkinsViewDetailResponse viewDetail(String viewName) {
return (ThirdPartyJenkinsViewDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB, viewName));
}
@Override
public ThirdPartyJenkinsJobDetailResponse job(String viewName, String jobName) {
return (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewName, jobName));
}
@Override
public ThirdPartyJenkinsBuildResponse build(String viewName, String jobName, Long buildNumber) {
return (ThirdPartyJenkinsBuildResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_BUILD, viewName, jobName, buildNumber));
}
}

View File

@ -1,106 +0,0 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import com.alibaba.fastjson2.JSON;
import com.qc.soft.deploy.ease.adapter.HttpClient;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.ThirdPartyJenkinsCrumbResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants;
import com.qc.soft.deploy.ease.adapter.enums.BusinessState;
import com.qc.soft.framework.basic.exception.BasicException;
import com.qc.soft.framework.basic.exception.BusinessException;
import com.qc.soft.framework.basic.utils.Base64AuthUtils;
import com.qc.soft.framework.basic.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.IdentityHashMap;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_BUILD;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL;
@Component
@Slf4j
public class JenkinsClientApi {
@Resource
private RedisTemplate<String, Object> redisTemplate;
public ThirdPartyJenkinsCrumbResponse getJenkinsCrumb(String url, String username, String password) throws BasicException {
IdentityHashMap<String, String> header = new IdentityHashMap<>();
header.put("Authorization", Base64AuthUtils.encode(username, password));
ThirdPartyJenkinsCrumbResponse thirdPartyJenkinsCrumbResponse = HttpUtils.cookieGet(url, header, ThirdPartyJenkinsCrumbResponse.class);
if (thirdPartyJenkinsCrumbResponse == null) {
log.error("Get jenkins crumb failed!");
throw new BusinessException(BusinessState.GET_JENKINS_CRUMB_FAILED);
}
if (StringUtils.isEmpty(thirdPartyJenkinsCrumbResponse.getCrumb()) || StringUtils.isEmpty(thirdPartyJenkinsCrumbResponse.getCookie())) {
log.error("Get jenkins crumb and cookie failed, response:{}!", JSON.toJSONString(thirdPartyJenkinsCrumbResponse));
throw new BusinessException(String.format("Get jenkins crumb and cookie failed, response %s!", JSON.toJSONString(thirdPartyJenkinsCrumbResponse)));
}
return thirdPartyJenkinsCrumbResponse;
}
public ThirdPartyJenkinsResponse getViews() {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", Base64AuthUtils.encode("admin", "3%(Lb5GN,M'Yk\\,)Dy\"*"));
ThirdPartyJenkinsResponse jenkins = HttpClient.get(String.format(JenkinsConstants.JENKINS_VIEWS_API, "http://192.168.2.200:9096"), headers, ThirdPartyJenkinsResponse.class);
redisTemplate.opsForValue().set(REDIS_JENKINS_ORIGINAL_VIEW, jenkins);
return (ThirdPartyJenkinsResponse) redisTemplate.opsForValue().get(REDIS_JENKINS_ORIGINAL_VIEW);
}
public ThirdPartyJenkinsViewDetailResponse jobs(String viewName) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", Base64AuthUtils.encode("admin", "3%(Lb5GN,M'Yk\\,)Dy\"*"));
String urlFormat = StringUtils.isEmpty(viewName) ?
String.format(JenkinsConstants.JENKINS_JOB_ALL_API, "http://192.168.2.200:9096") : String.format(JenkinsConstants.JENKINS_JOB_API, "http://192.168.2.200:9096", viewName);
try {
String redisKey = String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB, viewName);
ThirdPartyJenkinsViewDetailResponse jenkinsViewDetail = HttpClient.get(urlFormat, headers, ThirdPartyJenkinsViewDetailResponse.class);
redisTemplate.opsForValue().set(redisKey, jenkinsViewDetail);
return (ThirdPartyJenkinsViewDetailResponse) redisTemplate.opsForValue().get(redisKey);
} catch (Exception e) {
log.error("Get jenkins projects failed, url:{}", urlFormat, e);
return new ThirdPartyJenkinsViewDetailResponse();
}
}
public ThirdPartyJenkinsJobDetailResponse jobDetail(String viewName, String jobName) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", Base64AuthUtils.encode("admin", "3%(Lb5GN,M'Yk\\,)Dy\"*"));
String urlFormat = String.format(JenkinsConstants.JENKINS_JOB_DETAIL_API, "http://192.168.2.200:9096", viewName, jobName);
try {
String redisKey = String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewName, jobName);
ThirdPartyJenkinsJobDetailResponse jenkinsJobDetail = HttpClient.get(urlFormat, headers, ThirdPartyJenkinsJobDetailResponse.class);
redisTemplate.opsForValue().set(redisKey, jenkinsJobDetail);
return (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(redisKey);
} catch (Exception e) {
log.error("Get jenkins job detail failed, url:{}", urlFormat, e);
return new ThirdPartyJenkinsJobDetailResponse();
}
}
public ThirdPartyJenkinsBuildResponse jobBuild(String viewName, String jobName, Long buildNumber) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", Base64AuthUtils.encode("admin", "3%(Lb5GN,M'Yk\\,)Dy\"*"));
String urlFormat = String.format(JenkinsConstants.JENKINS_BUILD_API, "http://192.168.2.200:9096", viewName, jobName, buildNumber);
try {
String redisKey = String.format(REDIS_JENKINS_ORIGINAL_VIEW_BUILD, viewName, jobName, buildNumber);
ThirdPartyJenkinsBuildResponse jenkinsBuild = HttpClient.get(urlFormat, headers, ThirdPartyJenkinsBuildResponse.class);
redisTemplate.opsForValue().set(redisKey, jenkinsBuild);
return (ThirdPartyJenkinsBuildResponse) redisTemplate.opsForValue().get(redisKey);
} catch (Exception e) {
log.error("Get jenkins job build failed, url:{}", urlFormat, e);
return new ThirdPartyJenkinsBuildResponse();
}
}
}

View File

@ -0,0 +1,178 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import cn.hutool.core.lang.func.VoidFunc0;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewResponse;
import com.qc.soft.deploy.ease.adapter.convert.JenkinsBuildConvert;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_BUILD;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL;
@Component
@Slf4j
public class JenkinsDataCacheSynchronizer {
@Resource
private JenkinsRealTimeDataProvider realTimeDataProvider;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Scheduled(cron = "0 */30 * * * ?")
public void views() {
ThirdPartyJenkinsResponse redisValue = (ThirdPartyJenkinsResponse) redisTemplate.opsForValue().get(REDIS_JENKINS_ORIGINAL_VIEW);
if (redisValue == null) {
log.info("There is no view data in the cache and will be synchronized");
redisTemplate.opsForValue().set(REDIS_JENKINS_ORIGINAL_VIEW, realTimeDataProvider.views());
return;
}
ThirdPartyJenkinsResponse views = realTimeDataProvider.views();
if (views.hashCode() == redisValue.hashCode()) {
return;
}
log.info("The view data is not consistent with interface, will be updated");
redisTemplate.opsForValue().set(REDIS_JENKINS_ORIGINAL_VIEW, views);
}
@Scheduled(cron = "0 */10 * * * ?")
public void viewDetail() {
getCacheViews().forEach((view) -> {
val redisValue = (ThirdPartyJenkinsViewDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB, view.getName()));
if (redisValue == null) {
log.info("The view detail data was not found in the cache and will be inserted, viewName:{}", view.getName());
redisTemplate.opsForValue().set(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB, view.getName()), realTimeDataProvider.viewDetail(view.getName()));
return;
}
val jenkinsViewDetail = realTimeDataProvider.viewDetail(view.getName());
if (redisValue.hashCode() == jenkinsViewDetail.hashCode()) {
return;
}
log.info("The view detail data does not match the cache and will be updated, viewName:{}", view.getName());
redisTemplate.opsForValue().set(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB, view.getName()), jenkinsViewDetail);
});
}
@Scheduled(cron = "30 * * * * ?")
public void job() {
getCacheViewsDetail().forEach(viewDetail -> {
Optional.ofNullable(viewDetail.getJobs()).orElse(new ArrayList<>()).forEach(job -> {
AtomicBoolean needSyncBuild = new AtomicBoolean(false);
val redisValue = (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName()));
VoidFunc0 jobBusiness = () -> {
if (redisValue == null) {
log.info("The job data was not found in the cache and will be inserted, viewName:{}, jobName:{}", viewDetail.getName(), job.getName());
redisTemplate.opsForValue().set(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName()), realTimeDataProvider.job(viewDetail.getName(), job.getName()));
needSyncBuild.set(true);
return;
}
val jobDetail = realTimeDataProvider.job(viewDetail.getName(), job.getName());
if (redisValue.hashCode() == jobDetail.hashCode()) {
return;
}
log.info("The job data does not match the cache and will be updated, viewName:{}, jobName:{}", viewDetail.getName(), job.getName());
redisTemplate.opsForValue().set(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName()), realTimeDataProvider.job(viewDetail.getName(), job.getName()));
needSyncBuild.set(true);
};
try {
jobBusiness.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
if (needSyncBuild.get()) {
log.info("The job need to synchronize build data, viewName:{}, jobName:{}", viewDetail.getName(), job.getName());
buildSingleByJob(viewDetail.getName(), (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName())));
}
});
});
}
public void buildSingleByJob(String viewName, ThirdPartyJenkinsJobDetailResponse jobDetail) {
val jobBuilds = JenkinsBuildConvert.INSTANCE.aggregateJobBuildSimple(jobDetail);
jobBuilds.forEach(build -> {
Long buildNumber = build.getNumber();
ThirdPartyJenkinsBuildResponse redisValue = (ThirdPartyJenkinsBuildResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_BUILD, viewName, jobDetail.getName(), buildNumber));
if (redisValue == null) {
log.info("The build data was not found in the cache and will be inserted, viewName:{}, jobName:{}, buildNumber:{}", viewName, jobDetail.getName(), buildNumber);
redisTemplate.opsForValue().set(String.format(REDIS_JENKINS_ORIGINAL_VIEW_BUILD, viewName, jobDetail.getName(), buildNumber), realTimeDataProvider.build(viewName, jobDetail.getName(), buildNumber));
return;
}
ThirdPartyJenkinsBuildResponse jenkinsBuild = realTimeDataProvider.build(viewName, jobDetail.getName(), buildNumber);
if (jenkinsBuild.hashCode() == redisValue.hashCode()) {
return;
}
log.info("The build data does not match the cache and will be updated, viewName:{}, jobName:{}, buildNumber:{}", viewName, jobDetail.getName(), buildNumber);
redisTemplate.opsForValue().set(String.format(REDIS_JENKINS_ORIGINAL_VIEW_BUILD, viewName, jobDetail.getName(), buildNumber), realTimeDataProvider.build(viewName, jobDetail.getName(), buildNumber));
});
}
public void build() {
getCacheJobs().forEach(jobContainer -> {
String viewName = jobContainer.getLeft();
val jobDetail = jobContainer.getRight();
buildSingleByJob(viewName, jobDetail);
});
}
public List<ThirdPartyJenkinsViewResponse> getCacheViews() {
ThirdPartyJenkinsResponse thirdPartyJenkinsResponse = (ThirdPartyJenkinsResponse) redisTemplate.opsForValue().get(REDIS_JENKINS_ORIGINAL_VIEW);
if (thirdPartyJenkinsResponse == null) {
return new ArrayList<>();
}
return thirdPartyJenkinsResponse.getViews();
}
public List<ThirdPartyJenkinsViewDetailResponse> getCacheViewsDetail() {
List<ThirdPartyJenkinsViewDetailResponse> jenkinsViews = new ArrayList<>();
getCacheViews().forEach(view -> {
val jenkinsViewDetail = (ThirdPartyJenkinsViewDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB, view.getName()));
if (jenkinsViewDetail == null) {
return;
}
jenkinsViews.add(jenkinsViewDetail);
});
return jenkinsViews;
}
public List<Pair<String, ThirdPartyJenkinsJobDetailResponse>> getCacheJobs() {
List<Pair<String, ThirdPartyJenkinsJobDetailResponse>> jobsDetail = new ArrayList<>();
getCacheViewsDetail().forEach(detail -> {
if (CollectionUtils.isEmpty(detail.getJobs())) {
return;
}
detail.getJobs().forEach(job -> {
val redisValue = (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, detail.getName(), job.getName()));
if (redisValue == null) {
return;
}
jobsDetail.add(Pair.of(detail.getName(), redisValue));
});
});
return jobsDetail;
}
}

View File

@ -0,0 +1,16 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import lombok.Data;
@Data
public class JenkinsLoginBasic {
private String name;
private String url;
private String username;
private String password;
}

View File

@ -0,0 +1,69 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import com.qc.soft.deploy.ease.adapter.HttpClient;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
import com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants;
import com.qc.soft.deploy.ease.adapter.context.TenantAdapterContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class JenkinsRealTimeDataProvider extends IJenkinsDataProvider {
@Override
public ThirdPartyJenkinsResponse views() {
log.info("Query jenkins view api");
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization());
ThirdPartyJenkinsResponse jenkinsResponse = HttpClient.get(String.format(JenkinsConstants.JENKINS_VIEWS_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl()), headers, ThirdPartyJenkinsResponse.class);
jenkinsResponse.getViews().removeIf(next -> next.getName().equals("all"));
return jenkinsResponse;
}
@Override
public ThirdPartyJenkinsViewDetailResponse viewDetail(String viewName) {
log.info("Query jenkins view detail api, viewName:{}", viewName);
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization());
String urlFormat = StringUtils.isEmpty(viewName) ?
String.format(JenkinsConstants.JENKINS_JOB_ALL_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl()) : String.format(JenkinsConstants.JENKINS_JOB_API, "http://192.168.2.200:9096", viewName);
try {
return HttpClient.get(urlFormat, headers, ThirdPartyJenkinsViewDetailResponse.class);
} catch (Exception e) {
log.error("Get jenkins projects failed, url:{}", urlFormat, e);
return new ThirdPartyJenkinsViewDetailResponse();
}
}
@Override
public ThirdPartyJenkinsJobDetailResponse job(String viewName, String jobName) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization());
String urlFormat = String.format(JenkinsConstants.JENKINS_JOB_DETAIL_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl(), viewName, jobName);
try {
return HttpClient.get(urlFormat, headers, ThirdPartyJenkinsJobDetailResponse.class);
} catch (Exception e) {
log.error("Get jenkins job detail failed, url:{}", urlFormat, e);
return new ThirdPartyJenkinsJobDetailResponse();
}
}
@Override
public ThirdPartyJenkinsBuildResponse build(String viewName, String jobName, Long buildNumber) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization());
String urlFormat = String.format(JenkinsConstants.JENKINS_BUILD_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl(), viewName, jobName, buildNumber);
try {
return HttpClient.get(urlFormat, headers, ThirdPartyJenkinsBuildResponse.class);
} catch (Exception e) {
log.error("Get jenkins job build failed, url:{}", urlFormat, e);
return new ThirdPartyJenkinsBuildResponse();
}
}
}

View File

@ -1,18 +1,14 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty.aop; package com.qc.soft.deploy.ease.adapter.api.thirdparty.aop;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsClientApi;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.ThirdPartyJenkinsCrumbResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.ThirdPartyJenkinsCrumbResponse;
import com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants; import com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants;
import com.qc.soft.deploy.ease.adapter.context.JenkinsCrumbContext; import com.qc.soft.deploy.ease.adapter.context.JenkinsCrumbContext;
import com.qc.soft.deploy.ease.adapter.convert.JenkinsCrumbConvert; import com.qc.soft.deploy.ease.adapter.convert.JenkinsCrumbConvert;
import com.qc.soft.deploy.ease.adapter.enums.BusinessState; import com.qc.soft.deploy.ease.adapter.enums.BusinessState;
import com.qc.soft.framework.basic.exception.BusinessException; import com.qc.soft.framework.basic.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -22,30 +18,30 @@ import javax.annotation.Resource;
public class JenkinsClientApiAspect { public class JenkinsClientApiAspect {
@Resource // @Resource
private JenkinsClientApi jenkinsClientApi; // private JenkinsClientApi jenkinsClientApi;
//
@Pointcut("execution(* com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsClientApi.*(..))") // @Pointcut("execution(* com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsClientApi.*(..))")
public void pointcut() { // public void pointcut() {
} // }
//
//
@Pointcut("execution(* com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsClientApi.getJenkinsCrumb(..))") // @Pointcut("execution(* com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsClientApi.getJenkinsCrumb(..))")
public void excludedMethods() { // public void excludedMethods() {
} // }
//
@Before("pointcut() && !excludedMethods()") // @Before("pointcut() && !excludedMethods()")
public void before() { // public void before() {
ThirdPartyJenkinsCrumbResponse response = jenkinsClientApi.getJenkinsCrumb(String.format(JenkinsConstants.JENKINS_CRUMB_IS_SUER_API, "http://192.168.2.200:9096"), "admin", "3%(Lb5GN,M'Yk\\,)Dy\"*"); // ThirdPartyJenkinsCrumbResponse response = jenkinsClientApi.getJenkinsCrumb(String.format(JenkinsConstants.JENKINS_CRUMB_IS_SUER_API, "http://192.168.2.200:9096"), "admin", "3%(Lb5GN,M'Yk\\,)Dy\"*");
if (response == null) { // if (response == null) {
throw new BusinessException(BusinessState.GET_JENKINS_CRUMB_FAILED); // throw new BusinessException(BusinessState.GET_JENKINS_CRUMB_FAILED);
} // }
JenkinsCrumbContext.setJenkinsCrumb(JenkinsCrumbConvert.INSTANCE.response2DTO(response)); // JenkinsCrumbContext.setJenkinsCrumb(JenkinsCrumbConvert.INSTANCE.response2DTO(response));
} // }
//
@After("pointcut()") // @After("pointcut()")
public void after() { // public void after() {
JenkinsCrumbContext.clear(); // JenkinsCrumbContext.clear();
} // }
} }

View File

@ -21,8 +21,8 @@ public class ThirdPartyJenkinsBuildChangeSetDetailResponse implements Serializab
private String commitId; private String commitId;
@JsonDeserialize(using = Timestamp2StrDeserializer.class) // @JsonDeserialize(using = Timestamp2StrDeserializer.class)
private String timestamp; private Long timestamp;
private Map<String, String> author; private Map<String, String> author;
@ -30,7 +30,7 @@ public class ThirdPartyJenkinsBuildChangeSetDetailResponse implements Serializab
private String comment; private String comment;
@JsonDeserialize(using = DateStrToFormatDateStrDeserializer.class) // @JsonDeserialize(using = DateStrToFormatDateStrDeserializer.class)
private String date; private String date;
private String id; private String id;

View File

@ -17,7 +17,7 @@ public class ThirdPartyJenkinsBuildResponse implements Serializable{
private String projectName; private String projectName;
private Integer number; private Long number;
private Boolean inProgress; private Boolean inProgress;
@ -25,8 +25,8 @@ public class ThirdPartyJenkinsBuildResponse implements Serializable{
private String result; private String result;
@JsonDeserialize(using = Timestamp2StrDeserializer.class) // @JsonDeserialize(using = Timestamp2StrDeserializer.class)
private String timestamp; private Long timestamp;
private Long duration; private Long duration;

View File

@ -13,7 +13,7 @@ public class ThirdPartyJenkinsBuildSimpleResponse implements Serializable {
private static final long serialVersionUID = -1751553747449726589L; private static final long serialVersionUID = -1751553747449726589L;
Integer number; Long number;
String url; String url;

View File

@ -1,24 +0,0 @@
package com.qc.soft.deploy.ease.adapter.config;
import com.qc.soft.framework.basic.context.TenantContext;
import feign.RequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
@Configuration
public class AppConfig {
@Bean
public RequestInterceptor tenantHeaderInterceptor() {
return requestTemplate -> {
requestTemplate.header("Content-Type", "application/json;charset=UTF-8");
requestTemplate.header("x-tenant-code", TenantContext.getCurrentTenant());
};
}
}

View File

@ -0,0 +1,36 @@
package com.qc.soft.deploy.ease.adapter.config;
import com.qc.soft.framework.basic.context.TenantContext;
import feign.RequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class AppConfiguration {
@Bean
public RequestInterceptor tenantHeaderInterceptor() {
return requestTemplate -> {
requestTemplate.header("Content-Type", "application/json;charset=UTF-8");
requestTemplate.header("x-tenant-code", TenantContext.getCurrentTenant());
};
}
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(serializer);
return redisTemplate;
}
}

View File

@ -0,0 +1,104 @@
package com.qc.soft.deploy.ease.adapter.config;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsDataCacheSynchronizer;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsLoginBasic;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.context.TenantAdapterContext;
import com.qc.soft.framework.basic.context.TenantContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW;
@Configuration
@Slf4j
@Order(value = 100)
public class TenantBeanDefinitionRegistry implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware {
private ApplicationContext applicationContext;
private final ExecutorService executorService = Executors.newFixedThreadPool(3); // 线程池
private final Queue<Runnable> taskQueue = new LinkedList<>();
@Resource
private JenkinsDataCacheSynchronizer jenkinsDataCacheSynchronizer;
private RedisTemplate<String, Object> redisTemplate;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
}
@Override
public void afterPropertiesSet() {
Environment environment = applicationContext.getEnvironment();
if (ObjectUtils.isEmpty(environment.getProperty("TENANT_CODE"))) {
throw new NullPointerException("Adapter project tenant code not found!!!");
}
TenantContext.setCurrentTenant(environment.getProperty("TENANT_CODE"));
JenkinsLoginBasic loginBasic = new JenkinsLoginBasic();
loginBasic.setName("lianyu-dev");
loginBasic.setUrl("http://192.168.2.200:9096");
loginBasic.setUsername("admin");
loginBasic.setPassword("3%(Lb5GN,M'Yk\\,)Dy\"*");
TenantAdapterContext.buildJenkinsLoginBasic(loginBasic);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// log.info("The adapter checks if the item is initialized");
// ThirdPartyJenkinsResponse redisValue = (ThirdPartyJenkinsResponse) redisTemplate.opsForValue().get(REDIS_JENKINS_ORIGINAL_VIEW);
// if (redisValue != null) {
// log.info("Instead of initializing the project, the jenkins information will be incrementally synchronized");
// return;
// }
// addTask(jenkinsDataCacheSynchronizer::views);
// addTask(jenkinsDataCacheSynchronizer::viewDetail);
// addTask(jenkinsDataCacheSynchronizer::job);
// processNextTask().thenRun(() -> {
// System.out.println("All tasks completed.");
// executorService.shutdown();
// });
}
public void addTask(Runnable task) {
taskQueue.offer(task);
}
private CompletableFuture<Void> processNextTask() {
Runnable task = taskQueue.poll();
if (task == null) {
return CompletableFuture.completedFuture(null);
}
// 异步执行任务
return CompletableFuture.runAsync(task, executorService)
.thenCompose(v -> processNextTask());
}
}

View File

@ -1,47 +0,0 @@
package com.qc.soft.deploy.ease.adapter.config;
import com.qc.soft.framework.basic.context.TenantContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
@Configuration
@Slf4j
@Order(value = 100)
public class TenantProcessor implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
}
@Override
public void afterPropertiesSet() {
Environment environment = applicationContext.getEnvironment();
if (ObjectUtils.isEmpty(environment.getProperty("TENANT_CODE"))) {
throw new NullPointerException("Adapter project tenant code not found!!!");
}
TenantContext.setCurrentTenant(environment.getProperty("TENANT_CODE"));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}

View File

@ -1,5 +1,7 @@
package com.qc.soft.deploy.ease.adapter.consts; package com.qc.soft.deploy.ease.adapter.consts;
import com.qc.soft.deploy.ease.adapter.context.TenantAdapterContext;
public class JenkinsConstants { public class JenkinsConstants {
public static final String JENKINS_CRUMB_IS_SUER_API = "%s/crumbIssuer/api/json"; public static final String JENKINS_CRUMB_IS_SUER_API = "%s/crumbIssuer/api/json";
@ -14,11 +16,11 @@ public class JenkinsConstants {
public static final String JENKINS_BUILD_API = "%s/view/%s/job/%s/%s/api/json?pretty=true"; public static final String JENKINS_BUILD_API = "%s/view/%s/job/%s/%s/api/json?pretty=true";
public static final String REDIS_JENKINS_ORIGINAL_VIEW = "deploy-ease:jenkins:original:view"; public static final String REDIS_JENKINS_ORIGINAL_VIEW = "deploy-ease:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":jenkins:original";
public static final String REDIS_JENKINS_ORIGINAL_VIEW_JOB = "deploy-ease:jenkins:original:view:%s"; public static final String REDIS_JENKINS_ORIGINAL_VIEW_JOB = "deploy-ease:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":jenkins:original:view:%s";
public static final String REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL = "deploy-ease:jenkins:original:view:%s:%s"; public static final String REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL = "deploy-ease:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":jenkins:original:view:%s:job:%s";
public static final String REDIS_JENKINS_ORIGINAL_VIEW_BUILD = "deploy-ease:jenkins:original:view:%s:%s:%s"; public static final String REDIS_JENKINS_ORIGINAL_VIEW_BUILD = "deploy-ease:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":jenkins:original:view:%s:job:%s:build:%s";
} }

View File

@ -1,13 +1,26 @@
package com.qc.soft.deploy.ease.adapter.context; package com.qc.soft.deploy.ease.adapter.context;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsLoginBasic;
import com.qc.soft.framework.basic.utils.Base64AuthUtils;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
public class TenantAdapterContext { public class TenantAdapterContext {
@Getter
private static final JenkinsLoginBasic jenkinsLoginBasic = new JenkinsLoginBasic();
public static void buildJenkinsLoginBasic(JenkinsLoginBasic loginBasic) {
jenkinsLoginBasic.setName(loginBasic.getName());
jenkinsLoginBasic.setUrl(loginBasic.getUrl());
jenkinsLoginBasic.setUsername(loginBasic.getUsername());
jenkinsLoginBasic.setPassword(loginBasic.getPassword());
}
public static String getJenkinsAuthorization() {
return Base64AuthUtils.encode(jenkinsLoginBasic.getUsername(), jenkinsLoginBasic.getPassword());
}
} }

View File

@ -33,7 +33,7 @@ public class JenkinsController {
@GetMapping({"/jenkins/jobs", "/jenkins/jobs/{viewName}"}) @GetMapping({"/jenkins/jobs", "/jenkins/jobs/{viewName}"})
public JenkinsViewDetailResponse jobs(@PathVariable(value = "viewName", required = false) String viewName) { public JenkinsViewDetailResponse jobs(@PathVariable(value = "viewName", required = false) String viewName) {
return jenkinsService.jobs(viewName); return jenkinsService.viewDetail(viewName);
} }
@ -41,7 +41,7 @@ public class JenkinsController {
public JenkinsJobDetailResponse jobDetail( public JenkinsJobDetailResponse jobDetail(
@PathVariable(value = "viewName") String viewName, @PathVariable(value = "viewName") String viewName,
@PathVariable(value = "jobName") String jobName){ @PathVariable(value = "jobName") String jobName){
return jenkinsService.jobDetail(viewName, jobName); return jenkinsService.job(viewName, jobName);
} }
@ -50,7 +50,7 @@ public class JenkinsController {
@PathVariable(value = "viewName") String viewName, @PathVariable(value = "viewName") String viewName,
@PathVariable(value = "jobName") String jobName, @PathVariable(value = "jobName") String jobName,
@PathVariable(value = "buildNumber") Long buildNumber){ @PathVariable(value = "buildNumber") Long buildNumber){
return jenkinsService.jobBuild(viewName, jobName, buildNumber); return jenkinsService.build(viewName, jobName, buildNumber);
} }
@GetMapping("jenkins/aggregate") @GetMapping("jenkins/aggregate")

View File

@ -21,17 +21,17 @@ public class JenkinsViewProjectAggregateResponse {
String fullName; String fullName;
List<JenkinsViewProjectTaskAggregateResponse> builds; // List<JenkinsViewProjectTaskAggregateResponse> builds;
//
JenkinsViewProjectTaskAggregateResponse firstBuild; // JenkinsViewProjectTaskAggregateResponse firstBuild;
JenkinsViewProjectTaskAggregateResponse lastBuild; JenkinsViewProjectTaskAggregateResponse lastBuild;
JenkinsViewProjectTaskAggregateResponse lastCompletedBuild; // JenkinsViewProjectTaskAggregateResponse lastCompletedBuild;
//
JenkinsViewProjectTaskAggregateResponse lastStableBuild; // JenkinsViewProjectTaskAggregateResponse lastStableBuild;
//
JenkinsViewProjectTaskAggregateResponse lastSuccessfulBuild; // JenkinsViewProjectTaskAggregateResponse lastSuccessfulBuild;
int nextBuildNumber; int nextBuildNumber;

View File

@ -27,5 +27,5 @@ public class JenkinsBuildChangeSetDetailResponse {
private String msg; private String msg;
private List<Map<String, String>> paths; // private List<Map<String, String>> paths;
} }

View File

@ -9,6 +9,7 @@ import java.util.List;
@Data @Data
public class JenkinsBuildChangeSetResponse { public class JenkinsBuildChangeSetResponse {
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<JenkinsBuildChangeSetDetailResponse> items; private List<JenkinsBuildChangeSetDetailResponse> items;
} }

View File

@ -7,7 +7,7 @@ import lombok.Data;
@Data @Data
public class JenkinsBuildSimpleResponse { public class JenkinsBuildSimpleResponse {
Integer number; Long number;
String url; String url;

View File

@ -1,14 +1,20 @@
package com.qc.soft.deploy.ease.adapter.convert; package com.qc.soft.deploy.ease.adapter.convert;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildSimpleResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectTaskAggregateResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectTaskAggregateResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.build.JenkinsBuildResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.build.JenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.job.JenkinsJobDetailResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.job.JenkinsJobDetailResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget; import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Mapper @Mapper
public interface JenkinsBuildConvert { public interface JenkinsBuildConvert {
@ -16,6 +22,31 @@ public interface JenkinsBuildConvert {
JenkinsBuildResponse response2ApiResponse(ThirdPartyJenkinsBuildResponse response); JenkinsBuildResponse response2ApiResponse(ThirdPartyJenkinsBuildResponse response);
void response2ApiAggregateResponse(JenkinsBuildResponse response, @MappingTarget JenkinsViewProjectTaskAggregateResponse target); void response2ApiAggregateResponse(ThirdPartyJenkinsBuildResponse response, @MappingTarget JenkinsViewProjectTaskAggregateResponse target);
default List<ThirdPartyJenkinsBuildSimpleResponse> aggregateJobBuildSimple(ThirdPartyJenkinsJobDetailResponse jenkinsJobDetail) {
List<ThirdPartyJenkinsBuildSimpleResponse> jenkinsBuildsSimple = new ArrayList<>();
if (CollectionUtils.isNotEmpty(jenkinsJobDetail.getBuilds())) {
jenkinsBuildsSimple.addAll(jenkinsJobDetail.getBuilds());
}
if (jenkinsJobDetail.getFirstBuild() != null) {
jenkinsBuildsSimple.add(jenkinsJobDetail.getFirstBuild());
}
if (jenkinsJobDetail.getLastBuild() != null) {
jenkinsBuildsSimple.add(jenkinsJobDetail.getLastBuild());
}
if (jenkinsJobDetail.getLastCompletedBuild() != null) {
jenkinsBuildsSimple.add(jenkinsJobDetail.getLastCompletedBuild());
}
if (jenkinsJobDetail.getLastStableBuild() != null) {
jenkinsBuildsSimple.add(jenkinsJobDetail.getLastStableBuild());
}
if (jenkinsJobDetail.getLastSuccessfulBuild() != null) {
jenkinsBuildsSimple.add(jenkinsJobDetail.getLastSuccessfulBuild());
}
return jenkinsBuildsSimple.stream().distinct().collect(Collectors.toList());
}
} }

View File

@ -1,13 +1,14 @@
package com.qc.soft.deploy.ease.adapter.convert; package com.qc.soft.deploy.ease.adapter.convert;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsCacheDataProvider;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildSimpleResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.context.JenkinsBuildSimpleSupportContext; import com.qc.soft.deploy.ease.adapter.context.JenkinsBuildSimpleSupportContext;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectAggregateResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectAggregateResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectTaskAggregateResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectTaskAggregateResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.build.JenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.build.JenkinsBuildSimpleResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.build.JenkinsBuildSimpleResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.job.JenkinsJobDetailResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.job.JenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.service.IJenkinsService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.mapstruct.AfterMapping; import org.mapstruct.AfterMapping;
@ -23,19 +24,19 @@ import javax.annotation.Resource;
public abstract class JenkinsJobDetailConvert { public abstract class JenkinsJobDetailConvert {
@Resource @Resource
private IJenkinsService jenkinsService; private JenkinsCacheDataProvider jenkinsCacheDataProvider;
public abstract JenkinsJobDetailResponse response2ApiResponse(ThirdPartyJenkinsJobDetailResponse response); public abstract JenkinsJobDetailResponse response2ApiResponse(ThirdPartyJenkinsJobDetailResponse response);
@Mappings({ @Mappings({
@Mapping(source = "response.name", target = "projectName") @Mapping(source = "response.name", target = "projectName")
}) })
public abstract JenkinsViewProjectAggregateResponse response2AggregateResponse(JenkinsJobDetailResponse response); public abstract JenkinsViewProjectAggregateResponse response2AggregateResponse(ThirdPartyJenkinsJobDetailResponse response);
@AfterMapping @AfterMapping
void afterMapping(JenkinsBuildSimpleResponse source, @MappingTarget JenkinsViewProjectTaskAggregateResponse target) { void afterMapping(ThirdPartyJenkinsBuildSimpleResponse source, @MappingTarget JenkinsViewProjectTaskAggregateResponse target) {
Pair<String, String> value = JenkinsBuildSimpleSupportContext.getValue(); Pair<String, String> value = JenkinsBuildSimpleSupportContext.getValue();
JenkinsBuildResponse jenkinsBuildResponse = jenkinsService.jobBuild(value.getLeft(), value.getRight(), Long.valueOf(source.getNumber())); ThirdPartyJenkinsBuildResponse jenkinsBuild = jenkinsCacheDataProvider.build(value.getLeft(), value.getRight(), source.getNumber());
JenkinsBuildConvert.INSTANCE.response2ApiAggregateResponse(jenkinsBuildResponse, target); JenkinsBuildConvert.INSTANCE.response2ApiAggregateResponse(jenkinsBuild, target);
} }
} }

View File

@ -14,11 +14,11 @@ public interface IJenkinsService {
JenkinsResponse views(); JenkinsResponse views();
JenkinsViewDetailResponse jobs(String viewName); JenkinsViewDetailResponse viewDetail(String viewName);
JenkinsJobDetailResponse jobDetail(String viewName, String jobName); JenkinsJobDetailResponse job(String viewName, String jobName);
JenkinsBuildResponse jobBuild(String viewName, String jobName, Long buildNumber); JenkinsBuildResponse build(String viewName, String jobName, Long buildNumber);
JenkinsAggregateResponse aggregate(); JenkinsAggregateResponse aggregate();
} }

View File

@ -1,13 +1,11 @@
package com.qc.soft.deploy.ease.adapter.service.impl; package com.qc.soft.deploy.ease.adapter.service.impl;
import cn.hutool.core.date.StopWatch; import cn.hutool.core.date.StopWatch;
import com.alibaba.fastjson2.JSON; import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsBusinessProvider;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsClientApi;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.ThirdPartyJenkinsCrumbResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.ThirdPartyJenkinsCrumbResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJenkinsJobDetailResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsResponse;
import com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
import com.qc.soft.deploy.ease.adapter.context.JenkinsBuildSimpleSupportContext; import com.qc.soft.deploy.ease.adapter.context.JenkinsBuildSimpleSupportContext;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsAggregateResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsAggregateResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewAggregateResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewAggregateResponse;
@ -21,11 +19,9 @@ import com.qc.soft.deploy.ease.adapter.convert.JenkinsConvert;
import com.qc.soft.deploy.ease.adapter.convert.JenkinsJobDetailConvert; import com.qc.soft.deploy.ease.adapter.convert.JenkinsJobDetailConvert;
import com.qc.soft.deploy.ease.adapter.convert.JenkinsViewDetailConvert; import com.qc.soft.deploy.ease.adapter.convert.JenkinsViewDetailConvert;
import com.qc.soft.deploy.ease.adapter.service.IJenkinsService; import com.qc.soft.deploy.ease.adapter.service.IJenkinsService;
import com.qc.soft.framework.basic.context.SpringContext; import lombok.extern.slf4j.Slf4j;
import lombok.val; import lombok.val;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -33,69 +29,67 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@Service @Service
@Slf4j
public class JenkinsServiceImpl implements IJenkinsService { public class JenkinsServiceImpl implements IJenkinsService {
@Resource @Resource
private JenkinsClientApi jenkinsClientApi; private JenkinsBusinessProvider jenkinsBusinessProvider;
@Resource @Resource
private JenkinsJobDetailConvert jenkinsJobDetailConvert; private JenkinsJobDetailConvert jenkinsJobDetailConvert;
@Resource
private SpringContext springContext;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override @Override
public ThirdPartyJenkinsCrumbResponse getJenkinsCrumbIssue(String url, String username, String password) { public ThirdPartyJenkinsCrumbResponse getJenkinsCrumbIssue(String url, String username, String password) {
return jenkinsClientApi.getJenkinsCrumb(String.format(JenkinsConstants.JENKINS_CRUMB_IS_SUER_API, "http://192.168.2.200:9096"), "admin", "3%(Lb5GN,M'Yk\\,)Dy\"*"); // return jenkinsClientApi.getJenkinsCrumb(String.format(JenkinsConstants.JENKINS_CRUMB_IS_SUER_API, "http://192.168.2.200:9096"), "admin", "3%(Lb5GN,M'Yk\\,)Dy\"*");
return null;
} }
@Override @Override
public JenkinsResponse views() { public JenkinsResponse views() {
return JenkinsConvert.INSTANCE.response2ApiResponse(jenkinsClientApi.getViews()); return JenkinsConvert.INSTANCE.response2ApiResponse(jenkinsBusinessProvider.views());
} }
@Override @Override
public JenkinsViewDetailResponse jobs(String viewName) { public JenkinsViewDetailResponse viewDetail(String viewName) {
return JenkinsViewDetailConvert.INSTANCE.response2ApiResponse(jenkinsClientApi.jobs(viewName)); return JenkinsViewDetailConvert.INSTANCE.response2ApiResponse(jenkinsBusinessProvider.viewDetail(viewName));
} }
@Override @Override
public JenkinsJobDetailResponse jobDetail(String viewName, String jobName) { public JenkinsJobDetailResponse job(String viewName, String jobName) {
return jenkinsJobDetailConvert.response2ApiResponse(jenkinsClientApi.jobDetail(viewName, jobName)); return jenkinsJobDetailConvert.response2ApiResponse(jenkinsBusinessProvider.job(viewName, jobName));
} }
@Override @Override
public JenkinsBuildResponse jobBuild(String viewName, String jobName, Long buildNumber) { public JenkinsBuildResponse build(String viewName, String jobName, Long buildNumber) {
return JenkinsBuildConvert.INSTANCE.response2ApiResponse(jenkinsClientApi.jobBuild(viewName, jobName, buildNumber)); return JenkinsBuildConvert.INSTANCE.response2ApiResponse(jenkinsBusinessProvider.build(viewName, jobName, buildNumber));
} }
@Override @Override
public JenkinsAggregateResponse aggregate() { public JenkinsAggregateResponse aggregate() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
val aggregate = new JenkinsAggregateResponse(); val aggregate = new JenkinsAggregateResponse();
List<JenkinsViewAggregateResponse> viewsAggregate = new ArrayList<>(); List<JenkinsViewAggregateResponse> viewsAggregate = new ArrayList<>();
JenkinsResponse container = views(); val container = jenkinsBusinessProvider.views();
container.getViews().stream().filter(view -> !view.getName().equals("all")).forEach(view -> { container.getViews().forEach(view -> {
String viewName = view.getName(); String viewName = view.getName();
JenkinsViewDetailResponse jobsContainer = jobs(viewName); val jobsContainer = jenkinsBusinessProvider.viewDetail(viewName);
List<JenkinsViewProjectAggregateResponse> viewProjectsAggregate = new ArrayList<>(); List<JenkinsViewProjectAggregateResponse> viewProjectsAggregate = new ArrayList<>();
jobsContainer.getJobs().forEach(job -> { jobsContainer.getJobs().forEach(job -> {
JenkinsJobDetailResponse jobDetailContainer = jobDetail(viewName, job.getName()); val jobDetailContainer = jenkinsBusinessProvider.job(viewName, job.getName());
JenkinsBuildSimpleSupportContext.setValue(Pair.of(viewName, job.getName())); JenkinsBuildSimpleSupportContext.setValue(Pair.of(viewName, job.getName()));
JenkinsViewProjectAggregateResponse viewProjectAggregate = jenkinsJobDetailConvert.response2AggregateResponse(jobDetailContainer); val viewProjectAggregate = jenkinsJobDetailConvert.response2AggregateResponse(jobDetailContainer);
JenkinsBuildSimpleSupportContext.clear(); JenkinsBuildSimpleSupportContext.clear();
viewProjectsAggregate.add(viewProjectAggregate); viewProjectsAggregate.add(viewProjectAggregate);
}); });
JenkinsViewAggregateResponse viewAggregate = new JenkinsViewAggregateResponse(); val viewAggregate = new JenkinsViewAggregateResponse();
viewAggregate.setViewName(viewName); viewAggregate.setViewName(viewName);
viewAggregate.setProjects(viewProjectsAggregate); viewAggregate.setProjects(viewProjectsAggregate);
viewsAggregate.add(viewAggregate); viewsAggregate.add(viewAggregate);
}); });
aggregate.setViews(viewsAggregate); aggregate.setViews(viewsAggregate);
stopWatch.stop();
log.info("Elapsed time in seconds:{}", stopWatch.getTotalTimeSeconds());
return aggregate; return aggregate;
} }

View File

@ -1,6 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qc.soft.framework.basic.context.SpringContext,\ com.qc.soft.framework.basic.context.SpringContext,\
com.qc.soft.framework.basic.redis.RedisAutoConfiguration,\
com.qc.soft.framework.basic.http.HttpAutoConfiguration,\ com.qc.soft.framework.basic.http.HttpAutoConfiguration,\
com.qc.soft.framework.basic.config.GlobalResponseHandler,\ com.qc.soft.framework.basic.config.GlobalResponseHandler,\
com.qc.soft.framework.basic.config.GlobalExceptionHandler com.qc.soft.framework.basic.config.GlobalExceptionHandler

View File

@ -7,7 +7,7 @@ spring:
database: 0 database: 0
lettuce: lettuce:
pool: pool:
max-active: 8 max-active: 30
max-idle: 8 max-idle: 8
min-idle: 0 min-idle: 0
max-wait: 1ms max-wait: 1ms

View File

@ -1,6 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.qc.soft.framework.basic.context.SpringContext,\ com.qc.soft.framework.basic.context.SpringContext,\
com.qc.soft.framework.basic.redis.RedisAutoConfiguration,\
com.qc.soft.framework.basic.http.HttpAutoConfiguration,\ com.qc.soft.framework.basic.http.HttpAutoConfiguration,\
com.qc.soft.framework.basic.config.GlobalResponseHandler,\ com.qc.soft.framework.basic.config.GlobalResponseHandler,\
com.qc.soft.framework.basic.config.GlobalExceptionHandler com.qc.soft.framework.basic.config.GlobalExceptionHandler

View File

@ -7,7 +7,7 @@ spring:
database: 0 database: 0
lettuce: lettuce:
pool: pool:
max-active: 8 max-active: 30
max-idle: 8 max-idle: 8
min-idle: 0 min-idle: 0
max-wait: 1ms max-wait: 1ms