瀏覽代碼

版本分支提交

liukaixiong 4 年之前
父節點
當前提交
0443b0f920
共有 47 個文件被更改,包括 1799 次插入269 次删除
  1. 1 1
      README.md
  2. 1 1
      elab-alert/pom.xml
  3. 1 1
      elab-annotation/pom.xml
  4. 1 1
      elab-cache/pom.xml
  5. 1 1
      elab-core/pom.xml
  6. 7 1
      elab-core/src/main/java/com/elab/core/async/store/TaskExecutorQueue.java
  7. 75 0
      elab-core/src/main/java/com/elab/core/utils/DataUtils.java
  8. 1 1
      elab-db/pom.xml
  9. 2 2
      elab-es/pom.xml
  10. 160 0
      elab-kafka/README.md
  11. 54 0
      elab-kafka/pom.xml
  12. 180 0
      elab-kafka/src/main/java/com/elab/core/kafka/config/KafkaConsumerConfig.java
  13. 19 0
      elab-kafka/src/main/java/com/elab/core/kafka/consumer/AbstractKafkaConsumer.java
  14. 54 0
      elab-kafka/src/main/java/com/elab/core/kafka/consumer/KafkaMsgListener.java
  15. 30 0
      elab-kafka/src/main/java/com/elab/core/kafka/monitor/TopicMonitorRule.java
  16. 52 0
      elab-kafka/src/main/java/com/elab/core/kafka/sender/KafkaProducerImpl.java
  17. 1 0
      elab-kafka/src/main/resources/META-INF/spring.factories
  18. 31 0
      elab-kafka/src/test/java/com/elab/core/kafka/consumer/AbstractKafkaConsumerTest.java
  19. 34 0
      elab-kafka/src/test/java/com/elab/core/kafka/consumer/ConsumerListener.java
  20. 41 0
      elab-kafka/src/test/java/com/elab/core/kafka/monitor/TestTopicMonitorRule.java
  21. 64 0
      elab-kafka/src/test/java/com/elab/core/kafka/sender/KafkaProducerImplTest.java
  22. 32 0
      elab-kafka/src/test/resources/application.yml
  23. 二進制
      elab-kafka/src/test/resources/kafka.client.truststore.jks
  24. 5 0
      elab-kafka/src/test/resources/kafka_client_jaas.conf
  25. 1 1
      elab-log/pom.xml
  26. 1 1
      elab-log/src/main/java/com/elab/log/CatThreadProcess.java
  27. 1 1
      elab-log/src/main/java/com/elab/log/ext/CatRealTaskExecutor.java
  28. 50 0
      elab-log/src/main/java/com/elab/log/model/CatCrossIdModel.java
  29. 137 10
      elab-log/src/main/java/com/elab/log/utils/CatCrossProcess.java
  30. 72 0
      elab-log/src/test/java/com/elab/log/utils/CatCrossProcessTest.java
  31. 1 0
      elab-log/src/test/resources/META-INF/app.properties
  32. 112 0
      elab-log/src/test/resources/META-INF/plexus/components-cat-client.xml
  33. 31 0
      elab-log/src/test/resources/logback.xml
  34. 1 1
      elab-mongodb/pom.xml
  35. 1 1
      elab-mq/pom.xml
  36. 1 2
      elab-mq/src/main/java/com/elab/mq/listener/AbstractMessageListener.java
  37. 1 1
      elab-redis/pom.xml
  38. 0 1
      elab-redis/src/main/java/com/elab/redis/CacheTemplate.java
  39. 1 1
      elab-rocketMQ/pom.xml
  40. 5 1
      elab-spring/pom.xml
  41. 53 0
      elab-spring/src/main/java/com/elab/spring/config/ThreadConfiguration.java
  42. 51 0
      elab-spring/src/main/java/com/elab/spring/config/prop/ThreadProperties.java
  43. 38 0
      elab-spring/src/main/java/com/elab/spring/factory/HttpComponentsClientRestfulHttpRequestFactory.java
  44. 7 0
      elab-spring/src/main/java/com/elab/spring/factory/HttpsClientRequestFactory.java
  45. 127 6
      elab-spring/src/main/java/com/elab/spring/utils/RestTemplateUtils.java
  46. 248 232
      elab-spring/src/test/java/com/elab/spring/utils/RestTemplateUtilsTest.java
  47. 12 1
      pom.xml

+ 1 - 1
README.md

@@ -8,4 +8,4 @@
 - [elab-mq](./elab-mq/README.md) : 基于阿里云的商用版RocketMQ开发,为每个请求植入了CAT日志监控。
 - [elab-redis](./elab-redis/README.md) : 基于redis的一些简单封装
 - elab-spring : 对Spring的一些拓展封装
-
+- [elab-kafka](./elab-kafka/README.md) : 基于Kafka使用的封装

+ 1 - 1
elab-alert/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>elab-alert</artifactId>

+ 1 - 1
elab-annotation/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
elab-cache/pom.xml

@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.elab.core</groupId>
         <artifactId>elab-parent</artifactId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <groupId>com.elab.cache</groupId>
     <artifactId>elab-cache</artifactId>

+ 1 - 1
elab-core/pom.xml

@@ -7,7 +7,7 @@
     <parent>
         <groupId>com.elab.core</groupId>
         <artifactId>elab-parent</artifactId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
 
     <groupId>com.elab.core</groupId>

+ 7 - 1
elab-core/src/main/java/com/elab/core/async/store/TaskExecutorQueue.java

