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.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.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.Configuration;
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;
@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());
};
}
public class RedisConfiguration {
@Bean(name = "redisTemplate")
@Bean(name = "stringRedisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);

View File

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

View File

@ -113,10 +113,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<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.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 {
@ -28,9 +19,6 @@ public class JenkinsBusinessProvider {
@Resource
private JenkinsCacheDataProvider cacheDataProvider;
@Resource
private RedisTemplate<String, Object> redisTemplate;
public ThirdPartyJenkinsResponse views() {
ThirdPartyJenkinsResponse redisValue = cacheDataProvider.views();
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 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.ThirdPartyJenkinsJobResponse;
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;
@ -10,9 +11,9 @@ 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.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -22,6 +23,9 @@ import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
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 static com.qc.soft.deploy.ease.adapter.consts.JenkinsConstants.REDIS_JENKINS_ORIGINAL_VIEW;
@ -39,8 +43,28 @@ public class JenkinsDataCacheSynchronizer {
@Resource
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 * * * ?")
public void views() {
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() {
getCacheViewsDetail().forEach(viewDetail -> {
Optional.ofNullable(viewDetail.getJobs()).orElse(new ArrayList<>()).forEach(job -> {
List<ThirdPartyJenkinsViewDetailResponse> cacheViewsDetail = getCacheViewsDetail();
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);
val redisValue = (ThirdPartyJenkinsJobDetailResponse) redisTemplate.opsForValue().get(String.format(REDIS_JENKINS_ORIGINAL_VIEW_JOB_DETAIL, viewDetail.getName(), job.getName()));
VoidFunc0 jobBusiness = () -> {
@ -106,8 +143,19 @@ public class JenkinsDataCacheSynchronizer {
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())));
}
});
});
}, 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) {
@ -130,11 +178,19 @@ public class JenkinsDataCacheSynchronizer {
}
public void build() {
getCacheJobs().forEach(jobContainer -> {
String viewName = jobContainer.getLeft();
val jobDetail = jobContainer.getRight();
buildSingleByJob(viewName, jobDetail);
});
val cacheJobs = getCacheJobs();
if (CollectionUtils.isEmpty(cacheJobs)) {
return;
}
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() {

View File

@ -1,6 +1,6 @@
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.job.ThirdPartyJenkinsJobDetailResponse;
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 {
@Override
public ThirdPartyJenkinsResponse views() {
log.info("Query jenkins view api");
log.debug("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);
@ -28,11 +28,11 @@ public class JenkinsRealTimeDataProvider extends IJenkinsDataProvider {
@Override
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();
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);
String.format(JenkinsConstants.JENKINS_JOB_ALL_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl()) : String.format(JenkinsConstants.JENKINS_JOB_API, TenantAdapterContext.getJenkinsLoginBasic().getUrl(), viewName);
try {
return HttpClient.get(urlFormat, headers, ThirdPartyJenkinsViewDetailResponse.class);
} catch (Exception e) {

View File

@ -1,14 +1,10 @@
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.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

View File

@ -1,7 +1,5 @@
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.EqualsAndHashCode;
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 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 org.apache.commons.lang3.tuple.Pair;
public class JenkinsBuildSimpleSupportContext {
public class JenkinsBuildSimpleSupportAdhocContext {
private static final TransmittableThreadLocal<Pair<String, String>> context = new TransmittableThreadLocal<>();
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.JenkinsViewDetailResponse;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;
@RestController
@RequestMapping("/mgmt")
@ -53,8 +58,15 @@ public class JenkinsController {
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() {
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.ThirdPartyJenkinsBuildSimpleResponse;
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.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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
@ -35,7 +34,7 @@ public abstract class JenkinsJobDetailConvert {
@AfterMapping
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());
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 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.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.context.JenkinsBuildSimpleSupportContext;
import com.qc.soft.deploy.ease.adapter.context.JenkinsBuildSimpleSupportAdhocContext;
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.JenkinsViewProjectAggregateResponse;
@ -27,6 +24,10 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
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
@Slf4j
@ -71,22 +72,32 @@ public class JenkinsServiceImpl implements IJenkinsService {
val aggregate = new JenkinsAggregateResponse();
List<JenkinsViewAggregateResponse> viewsAggregate = new ArrayList<>();
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();
val jobsContainer = jenkinsBusinessProvider.viewDetail(viewName);
List<JenkinsViewProjectAggregateResponse> viewProjectsAggregate = new ArrayList<>();
jobsContainer.getJobs().forEach(job -> {
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);
JenkinsBuildSimpleSupportContext.clear();
JenkinsBuildSimpleSupportAdhocContext.clear();
viewProjectsAggregate.add(viewProjectAggregate);
});
val viewAggregate = new JenkinsViewAggregateResponse();
viewAggregate.setViewName(viewName);
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);
stopWatch.stop();
log.info("Elapsed time in seconds:{}", stopWatch.getTotalTimeSeconds());

View File

@ -1,5 +1,6 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
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.config.GlobalResponseHandler,\
com.qc.soft.framework.basic.config.GlobalExceptionHandler

View File

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

View File

@ -1,5 +1,6 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
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.config.GlobalResponseHandler,\
com.qc.soft.framework.basic.config.GlobalExceptionHandler

View File

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