nacos加入到项目当中

This commit is contained in:
dengqichen 2024-08-23 11:00:34 +08:00
parent 016280fe4d
commit c934c75264
26 changed files with 518 additions and 514 deletions

View File

@ -1,4 +1,4 @@
package com.qc.soft.deploy.ease.adapter.config; package com.qc.soft.framework.basic.deserializer;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationContext;

View File

@ -1,4 +1,4 @@
package com.qc.soft.deploy.ease.adapter.config; package com.qc.soft.framework.basic.deserializer;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationContext;

View File

@ -0,0 +1,30 @@
package com.qc.soft.framework.basic.http;
import com.qc.soft.framework.basic.context.ApplicationContextProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class HttpClient {
private static final ApplicationContext context;
static {
context = ApplicationContextProvider.getApplicationContext();
}
public static <H extends HttpHeaders, T> T get(String url, H headers, Class<T> cls) {
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<T> response = getRestTemplate().exchange(url, HttpMethod.GET, entity, cls);
return response.getBody();
}
private static RestTemplate getRestTemplate() {
return context.getBean(RestTemplate.class);
}
}

View File

@ -1,7 +1,6 @@
package com.qc.soft.deploy.ease.adapter.config; package com.qc.soft.framework.basic.http;
import com.qc.soft.framework.basic.context.TenantContext;
import feign.RequestInterceptor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
@ -11,16 +10,10 @@ import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration @Configuration
public class AppConfiguration { public class RedisConfiguration {
@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")
@Bean(name = "stringRedisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory); redisTemplate.setConnectionFactory(factory);

View File

@ -1,60 +1,35 @@
package com.qc.soft.framework.basic.redis; package com.qc.soft.framework.basic.redis;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; 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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
//@Configuration @Configuration
//@ConditionalOnProperty(name = "spring.redis", havingValue = "true") @ConditionalOnProperty(name = "spring.redis.enabled", havingValue = "true")
@Slf4j @Slf4j
public class RedisAutoConfiguration { public class RedisAutoConfiguration {
public RedisAutoConfiguration() { public RedisAutoConfiguration() {
log.info("Framework redis template registered successfully!!!");
} }
// @Bean @Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// RedisTemplate<String, Object> template = new RedisTemplate<>(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// template.setConnectionFactory(redisConnectionFactory); redisTemplate.setConnectionFactory(factory);
// FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(); RedisSerializer<String> stringSerializer = new StringRedisSerializer();
// template.setDefaultSerializer(new StringRedisSerializer()); GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
// template.setValueSerializer(serializer); redisTemplate.setKeySerializer(stringSerializer);
// template.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(serializer);
// template.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(stringSerializer);
// template.setHashValueSerializer(serializer); redisTemplate.setHashValueSerializer(serializer);
// template.afterPropertiesSet(); log.info("Framework string redis template registered successfully!!!");
// return template; return redisTemplate;
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

@ -1,258 +1,258 @@
package com.qc.soft.framework.basic.utils; //package com.qc.soft.framework.basic.utils;
//
import cn.hutool.core.map.MapUtil; //import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson2.JSON; //import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; //import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpDelete; //import org.apache.hc.client5.http.classic.methods.HttpDelete;
import org.apache.hc.client5.http.classic.methods.HttpGet; //import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost; //import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder; //import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; //import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; //import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients; //import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.Header; //import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpEntity; //import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils; //import org.apache.hc.core5.http.io.entity.EntityUtils;
//
import java.io.File; //import java.io.File;
import java.io.FileOutputStream; //import java.io.FileOutputStream;
import java.io.IOException; //import java.io.IOException;
import java.io.InputStream; //import java.io.InputStream;
import java.util.Arrays; //import java.util.Arrays;
import java.util.HashMap; //import java.util.HashMap;
import java.util.IdentityHashMap; //import java.util.IdentityHashMap;
import java.util.Map; //import java.util.Map;
import java.util.Optional; //import java.util.Optional;
//
@Slf4j //@Slf4j
public class HttpUtils<T> { //public class HttpUtils<T> {
//
public static final int fileSize = 10 * 1024; // public static final int fileSize = 10 * 1024;
//
public static <T> T get(String url, Map<String, String> header, Class<T> cls) { // public static <T> T get(String url, Map<String, String> header, Class<T> cls) {
CloseableHttpClient httpclient = HttpClients.createDefault(); // CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet(url); // HttpGet get = new HttpGet(url);
CloseableHttpResponse response = null; // CloseableHttpResponse response = null;
try { // try {
if (!MapUtil.isEmpty(header)) { // if (!MapUtil.isEmpty(header)) {
header.forEach(get::setHeader); // header.forEach(get::setHeader);
} // }
response = httpclient.execute(get); // response = httpclient.execute(get);
HttpEntity entity = response.getEntity(); // HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity); // String result = EntityUtils.toString(entity);
EntityUtils.consume(entity); // EntityUtils.consume(entity);
return JSON.parseObject(result, cls); // return JSON.parseObject(result, cls);
} catch (Exception e) { // } catch (Exception e) {
log.error("http get error, url:{}", url, e); // log.error("http get error, url:{}", url, e);
} finally { // } finally {
try { // try {
if (response != null) { // if (response != null) {
response.close(); // response.close();
} // }
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
return null; // return null;
} // }
//
public static Map<String, Object> get(String url, Map<String, String> header) { // public static Map<String, Object> get(String url, Map<String, String> header) {
CloseableHttpClient httpclient = HttpClients.createDefault(); // CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet(url); // HttpGet get = new HttpGet(url);
CloseableHttpResponse response = null; // CloseableHttpResponse response = null;
try { // try {
if (!MapUtil.isEmpty(header)) { // if (!MapUtil.isEmpty(header)) {
header.forEach(get::setHeader); // header.forEach(get::setHeader);
} // }
response = httpclient.execute(get); // response = httpclient.execute(get);
HttpEntity entity = response.getEntity(); // HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity); // String result = EntityUtils.toString(entity);
EntityUtils.consume(entity); // EntityUtils.consume(entity);
return JSON.parseObject(result, Map.class); // return JSON.parseObject(result, Map.class);
} catch (Exception e) { // } catch (Exception e) {
log.error("http get error, url:{}", url); // log.error("http get error, url:{}", url);
} finally { // } finally {
try { // try {
if (response != null) { // if (response != null) {
response.close(); // response.close();
} // }
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
return new HashMap<>(); // return new HashMap<>();
} // }
//
//
public static void delete(String url, Map<String, String> header) { // public static void delete(String url, Map<String, String> header) {
CloseableHttpClient httpclient = HttpClients.createDefault(); // CloseableHttpClient httpclient = HttpClients.createDefault();
HttpDelete delete = new HttpDelete(url); // HttpDelete delete = new HttpDelete(url);
CloseableHttpResponse response = null; // CloseableHttpResponse response = null;
try { // try {
if (!MapUtil.isEmpty(header)) { // if (!MapUtil.isEmpty(header)) {
header.forEach(delete::setHeader); // header.forEach(delete::setHeader);
} // }
response = httpclient.execute(delete); // response = httpclient.execute(delete);
log.info("Remove nexus url:{} success", url); // log.info("Remove nexus url:{} success", url);
} catch (Exception e) { // } catch (Exception e) {
log.error("http delete error, url:{}", url, e); // log.error("http delete error, url:{}", url, e);
} finally { // } finally {
try { // try {
if (response != null) { // if (response != null) {
response.close(); // response.close();
} // }
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
} // }
//
public static Map<String, Object> post(String url, IdentityHashMap<String, String> header) { // public static Map<String, Object> post(String url, IdentityHashMap<String, String> header) {
CloseableHttpClient httpclient = HttpClients.createDefault(); // CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost post = new HttpPost(url); // HttpPost post = new HttpPost(url);
CloseableHttpResponse response = null; // CloseableHttpResponse response = null;
Map<String, Object> result = new HashMap<>(); // Map<String, Object> result = new HashMap<>();
try { // try {
if (!MapUtil.isEmpty(header)) { // if (!MapUtil.isEmpty(header)) {
header.forEach(post::setHeader); // header.forEach(post::setHeader);
} // }
response = httpclient.execute(post); // response = httpclient.execute(post);
HttpEntity entity = response.getEntity(); // HttpEntity entity = response.getEntity();
result.put("code", response.getCode()); // result.put("code", response.getCode());
result.put("message", EntityUtils.toString(response.getEntity())); // result.put("message", EntityUtils.toString(response.getEntity()));
EntityUtils.consume(entity); // EntityUtils.consume(entity);
log.info("Http client post success, response:{}", response); // log.info("Http client post success, response:{}", response);
return result; // return result;
} catch (Exception e) { // } catch (Exception e) {
log.error("http post error, url:{}", url, e); // log.error("http post error, url:{}", url, e);
} finally { // } finally {
try { // try {
if (response != null) { // if (response != null) {
response.close(); // response.close();
} // }
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
result.put("code", 0); // result.put("code", 0);
return result; // return result;
} // }
//
public static <T> T cookieGet(String url, Map<String, String> header, Class<T> cls) { // public static <T> T cookieGet(String url, Map<String, String> header, Class<T> cls) {
CloseableHttpClient httpclient = HttpClients.createDefault(); // CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet(url); // HttpGet get = new HttpGet(url);
CloseableHttpResponse response = null; // CloseableHttpResponse response = null;
try { // try {
if (!MapUtil.isEmpty(header)) { // if (!MapUtil.isEmpty(header)) {
header.forEach(get::setHeader); // header.forEach(get::setHeader);
} // }
response = httpclient.execute(get); // response = httpclient.execute(get);
HttpEntity entity = response.getEntity(); // HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity); // String result = EntityUtils.toString(entity);
Optional<Header> cookieOptional = Arrays.stream(response.getHeaders()).filter(v -> v.getName().equals("Set-Cookie")).findFirst(); // Optional<Header> cookieOptional = Arrays.stream(response.getHeaders()).filter(v -> v.getName().equals("Set-Cookie")).findFirst();
if (cookieOptional.isPresent()) { // if (cookieOptional.isPresent()) {
Header cookie = cookieOptional.get(); // Header cookie = cookieOptional.get();
String cookieValue = cookie.getValue().substring(0, cookie.getValue().indexOf(";")); // String cookieValue = cookie.getValue().substring(0, cookie.getValue().indexOf(";"));
JSONObject tempObject = JSON.parseObject(result); // JSONObject tempObject = JSON.parseObject(result);
tempObject.put("cookie", cookieValue); // tempObject.put("cookie", cookieValue);
result = JSON.toJSONString(tempObject); // result = JSON.toJSONString(tempObject);
} // }
EntityUtils.consume(entity); // EntityUtils.consume(entity);
log.info("http cookie get result:{}", result); // log.info("http cookie get result:{}", result);
return JSON.parseObject(result, cls); // return JSON.parseObject(result, cls);
} catch (Exception e) { // } catch (Exception e) {
log.error("http get error, url:{}", url, e); // log.error("http get error, url:{}", url, e);
} finally { // } finally {
try { // try {
if (response != null) { // if (response != null) {
response.close(); // response.close();
} // }
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
return null; // return null;
} // }
//
public static String downloadFile(String url, Map<String, String> header, String downloadBuildFailedFilePath, String fileName) { // public static String downloadFile(String url, Map<String, String> header, String downloadBuildFailedFilePath, String fileName) {
String fullFilePath = downloadBuildFailedFilePath + File.separator + fileName; // String fullFilePath = downloadBuildFailedFilePath + File.separator + fileName;
CloseableHttpClient httpclient = HttpClients.createDefault(); // CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet get = new HttpGet(url); // HttpGet get = new HttpGet(url);
CloseableHttpResponse response = null; // CloseableHttpResponse response = null;
try { // try {
File directory = new File(downloadBuildFailedFilePath); // File directory = new File(downloadBuildFailedFilePath);
if (!directory.exists()) { // if (!directory.exists()) {
directory.mkdirs(); // directory.mkdirs();
} // }
if (!directory.isDirectory()) { // if (!directory.isDirectory()) {
return null; // return null;
} // }
if (!MapUtil.isEmpty(header)) { // if (!MapUtil.isEmpty(header)) {
header.forEach(get::setHeader); // header.forEach(get::setHeader);
} // }
response = httpclient.execute(get); // response = httpclient.execute(get);
HttpEntity entity = response.getEntity(); // HttpEntity entity = response.getEntity();
InputStream is = entity.getContent(); // InputStream is = entity.getContent();
File file = new File(fullFilePath); // File file = new File(fullFilePath);
if (file.exists()) { // if (file.exists()) {
log.info("Download file exists,will be deleted, fileName:{}", fileName); // log.info("Download file exists,will be deleted, fileName:{}", fileName);
file.delete(); // file.delete();
} // }
file.createNewFile(); // file.createNewFile();
FileOutputStream os = new FileOutputStream(file); // FileOutputStream os = new FileOutputStream(file);
byte[] buffer = new byte[fileSize]; // byte[] buffer = new byte[fileSize];
int ch = 0; // int ch = 0;
while ((ch = is.read(buffer)) != -1) { // while ((ch = is.read(buffer)) != -1) {
os.write(buffer, 0, ch); // os.write(buffer, 0, ch);
} // }
is.close(); // is.close();
os.flush(); // os.flush();
os.close(); // os.close();
EntityUtils.consume(entity); // EntityUtils.consume(entity);
log.info("Download file success, url:{}, filePath:{}", url, fullFilePath); // log.info("Download file success, url:{}, filePath:{}", url, fullFilePath);
return fullFilePath; // return fullFilePath;
} catch (Exception e) { // } catch (Exception e) {
log.error("Download file failed, url:{}", url); // log.error("Download file failed, url:{}", url);
} finally { // } finally {
try { // try {
if (response != null) { // if (response != null) {
response.close(); // response.close();
} // }
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
return null; // return null;
} // }
//
public static <T> T uploadFile(String url, String filePath, Class<T> cls) { // public static <T> T uploadFile(String url, String filePath, Class<T> cls) {
CloseableHttpResponse response = null; // CloseableHttpResponse response = null;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(url); // HttpPost httpPost = new HttpPost(url);
File file = new File(filePath); // File file = new File(filePath);
if (!file.exists()) { // if (!file.exists()) {
log.error("Upload file not exists, filePath:{}", filePath); // log.error("Upload file not exists, filePath:{}", filePath);
return null; // return null;
} // }
HttpEntity fileEntity = MultipartEntityBuilder.create().addBinaryBody("file", file).build(); // HttpEntity fileEntity = MultipartEntityBuilder.create().addBinaryBody("file", file).build();
httpPost.setEntity(fileEntity); // httpPost.setEntity(fileEntity);
response = httpClient.execute(httpPost); // response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity(); // HttpEntity entity = response.getEntity();
String content = EntityUtils.toString(entity); // String content = EntityUtils.toString(entity);
EntityUtils.consume(entity); // EntityUtils.consume(entity);
return JSON.parseObject(content, cls); // return JSON.parseObject(content, cls);
} catch (Exception e) { // } catch (Exception e) {
log.error("Upload file failed, url:{}, filePath:{}, response:{}", url, filePath, JSON.toJSONString(response)); // log.error("Upload file failed, url:{}, filePath:{}, response:{}", url, filePath, JSON.toJSONString(response));
} finally { // } finally {
if (response != null) { // if (response != null) {
try { // try {
response.close(); // response.close();
} catch (IOException e) { // } catch (IOException e) {
log.error("Upload file close response failed, url:{}, filePath:{}", url, filePath); // log.error("Upload file close response failed, url:{}, filePath:{}", url, filePath);
} // }
} // }
} // }
return null; // return null;
} // }
} //}

View File

@ -113,10 +113,6 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>

View File

@ -1,30 +0,0 @@
package com.qc.soft.deploy.ease.adapter;
import com.qc.soft.framework.basic.context.ApplicationContextProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class HttpClient {
private static final ApplicationContext context;
static {
context = ApplicationContextProvider.getApplicationContext();
}
public static <H extends HttpHeaders, T> T get(String url, H headers, Class<T> cls) {
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<T> response = getRestTemplate().exchange(url, HttpMethod.GET, entity, cls);
return response.getBody();
}
private static RestTemplate getRestTemplate() {
return context.getBean(RestTemplate.class);
}
}

View File

@ -5,19 +5,10 @@ import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.job.ThirdPartyJen
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.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse; import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; 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 @Component
@Slf4j @Slf4j
public class JenkinsBusinessProvider { public class JenkinsBusinessProvider {
@ -28,9 +19,6 @@ public class JenkinsBusinessProvider {
@Resource @Resource
private JenkinsCacheDataProvider cacheDataProvider; private JenkinsCacheDataProvider cacheDataProvider;
@Resource
private RedisTemplate<String, Object> redisTemplate;
public ThirdPartyJenkinsResponse views() { public ThirdPartyJenkinsResponse views() {
ThirdPartyJenkinsResponse redisValue = cacheDataProvider.views(); ThirdPartyJenkinsResponse redisValue = cacheDataProvider.views();
if (redisValue == null) { if (redisValue == null) {

View File

@ -3,6 +3,7 @@ package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import cn.hutool.core.lang.func.VoidFunc0; 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.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.job.ThirdPartyJenkinsJobResponse;
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.api.thirdparty.response.view.ThirdPartyJenkinsViewDetailResponse; 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.api.thirdparty.response.view.ThirdPartyJenkinsViewResponse;
@ -10,9 +11,9 @@ import com.qc.soft.deploy.ease.adapter.convert.JenkinsBuildConvert;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import lombok.val; import lombok.val;
import org.apache.commons.collections4.CollectionUtils; 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.Pair;
import org.apache.commons.lang3.tuple.Triple; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -22,6 +23,9 @@ import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean; 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;
@ -39,8 +43,28 @@ public class JenkinsDataCacheSynchronizer {
@Resource @Resource
private RedisTemplate<String, Object> redisTemplate; private RedisTemplate<String, Object> redisTemplate;
private final ExecutorService executorService = Executors.newFixedThreadPool(4);
@EventListener(ApplicationReadyEvent.class)
public void firstSyncCheck() {
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;
}
CompletableFuture<Void> future = CompletableFuture.runAsync(this::views, executorService)
.thenRun(this::viewDetail)
.thenRun(this::job)
.thenRun(this::build)
.thenRun(() -> {
executorService.shutdown();
log.info("Jenkins initialization is synchronized completed");
});
future.join();
}
@Scheduled(cron = "0 */30 * * * ?") @Scheduled(cron = "0 */30 * * * ?")
public void views() { public void views() {
ThirdPartyJenkinsResponse redisValue = (ThirdPartyJenkinsResponse) redisTemplate.opsForValue().get(REDIS_JENKINS_ORIGINAL_VIEW); ThirdPartyJenkinsResponse redisValue = (ThirdPartyJenkinsResponse) redisTemplate.opsForValue().get(REDIS_JENKINS_ORIGINAL_VIEW);
@ -76,10 +100,23 @@ public class JenkinsDataCacheSynchronizer {
}); });
} }
@Scheduled(cron = "30 * * * * ?") @Scheduled(cron = "15 * * * * ?")
public void job() { public void job() {
getCacheViewsDetail().forEach(viewDetail -> { List<ThirdPartyJenkinsViewDetailResponse> cacheViewsDetail = getCacheViewsDetail();
Optional.ofNullable(viewDetail.getJobs()).orElse(new ArrayList<>()).forEach(job -> { ExecutorService viewPool = Executors.newFixedThreadPool(cacheViewsDetail.size(), r -> {
Thread thread = new Thread(r);
thread.setName("jenkins-sync-view-thread-" + System.currentTimeMillis());
return thread;
});
CompletableFuture[] viewFutures = cacheViewsDetail.parallelStream().map(viewDetail -> CompletableFuture.runAsync(() -> {
List<ThirdPartyJenkinsJobResponse> jobs = Optional.ofNullable(viewDetail.getJobs()).orElse(new ArrayList<>());
ExecutorService jobPool = Executors.newFixedThreadPool(jobs.size(), r -> {
Thread thread = new Thread(r);
thread.setName("jenkins-sync-view-job-thread-" + System.currentTimeMillis());
return thread;
});
log.debug("The job pool size:{}, viewName:{}", jobs.size(), viewDetail.getName());
CompletableFuture[] jobFutures = jobs.parallelStream().map(job -> CompletableFuture.runAsync(() -> {
AtomicBoolean needSyncBuild = new AtomicBoolean(false); AtomicBoolean needSyncBuild = new AtomicBoolean(false);
val redisValue = (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName())); val redisValue = (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName()));
VoidFunc0 jobBusiness = () -> { VoidFunc0 jobBusiness = () -> {
@ -106,8 +143,19 @@ public class JenkinsDataCacheSynchronizer {
log.info("The job need to synchronize build data, viewName:{}, jobName:{}", viewDetail.getName(), job.getName()); 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()))); buildSingleByJob(viewDetail.getName(), (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName())));
} }
});
}); }, jobPool)).toArray(CompletableFuture[]::new);
CompletableFuture<Void> jobAllOf = CompletableFuture.allOf(jobFutures);
jobAllOf.thenRun(() -> {
log.debug("All future jenkins view sync job completed, viewName:{}", viewDetail.getName());
jobPool.shutdown();
}).join();
}, viewPool)).toArray(CompletableFuture[]::new);
CompletableFuture<Void> allOf = CompletableFuture.allOf(viewFutures);
allOf.thenRun(() -> {
log.debug("All future jenkins view sync task completed");
viewPool.shutdown();
}).join();
} }
public void buildSingleByJob(String viewName, ThirdPartyJenkinsJobDetailResponse jobDetail) { public void buildSingleByJob(String viewName, ThirdPartyJenkinsJobDetailResponse jobDetail) {
@ -130,11 +178,19 @@ public class JenkinsDataCacheSynchronizer {
} }
public void build() { public void build() {
getCacheJobs().forEach(jobContainer -> { val cacheJobs = getCacheJobs();
String viewName = jobContainer.getLeft(); if (CollectionUtils.isEmpty(cacheJobs)) {
val jobDetail = jobContainer.getRight(); return;
buildSingleByJob(viewName, jobDetail); }
}); ExecutorService pools = Executors.newFixedThreadPool(cacheJobs.size());
CompletableFuture[] futures = cacheJobs.parallelStream().map(jobContainer -> CompletableFuture.runAsync(() -> {
buildSingleByJob(jobContainer.getLeft(), jobContainer.getRight());
}, pools)).toArray(CompletableFuture[]::new);
CompletableFuture<Void> allOf = CompletableFuture.allOf(futures);
allOf.thenRun(() -> {
log.info("All future jenkins build sync task completed");
pools.shutdown();
}).join();
} }
public List<ThirdPartyJenkinsViewResponse> getCacheViews() { public List<ThirdPartyJenkinsViewResponse> getCacheViews() {

View File

@ -1,6 +1,6 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty; package com.qc.soft.deploy.ease.adapter.api.thirdparty;
import com.qc.soft.deploy.ease.adapter.HttpClient; import com.qc.soft.framework.basic.http.HttpClient;
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.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;
@ -18,7 +18,7 @@ import org.springframework.stereotype.Component;
public class JenkinsRealTimeDataProvider extends IJenkinsDataProvider { public class JenkinsRealTimeDataProvider extends IJenkinsDataProvider {
@Override @Override
public ThirdPartyJenkinsResponse views() { public ThirdPartyJenkinsResponse views() {
log.info("Query jenkins view api"); log.debug("Query jenkins view api");
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization()); headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization());
ThirdPartyJenkinsResponse jenkinsResponse = HttpClient.get(String.format(JenkinsConstants.JENKINS_VIEWS_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl()), headers, ThirdPartyJenkinsResponse.class); ThirdPartyJenkinsResponse jenkinsResponse = HttpClient.get(String.format(JenkinsConstants.JENKINS_VIEWS_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl()), headers, ThirdPartyJenkinsResponse.class);
@ -28,11 +28,11 @@ public class JenkinsRealTimeDataProvider extends IJenkinsDataProvider {
@Override @Override
public ThirdPartyJenkinsViewDetailResponse viewDetail(String viewName) { public ThirdPartyJenkinsViewDetailResponse viewDetail(String viewName) {
log.info("Query jenkins view detail api, viewName:{}", viewName); log.debug("Query jenkins view detail api, viewName:{}", viewName);
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization()); headers.set("Authorization", TenantAdapterContext.getJenkinsAuthorization());
String urlFormat = StringUtils.isEmpty(viewName) ? 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); String.format(JenkinsConstants.JENKINS_JOB_ALL_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl()) : String.format(JenkinsConstants.JENKINS_JOB_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl(), viewName);
try { try {
return HttpClient.get(urlFormat, headers, ThirdPartyJenkinsViewDetailResponse.class); return HttpClient.get(urlFormat, headers, ThirdPartyJenkinsViewDetailResponse.class);
} catch (Exception e) { } catch (Exception e) {

View File

@ -1,14 +1,10 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build; package com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.qc.soft.deploy.ease.adapter.config.DateStrToFormatDateStrDeserializer;
import com.qc.soft.deploy.ease.adapter.config.Timestamp2StrDeserializer;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;

View File

@ -1,7 +1,5 @@
package com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build; package com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.qc.soft.deploy.ease.adapter.config.Timestamp2StrDeserializer;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;

View File

@ -0,0 +1,56 @@
package com.qc.soft.deploy.ease.adapter.config;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsLoginBasic;
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;
@Configuration
@Slf4j
@Order(value = 100)
public class TenantAdapterBeanRegistry 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"));
JenkinsLoginBasic loginBasic = new JenkinsLoginBasic();
loginBasic.setName("longi-dev&uat");
loginBasic.setUrl("http://jenkins-rd.longi.com:8080");
loginBasic.setUsername("ibpuser");
loginBasic.setPassword("ibp@ibp!2023");
TenantAdapterContext.buildJenkinsLoginBasic(loginBasic);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}

View File

@ -0,0 +1,31 @@
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;
@Configuration
public class TenantAdapterConfiguration {
@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

@ -1,104 +0,0 @@
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,7 +0,0 @@
package com.qc.soft.deploy.ease.adapter.consts;
public class Consts {
}

View File

@ -16,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:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":jenkins:original"; public static final String REDIS_JENKINS_ORIGINAL_VIEW = "deploy-ease:jenkins:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":original";
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 = "deploy-ease:jenkins:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":original:view:%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_JOB_DETAIL = "deploy-ease:jenkins:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":original:view:%s:job:%s";
public static final String REDIS_JENKINS_ORIGINAL_VIEW_BUILD = "deploy-ease:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":jenkins:original:view:%s:job:%s:build:%s"; public static final String REDIS_JENKINS_ORIGINAL_VIEW_BUILD = "deploy-ease:jenkins:" + TenantAdapterContext.getJenkinsLoginBasic().getName() + ":original:view:%s:job:%s:build:%s";
} }

View File

@ -3,7 +3,7 @@ package com.qc.soft.deploy.ease.adapter.context;
import com.alibaba.ttl.TransmittableThreadLocal; import com.alibaba.ttl.TransmittableThreadLocal;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
public class JenkinsBuildSimpleSupportContext { public class JenkinsBuildSimpleSupportAdhocContext {
private static final TransmittableThreadLocal<Pair<String, String>> context = new TransmittableThreadLocal<>(); private static final TransmittableThreadLocal<Pair<String, String>> context = new TransmittableThreadLocal<>();
public static void setValue(Pair<String, String> value) { public static void setValue(Pair<String, String> value) {

View File

@ -6,12 +6,17 @@ import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.job.JenkinsJo
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.view.JenkinsResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.view.JenkinsResponse;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.view.JenkinsViewDetailResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.view.JenkinsViewDetailResponse;
import com.qc.soft.deploy.ease.adapter.service.IJenkinsService; import com.qc.soft.deploy.ease.adapter.service.IJenkinsService;
import com.qc.soft.deploy.ease.api.response.TenantDictionaryResponse;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;
@RestController @RestController
@RequestMapping("/mgmt") @RequestMapping("/mgmt")
@ -53,8 +58,15 @@ public class JenkinsController {
return jenkinsService.build(viewName, jobName, buildNumber); return jenkinsService.build(viewName, jobName, buildNumber);
} }
@GetMapping("jenkins/aggregate") // @GetMapping(value = "jenkins/aggregate", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
// public Flux<JenkinsAggregateResponse> aggregate() {
// return Flux.interval(Duration.ofSeconds(2)).map(index -> jenkinsService.aggregate());
// }
@GetMapping(value = "jenkins/aggregate")
public JenkinsAggregateResponse aggregate() { public JenkinsAggregateResponse aggregate() {
return jenkinsService.aggregate(); return jenkinsService.aggregate();
} }
} }

View File

@ -4,10 +4,9 @@ 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.ThirdPartyJenkinsBuildResponse;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.response.build.ThirdPartyJenkinsBuildSimpleResponse; 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.JenkinsBuildSimpleSupportAdhocContext;
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.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 lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@ -35,7 +34,7 @@ public abstract class JenkinsJobDetailConvert {
@AfterMapping @AfterMapping
void afterMapping(ThirdPartyJenkinsBuildSimpleResponse source, @MappingTarget JenkinsViewProjectTaskAggregateResponse target) { void afterMapping(ThirdPartyJenkinsBuildSimpleResponse source, @MappingTarget JenkinsViewProjectTaskAggregateResponse target) {
Pair<String, String> value = JenkinsBuildSimpleSupportContext.getValue(); Pair<String, String> value = JenkinsBuildSimpleSupportAdhocContext.getValue();
ThirdPartyJenkinsBuildResponse jenkinsBuild = jenkinsCacheDataProvider.build(value.getLeft(), value.getRight(), source.getNumber()); ThirdPartyJenkinsBuildResponse jenkinsBuild = jenkinsCacheDataProvider.build(value.getLeft(), value.getRight(), source.getNumber());
JenkinsBuildConvert.INSTANCE.response2ApiAggregateResponse(jenkinsBuild, target); JenkinsBuildConvert.INSTANCE.response2ApiAggregateResponse(jenkinsBuild, target);
} }

View File

@ -3,10 +3,7 @@ package com.qc.soft.deploy.ease.adapter.service.impl;
import cn.hutool.core.date.StopWatch; import cn.hutool.core.date.StopWatch;
import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsBusinessProvider; import com.qc.soft.deploy.ease.adapter.api.thirdparty.JenkinsBusinessProvider;
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.job.ThirdPartyJenkinsJobDetailResponse; import com.qc.soft.deploy.ease.adapter.context.JenkinsBuildSimpleSupportAdhocContext;
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.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;
import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectAggregateResponse; import com.qc.soft.deploy.ease.adapter.controller.response.jenkins.aggregate.JenkinsViewProjectAggregateResponse;
@ -27,6 +24,10 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service @Service
@Slf4j @Slf4j
@ -71,22 +72,32 @@ public class JenkinsServiceImpl implements IJenkinsService {
val aggregate = new JenkinsAggregateResponse(); val aggregate = new JenkinsAggregateResponse();
List<JenkinsViewAggregateResponse> viewsAggregate = new ArrayList<>(); List<JenkinsViewAggregateResponse> viewsAggregate = new ArrayList<>();
val container = jenkinsBusinessProvider.views(); val container = jenkinsBusinessProvider.views();
container.getViews().forEach(view -> { ExecutorService pool = Executors.newFixedThreadPool(container.getViews().size());
CompletableFuture[] futures = container.getViews().parallelStream().map(view -> CompletableFuture.supplyAsync(() -> {
String viewName = view.getName(); String viewName = view.getName();
val jobsContainer = jenkinsBusinessProvider.viewDetail(viewName); val jobsContainer = jenkinsBusinessProvider.viewDetail(viewName);
List<JenkinsViewProjectAggregateResponse> viewProjectsAggregate = new ArrayList<>(); List<JenkinsViewProjectAggregateResponse> viewProjectsAggregate = new ArrayList<>();
jobsContainer.getJobs().forEach(job -> { jobsContainer.getJobs().forEach(job -> {
val jobDetailContainer = jenkinsBusinessProvider.job(viewName, job.getName()); val jobDetailContainer = jenkinsBusinessProvider.job(viewName, job.getName());
JenkinsBuildSimpleSupportContext.setValue(Pair.of(viewName, job.getName())); JenkinsBuildSimpleSupportAdhocContext.setValue(Pair.of(viewName, job.getName()));
val viewProjectAggregate = jenkinsJobDetailConvert.response2AggregateResponse(jobDetailContainer); val viewProjectAggregate = jenkinsJobDetailConvert.response2AggregateResponse(jobDetailContainer);
JenkinsBuildSimpleSupportContext.clear(); JenkinsBuildSimpleSupportAdhocContext.clear();
viewProjectsAggregate.add(viewProjectAggregate); viewProjectsAggregate.add(viewProjectAggregate);
}); });
val viewAggregate = new JenkinsViewAggregateResponse(); val viewAggregate = new JenkinsViewAggregateResponse();
viewAggregate.setViewName(viewName); viewAggregate.setViewName(viewName);
viewAggregate.setProjects(viewProjectsAggregate); viewAggregate.setProjects(viewProjectsAggregate);
viewsAggregate.add(viewAggregate); return viewAggregate;
}); }, pool)).toArray(CompletableFuture[]::new);
try {
CompletableFuture.allOf(futures).thenRun(pool::shutdown);
for (CompletableFuture<JenkinsViewAggregateResponse> future : futures) {
JenkinsViewAggregateResponse result = future.get();
viewsAggregate.add(result);
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
aggregate.setViews(viewsAggregate); aggregate.setViews(viewsAggregate);
stopWatch.stop(); stopWatch.stop();
log.info("Elapsed time in seconds:{}", stopWatch.getTotalTimeSeconds()); log.info("Elapsed time in seconds:{}", stopWatch.getTotalTimeSeconds());

View File

@ -1,5 +1,6 @@
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

@ -2,6 +2,7 @@ spring:
application: application:
name: deploy-ease-tenant-adapter name: deploy-ease-tenant-adapter
redis: redis:
enabled: true
host: localhost host: localhost
port: 6379 port: 6379
database: 0 database: 0

View File

@ -1,5 +1,6 @@
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

@ -2,6 +2,7 @@ spring:
application: application:
name: deploy-ease-tenant-adapter name: deploy-ease-tenant-adapter
redis: redis:
enabled: true
host: localhost host: localhost
port: 6379 port: 6379
database: 0 database: 0