@@ -15,10 +15,16 @@ import java.util.concurrent.ArrayBlockingQueue;
  */
 public class TaskExecutorQueue {
 
-    private Queue<TaskExecutorDecoration> realTimeQueue = new ArrayBlockingQueue<TaskExecutorDecoration>(1000);
+
+
+    private Queue<TaskExecutorDecoration> realTimeQueue;
 
     private List<SchedulingTaskExecutor> schedulingList = new ArrayList<>();
 
+//    public TaskExecutorQueue(Integer threadCore, Integer realQueueSize) {
+//        this.realTimeQueue = new ArrayBlockingQueue<TaskExecutorDecoration>(realQueueSize);
+//    }
+
     public void setRealTimeQueue(Queue<TaskExecutorDecoration> realTimeQueue) {
         this.realTimeQueue = realTimeQueue;
     }

+ 75 - 0
elab-core/src/main/java/com/elab/core/utils/DataUtils.java

@@ -0,0 +1,75 @@
+package com.elab.core.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.elab.core.utils.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 数据工具类
+ *
+ * @author : liukx
+ * @time : 2020/4/7 - 14:07
+ */
+public class DataUtils {
+
+    /**
+     * 生成的唯一key
+     *
+     * @param separator 分割符号
+     * @param str       参数内容
+     * @return
+     */
+    public static String genUnionKey(String separator, Object... str) {
+        List<Object> collect = Arrays.stream(str).filter(x -> ObjectUtils.isNotEmpty(x)).collect(Collectors.toList());
+        return StringUtils.join(collect.toArray(), separator);
+    }
+
+    /**
+     * 获取存在的key
+     *
+     * @param jsonObject
+     * @param keys
+     * @return
+     */
+    public static String getDefaultKey(JSONObject jsonObject, String... keys) {
+        for (int i = 0; i < keys.length; i++) {
+            if (jsonObject.containsKey(keys[i]) && jsonObject.get(keys[i]) != null) {
+                return keys[i];
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 获取存在key的值
+     *
+     * @param jsonObject
+     * @param keys
+     * @return
+     */
+    public static Object getDefaultValue(JSONObject jsonObject, String... keys) {
+        for (int i = 0; i < keys.length; i++) {
+            if (jsonObject.containsKey(keys[i])) {
+                return jsonObject.get(keys[i]);
+            }
+        }
+        return null;
+    }
+
+    public static JSONObject getJSONObject(Object obj) {
+        String text = JSON.toJSONString(obj);
+        return JSON.parseObject(text);
+    }
+
+    public static Integer getIntegerValue(Integer value, int defaultValue) {
+        if (value == null) {
+            return defaultValue;
+        }
+        return value;
+    }
+}

+ 1 - 1
elab-db/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <groupId>com.elab.core</groupId>
         <artifactId>elab-parent</artifactId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>elab-db</artifactId>

+ 2 - 2
elab-es/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -40,7 +40,7 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.zxp</groupId>
+            <groupId>cn.zxporz</groupId>
             <artifactId>esclientrhl</artifactId>
             <version>7.0.0</version>
         </dependency>

+ 160 - 0
elab-kafka/README.md

@@ -0,0 +1,160 @@
+# Elab-kafka 使用介绍
+
+## Maven 依赖配置
+
+1. 正常依赖
+
+```xml
+ <dependency>
+     <groupId>com.elab.core</groupId>
+     <artifactId>elab-kafka</artifactId>
+     <version>${elab.version}</version> <!-- 必须大于等于2.0.5.1-SNAPSHOT -->
+</dependency>
+```
+
+2. 如果出现jar包依赖冲突则可以尝试
+
+```xml
+ <dependency>
+     <groupId>com.elab.core</groupId>
+     <artifactId>elab-kafka</artifactId>
+     <version>${elab.version}</version>
+     <exclusions>
+         <exclusion>
+             <artifactId>spring-kafka</artifactId>
+             <groupId>org.springframework.kafka</groupId>
+         </exclusion>
+         <exclusion>
+             <artifactId>kafka-clients</artifactId>
+             <groupId>org.apache.kafka</groupId>
+         </exclusion>
+     </exclusions>
+</dependency>
+<dependency>
+    <groupId>org.springframework.kafka</groupId>
+    <artifactId>spring-kafka</artifactId>
+    <version>2.2.7.RELEASE</version>
+    <exclusions>
+        <exclusion>
+            <artifactId>kafka-clients</artifactId>
+            <groupId>org.apache.kafka</groupId>
+        </exclusion>
+    </exclusions>
+</dependency>
+<dependency>
+    <groupId>org.apache.kafka</groupId>
+    <artifactId>kafka-clients</artifactId>
+    <version>2.0.1</version>
+</dependency>
+```
+
+需要注意的是目前该版本测试是基于SpringBoot 2.1.6.RELEASE 通过。
+
+## 配置文件
+
+```yaml
+spring:
+  kafka:
+    bootstrap-servers: 47.103.15.48:9093,47.103.17.231:9093,47.103.23.79:9093
+    producer:
+      key-serializer: org.apache.kafka.common.serialization.StringSerializer
+      value-serializer: org.apache.kafka.common.serialization.StringSerializer 
+    template:
+      default-topic: uat-mysql-dts
+    consumer:
+      group-id: test-market-db
+      max-poll-records: 30
+      fetch-min-size: 32000
+      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+      enable-auto-commit: false
+```
+
+如果涉及到ssl配置:
+
+```yaml
+java:
+  security:
+    auth:
+      login:
+        config: E:/temp/java/kafka_client_jaas.conf                     # 基于阿里云提供的
+        trust-store-location: E:/temp/java/kafka.client.truststore.jks  # 基于阿里云提供参考 : https://help.aliyun.com/document_detail/99958.html?spm=a2c4g.11186623.2.14.4c2a30f0KEj6Av#concept-99958-zh
+
+```
+
+## 代码使用:
+
+### 发送
+
+```java
+// 引入kafkaTemplate<String,String> 注意,目前还是请用String json的方式进行数据发送
+@Autowired
+private KafkaTemplate<String, String> kafkaTemplate;
+
+
+Map<String, Object> map = new HashMap<>();
+map.put("est", "123123");
+ListenableFuture<SendResult<String, String>> send = kafkaTemplate.send(defaultTopic, JSON.toJSONString(map));
+SendResult<String, String> stringStringSendResult = send.get();
+RecordMetadata recordMetadata = stringStringSendResult.getRecordMetadata();
+
+// 关于顺序消息,希望某一类消息能够顺序消费掉,请将数据的分区下标指定成同一个
+ListenableFuture<SendResult<String, String>> send = kafkaTemplate.send("订阅主题","分区下标","唯一key","Stringjson");
+
+```
+
+
+
+### 消费
+
+请先集成`AbstractKafkaConsumer`,然实现**subscribeTopic**方法,告诉自己到底关注哪类topic.后续会将该类的topic消息回调给onMessage方法
+
+```java
+@Component
+public class ConsumerListener extends AbstractKafkaConsumer {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Override
+    public String subscribeTopic() {
+        return "uat-mysql-dts";
+    }
+
+    @Override
+    public void onMessage(ConsumerRecord<String, String> data, Acknowledgment acknowledgment) {
+        logger.info("------->" + data); 
+    }
+}
+```
+
+## 关于监控
+
+所有kafka 的数据都会基于一个监控数据传输器传送到一个数据收集服务端,如果你有需要根据某些特定的参数查询数据的话可以使用以下方式:
+
+实现`TopicMonitorRule`接口: 以下是参考案例
+
+```java
+@Component
+public class TestTopicMonitorRule implements TopicMonitorRule {
+
+    @Override
+    public Map<String, BiConsumer<String, MQDataDTO>> getRuleMap() {
+        Map<String, BiConsumer<String, MQDataDTO>> map = new HashMap<>();
+        // key 是对应的topic
+        map.put("uat-mysql-dts", (value, mqData) -> {
+            // value就是kafka发送的数据,mqData就是监控数据的结构
+            JSONObject jsonObject = JSON.parseObject(value);
+            mqData.setGroupName(xxx);
+            mqData.setGroupKeyName(xxx);
+            mqData.setDataId(xxx);
+        });
+        return map;
+    }
+}
+```
+
+通常数据采集器会提供三个参数作为搜索条件,你可以利用这三个参数将你**感兴趣或者数据的标识**记录到这三个参数当中,后续可以利用这三个标识快速定位到数据来了解当时执行情况.
+
+>  注意该接口每个项目实现一个即可,一个topic的发送数据对应一个结构对象.
+
+
+

+ 54 - 0
elab-kafka/pom.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>elab-parent</artifactId>
+        <groupId>com.elab.core</groupId>
+        <version>2.0.5.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>elab-kafka</artifactId>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.jay.monitor.data</groupId>
+            <artifactId>jay-monitor-data-client</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.kafka</groupId>
+            <artifactId>spring-kafka</artifactId>
+            <version>2.2.0.RELEASE</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>kafka-clients</artifactId>
+                    <groupId>org.apache.kafka</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.elab.log</groupId>
+            <artifactId>elab-log</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 180 - 0
elab-kafka/src/main/java/com/elab/core/kafka/config/KafkaConsumerConfig.java

@@ -0,0 +1,180 @@
+package com.elab.core.kafka.config;
+
+import com.elab.core.kafka.consumer.AbstractKafkaConsumer;
+import com.elab.core.kafka.consumer.KafkaMsgListener;
+import com.elab.core.kafka.monitor.TopicMonitorRule;
+import com.elab.core.kafka.sender.KafkaProducerImpl;
+import com.jay.monitor.data.client.ext.MqMonitorRuleCallback;
+import com.jay.monitor.data.client.ext.kafka.consumer.KafkaMonitorConsumerListener;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.kafka.clients.CommonClientConfigs;
+import org.apache.kafka.clients.consumer.ConsumerConfig;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.config.SaslConfigs;
+import org.apache.kafka.common.config.SslConfigs;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.core.ConsumerFactory;
+import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
+import org.springframework.kafka.core.DefaultKafkaProducerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.listener.ContainerProperties;
+import org.springframework.kafka.listener.KafkaMessageListenerContainer;
+import org.springframework.kafka.support.ProducerListener;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Configuration
+// @EnableKafka // 这里是 可以开启@Listener注解的
+@EnableConfigurationProperties({KafkaProperties.class})
+public class KafkaConsumerConfig {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Value(value = "${java.security.auth.login.trust-store-location:}")
+    private String sslTruststoreLocation;
+
+    @Value(value = "${java.security.auth.login.config:}")
+    private String authConfig;
+
+    @Autowired(required = false)
+    private List<MqMonitorRuleCallback> monitorRuleCallbacks;
+
+    @Autowired(required = false)
+    private ProducerListener<String, String> producerListeners;
+
+//    @Bean
+//    public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory(KafkaProperties kafkaProperties) {
+//        ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
+//        factory.setConsumerFactory(consumerFactory(kafkaProperties));
+//        // 多线程并发消费
+////        factory.setConcurrency(concurrency);
+//        // 设置手动提交
+//        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
+//        factory.getContainerProperties().setPollTimeout(1500);
+//        return factory;
+//    }
+
+    @Bean
+    @ConditionalOnBean(value = {AbstractKafkaConsumer.class})
+    public KafkaMessageListenerContainer<String, String> kafkaMessageListenerContainer(KafkaProperties kafkaProperties, List<AbstractKafkaConsumer> kafkaConsumer) {
+        List<String> topicList = kafkaConsumer.stream().map(AbstractKafkaConsumer::subscribeTopic).collect(Collectors.toList());
+        logger.info("关注kafka的topic:" + topicList);
+        ContainerProperties containerProps = new ContainerProperties(topicList.toArray(new String[topicList.size()]));
+
+        KafkaMsgListener kafkaMsgListener = new KafkaMsgListener(kafkaConsumer);
+        // 包装成监控
+        KafkaMonitorConsumerListener kafkaMonitorConsumerListener = new KafkaMonitorConsumerListener(kafkaMsgListener, monitorRuleCallbacks);
+
+        containerProps.setMessageListener(kafkaMonitorConsumerListener);
+        containerProps.setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
+        containerProps.setSyncCommits(true);
+        DefaultKafkaConsumerFactory<String, String> cf =
+                new DefaultKafkaConsumerFactory<String, String>(getConfigConsumerMap(kafkaProperties));
+        KafkaMessageListenerContainer<String, String> container =
+                new KafkaMessageListenerContainer<>(cf, containerProps);
+        return container;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(value = {TopicMonitorRule.class})
+    public TopicMonitorRule topicMonitorRule() {
+        return new TopicMonitorRule();
+    }
+
+
+    public ConsumerFactory<String, String> consumerFactory(KafkaProperties kafkaProperties) {
+        Map<String, Object> props = getConfigConsumerMap(kafkaProperties);
+        return new DefaultKafkaConsumerFactory<String, String>(props);
+    }
+
+    @Bean
+    public KafkaTemplate<String, String> kafkaTemplate(KafkaProperties kafkaProperties) {
+        Map<String, Object> props = new LinkedHashMap<>();
+        //设置接入点,请通过控制台获取对应 Topic 的接入点
+        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getBootstrapServers());
+        //消息队列 Kafka 消息的序列化方式
+        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+        //请求的最长等待时间
+        props.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 30 * 1000);
+        //设置客户端内部重试次数。
+        props.put(ProducerConfig.RETRIES_CONFIG, 5);
+        //设置客户端内部重试间隔。
+        props.put(ProducerConfig.RECONNECT_BACKOFF_MS_CONFIG, 3000);
+        if (StringUtils.isNotBlank(sslTruststoreLocation)) {
+            // 外网配置
+            props.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, sslTruststoreLocation);
+            props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, "KafkaOnsClient");
+            props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_SSL");
+            //SASL鉴权方式,保持不变
+            props.put(SaslConfigs.SASL_MECHANISM, "PLAIN");
+            System.setProperty("java.security.auth.login.config", authConfig);
+            props.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
+        }
+        DefaultKafkaProducerFactory<String, String> producerFactory = new DefaultKafkaProducerFactory<String, String>(props);
+        KafkaProducerImpl<String, String> kafkaTemplate = new KafkaProducerImpl<>(producerFactory, false);
+        kafkaTemplate.setProducerListener(producerListeners);
+        return kafkaTemplate;
+    }
+
+
+//    public Map<String, Object> getConfigProducerMap(KafkaProperties kafkaProperties) {
+//        System.setProperty("java.security.auth.login.config", "D:/application/kafka/kafka_client_jaas.conf");
+//        Map<String, Object> props = kafkaProperties.buildProducerProperties();
+//        //设置接入点,请通过控制台获取对应 Topic 的接入点
+//        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getBootstrapServers());
+//        //消息队列 Kafka 消息的序列化方式
+//        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+//        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+//        //请求的最长等待时间
+//        props.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 30 * 1000);
+//        //设置客户端内部重试次数。
+//        props.put(ProducerConfig.RETRIES_CONFIG, 5);
+//        //设置客户端内部重试间隔。
+//        props.put(ProducerConfig.RECONNECT_BACKOFF_MS_CONFIG, 3000);
+//        // 外网配置
+//        props.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, "D:/application/kafka/kafka.client.truststore.jks");
+//        props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, "KafkaOnsClient");
+//        props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_SSL");
+//        //SASL鉴权方式,保持不变
+//        props.put(SaslConfigs.SASL_MECHANISM, "PLAIN");
+//        props.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
+//        return props;
+//    }
+
+    private Map<String, Object> getConfigConsumerMap(KafkaProperties kafkaProperties) {
+
+        Map<String, Object> props = kafkaProperties.buildConsumerProperties();
+        if (StringUtils.isNotBlank(sslTruststoreLocation)) {
+            System.setProperty("java.security.auth.login.config", authConfig);
+            props.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, sslTruststoreLocation);
+            //根证书存储的密码,保持不变。
+            props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, "KafkaOnsClient");
+            //接入协议,目前支持使用SASL_SSL协议接入。
+            props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_SSL");
+            //SASL鉴权方式,保持不变。
+            props.put(SaslConfigs.SASL_MECHANISM, "PLAIN");
+        }
+        //两次Poll之间的最大允许间隔。
+        //消费者超过该值没有返回心跳,服务端判断消费者处于非存活状态,服务端将消费者从Consumer Group移除并触发rebalance,默认30s。
+        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 30000);
+        //设置单次拉取的量,走公网访问时,该参数会有较大影响。
+        props.put(ConsumerConfig.MAX_PARTITION_FETCH_BYTES_CONFIG, 32000);
+        props.put(ConsumerConfig.FETCH_MAX_BYTES_CONFIG, 32000);
+        //Hostname校验改成空。
+        props.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
+        return props;
+    }
+
+}

+ 19 - 0
elab-kafka/src/main/java/com/elab/core/kafka/consumer/AbstractKafkaConsumer.java

@@ -0,0 +1,19 @@
+package com.elab.core.kafka.consumer;
+
+import org.springframework.kafka.listener.AcknowledgingMessageListener;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/10/27 16:05
+ */
+public abstract class AbstractKafkaConsumer implements AcknowledgingMessageListener<String, String> {
+    /**
+     * 订阅的topic消息
+     *
+     * @return
+     */
+    public abstract String subscribeTopic();
+
+}

+ 54 - 0
elab-kafka/src/main/java/com/elab/core/kafka/consumer/KafkaMsgListener.java

@@ -0,0 +1,54 @@
+package com.elab.core.kafka.consumer;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.log.utils.CatCrossProcess;
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.kafka.listener.AcknowledgingMessageListener;
+import org.springframework.kafka.support.Acknowledgment;
+import org.springframework.util.Assert;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/10/27 19:14
+ */
+public class KafkaMsgListener implements AcknowledgingMessageListener<String, String>, InitializingBean {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+    private List<AbstractKafkaConsumer> messageListeners;
+
+    public KafkaMsgListener(List<AbstractKafkaConsumer> messageListeners) {
+        Assert.notNull(messageListeners, "请实现一个AbstractKafkaConsumer的子类,并注册到ioc容器中");
+        this.messageListeners = messageListeners;
+    }
+
+    @Override
+    public void onMessage(ConsumerRecord<String, String> data, Acknowledgment acknowledgment) {
+        Map<String, String> valueMap = JSON.parseObject(data.value(), Map.class);
+        CatCrossProcess.buildRemoteMQMsg("kafka-" + data.topic(), data.partition() + "", valueMap, () -> {
+            try {
+                String topic = data.topic();
+                this.messageListeners.forEach((listener) -> {
+                    if (listener.subscribeTopic().equals(topic)) {
+                        listener.onMessage(data, acknowledgment);
+                    }
+                });
+            } catch (Exception e) {
+                throw e;
+            }
+            return acknowledgment;
+        });
+    }
+
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+
+    }
+}

+ 30 - 0
elab-kafka/src/main/java/com/elab/core/kafka/monitor/TopicMonitorRule.java

@@ -0,0 +1,30 @@
+package com.elab.core.kafka.monitor;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.log.model.CatCrossIdModel;
+import com.jay.monitor.data.client.ext.MqMonitorRuleCallback;
+import com.jay.monitor.data.core.model.serializable.MQDataDTO;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+
+@Component
+public class TopicMonitorRule extends MqMonitorRuleCallback {
+
+    @Override
+    public Map<String, BiConsumer<String, MQDataDTO>> getRuleMap() {
+        Map<String, BiConsumer<String, MQDataDTO>> map = new HashMap<>();
+
+        map.put("DEFAULT_ALL", (value, mqData) -> {
+            CatCrossIdModel catCrossIdModel = JSON.parseObject(value, CatCrossIdModel.class);
+            mqData.setRootLogId(catCrossIdModel.get_catRootMessageId());
+            mqData.setParentLogId(catCrossIdModel.get_catParentMessageId());
+            // 这里不用get_catChildMessageId的原因是因为生产者是不确定下游的消费者是谁的。所以还是先把子id在监控构建中传递上级,也就是自己
+            mqData.setLogId(catCrossIdModel.get_catParentMessageId());
+        });
+
+        return map;
+    }
+}

