diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/DateStrToFormatDateStrDeserializer.java b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/deserializer/DateStrToFormatDateStrDeserializer.java similarity index 96% rename from deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/DateStrToFormatDateStrDeserializer.java rename to deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/deserializer/DateStrToFormatDateStrDeserializer.java index ed6a768..b6e1755 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/DateStrToFormatDateStrDeserializer.java +++ b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/deserializer/DateStrToFormatDateStrDeserializer.java @@ -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; diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/Timestamp2StrDeserializer.java b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/deserializer/Timestamp2StrDeserializer.java similarity index 94% rename from deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/Timestamp2StrDeserializer.java rename to deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/deserializer/Timestamp2StrDeserializer.java index 356a7b4..1d71c1a 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/Timestamp2StrDeserializer.java +++ b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/deserializer/Timestamp2StrDeserializer.java @@ -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; diff --git a/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/http/HttpClient.java b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/http/HttpClient.java index e69de29..8138443 100644 --- a/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/http/HttpClient.java +++ b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/http/HttpClient.java @@ -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 T get(String url, H headers, Class cls) { + HttpEntity entity = new HttpEntity<>(headers); + ResponseEntity response = getRestTemplate().exchange(url, HttpMethod.GET, entity, cls); + return response.getBody(); + } + + + private static RestTemplate getRestTemplate() { + return context.getBean(RestTemplate.class); + } + +} diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/AppConfiguration.java b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/http/RedisConfiguration.java similarity index 69% rename from deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/AppConfiguration.java rename to deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/http/RedisConfiguration.java index 6b2c564..9e46af2 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/AppConfiguration.java +++ b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/http/RedisConfiguration.java @@ -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 redisTemplate(RedisConnectionFactory factory) { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); diff --git a/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/redis/RedisAutoConfiguration.java b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/redis/RedisAutoConfiguration.java index 3ed78ef..9ed6a6f 100644 --- a/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/redis/RedisAutoConfiguration.java +++ b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/redis/RedisAutoConfiguration.java @@ -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 redisTemplate(RedisConnectionFactory redisConnectionFactory) { -// RedisTemplate template = new RedisTemplate<>(); -// template.setConnectionFactory(redisConnectionFactory); -// FastJson2JsonRedisSerializer 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 redisTemplate(RedisConnectionFactory factory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(factory); + RedisSerializer 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 limitScript() -// { -// DefaultRedisScript 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);"; -// } } diff --git a/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/utils/HttpUtils.java b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/utils/HttpUtils.java index 70e1c31..4db19f6 100644 --- a/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/utils/HttpUtils.java +++ b/deploy-ease-basic/src/main/java/com/qc/soft/framework/basic/utils/HttpUtils.java @@ -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 { - - public static final int fileSize = 10 * 1024; - - public static T get(String url, Map header, Class 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 get(String url, Map 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 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 post(String url, IdentityHashMap header) { - CloseableHttpClient httpclient = HttpClients.createDefault(); - HttpPost post = new HttpPost(url); - CloseableHttpResponse response = null; - Map 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 cookieGet(String url, Map header, Class 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
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 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 uploadFile(String url, String filePath, Class 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 { +// +// public static final int fileSize = 10 * 1024; +// +// public static T get(String url, Map header, Class 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 get(String url, Map 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 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 post(String url, IdentityHashMap header) { +// CloseableHttpClient httpclient = HttpClients.createDefault(); +// HttpPost post = new HttpPost(url); +// CloseableHttpResponse response = null; +// Map 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 cookieGet(String url, Map header, Class 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
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 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 uploadFile(String url, String filePath, Class 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; +// } +//} diff --git a/deploy-ease-tenant-adapter/pom.xml b/deploy-ease-tenant-adapter/pom.xml index fdf3a08..595a685 100644 --- a/deploy-ease-tenant-adapter/pom.xml +++ b/deploy-ease-tenant-adapter/pom.xml @@ -113,10 +113,6 @@ org.springframework.boot spring-boot-starter-aop - - org.springframework.boot - spring-boot-starter-data-redis - org.apache.commons commons-pool2 diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/HttpClient.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/HttpClient.java deleted file mode 100644 index 4c23696..0000000 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/HttpClient.java +++ /dev/null @@ -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 T get(String url, H headers, Class cls) { - HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = getRestTemplate().exchange(url, HttpMethod.GET, entity, cls); - return response.getBody(); - } - - - private static RestTemplate getRestTemplate() { - return context.getBean(RestTemplate.class); - } - -} diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsBusinessProvider.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsBusinessProvider.java index 5797700..7bffc20 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsBusinessProvider.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsBusinessProvider.java @@ -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 redisTemplate; - public ThirdPartyJenkinsResponse views() { ThirdPartyJenkinsResponse redisValue = cacheDataProvider.views(); if (redisValue == null) { diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsDataCacheSynchronizer.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsDataCacheSynchronizer.java index 75fe888..4d1ee44 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsDataCacheSynchronizer.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsDataCacheSynchronizer.java @@ -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 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 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 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 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 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 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 allOf = CompletableFuture.allOf(futures); + allOf.thenRun(() -> { + log.info("All future jenkins build sync task completed"); + pools.shutdown(); + }).join(); } public List getCacheViews() { diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsRealTimeDataProvider.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsRealTimeDataProvider.java index 4d986d5..7ba439f 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsRealTimeDataProvider.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/JenkinsRealTimeDataProvider.java @@ -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) { diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildChangeSetDetailResponse.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildChangeSetDetailResponse.java index 98633da..76fdda8 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildChangeSetDetailResponse.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildChangeSetDetailResponse.java @@ -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; diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildResponse.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildResponse.java index f59500c..4e7ba0f 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildResponse.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/api/thirdparty/response/build/ThirdPartyJenkinsBuildResponse.java @@ -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; diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantAdapterBeanRegistry.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantAdapterBeanRegistry.java new file mode 100644 index 0000000..c16657d --- /dev/null +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantAdapterBeanRegistry.java @@ -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 { + } + +} diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantAdapterConfiguration.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantAdapterConfiguration.java new file mode 100644 index 0000000..78f4c23 --- /dev/null +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantAdapterConfiguration.java @@ -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 redisTemplate(RedisConnectionFactory factory) { +// RedisTemplate redisTemplate = new RedisTemplate<>(); +// redisTemplate.setConnectionFactory(factory); +// RedisSerializer stringSerializer = new StringRedisSerializer(); +// GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(); +// redisTemplate.setKeySerializer(stringSerializer); +// redisTemplate.setValueSerializer(serializer); +// redisTemplate.setHashKeySerializer(stringSerializer); +// redisTemplate.setHashValueSerializer(serializer); +// return redisTemplate; +// } + + +} diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantBeanDefinitionRegistry.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantBeanDefinitionRegistry.java deleted file mode 100644 index d45b060..0000000 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/config/TenantBeanDefinitionRegistry.java +++ /dev/null @@ -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 taskQueue = new LinkedList<>(); - - @Resource - private JenkinsDataCacheSynchronizer jenkinsDataCacheSynchronizer; - - private RedisTemplate 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 processNextTask() { - Runnable task = taskQueue.poll(); - if (task == null) { - return CompletableFuture.completedFuture(null); - } - // 异步执行任务 - return CompletableFuture.runAsync(task, executorService) - .thenCompose(v -> processNextTask()); - } - -} diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/consts/Consts.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/consts/Consts.java deleted file mode 100644 index e26eff4..0000000 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/consts/Consts.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.qc.soft.deploy.ease.adapter.consts; - -public class Consts { - - - -} diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/consts/JenkinsConstants.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/consts/JenkinsConstants.java index cc64a42..365e821 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/consts/JenkinsConstants.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/consts/JenkinsConstants.java @@ -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"; } diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/context/JenkinsBuildSimpleSupportContext.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/context/JenkinsBuildSimpleSupportAdhocContext.java similarity index 90% rename from deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/context/JenkinsBuildSimpleSupportContext.java rename to deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/context/JenkinsBuildSimpleSupportAdhocContext.java index b2fe5c7..8ee309a 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/context/JenkinsBuildSimpleSupportContext.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/context/JenkinsBuildSimpleSupportAdhocContext.java @@ -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> context = new TransmittableThreadLocal<>(); public static void setValue(Pair value) { diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/controller/JenkinsController.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/controller/JenkinsController.java index ccedb60..2174407 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/controller/JenkinsController.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/controller/JenkinsController.java @@ -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") @@ -40,7 +45,7 @@ public class JenkinsController { @GetMapping({"/jenkins/{viewName}/job/{jobName}/detail"}) public JenkinsJobDetailResponse jobDetail( @PathVariable(value = "viewName") String viewName, - @PathVariable(value = "jobName") String jobName){ + @PathVariable(value = "jobName") String jobName) { return jenkinsService.job(viewName, jobName); } @@ -49,12 +54,19 @@ public class JenkinsController { public JenkinsBuildResponse jobBuild( @PathVariable(value = "viewName") String viewName, @PathVariable(value = "jobName") String jobName, - @PathVariable(value = "buildNumber") Long buildNumber){ + @PathVariable(value = "buildNumber") Long buildNumber) { return jenkinsService.build(viewName, jobName, buildNumber); } - @GetMapping("jenkins/aggregate") - public JenkinsAggregateResponse aggregate(){ +// @GetMapping(value = "jenkins/aggregate", produces = MediaType.TEXT_EVENT_STREAM_VALUE) +// public Flux aggregate() { +// return Flux.interval(Duration.ofSeconds(2)).map(index -> jenkinsService.aggregate()); +// } + + @GetMapping(value = "jenkins/aggregate") + public JenkinsAggregateResponse aggregate() { return jenkinsService.aggregate(); } + + } diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/convert/JenkinsJobDetailConvert.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/convert/JenkinsJobDetailConvert.java index fd0f8d0..3c8016d 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/convert/JenkinsJobDetailConvert.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/convert/JenkinsJobDetailConvert.java @@ -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 value = JenkinsBuildSimpleSupportContext.getValue(); + Pair value = JenkinsBuildSimpleSupportAdhocContext.getValue(); ThirdPartyJenkinsBuildResponse jenkinsBuild = jenkinsCacheDataProvider.build(value.getLeft(), value.getRight(), source.getNumber()); JenkinsBuildConvert.INSTANCE.response2ApiAggregateResponse(jenkinsBuild, target); } diff --git a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/service/impl/JenkinsServiceImpl.java b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/service/impl/JenkinsServiceImpl.java index 069facd..ca21b39 100644 --- a/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/service/impl/JenkinsServiceImpl.java +++ b/deploy-ease-tenant-adapter/src/main/java/com/qc/soft/deploy/ease/adapter/service/impl/JenkinsServiceImpl.java @@ -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 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 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 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()); diff --git a/deploy-ease-tenant-adapter/src/main/resources/META-INF/spring.factories b/deploy-ease-tenant-adapter/src/main/resources/META-INF/spring.factories index 5ae339f..039f92d 100644 --- a/deploy-ease-tenant-adapter/src/main/resources/META-INF/spring.factories +++ b/deploy-ease-tenant-adapter/src/main/resources/META-INF/spring.factories @@ -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 \ No newline at end of file diff --git a/deploy-ease-tenant-adapter/src/main/resources/application-dev.yml b/deploy-ease-tenant-adapter/src/main/resources/application-dev.yml index 3e5a51d..9488fa3 100644 --- a/deploy-ease-tenant-adapter/src/main/resources/application-dev.yml +++ b/deploy-ease-tenant-adapter/src/main/resources/application-dev.yml @@ -2,6 +2,7 @@ spring: application: name: deploy-ease-tenant-adapter redis: + enabled: true host: localhost port: 6379 database: 0 diff --git a/deploy-ease-tenant-adapter/target/classes/META-INF/spring.factories b/deploy-ease-tenant-adapter/target/classes/META-INF/spring.factories index 5ae339f..039f92d 100644 --- a/deploy-ease-tenant-adapter/target/classes/META-INF/spring.factories +++ b/deploy-ease-tenant-adapter/target/classes/META-INF/spring.factories @@ -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 \ No newline at end of file diff --git a/deploy-ease-tenant-adapter/target/classes/application-dev.yml b/deploy-ease-tenant-adapter/target/classes/application-dev.yml index 3e5a51d..9488fa3 100644 --- a/deploy-ease-tenant-adapter/target/classes/application-dev.yml +++ b/deploy-ease-tenant-adapter/target/classes/application-dev.yml @@ -2,6 +2,7 @@ spring: application: name: deploy-ease-tenant-adapter redis: + enabled: true host: localhost port: 6379 database: 0