+ 52 - 0
elab-kafka/src/main/java/com/elab/core/kafka/sender/KafkaProducerImpl.java

@@ -0,0 +1,52 @@
+package com.elab.core.kafka.sender;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.elab.log.utils.CatCrossProcess;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.core.ProducerFactory;
+import org.springframework.kafka.support.SendResult;
+import org.springframework.util.concurrent.ListenableFuture;
+
+/**
+ * @Module kafka生产者
+ * @Description 负责产生消息的对象
+ * @Author liukaixiong
+ * @Date 2020/10/27 15:02
+ */
+public class KafkaProducerImpl<K, V> extends KafkaTemplate<K, V> {
+
+    private Logger LOG = LoggerFactory.getLogger(KafkaProducerImpl.class);
+
+    private final String defaultType = "kafka";
+
+    public KafkaProducerImpl(ProducerFactory<K, V> producerFactory, boolean autoFlush) {
+        super(producerFactory, autoFlush);
+    }
+
+    @Override
+    protected ListenableFuture<SendResult<K, V>> doSend(ProducerRecord<K, V> record) {
+        String topic = record.topic();
+        ListenableFuture<SendResult<K, V>> recordMetadata = (ListenableFuture<SendResult<K, V>>) CatCrossProcess.createRemoteMQMsg(defaultType, topic, (msgContextMap) -> {
+//            // 将上下文消息携带到请求中
+            JSONObject valueObject = JSON.parseObject(record.value().toString());
+            msgContextMap.forEach((K, V) -> {
+                valueObject.put(K, V);
+            });
+            ProducerRecord<K, V> producerRecord = new ProducerRecord<K, V>(topic, record.partition(), record.timestamp(), record.key(), (V) valueObject.toJSONString());
+            try {
+                ListenableFuture<SendResult<K, V>> listenableFuture = KafkaProducerImpl.super.doSend(producerRecord);
+                return listenableFuture;
+            } catch (Exception e) {
+                LOG.error("推送kafka失败", e);
+            }
+            return null;
+        });
+        return recordMetadata;
+    }
+
+
+}

+ 1 - 0
elab-kafka/src/main/resources/META-INF/spring.factories

@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.elab.core.kafka.config.KafkaConsumerConfig

+ 31 - 0
elab-kafka/src/test/java/com/elab/core/kafka/consumer/AbstractKafkaConsumerTest.java

@@ -0,0 +1,31 @@
+package com.elab.core.kafka.consumer;
+
+
+import com.elab.core.kafka.config.KafkaConsumerConfig;
+import com.elab.core.kafka.monitor.TestTopicMonitorRule;
+import com.jay.monitor.data.client.config.ClientMonitorAutoConfiguration;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/10/27 16:21
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = { TestTopicMonitorRule.class, KafkaConsumerConfig.class, ConsumerListener.class, ClientMonitorAutoConfiguration.class})
+public class AbstractKafkaConsumerTest {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Test
+    public void test() throws Exception {
+        System.in.read();
+    }
+
+}

+ 34 - 0
elab-kafka/src/test/java/com/elab/core/kafka/consumer/ConsumerListener.java

@@ -0,0 +1,34 @@
+package com.elab.core.kafka.consumer;
+
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.kafka.support.Acknowledgment;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/10/27 16:36
+ */
+@Component
+public class ConsumerListener extends AbstractKafkaConsumer {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Override
+    public String subscribeTopic() {
+        return "uat-mysql-dts";
+    }
+
+    @Override
+    public void onMessage(ConsumerRecord<String, String> data, Acknowledgment acknowledgment) {
+        logger.info("------->" + data);
+        //int i = 1/0;
+    }
+    //    @KafkaListener(topics = {"uat-mysql-dts"})
+//    public void listen(ConsumerRecord<?, ?> record, Acknowledgment ack) {
+//        logger.info("kafka : " + record.topic());
+//    }
+}

+ 41 - 0
elab-kafka/src/test/java/com/elab/core/kafka/monitor/TestTopicMonitorRule.java

@@ -0,0 +1,41 @@
+package com.elab.core.kafka.monitor;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.log.model.CatCrossIdModel;
+import com.jay.monitor.data.client.ext.MqMonitorRuleCallback;
+import com.jay.monitor.data.core.model.serializable.MQDataDTO;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiConsumer;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/10/30 19:42
+ */
+@Component
+public class TestTopicMonitorRule extends MqMonitorRuleCallback {
+
+    @Override
+    public Map<String, BiConsumer<String, MQDataDTO>> getRuleMap() {
+        Map<String, BiConsumer<String, MQDataDTO>> map = new HashMap<>();
+
+        map.put("DEFAULT_ALL", (value, mqData) -> {
+            CatCrossIdModel catCrossIdModel = JSON.parseObject(value, CatCrossIdModel.class);
+            mqData.setRootLogId(catCrossIdModel.get_catRootMessageId());
+            mqData.setParentLogId(catCrossIdModel.get_catParentMessageId());
+            mqData.setLogId(catCrossIdModel.get_catChildMessageId());
+        });
+
+        map.put("uat-mysql-dts", (value, mqData) -> {
+            mqData.setGroupName("aaaa");
+            mqData.setGroupKeyName("bbbb");
+            mqData.setDataId("cccc");
+        });
+
+        return map;
+    }
+}

+ 64 - 0
elab-kafka/src/test/java/com/elab/core/kafka/sender/KafkaProducerImplTest.java

@@ -0,0 +1,64 @@
+package com.elab.core.kafka.sender;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.core.kafka.config.KafkaConsumerConfig;
+import junit.framework.TestCase;
+import org.apache.kafka.clients.producer.RecordMetadata;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.support.SendResult;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.concurrent.ListenableFuture;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/10/28 13:49
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {KafkaConsumerConfig.class})
+public class KafkaProducerImplTest extends TestCase {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+//    @Autowired
+//    private KafkaProducer<String, String> kafkaProducer;
+
+    @Autowired
+    private KafkaTemplate<String, String> kafkaTemplate;
+
+    private final String defaultTopic = "xcx_behavior_topic_test";
+
+    @Test
+    public void testTemplate() throws ExecutionException, InterruptedException {
+        Map<String, Object> map = new HashMap<>();
+        map.put("est", "123123");
+        kafkaTemplate.setDefaultTopic(defaultTopic);
+        ListenableFuture<SendResult<String, String>> send = kafkaTemplate.send(defaultTopic, JSON.toJSONString(map));
+
+        SendResult<String, String> stringStringSendResult = send.get();
+        RecordMetadata recordMetadata = stringStringSendResult.getRecordMetadata();
+        Assert.assertTrue(recordMetadata.hasOffset());
+    }
+
+//    @Test
+//    public void testSend() throws Exception {
+//        String value = "abc";
+//        ProducerRecord<String, String> record = new ProducerRecord<String, String>(defaultTopic, value);
+//
+//        Future<RecordMetadata> send = kafkaProducer.send(record);
+//
+//        RecordMetadata recordMetadata = send.get();
+//        logger.info(" 结果: " + JSON.toJSONString(recordMetadata));
+//        Assert.assertTrue(recordMetadata.hasOffset());
+//    }
+}

+ 32 - 0
elab-kafka/src/test/resources/application.yml

@@ -0,0 +1,32 @@
+server:
+  port: 8686
+spring:
+  profiles:
+    active: dev
+  kafka:
+    bootstrap-servers: 47.103.15.48:9093,47.103.17.231:9093,47.103.23.79:9093
+    producer:
+      key-serializer: org.apache.kafka.common.serialization.StringSerializer
+      value-serializer: org.apache.kafka.common.serialization.StringSerializer
+    #      client-id: kafka-server-1
+    template:
+      default-topic: uat-mysql-dts
+    consumer:
+      group-id: test-market-db
+      max-poll-records: 30
+      fetch-min-size: 32000
+      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+      enable-auto-commit: false
+    ssl:
+      truststore-password: KafkaOnsClient
+      truststore-location: kafka.client.truststore.jks
+#  monitor-data:
+#    host: 127.0.0.1
+#    port: 9420
+java:
+  security:
+    auth:
+      login:
+        config: D:/application/kafka/kafka_client_jaas.conf                     # 基于阿里云提供的
+        trust-store-location: D:/application/kafka/kafka.client.truststore.jks  # 基于阿里云提供参考 : https://help.aliyun.com/document_detail/99958.html?spm=a2c4g.11186623.2.14.4c2a30f0KEj6Av#concept-99958-zh

二進制
elab-kafka/src/test/resources/kafka.client.truststore.jks


+ 5 - 0
elab-kafka/src/test/resources/kafka_client_jaas.conf

@@ -0,0 +1,5 @@
+KafkaClient {
+  org.apache.kafka.common.security.plain.PlainLoginModule required
+  username="alikafka_pre-cn-45918kjco002"
+  password="THlIuN7izsIzFDEhONk5dxTTRnXtEsTB";
+};

+ 1 - 1
elab-log/pom.xml

@@ -7,7 +7,7 @@
     <parent>
         <groupId>com.elab.core</groupId>
         <artifactId>elab-parent</artifactId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
 
     <groupId>com.elab.log</groupId>

+ 1 - 1
elab-log/src/main/java/com/elab/log/CatThreadProcess.java

@@ -32,7 +32,7 @@ public abstract class CatThreadProcess implements Runnable {
         this.threadName = threadName;
         this.object = object;
         CatMsgContext context = new CatMsgContext();
-        Cat.logRemoteCallClient(context);
+        Cat.logRemoteCallClient(context, Cat.getManager().getDomain());
         this.parentId = context.getProperty(Cat.Context.PARENT);
         this.rootId = context.getProperty(Cat.Context.ROOT);
         this.childId = context.getProperty(Cat.Context.CHILD);

+ 1 - 1
elab-log/src/main/java/com/elab/log/ext/CatRealTaskExecutor.java

@@ -32,7 +32,7 @@ public class CatRealTaskExecutor implements RealTaskExecutor {
     @Override
     public void run() {
         Map<String, String> dataMap = taskStoreData.getDataMap();
-        Transaction t = CatCrossProcess.buildCrossMsg("privateQueue", taskEnums.name(), dataMap);
+        Transaction t = CatCrossProcess.getCrossTransactionMsg("privateQueue", taskEnums.name(), dataMap);
         try {
             realTaskExecutor.run();
             t.setSuccessStatus();

+ 50 - 0
elab-log/src/main/java/com/elab/log/model/CatCrossIdModel.java

@@ -0,0 +1,50 @@
+package com.elab.log.model;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/10/30 10:54
+ */
+public class CatCrossIdModel {
+
+    /**
+     * 根消息-最上层
+     */
+    private String _catRootMessageId;
+
+    /**
+     * 上级消息
+     */
+    private String _catParentMessageId;
+
+    /**
+     * 当前消息编号
+     */
+    private String _catChildMessageId;
+
+
+    public String get_catRootMessageId() {
+        return _catRootMessageId;
+    }
+
+    public void set_catRootMessageId(String _catRootMessageId) {
+        this._catRootMessageId = _catRootMessageId;
+    }
+
+    public String get_catParentMessageId() {
+        return _catParentMessageId;
+    }
+
+    public void set_catParentMessageId(String _catParentMessageId) {
+        this._catParentMessageId = _catParentMessageId;
+    }
+
+    public String get_catChildMessageId() {
+        return _catChildMessageId;
+    }
+
+    public void set_catChildMessageId(String _catChildMessageId) {
+        this._catChildMessageId = _catChildMessageId;
+    }
+}

+ 137 - 10
elab-log/src/main/java/com/elab/log/utils/CatCrossProcess.java

@@ -10,6 +10,8 @@ import org.springframework.web.context.request.RequestContextHolder;
 import javax.servlet.http.HttpServletRequest;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Supplier;
 
 /**
  * @author : liukx
@@ -25,16 +27,100 @@ public class CatCrossProcess {
         crossAppEvent.setStatus(Event.SUCCESS);
         crossServerEvent.setStatus(Event.SUCCESS);
         crossPortEvent.setStatus(Event.SUCCESS);
-//        completeEvent(crossAppEvent);
-//        completeEvent(crossPortEvent);
-//        completeEvent(crossServerEvent);
         transaction.addChild(crossAppEvent);
         transaction.addChild(crossPortEvent);
         transaction.addChild(crossServerEvent);
     }
 
-    public static void completeEvent(Event event) {
-        event.complete();
+    /**
+     * 创建远程事务消息
+     *
+     * @param type     消费类型
+     * @param name     消费名称
+     * @param consumer 消费者
+     * @return
+     */
+    public static Object createRemoteMsg(String type, String name, Function<Map<String, String>, Object> consumer) {
+        // 构建一个事务日志
+        Transaction t = Cat.newTransaction(type, name);
+        try {
+            // 构建一个上下文事务消息
+            Map<String, String> msgContextMap = getMsgContextMap();
+            Object apply = consumer.apply(msgContextMap);
+            t.setSuccessStatus();
+            return apply;
+        } catch (Exception e) {
+            t.setStatus(e);
+        } finally {
+            t.complete();
+        }
+        return null;
+    }
+
+    /**
+     * 创建远程MQ消息
+     *
+     * @param type     消息类型
+     * @param name     消息名称
+     * @param consumer 消费者
+     * @return
+     */
+    public static Object createRemoteMQMsg(String type, String name, Function<Map<String, String>, Object> consumer) {
+        // 构建一个事务日志
+        Transaction t = Cat.newTransaction(type, name);
+        try {
+            // 构建一个上下文事务消息
+            Map<String, String> msgContextMap = getDomainMsgContextMap("MQ-CONSUMER");
+            Object apply = consumer.apply(msgContextMap);
+            t.setSuccessStatus();
+            return apply;
+        } catch (Exception e) {
+            t.setStatus(e);
+        } finally {
+            t.complete();
+        }
+        return null;
+    }
+
+    /**
+     * 构建消息树串联
+     *
+     * @param type
+     * @param name
+     * @param msgIdMap
+     * @param process
+     * @return
+     */
+    public static <T> T buildRemoteMsg(String type, String name, Map<String, String> msgIdMap, Supplier<T> process) {
+        Transaction transaction = getCrossTransactionMsg(type, name, msgIdMap);
+        return getTransaction(transaction, process);
+    }
+
+    /**
+     * 构建远程传递来的MQ类型的消息
+     *
+     * @param type     消息类型
+     * @param name     消息名称
+     * @param msgIdMap 客户端携带过来的上下文编号
+     * @param process  具体的执行业务
+     * @return
+     */
+    public static <T> T buildRemoteMQMsg(String type, String name, Map<String, String> msgIdMap, Supplier<T> process) {
+        Transaction transaction = getCrossMQTransactionMsg(type, name, msgIdMap);
+        return getTransaction(transaction, process);
+    }
+
+    private static <T> T getTransaction(Transaction t, Supplier<T> process) {
+        try {
+            Object result = process.get();
+            t.setSuccessStatus();
+            return (T) result;
+        } catch (Exception e) {
+            t.setStatus(e);
+            throw e;
+        } finally {
+            t.complete();
+        }
     }
 
     public static String getProviderAppName(HttpServletRequest request) {
@@ -57,8 +143,6 @@ public class CatCrossProcess {
         Event crossServerEvent = Cat.newEvent(CatMsgConstants.PROVIDER_CALL_SERVER, request.getRemoteAddr());    //clientIp
         crossAppEvent.setStatus(Event.SUCCESS);
         crossServerEvent.setStatus(Event.SUCCESS);
-//        completeEvent(crossAppEvent);
-//        completeEvent(crossServerEvent);
         t.addChild(crossAppEvent);
         t.addChild(crossServerEvent);
     }
@@ -68,7 +152,7 @@ public class CatCrossProcess {
      */
     public static void createMessageTree() {
         CatMsgContext context = new CatMsgContext();
-        Cat.logRemoteCallClient(context);
+        Cat.logRemoteCallClient(context, Cat.getManager().getDomain());
         RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
         requestAttributes.setAttribute(Cat.Context.PARENT, context.getProperty(Cat.Context.PARENT), 0);
         requestAttributes.setAttribute(Cat.Context.ROOT, context.getProperty(Cat.Context.ROOT), 0);
@@ -82,8 +166,18 @@ public class CatCrossProcess {
      * @return
      */
     public static Map<String, String> getMsgContextMap() {
+        return getDomainMsgContextMap(Cat.getManager().getDomain());
+    }
+
+    /**
+     * 构建远程服务类型
+     *
+     * @param remoteDomain
+     * @return
+     */
+    public static Map<String, String> getDomainMsgContextMap(String remoteDomain) {
         CatMsgContext context = new CatMsgContext();
-        Cat.logRemoteCallClient(context);
+        Cat.logRemoteCallClient(context, remoteDomain);
         Map<String, String> contextMap = new LinkedHashMap<>();
         contextMap.put(Cat.Context.PARENT, context.getProperty(Cat.Context.PARENT));
         contextMap.put(Cat.Context.ROOT, context.getProperty(Cat.Context.ROOT));
@@ -92,7 +186,17 @@ public class CatCrossProcess {
         return contextMap;
     }
 
-    public static Transaction buildCrossMsg(String crossName, String crossValue, Map<String, String> msgIdMap) {
+    ;
+
+    /**
+     * 构建远程客户端
+     *
+     * @param crossName  埋点名称
+     * @param crossValue 埋点值
+     * @param msgIdMap   远程客户端携带过来的消息编号
+     * @return
+     */
+    public static Transaction getCrossTransactionMsg(String crossName, String crossValue, Map<String, String> msgIdMap) {
         Transaction transaction = Cat.newTransaction(crossName, crossValue);
 
         if (msgIdMap != null && msgIdMap.get(Cat.Context.ROOT) != null) {
@@ -106,8 +210,31 @@ public class CatCrossProcess {
             crossAppEvent.setStatus(Event.SUCCESS);
             transaction.addChild(crossAppEvent);
         }
+        return transaction;
+    }
 
+    /**
+     * 构建消费者消息
+     *
+     * @param crossName  消息name
+     * @param crossValue 消息值
+     * @param msgIdMap   消息串联编号,由远程客户端携带过来的客户编号
+     * @return
+     */
+    public static Transaction getCrossMQTransactionMsg(String crossName, String crossValue, Map<String, String> msgIdMap) {
+        Transaction transaction = Cat.newTransaction(crossName, crossValue);
 
+        if (msgIdMap != null && msgIdMap.get(Cat.Context.ROOT) != null) {
+            Cat.Context context = new CatMsgContext();
+            context.addProperty(Cat.Context.ROOT, msgIdMap.get(Cat.Context.ROOT));
+            context.addProperty(Cat.Context.PARENT, msgIdMap.get(Cat.Context.PARENT));
+            // 这里不需要构建客户端带过来的编号,因为消费者是多个,避免LOG被覆盖的情况。
+            Cat.logRemoteCallServer(context);
+
+            Event crossAppEvent = Cat.newEvent(CatMsgConstants.PROVIDER_CALL_APP, msgIdMap.get(CatMsgConstants.APPLICATION_KEY));
+            crossAppEvent.setStatus(Event.SUCCESS);
+            transaction.addChild(crossAppEvent);
+        }
         return transaction;
     }
 }

+ 72 - 0
elab-log/src/test/java/com/elab/log/utils/CatCrossProcessTest.java

@@ -0,0 +1,72 @@
+package com.elab.log.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.dianping.cat.Cat;
+import junit.framework.TestCase;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+/**
+ * @Module TODO
+ * @Description TODO
+ * @Author liukaixiong
+ * @Date 2020/11/4 11:41
+ */
+public class CatCrossProcessTest extends TestCase {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Test
+    public void testCreateConsumerCross() throws Exception {
+        CatCrossProcess.createRemoteMQMsg("TEST", "LOG-MSG", (idMap) -> {
+            String logInfo = JSON.toJSONString(idMap);
+            String logId = Cat.getCurrentMessageId();
+            logger.info("cat test");
+            logger.info("---------->>>>>" + JSON.toJSONString(idMap));
+            logger.info("---------->>>>>msg id : " + Cat.getCurrentMessageId());
+            System.out.println(logInfo);
+            try {
+                // 根据当前上下文产生的消息
+                buildRemoteMQMsg(idMap, "  1 收到消息");
+                buildRemoteMQMsg(idMap, "  2 收到消息");
+                buildRemoteMQMsg(idMap, "  3 收到消息");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            // 全新的远程消息
+            CatCrossProcess.createRemoteMsg("TEST", "LOG-MSG", (idMaps) -> {
+                try {
+                    buildRemoteMsg(idMaps, "  4 收到消息");
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return null;
+            });
+
+            return null;
+        });
+        // Thread.sleep(5000);
+        System.in.read();
+    }
+
+    private void buildRemoteMQMsg(Map<String, String> idMap, String text) throws Exception {
+        new Thread(() -> {
+            CatCrossProcess.buildRemoteMQMsg("TEST", "REMOTE-LOG-MSG", idMap, () -> {
+                logger.info(" 远程接收到消息 :" + text + " \t 消息编号 : " + Cat.getCurrentMessageId());
+                return null;
+            });
+        }).start();
+    }
+
+    private void buildRemoteMsg(Map<String, String> idMap, String text) throws Exception {
+        new Thread(() -> {
+            CatCrossProcess.buildRemoteMsg("TEST", "REMOTE-LOG-MSG", idMap, () -> {
+                logger.info(" 远程接收到消息 :" + text + " \t 消息编号 : " + Cat.getCurrentMessageId());
+                return null;
+            });
+        }).start();
+    }
+}

+ 1 - 0
elab-log/src/test/resources/META-INF/app.properties

@@ -0,0 +1 @@
+app.name=cat-demo

+ 112 - 0
elab-log/src/test/resources/META-INF/plexus/components-cat-client.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- THIS FILE WAS AUTO GENERATED FROM class com.dianping.cat.build.ComponentsConfigurator, DO NOT EDIT IT -->
+<plexus>
+	<components>
+		<component>
+			<role>com.dianping.cat.configuration.ClientConfigManager</role>
+			<implementation>com.dianping.cat.configuration.DefaultClientConfigManager</implementation>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.internal.MessageIdFactory</role>
+			<implementation>com.dianping.cat.message.internal.MessageIdFactory</implementation>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.spi.MessageManager</role>
+			<implementation>com.dianping.cat.message.internal.DefaultMessageManager</implementation>
+			<requirements>
+				<requirement>
+					<role>com.dianping.cat.configuration.ClientConfigManager</role>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.message.io.TransportManager</role>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.message.internal.MessageIdFactory</role>
+				</requirement>
+			</requirements>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.MessageProducer</role>
+			<implementation>com.dianping.cat.message.internal.DefaultMessageProducer</implementation>
+			<!--<implementation>com.elab.log.message.CatMessageProducer</implementation>-->
+			<requirements>
+				<requirement>
+					<role>com.dianping.cat.message.spi.MessageManager</role>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.message.internal.MessageIdFactory</role>
+				</requirement>
+			</requirements>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.io.TcpSocketSender</role>
+			<implementation>com.dianping.cat.message.io.TcpSocketSender</implementation>
+			<requirements>
+				<requirement>
+					<role>com.dianping.cat.configuration.ClientConfigManager</role>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.message.internal.MessageIdFactory</role>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.message.spi.MessageStatistics</role>
+					<field-name>m_statistics</field-name>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.message.spi.MessageCodec</role>
+					<role-hint>plain-text</role-hint>
+					<field-name>m_codec</field-name>
+				</requirement>
+			</requirements>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.io.TransportManager</role>
+			<implementation>com.dianping.cat.message.io.DefaultTransportManager</implementation>
+			<requirements>
+				<requirement>
+					<role>com.dianping.cat.configuration.ClientConfigManager</role>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.message.io.TcpSocketSender</role>
+				</requirement>
+			</requirements>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.spi.MessageStatistics</role>
+			<implementation>com.dianping.cat.message.spi.internal.DefaultMessageStatistics</implementation>
+		</component>
+		<component>
+			<role>com.dianping.cat.status.StatusUpdateTask</role>
+			<implementation>com.dianping.cat.status.StatusUpdateTask</implementation>
+			<requirements>
+				<requirement>
+					<role>com.dianping.cat.message.spi.MessageStatistics</role>
+				</requirement>
+				<requirement>
+					<role>com.dianping.cat.configuration.ClientConfigManager</role>
+				</requirement>
+			</requirements>
+		</component>
+		<component>
+			<role>org.unidal.initialization.Module</role>
+			<role-hint>cat-client</role-hint>
+			<implementation>com.dianping.cat.CatClientModule</implementation>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.spi.codec.BufferWriter</role>
+			<role-hint>escape</role-hint>
+			<implementation>com.dianping.cat.message.spi.codec.EscapingBufferWriter</implementation>
+		</component>
+		<component>
+			<role>com.dianping.cat.message.spi.MessageCodec</role>
+			<role-hint>plain-text</role-hint>
+			<implementation>com.dianping.cat.message.spi.codec.PlainTextMessageCodec</implementation>
+			<requirements>
+				<requirement>
+					<role>com.dianping.cat.message.spi.codec.BufferWriter</role>
+					<role-hint>escape</role-hint>
+				</requirement>
+			</requirements>
+		</component>
+	</components>
+</plexus>

+ 31 - 0
elab-log/src/test/resources/logback.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/base.xml"/>
+    <jmxConfigurator/>
+    <property name="LOG_PATH" value="logs"/>
+    <property name="APPLICATION" value="elab-log" />
+
+    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder charset="UTF-8">
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="console-log" level="INFO" additivity="false">
+        <appender-ref ref="stdout"/>
+    </logger>
+
+    <appender name="cat" class="com.elab.log.log4j.CatLogbackLog">
+
+    </appender>
+
+    <root level="WARN">
+<!--        <appender-ref ref="cat"/>-->
+        <appender-ref ref="stdout"/>
+    </root>
+
+    <logger name="com.elab.log.ext" level="INFO" additivity="false">
+        <appender-ref ref="cat"/>
+    </logger>
+
+</configuration>

+ 1 - 1
elab-mongodb/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
elab-mq/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 2
elab-mq/src/main/java/com/elab/mq/listener/AbstractMessageListener.java

@@ -126,10 +126,9 @@ public abstract class AbstractMessageListener implements MessageListener {
         String topic = message.getTopic();
         String tag = message.getTag();
 
-
         Map<String, String> msgMap = conversionPropertyToMap(message.getUserProperties());
 
-        Transaction t = CatCrossProcess.buildCrossMsg(MQ_CONSUMER, topic + "_" + tag + "_" + getClass().getSimpleName(), msgMap);
+        Transaction t = CatCrossProcess.getCrossTransactionMsg(MQ_CONSUMER, topic + "_" + tag + "_" + getClass().getSimpleName(), msgMap);
 
         MessageModel messageModel = new MessageModel(message);
         logger.debug("消息处理被触发 : " + message.toString());

+ 1 - 1
elab-redis/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 0 - 1
elab-redis/src/main/java/com/elab/redis/CacheTemplate.java

@@ -21,7 +21,6 @@ public class CacheTemplate {
 
     private RedisTemplate<String, Object> redisTemplate;
 
-
     public ValueOperations string() {
         return redisTemplate.opsForValue();
     }

+ 1 - 1
elab-rocketMQ/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 5 - 1
elab-spring/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.14-SNAPSHOT</version>
+        <version>2.0.5.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -154,6 +154,10 @@
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
 
         <!--<dependency>-->
         <!--<groupId>ch.qos.logback</groupId>-->

+ 53 - 0
elab-spring/src/main/java/com/elab/spring/config/ThreadConfiguration.java

@@ -0,0 +1,53 @@
+//package com.elab.spring.config;
+//
+//import com.elab.core.async.consumer.TaskConsumer;
+//import com.elab.core.async.pruducer.ITaskProducer;
+//import com.elab.core.async.store.TaskExecutorQueue;
+//import com.elab.core.utils.DataUtils;
+//import com.elab.log.ext.CatTaskProducer;
+//import com.elab.spring.config.prop.ThreadProperties;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.context.properties.EnableConfigurationProperties;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//
+//import java.util.concurrent.ExecutorCompletionService;
+//
+///**
+// * 线程配置
+// *
+// * @author : liukx
+// * @time : 2020/8/10 - 19:50
+// */
+//@Configuration
+//@EnableConfigurationProperties(ThreadProperties.class)
+//public class ThreadConfiguration {
+//
+//    @Autowired
+//    private ThreadProperties threadProperties;
+//
+//    @Bean
+//    public TaskExecutorQueue taskExecutorQueue() {
+//        Integer threadCore = DataUtils.getIntegerValue(threadProperties.getThreadCore(), 5);
+//        Integer realQueueSize = DataUtils.getIntegerValue(threadProperties.getRealQueueSize(), 1000);
+//        TaskExecutorQueue queue = new TaskExecutorQueue(threadCore, realQueueSize);
+//        return queue;
+//    }
+//
+//    @Bean
+//    public TaskConsumer taskConsumer(@Autowired TaskExecutorQueue taskExecutorQueue) {
+//        TaskConsumer taskConsumer = new TaskConsumer(taskExecutorQueue);
+//        // 开启定时调度
+//        taskConsumer.startSchedulingConsumer(DataUtils.getIntegerValue(threadProperties.getSchedulingIntervalSecond(), 5));
+//        // 开启异步队列
+//        taskConsumer.startRealTimeConsumer();
+//        return taskConsumer;
+//    }
+//
+//    @Bean
+//    public ITaskProducer taskProducer(@Autowired TaskExecutorQueue taskExecutorQueue) {
+//        ITaskProducer producer = new CatTaskProducer(taskExecutorQueue);
+//        return producer;
+//    }
+//
+//}

+ 51 - 0
elab-spring/src/main/java/com/elab/spring/config/prop/ThreadProperties.java

@@ -0,0 +1,51 @@
+package com.elab.spring.config.prop;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 线程配置
+ *
+ * @author : liukx
+ * @time : 2020/8/14 - 14:19
+ */
+
+@ConfigurationProperties(prefix = "elab.thread")
+public class ThreadProperties {
+
+    /**
+     * 调度间隔时间
+     */
+    private Integer schedulingIntervalSecond;
+    /**
+     * 初始化核心线程池大小
+     */
+    private Integer threadCore;
+    /**
+     * 实时队列大小
+     */
+    private Integer realQueueSize;
+
+    public Integer getSchedulingIntervalSecond() {
+        return schedulingIntervalSecond;
+    }
+
+    public void setSchedulingIntervalSecond(Integer schedulingIntervalSecond) {
+        this.schedulingIntervalSecond = schedulingIntervalSecond;
+    }
+
+    public Integer getThreadCore() {
+        return threadCore;
+    }
+
+    public void setThreadCore(Integer threadCore) {
+        this.threadCore = threadCore;
+    }
+
+    public Integer getRealQueueSize() {
+        return realQueueSize;
+    }
+
+    public void setRealQueueSize(Integer realQueueSize) {
+        this.realQueueSize = realQueueSize;
+    }
+}

+ 38 - 0
elab-spring/src/main/java/com/elab/spring/factory/HttpComponentsClientRestfulHttpRequestFactory.java

@@ -0,0 +1,38 @@
+package com.elab.spring.factory;
+
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+
+import java.net.URI;
+
+/**
+ * 为了处理get请求能够携带body参数所创建的工厂类
+ *
+ * @author
+ */
+public class HttpComponentsClientRestfulHttpRequestFactory extends HttpComponentsClientHttpRequestFactory {
+    @Override
+    protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
+
+        if (httpMethod == HttpMethod.GET) {
+            return new HttpGetRequestWithEntity(uri);
+        }
+        return super.createHttpUriRequest(httpMethod, uri);
+    }
+
+    /**
+     * 定义HttpGetRequestWithEntity实现HttpEntityEnclosingRequestBase抽象类,以支持GET请求携带body数据
+     */
+    private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
+        public HttpGetRequestWithEntity(final URI uri) {
+            super.setURI(uri);
+        }
+
+        @Override
+        public String getMethod() {
+            return HttpMethod.GET.name();
+        }
+    }
+}

+ 7 - 0
elab-spring/src/main/java/com/elab/spring/factory/HttpsClientRequestFactory.java

@@ -1,5 +1,7 @@
 package com.elab.spring.factory;
 
+import org.springframework.http.HttpMethod;
+import org.springframework.http.client.ClientHttpRequest;
 import org.springframework.http.client.SimpleClientHttpRequestFactory;
 
 import javax.net.ssl.*;
@@ -7,6 +9,7 @@ import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.Socket;
+import java.net.URI;
 import java.security.cert.X509Certificate;
 
 /**
@@ -17,6 +20,10 @@ import java.security.cert.X509Certificate;
  * @DATE 2018年9月8日 下午4:34:02
  */
 public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
+    @Override
+    public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
+        return super.createRequest(uri, httpMethod);
+    }
 
     @Override
     protected void prepareConnection(HttpURLConnection connection, String httpMethod) {

+ 127 - 6
elab-spring/src/main/java/com/elab/spring/utils/RestTemplateUtils.java

@@ -9,14 +9,19 @@ import com.elab.core.utils.StringUtils;
 import com.elab.log.utils.CatMsgConstants;
 import com.elab.spring.callback.IRestFallback;
 import com.elab.spring.exception.rest.CoolingException;
+import com.elab.spring.factory.HttpComponentsClientRestfulHttpRequestFactory;
 import com.elab.spring.factory.HttpsClientRequestFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.*;
 import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.client.RestTemplate;
 
 import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Map;
 
 /**
  * http调用工具
@@ -31,9 +36,19 @@ public class RestTemplateUtils {
     private Logger logger = LoggerFactory.getLogger(RestTemplateUtils.class);
     public RestTemplate restTemplate;
 
+    public RestTemplate getRestTemplate;
+
     private HttpHeaders headers;
 
     private IRestFallback restFallback;
+    /**
+     * 连接时长
+     */
+    private Integer connectTimeout = 1000;
+    /**
+     * 读取时长
+     */
+    private Integer readTimeout = 5000;
 
     private RestTemplate getRestTemplate() {
         return restTemplate;
@@ -51,18 +66,48 @@ public class RestTemplateUtils {
         this.headers = headers;
     }
 
+    public Integer getConnectTimeout() {
+        return connectTimeout;
+    }
+
+    public void setConnectTimeout(Integer connectTimeout) {
+        this.connectTimeout = connectTimeout;
+    }
+
+    public Integer getReadTimeout() {
+        return readTimeout;
+    }
+
+    public void setReadTimeout(Integer readTimeout) {
+        this.readTimeout = readTimeout;
+    }
+
     public RestTemplateUtils() {
         System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
         //复杂构造函数的使用
         SimpleClientHttpRequestFactory requestFactory = new HttpsClientRequestFactory();
         // 设置超时
-        requestFactory.setConnectTimeout(1000);
+        requestFactory.setConnectTimeout(getConnectTimeout());
         // 读取超时
-        requestFactory.setReadTimeout(5000);
+        requestFactory.setReadTimeout(getReadTimeout());
 
-        //利用复杂构造器可以实现超时设置,内部实际实现为 HttpClient
 //        restTemplate = new RestTemplate(requestFactory);
         restTemplate = new RestTemplate(requestFactory);
+//         替换String的默认字符集
+        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+
+        //get请求适配body的请求工厂,内部采用httpclient
+        HttpComponentsClientRestfulHttpRequestFactory getRequestFactory = new HttpComponentsClientRestfulHttpRequestFactory();
+        // 设置超时
+        requestFactory.setConnectTimeout(getConnectTimeout());
+        // 读取超时
+        requestFactory.setReadTimeout(getReadTimeout());
+
+        //利用复杂构造器可以实现超时设置,内部实际实现为 HttpClient
+        getRestTemplate = new RestTemplate(getRequestFactory);
+        //         替换String的默认字符集
+        getRestTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+
 
         //设置HTTP请求头信息,实现编码等
         headers = new HttpHeaders();
@@ -131,6 +176,11 @@ public class RestTemplateUtils {
         String newUrl = getUrl(url);
         Transaction t = Cat.getProducer().newTransaction(CatMsgConstants.THIRD_PARTY, newUrl);
         logger.debug(" URL : " + url);
+
+        if (httpHeaders != null) {
+            logger.debug(" hreader : " + JSON.toJSONString(httpHeaders));
+        }
+
         if (reqParam != null) {
             logger.debug(" RequestData : " + StringUtils.logOut(logData(reqParam)));
         }
@@ -146,7 +196,7 @@ public class RestTemplateUtils {
         } catch (Exception e) {
             e.printStackTrace();
             if (!(e instanceof CoolingException)) {
-                logger.error("第三方调用异常:", e);
+                logger.warn("第三方调用异常:", e);
             }
             t.setStatus(e.getClass().getSimpleName());
             if (restFallback != null) {
@@ -211,7 +261,78 @@ public class RestTemplateUtils {
             }
         } catch (Exception e) {
             if (!(e instanceof CoolingException)) {
-                logger.error("第三方调用异常:", e);
+                logger.warn("第三方调用异常:", e);
+            }
+            t.setStatus(e.getClass().getSimpleName());
+            if (restFallback != null) {
+                logger.debug("触发失败回调 : " + restFallback.toString());
+                return (T) restFallback.get(url, clazz, e);
+            }
+        } finally {
+            t.complete();
+        }
+        return responseData;
+    }
+
+    public <T> T get(String url, Map<String, String> httpHeaders, Class<T> clazz) {
+        HttpHeaders headerMap = new HttpHeaders();
+        httpHeaders.forEach((K, V) -> {
+            headerMap.put(K, Arrays.asList(V));
+        });
+        return get(url, null, clazz, headerMap, this.restFallback);
+    }
+
+    /**
+     * get方法请求
+     *
+     * @param url
+     * @param clazz
+     * @param httpHeaders
+     * @param restFallback
+     * @param <T>
+     * @return
+     */
+    public <T> T get(String url, Class<T> clazz, HttpHeaders httpHeaders, IRestFallback restFallback) {
+        return get(url, null, clazz, httpHeaders, restFallback);
+    }
+
+    /**
+     * get请求最终执行的方法
+     *
+     * @param url          URL
+     * @param body         请求体
+     * @param clazz        转换的结果类对象型
+     * @param httpHeaders  header
+     * @param restFallback 失败回调的类
+     * @param <T>
+     * @return
+     */
+    public <T> T get(String url, Object body, Class<T> clazz, HttpHeaders httpHeaders, IRestFallback restFallback) {
+        String newUrl = getUrl(url);
+        Transaction t = Cat.getProducer().newTransaction(CatMsgConstants.THIRD_PARTY, newUrl);
+        logger.debug(" URL : " + url);
+        if (httpHeaders != null) {
+            logger.debug(" header : " + JSON.toJSONString(httpHeaders));
+        }
+        //利用容器实现数据封装,发送
+        T responseData = null;
+        try {
+            HttpEntity<Object> entity = new HttpEntity<Object>(body, httpHeaders);
+            ResponseEntity<T> result = null;
+            if (body == null) {
+                result = restTemplate.exchange(url, HttpMethod.GET, entity, clazz);
+            } else {
+                // todo 待优化,由于每次都是创建的
+                result = getRestTemplate.exchange(url, HttpMethod.GET, entity, clazz);
+            }
+            responseData = result.getBody();
+            t.setStatus(Transaction.SUCCESS);
+            if (responseData != null) {
+                logResponse((T) responseData);
+            }
+        } catch (Exception e) {
+            if (!(e instanceof CoolingException)) {
+                logger.warn("第三方调用异常:", e);
             }
             t.setStatus(e.getClass().getSimpleName());
             if (restFallback != null) {
@@ -254,7 +375,7 @@ public class RestTemplateUtils {
             }
             t.setStatus(Transaction.SUCCESS);
         } catch (Exception e) {
-            logger.error("------ 第三方接口调用失败 : ", e);
+            logger.warn("------ 第三方接口调用失败 : ", e);
             t.setStatus(e.getClass().getSimpleName());
         } finally {
             t.complete();

+ 248 - 232
elab-spring/src/test/java/com/elab/spring/utils/RestTemplateUtilsTest.java

@@ -74,6 +74,22 @@ public class RestTemplateUtilsTest {
         Assert.assertNotNull(get);
     }
 
+    @Test
+    public void getBody() {
+        String url = "https://api-test-e.source3g.com/third-face-detect/foreign/face/customer/detail";
+        String body = "{\n" +
+                "    \"ak\":\"dfcf9588869c4679af62592d2b8488fa\",\n" +
+                "    \"nonce\":\"602933e0cb0b4ab798043627f760bf49\",\n" +
+                "    \"ts\":\"1603345255\",\n" +
+                "    \"sign\":\"8fe0bb25f735e6982b4523cf7c1bb116\",\n" +
+                "    \"projectId\":\"b7a782741f667201b54880c925faec4b\",\n" +
+                "    \"idNumber\":\"110101198904072992\"\n" +
+                "}";
+
+        String s = restTemplateUtils.get(url, JSON.parseObject(body), String.class, null, null);
+        System.out.println(s);
+    }
+
     public static String conventFromGzip(String str) throws IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         ByteArrayInputStream in;
@@ -95,7 +111,7 @@ public class RestTemplateUtilsTest {
         byte[] bytes = restTemplateUtils.get(url, byte[].class);
         String s1 = GzipUtils.unZip(bytes);
         System.out.println(s1);
-
+        Assert.assertTrue(s1.startsWith("{\"data\":"));
     }
 
     @Test
@@ -144,237 +160,237 @@ public class RestTemplateUtilsTest {
     }
 
 
-    @Test
-    public void dowloadImg() {
-        String img = "https://image1.ljcdn.com/x-se/hdic-frame/prod-bfd3b9b7-a806-4a87-b698-ed917c06211a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7c46b149-ae30-4be1-a263-ab175243282a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e5cf3040-aa82-43b8-98df-7fbddaeb16c0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-528bf7e3-5b89-4559-9ee4-11ae7ad369d0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-23729179-edcd-480e-88bc-dad6e1d3c267.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2734f121-8fa2-40d3-9d57-24f0af794e71.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2a9f5018-99ef-4fbe-a8fc-3492637f1ad3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0765219d-0b74-4317-bdce-c2756c4b63c4.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-45790885-ce05-4e5d-8b61-8dfe01f3cbb4.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f7b2dfb7-282c-4c60-9cee-1405f345ace5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0d947000-ca31-466c-be03-29d36a963b4e.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f8a0138d-675b-4a94-b82d-85a5f1175be2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8900b029-fe84-4492-b3fe-400d4ff0c7f1.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d1824b02-d9ef-455a-8c63-155295b2f85e.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0aa34348-5497-4099-be46-26475a4cea7f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7dc749da-50c2-43f5-aaf2-dd2520e43dce.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-05502762-de5d-432c-b34e-48fc17626ee8.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bd158eab-4be2-4b33-b217-3b2a7cbb127c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-86019a37-2d06-40de-b9fc-58e7953d0566.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-92352810-1d78-40a2-8fb4-a58fcb085835.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9858afd1-c966-4f8b-b8aa-d4d93e1d7c0a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2728c804-d1a7-4654-81f9-6b981a8753ac.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-5fc826b3-594d-484c-bf60-9233e39d325d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-46f41f29-d4b4-4c8b-b664-1620c7fefcf3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1a1f66d2-07fc-4de0-b761-9402f189ef70.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2a1c3845-6d9b-4391-9496-33d60b195f58.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4676de1d-4a2e-484a-9082-0edd037245f6.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c126c932-510e-4539-b69d-f1076ca6b13b.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b513d7d5-dfe4-4f2b-a0c4-82054dd905dd.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8e6ffcd5-fdea-4427-820c-9c491235f431.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-10e7d74b-32c5-4202-992b-f1ec8f02b5e1.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-72434446-c7e7-465e-a874-36fa40f4495d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bec6582d-8d09-43cc-8538-bd983b8acd9b.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-e85f3248-563d-4aef-b42d-6acff394f8c2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a4f2a118-31f3-4e5f-868d-e3c46c6311e1.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-5d2943da-5592-461c-943d-3e473aa5706c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-deb84650-1cba-45f2-8b7f-2629fc2795f7.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4a5cb513-e0a5-4ffd-849e-dcfb9e4f59be.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4ab3e9db-9f81-47cc-bd6e-68b460faa598.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4f969cfd-ffdb-45c0-8829-f6d1ef059b1a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-66d394fd-a3f7-4213-9127-024ae004b15c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1fab560d-520d-4cda-8efe-1d7ae28fb25a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9e15c80e-0502-4d4e-8d4e-54e13c811109.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9b9da5dc-91b1-4913-942e-eafc9a98e8a8.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-80ff9510-7504-45c4-b49c-92d359491753.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b0488260-478f-4af1-9505-9c244a78dd71.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0c1be4d7-7a8b-4142-ad40-638ce521c3be.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-21197991-e60b-426a-9143-2340711da68c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c5ad83c4-b5ae-4a90-b197-9c69033bac1d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/40c271d2-68aa-4c67-bbec-a274a26a0c58.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/2372564f-55a4-4376-8574-a553210c42bb.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-6d0357fc-8117-46a4-900a-8995713469fb.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-ce03e966-040c-4378-aa57-72ade311ed82.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-d0211e1c-e463-4e0b-abd4-04bd2b0e9ee5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ab5b5dd5-316c-493d-a3f0-820e3e808ad8.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-fdc1497b-1773-4a9a-a516-02776b1dbd54.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-6a51da59-412b-477a-858d-2b6a8d26c98f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-a1df6e86-7202-490a-926e-8d7f6bd7a373.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-541cde2e-b69a-40db-a943-963ff141a5c3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-5cd81120-6ca3-4cc8-bfb9-27e24add0c39.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9b730207-58a5-4d9b-b980-02b2dd7c362d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9b6438a3-dabd-409d-b319-461425c01202.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-f432592e-c5fa-4cac-9a36-69a43efe38ac.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-bcfe644a-3fb1-4ff3-965d-ac6e17edbcaf.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7cb323f4-c705-47ab-9e2e-86b7160dbade.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b867bbb2-3114-4ff6-81fa-a4ca139ee2a0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b1bf05f4-c6fb-4872-aa51-e1138b4b08a2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-9b1bc445-ad59-41e8-b4db-1dffb569dec3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-4ec2283a-10b9-4203-8640-69e70c1eadc5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-8a21f7ee-47a4-49e0-a772-bd5da5af98b2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-7fdfeed0-56fe-4e60-92ae-4d09eb3f62d3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2473e607-eb48-4dc0-95bc-d4d037adbf29.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-51884466-c928-437f-ac39-a59f839c21cd.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b9ae80af-2153-4ea1-a1c0-0cca979becba.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ddf5062c-b89b-40bd-8eb9-8557c8b053f4.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8c622f2f-3a60-40f0-a0b8-6ed660fc4756.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-a1d71be0-4506-48c0-ae84-f2fde02cab9c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-19f9b208-fe7e-4b16-bf07-f7b217a51f33.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b11558ea-876a-4d4f-b38b-54c243c8488d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3664742e-8e03-46af-ac6c-05f62293fe4d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-9ff3ba52-d0f3-4deb-a44b-2e436067b5a0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-03dd39ac-ee90-44b4-87d9-5f0f1a838bc2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-fe813a90-0ede-4a0e-862e-604f76159514.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-564be582-e937-4433-bc75-c30b83b65757.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a48ae876-ee41-49fa-a7f5-9958670950e4.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bbd0a34d-dad6-4b10-9f27-56f9051de58d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4c8019b1-050e-48a9-b634-67c36507d5ff.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a173bc3d-153c-4fc1-8fa6-3691cb922561.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-412f8ce3-14a9-4ca5-8e09-7c6273234ffb.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-8a3afaf4-666d-48ab-b363-b50b311e7a51.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-9c049e71-55a7-44a2-b851-946b1ddb3d80.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e8f502b4-491d-467d-8c8f-c4a79adf29ff.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-079db416-3faf-4afd-9ba0-45a1aefd01f2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c1f458cd-6a08-4734-893a-102493668b27.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-31a8e003-438e-4812-8428-728c22aa7f12.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8f309c46-cdd9-4e12-8f60-c79c59baf439.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8b8e4441-6f3f-46fb-86c9-16706181d3cf.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-af75ea5d-79ab-458a-b92c-8e1860201964.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-ba6eef44-8a80-446c-89b1-3ca40b9e67b7.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-09ad34fa-7846-4e38-abf4-a1279f768cca.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-80b123ad-9084-4b77-a0b2-7b7087ed644f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7d5616d8-b620-4259-b70f-1ce29bebd8ca.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d7eb924f-e0a1-41f0-ba24-f514d97748de.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8018165d-72dd-4e09-b23f-473bd80fdf44.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-097e1fa2-f1b4-4069-80b7-5c9e8688ad94.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f5504361-bce9-4d97-b2c2-c1bb1219a018.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0c382fed-0504-454d-baf9-82edcc7a2433.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3cd41a38-b858-4c03-9d39-d4842e85fc3d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-71cb6f5f-2367-42a6-bb3b-77b45313e898.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c87f003f-8370-42dc-9136-f9e693ebf91f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0f66797c-6c5c-4b06-9d44-79c754635882.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-af95facc-f6fd-46df-b73a-4b21c2958e86.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-aeac92fe-5165-48a4-9bce-a0ddb3f94618.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4af40aaa-f269-41a6-9578-e5c5df29dc57.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-5d00d77f-96d4-43a6-b703-a7298f48cfc5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7dc21724-7f87-44e5-ba96-3c45b35b4c16.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-afec3724-53df-469a-a141-34992d7352a7.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-47f6ba1f-eeef-4d7c-a06f-d7897c16216c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-6baf0dfa-6d23-4e4f-b2bd-0da1d1fbba92.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b4d1575e-6029-4634-849e-c66410acd3e0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-c97e9edc-e34a-42b8-8484-8c0f8a42b847.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-9f18c891-c391-4bce-8dd6-9866e5c3ad6e.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-3db353ed-b67f-45df-abe1-b6be04d7011c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-7eed6a2b-48b0-4ca9-8af6-f6705b0eeab9.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-04163ded-ec5d-4a5a-a388-7b47202ce6e5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-6f374538-e0a3-46da-91d2-437b7418f70a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-dfb29eb4-74e6-4469-bf34-7565bc9a545d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-725b0e15-fe28-4379-b944-c9fb102d064a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-cd44387f-05e1-4afe-9cee-597a9b9b5a01.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-23931003-0676-4142-abce-cd62ffb5c204.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-cdc791a0-735b-46e0-93f5-415cce8f966b.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d4fc151f-e4a3-473c-bf5f-2af4bef358bf.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-e2fb2c74-6b53-4627-8d4a-ccdce4e72f3f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2cfe457b-1cd1-4e73-af4c-c96a3523c9cb.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ac9277b6-f75b-4a62-af7f-7aabccce15f3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-90a11eba-8941-40a4-a948-c5bb0a9e20ea.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-64bdcc45-7992-4a0f-85f4-1c04dec6b407.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0d169c66-a2da-4549-ab65-b9a8f81cbbd1.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-57f5ec1b-59f4-4a99-b949-55feb7571a9f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e705b601-af0d-4c9a-b7ef-200738b3442d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c9485caa-a810-4027-80b7-57e1ceb18ec0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e1945451-f3ba-48b5-b141-745838b988dd.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-041c70fa-c5d8-414d-9641-1c4f256d0da3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f3d6b99f-6267-4b74-af57-2e2bb1a003bd.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1916332f-0a9a-462b-8278-56aaf34ad205.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-54731682-614f-466a-a261-737629b86161.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7f654047-452a-4f97-a6fb-e21e9e9089a5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ae18d405-b432-4b59-84bb-713bdcd8dac4.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-d4f3b8c6-147e-4139-8f0f-c5c067b8fbb2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-7b097521-74e9-44a6-92fa-5563740e900e.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3818f48d-7eab-401f-9211-068b6dd41d33.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-dadb23f2-d00a-450e-8d00-efd35f9255e2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-1296314e-f737-47ad-b08a-65ad0e22e2df.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7be26721-2831-4eb5-bff8-73994998f1d4.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1f074b76-35e8-4af4-94f9-75e96b73877d.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-17eab53e-ddb3-4a13-be31-e623c049cfef.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fe17e3af-7e01-455b-ae41-6b3ec892bbe2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e88f5e37-f6e9-4711-8537-3c0f6bb7c298.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-462fd242-5037-4662-abab-4d9269270b38.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e17b589f-af1b-4d31-ba0f-e347bd4d7bb0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-4c5d7058-1356-4927-b215-a3a503031f17.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-067d1e3a-780a-4931-a067-4a5ee73d8757.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bfac3193-7db5-4082-9669-1db000869e72.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-03c96953-9832-4f34-ae60-39aeb1843ff5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-51092b79-5325-41c2-b705-79e8a33b3529.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-035b007e-c593-4d5b-afa9-d0f8207dc091.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e5d0913b-c7f5-47a3-b0b9-e87a68f87164.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-c531fc58-25ed-4138-a3c5-d1fb4cd097cc.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-74a13c5a-c847-4e3f-96a6-d5b40659d405.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3a99c880-b257-4d72-8e48-5c0e3fd0525f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-935095c0-287f-4aff-b3e5-66b83976b48a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2551e19d-2ddb-4666-bb31-22f65e83290e.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bb1dcd8c-d302-474a-ad13-cbbd63b4e05c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0962439b-0a20-4348-ae53-e68748087b6a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-36cea2eb-dc8d-4d92-b149-ec1dc3fd9679.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9afe5989-3250-488d-8676-9ebcff443c46.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-74444f52-6ab2-4c2c-a85d-98c40199c557.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bf69e8ef-ed52-4b1a-b7cf-39e1f15b56e3.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-6af3c7fa-cc01-490c-9d57-2c3c84e08727.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e7f6e16a-db79-4388-b549-df4519cfaee2.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ea497d79-d8a5-4371-8a43-a5f019d35f3c.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-609e14ef-f7ea-40b0-bad3-ab829278bc78.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ded7bd32-fd9e-4a78-9d1b-b84a3f7f93e7.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fd30187c-62bc-4681-a7b9-b0a1fbc99d11.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f198155a-c965-4ab2-bb14-4a102fed513e.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-37c6be60-4e87-49eb-862d-6c3148044edf.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-aab09108-68e4-457b-b391-a9c5eec1d149.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3f1a66eb-9a10-4084-9c6b-ed0a319b5af5.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fac41bf4-ad07-4625-bdb8-f7378da0f596.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b45d9502-fbc4-42a0-9a39-99ece5e437b4.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-113ffff8-26ad-472f-abc0-2228be58eb4f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fbeb390e-3141-4c70-ac9e-b8742c7ffcfe.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f0fca30a-3149-4bb6-928a-cd1a09ce88ea.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-1f411848-fec2-49bb-a313-9b7a3f39079a.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-dd762523-065b-4203-a174-5a389263592b.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bbca6612-b5f4-4450-9fa1-0232e3397255.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-87bfa835-251f-4741-9d9c-b8b7d7f1b0b6.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-08e9bf85-12af-47bf-9612-86d33f6e089f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-50a5792c-0a17-4630-a6ec-c00e32b9e4f1.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-602ba5d4-e77f-4108-83d0-65c0e3989d06.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-5a57f65a-5445-4c90-8eee-8137e67c35bb.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f997b43d-587c-488b-8786-393eb0a357ca.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0abfdfd6-1c2f-4236-809c-4a7914b7065f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ae8768c4-04c9-4621-9658-7fb17870f903.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7588b562-ad55-466f-862a-6e7a4cbfbb83.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3db94da1-ed2a-4540-b754-6da3bc4988df.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-31138d7c-ef87-4a8d-a74c-a1c1f7cd641b.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f8869aa6-98d3-4cc1-8025-8a815a410625.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-66446d7f-2602-43c1-a70f-4b736c7917a0.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-80b487f5-1989-444b-9c65-7864e247b936.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/test-629228d6-632e-4da1-bacc-c53ead904983.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-35ca1d36-60a9-4e2c-8ed6-bfdd69ad38ec.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9a00b673-8bfb-4b59-a72e-5ce3e2979923.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d6f05e95-fe8f-4a57-9494-9b0198a4d49f.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a00071a2-cfa5-4c53-99aa-cc2f50caa069.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-686eaed2-917b-40fd-882c-3eea8d24d1df.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-76e3eabd-d0c2-401d-97cc-4c7235bfed03.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-845cb713-a83d-4fd9-93bb-832fd447d5ed.png.1920x1880.jpg\n" +
-                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c1d5f8dc-1888-4f45-b9bd-bf9403e4abcd.png.1920x1880.jpg\n";
-
-
-        String[] split = img.split("\n");
-        for (int i = 0; i < split.length; i++) {
-            String url = split[i];
-            if (StringUtils.isNotEmpty(url)) {
-                downloadPicture(url, "E:\\temp\\img\\" + (i + 1) + ".jpg");
-            }
-        }
-    }
+//    @Test
+//    public void dowloadImg() {
+//        String img = "https://image1.ljcdn.com/x-se/hdic-frame/prod-bfd3b9b7-a806-4a87-b698-ed917c06211a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7c46b149-ae30-4be1-a263-ab175243282a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e5cf3040-aa82-43b8-98df-7fbddaeb16c0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-528bf7e3-5b89-4559-9ee4-11ae7ad369d0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-23729179-edcd-480e-88bc-dad6e1d3c267.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2734f121-8fa2-40d3-9d57-24f0af794e71.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2a9f5018-99ef-4fbe-a8fc-3492637f1ad3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0765219d-0b74-4317-bdce-c2756c4b63c4.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-45790885-ce05-4e5d-8b61-8dfe01f3cbb4.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f7b2dfb7-282c-4c60-9cee-1405f345ace5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0d947000-ca31-466c-be03-29d36a963b4e.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f8a0138d-675b-4a94-b82d-85a5f1175be2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8900b029-fe84-4492-b3fe-400d4ff0c7f1.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d1824b02-d9ef-455a-8c63-155295b2f85e.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0aa34348-5497-4099-be46-26475a4cea7f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7dc749da-50c2-43f5-aaf2-dd2520e43dce.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-05502762-de5d-432c-b34e-48fc17626ee8.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bd158eab-4be2-4b33-b217-3b2a7cbb127c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-86019a37-2d06-40de-b9fc-58e7953d0566.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-92352810-1d78-40a2-8fb4-a58fcb085835.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9858afd1-c966-4f8b-b8aa-d4d93e1d7c0a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2728c804-d1a7-4654-81f9-6b981a8753ac.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-5fc826b3-594d-484c-bf60-9233e39d325d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-46f41f29-d4b4-4c8b-b664-1620c7fefcf3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1a1f66d2-07fc-4de0-b761-9402f189ef70.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2a1c3845-6d9b-4391-9496-33d60b195f58.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4676de1d-4a2e-484a-9082-0edd037245f6.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c126c932-510e-4539-b69d-f1076ca6b13b.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b513d7d5-dfe4-4f2b-a0c4-82054dd905dd.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8e6ffcd5-fdea-4427-820c-9c491235f431.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-10e7d74b-32c5-4202-992b-f1ec8f02b5e1.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-72434446-c7e7-465e-a874-36fa40f4495d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bec6582d-8d09-43cc-8538-bd983b8acd9b.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-e85f3248-563d-4aef-b42d-6acff394f8c2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a4f2a118-31f3-4e5f-868d-e3c46c6311e1.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-5d2943da-5592-461c-943d-3e473aa5706c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-deb84650-1cba-45f2-8b7f-2629fc2795f7.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4a5cb513-e0a5-4ffd-849e-dcfb9e4f59be.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4ab3e9db-9f81-47cc-bd6e-68b460faa598.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4f969cfd-ffdb-45c0-8829-f6d1ef059b1a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-66d394fd-a3f7-4213-9127-024ae004b15c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1fab560d-520d-4cda-8efe-1d7ae28fb25a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9e15c80e-0502-4d4e-8d4e-54e13c811109.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9b9da5dc-91b1-4913-942e-eafc9a98e8a8.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-80ff9510-7504-45c4-b49c-92d359491753.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b0488260-478f-4af1-9505-9c244a78dd71.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0c1be4d7-7a8b-4142-ad40-638ce521c3be.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-21197991-e60b-426a-9143-2340711da68c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c5ad83c4-b5ae-4a90-b197-9c69033bac1d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/40c271d2-68aa-4c67-bbec-a274a26a0c58.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/2372564f-55a4-4376-8574-a553210c42bb.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-6d0357fc-8117-46a4-900a-8995713469fb.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-ce03e966-040c-4378-aa57-72ade311ed82.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-d0211e1c-e463-4e0b-abd4-04bd2b0e9ee5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ab5b5dd5-316c-493d-a3f0-820e3e808ad8.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-fdc1497b-1773-4a9a-a516-02776b1dbd54.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-6a51da59-412b-477a-858d-2b6a8d26c98f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-a1df6e86-7202-490a-926e-8d7f6bd7a373.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-541cde2e-b69a-40db-a943-963ff141a5c3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-5cd81120-6ca3-4cc8-bfb9-27e24add0c39.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9b730207-58a5-4d9b-b980-02b2dd7c362d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9b6438a3-dabd-409d-b319-461425c01202.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-f432592e-c5fa-4cac-9a36-69a43efe38ac.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-bcfe644a-3fb1-4ff3-965d-ac6e17edbcaf.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7cb323f4-c705-47ab-9e2e-86b7160dbade.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b867bbb2-3114-4ff6-81fa-a4ca139ee2a0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b1bf05f4-c6fb-4872-aa51-e1138b4b08a2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-9b1bc445-ad59-41e8-b4db-1dffb569dec3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-4ec2283a-10b9-4203-8640-69e70c1eadc5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-8a21f7ee-47a4-49e0-a772-bd5da5af98b2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-7fdfeed0-56fe-4e60-92ae-4d09eb3f62d3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2473e607-eb48-4dc0-95bc-d4d037adbf29.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-51884466-c928-437f-ac39-a59f839c21cd.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b9ae80af-2153-4ea1-a1c0-0cca979becba.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ddf5062c-b89b-40bd-8eb9-8557c8b053f4.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8c622f2f-3a60-40f0-a0b8-6ed660fc4756.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-a1d71be0-4506-48c0-ae84-f2fde02cab9c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-19f9b208-fe7e-4b16-bf07-f7b217a51f33.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b11558ea-876a-4d4f-b38b-54c243c8488d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3664742e-8e03-46af-ac6c-05f62293fe4d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-9ff3ba52-d0f3-4deb-a44b-2e436067b5a0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-03dd39ac-ee90-44b4-87d9-5f0f1a838bc2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-fe813a90-0ede-4a0e-862e-604f76159514.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-564be582-e937-4433-bc75-c30b83b65757.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a48ae876-ee41-49fa-a7f5-9958670950e4.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bbd0a34d-dad6-4b10-9f27-56f9051de58d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4c8019b1-050e-48a9-b634-67c36507d5ff.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a173bc3d-153c-4fc1-8fa6-3691cb922561.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-412f8ce3-14a9-4ca5-8e09-7c6273234ffb.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-8a3afaf4-666d-48ab-b363-b50b311e7a51.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-9c049e71-55a7-44a2-b851-946b1ddb3d80.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e8f502b4-491d-467d-8c8f-c4a79adf29ff.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-079db416-3faf-4afd-9ba0-45a1aefd01f2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c1f458cd-6a08-4734-893a-102493668b27.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-31a8e003-438e-4812-8428-728c22aa7f12.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8f309c46-cdd9-4e12-8f60-c79c59baf439.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8b8e4441-6f3f-46fb-86c9-16706181d3cf.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-af75ea5d-79ab-458a-b92c-8e1860201964.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-ba6eef44-8a80-446c-89b1-3ca40b9e67b7.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-09ad34fa-7846-4e38-abf4-a1279f768cca.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-80b123ad-9084-4b77-a0b2-7b7087ed644f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7d5616d8-b620-4259-b70f-1ce29bebd8ca.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d7eb924f-e0a1-41f0-ba24-f514d97748de.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-8018165d-72dd-4e09-b23f-473bd80fdf44.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-097e1fa2-f1b4-4069-80b7-5c9e8688ad94.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f5504361-bce9-4d97-b2c2-c1bb1219a018.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0c382fed-0504-454d-baf9-82edcc7a2433.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3cd41a38-b858-4c03-9d39-d4842e85fc3d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-71cb6f5f-2367-42a6-bb3b-77b45313e898.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c87f003f-8370-42dc-9136-f9e693ebf91f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0f66797c-6c5c-4b06-9d44-79c754635882.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-af95facc-f6fd-46df-b73a-4b21c2958e86.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-aeac92fe-5165-48a4-9bce-a0ddb3f94618.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-4af40aaa-f269-41a6-9578-e5c5df29dc57.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-5d00d77f-96d4-43a6-b703-a7298f48cfc5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7dc21724-7f87-44e5-ba96-3c45b35b4c16.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-afec3724-53df-469a-a141-34992d7352a7.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-47f6ba1f-eeef-4d7c-a06f-d7897c16216c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-6baf0dfa-6d23-4e4f-b2bd-0da1d1fbba92.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b4d1575e-6029-4634-849e-c66410acd3e0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-c97e9edc-e34a-42b8-8484-8c0f8a42b847.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-9f18c891-c391-4bce-8dd6-9866e5c3ad6e.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-3db353ed-b67f-45df-abe1-b6be04d7011c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-7eed6a2b-48b0-4ca9-8af6-f6705b0eeab9.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-04163ded-ec5d-4a5a-a388-7b47202ce6e5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-6f374538-e0a3-46da-91d2-437b7418f70a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-dfb29eb4-74e6-4469-bf34-7565bc9a545d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-725b0e15-fe28-4379-b944-c9fb102d064a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-cd44387f-05e1-4afe-9cee-597a9b9b5a01.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-23931003-0676-4142-abce-cd62ffb5c204.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-cdc791a0-735b-46e0-93f5-415cce8f966b.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d4fc151f-e4a3-473c-bf5f-2af4bef358bf.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-e2fb2c74-6b53-4627-8d4a-ccdce4e72f3f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2cfe457b-1cd1-4e73-af4c-c96a3523c9cb.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ac9277b6-f75b-4a62-af7f-7aabccce15f3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-90a11eba-8941-40a4-a948-c5bb0a9e20ea.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-64bdcc45-7992-4a0f-85f4-1c04dec6b407.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0d169c66-a2da-4549-ab65-b9a8f81cbbd1.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-57f5ec1b-59f4-4a99-b949-55feb7571a9f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e705b601-af0d-4c9a-b7ef-200738b3442d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c9485caa-a810-4027-80b7-57e1ceb18ec0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e1945451-f3ba-48b5-b141-745838b988dd.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-041c70fa-c5d8-414d-9641-1c4f256d0da3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f3d6b99f-6267-4b74-af57-2e2bb1a003bd.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1916332f-0a9a-462b-8278-56aaf34ad205.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-54731682-614f-466a-a261-737629b86161.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7f654047-452a-4f97-a6fb-e21e9e9089a5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ae18d405-b432-4b59-84bb-713bdcd8dac4.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-d4f3b8c6-147e-4139-8f0f-c5c067b8fbb2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-7b097521-74e9-44a6-92fa-5563740e900e.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3818f48d-7eab-401f-9211-068b6dd41d33.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-dadb23f2-d00a-450e-8d00-efd35f9255e2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-1296314e-f737-47ad-b08a-65ad0e22e2df.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7be26721-2831-4eb5-bff8-73994998f1d4.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-1f074b76-35e8-4af4-94f9-75e96b73877d.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-17eab53e-ddb3-4a13-be31-e623c049cfef.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fe17e3af-7e01-455b-ae41-6b3ec892bbe2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e88f5e37-f6e9-4711-8537-3c0f6bb7c298.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-462fd242-5037-4662-abab-4d9269270b38.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e17b589f-af1b-4d31-ba0f-e347bd4d7bb0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-4c5d7058-1356-4927-b215-a3a503031f17.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-067d1e3a-780a-4931-a067-4a5ee73d8757.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bfac3193-7db5-4082-9669-1db000869e72.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-03c96953-9832-4f34-ae60-39aeb1843ff5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-51092b79-5325-41c2-b705-79e8a33b3529.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-035b007e-c593-4d5b-afa9-d0f8207dc091.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e5d0913b-c7f5-47a3-b0b9-e87a68f87164.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-c531fc58-25ed-4138-a3c5-d1fb4cd097cc.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-74a13c5a-c847-4e3f-96a6-d5b40659d405.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3a99c880-b257-4d72-8e48-5c0e3fd0525f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-935095c0-287f-4aff-b3e5-66b83976b48a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-2551e19d-2ddb-4666-bb31-22f65e83290e.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bb1dcd8c-d302-474a-ad13-cbbd63b4e05c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0962439b-0a20-4348-ae53-e68748087b6a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-36cea2eb-dc8d-4d92-b149-ec1dc3fd9679.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9afe5989-3250-488d-8676-9ebcff443c46.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-74444f52-6ab2-4c2c-a85d-98c40199c557.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bf69e8ef-ed52-4b1a-b7cf-39e1f15b56e3.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-6af3c7fa-cc01-490c-9d57-2c3c84e08727.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-e7f6e16a-db79-4388-b549-df4519cfaee2.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ea497d79-d8a5-4371-8a43-a5f019d35f3c.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-609e14ef-f7ea-40b0-bad3-ab829278bc78.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ded7bd32-fd9e-4a78-9d1b-b84a3f7f93e7.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fd30187c-62bc-4681-a7b9-b0a1fbc99d11.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f198155a-c965-4ab2-bb14-4a102fed513e.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-37c6be60-4e87-49eb-862d-6c3148044edf.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-aab09108-68e4-457b-b391-a9c5eec1d149.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3f1a66eb-9a10-4084-9c6b-ed0a319b5af5.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fac41bf4-ad07-4625-bdb8-f7378da0f596.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-b45d9502-fbc4-42a0-9a39-99ece5e437b4.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-113ffff8-26ad-472f-abc0-2228be58eb4f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-fbeb390e-3141-4c70-ac9e-b8742c7ffcfe.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f0fca30a-3149-4bb6-928a-cd1a09ce88ea.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-1f411848-fec2-49bb-a313-9b7a3f39079a.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-dd762523-065b-4203-a174-5a389263592b.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-bbca6612-b5f4-4450-9fa1-0232e3397255.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-87bfa835-251f-4741-9d9c-b8b7d7f1b0b6.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-08e9bf85-12af-47bf-9612-86d33f6e089f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-50a5792c-0a17-4630-a6ec-c00e32b9e4f1.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-602ba5d4-e77f-4108-83d0-65c0e3989d06.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-5a57f65a-5445-4c90-8eee-8137e67c35bb.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f997b43d-587c-488b-8786-393eb0a357ca.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-0abfdfd6-1c2f-4236-809c-4a7914b7065f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-ae8768c4-04c9-4621-9658-7fb17870f903.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-7588b562-ad55-466f-862a-6e7a4cbfbb83.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-3db94da1-ed2a-4540-b754-6da3bc4988df.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-31138d7c-ef87-4a8d-a74c-a1c1f7cd641b.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-f8869aa6-98d3-4cc1-8025-8a815a410625.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-66446d7f-2602-43c1-a70f-4b736c7917a0.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-80b487f5-1989-444b-9c65-7864e247b936.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/test-629228d6-632e-4da1-bacc-c53ead904983.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-35ca1d36-60a9-4e2c-8ed6-bfdd69ad38ec.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-9a00b673-8bfb-4b59-a72e-5ce3e2979923.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-d6f05e95-fe8f-4a57-9494-9b0198a4d49f.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-a00071a2-cfa5-4c53-99aa-cc2f50caa069.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-686eaed2-917b-40fd-882c-3eea8d24d1df.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-76e3eabd-d0c2-401d-97cc-4c7235bfed03.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-845cb713-a83d-4fd9-93bb-832fd447d5ed.png.1920x1880.jpg\n" +
+//                "https://image1.ljcdn.com/x-se/hdic-frame/prod-c1d5f8dc-1888-4f45-b9bd-bf9403e4abcd.png.1920x1880.jpg\n";
+//
+//
+//        String[] split = img.split("\n");
+//        for (int i = 0; i < split.length; i++) {
+//            String url = split[i];
+//            if (StringUtils.isNotEmpty(url)) {
+//                downloadPicture(url, "E:\\temp\\img\\" + (i + 1) + ".jpg");
+//            }
+//        }
+//    }
 
     //链接url下载图片
     private static void downloadPicture(String urlList, String path) {

+ 12 - 1
pom.xml

@@ -7,7 +7,7 @@
     <groupId>com.elab.core</groupId>
     <artifactId>elab-parent</artifactId>
     <packaging>pom</packaging>
-    <version>2.0.4.14-SNAPSHOT</version>
+    <version>2.0.5.1-SNAPSHOT</version>
     <modules>
         <module>elab-core</module>
         <module>elab-cache</module>
@@ -22,6 +22,7 @@
         <module>elab-rocketMQ</module>
         <module>elab-es</module>
         <module>elab-redis</module>
+        <module>elab-kafka</module>
     </modules>
 
 
@@ -326,6 +327,16 @@
                 <scope>compile</scope>
                 <version>1.5.19</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents</groupId>
+                <artifactId>httpclient</artifactId>
+                <version>4.5.6</version>
+            </dependency>
+            <dependency>
+                <groupId>com.jay.monitor.data</groupId>
+                <artifactId>jay-monitor-data-client</artifactId>
+                <version>1.0-SNAPSHOT</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>