소스 검색

新增消息队列功能

liukx@elab 5 년 전
부모
커밋
ddff71cb48
65개의 변경된 파일4429개의 추가작업 그리고 20개의 파일을 삭제
  1. 1 1
      elab-alert/pom.xml
  2. 1 1
      elab-annotation/pom.xml
  3. 1 1
      elab-cache/pom.xml
  4. 1 1
      elab-core/pom.xml
  5. 1 1
      elab-db/pom.xml
  6. 0 4
      elab-db/src/main/java/com/elab/core/aop/annotations/EnableElabDB.java
  7. 242 0
      elab-es/README.md
  8. 54 0
      elab-es/pom.xml
  9. 15 0
      elab-es/src/main/java/com/elab/es/client/DefaultElasticSearchTemplate.java
  10. 17 0
      elab-es/src/main/java/com/elab/es/client/configuration/ESConfiguration.java
  11. 1 0
      elab-es/src/main/resources/META-INF/spring.factories
  12. 29 0
      elab-es/src/test/java/com/elab/es/App.java
  13. 563 0
      elab-es/src/test/java/com/elab/es/data/DataTest.java
  14. 349 0
      elab-es/src/test/java/com/elab/es/data/RestHighLevelClientTest.java
  15. 44 0
      elab-es/src/test/java/com/elab/es/model/User.java
  16. 4 0
      elab-es/src/test/resources/application.yml
  17. 1 1
      elab-log/pom.xml
  18. 1 1
      elab-mongodb/pom.xml
  19. 1 1
      elab-mq/pom.xml
  20. 116 0
      elab-rocketMQ/REDERME.md
  21. 52 0
      elab-rocketMQ/pom.xml
  22. 29 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/App.java
  23. 19 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/anno/EnableRocketMQ.java
  24. 67 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/configuration/RocketMQConfiguration.java
  25. 45 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/consumer/StringConsumer.java
  26. 14 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/exception/MsgProcessException.java
  27. 14 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/exception/MsgRecurringException.java
  28. 14 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/exception/MsgWaitException.java
  29. 128 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/listener/DefaultRocketMQListener.java
  30. 66 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/listener/TagInvokerListener.java
  31. 24 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/listener/TagRocketMQListener.java
  32. 47 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/ConsumerDataStore.java
  33. 114 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/DefaultConsumeMessageHook.java
  34. 38 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/DefaultSendMessageHook.java
  35. 18 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/IRmqConsumerDao.java
  36. 17 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/IRmqProducerDao.java
  37. 67 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/MemoryDataStore.java
  38. 55 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/MysqlDataStore.java
  39. 36 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/ProducerDataStore.java
  40. 241 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/entity/RmqConsumerEntity.java
  41. 198 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/entity/RmqProducerEntity.java
  42. 17 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/producer/DefaultMQProducerExt.java
  43. 47 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/template/DefaultMQProducerExt.java
  44. 25 0
      elab-rocketMQ/src/main/java/com/elab/mq/rocket/utils/MsgConstants.java
  45. 43 0
      elab-rocketMQ/src/test/java/com/elab/mq/rocket/msg/DefaultSendMessageHookTest.java
  46. 16 0
      elab-rocketMQ/src/test/resources/application.yml
  47. 1 1
      elab-spring/pom.xml
  48. 264 4
      elab-spring/src/test/java/com/elab/spring/utils/RestTemplateUtilsTest.java
  49. 4 3
      pom.xml
  50. 45 0
      springboot-demo/src/main/java/com/elab/example/springbootdemo/configuration/KafkaConfiguration.java
  51. 39 0
      springboot-demo/src/main/java/com/elab/example/springbootdemo/consumer/JSONConsumer.java
  52. 43 0
      springboot-demo/src/main/java/com/elab/example/springbootdemo/consumer/StringConsumer.java
  53. 43 0
      springboot-demo/src/main/java/com/elab/example/springbootdemo/consumer/StringTagConsumer.java
  54. 50 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/App.java
  55. 103 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/AxinBlockQueue.java
  56. 33 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/ConditionSignal.java
  57. 37 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/ConditionWait.java
  58. 109 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/MyBlockingArray.java
  59. 114 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/XBlockingQueue.java
  60. 256 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/es/EsTest.java
  61. 67 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/es/entity/User.java
  62. 76 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/es/entity/UserTable.java
  63. 46 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/kafka/KafkaSpringTest.java
  64. 152 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/kafka/KafkaTest.java
  65. 54 0
      springboot-demo/src/test/java/com/elab/example/springbootdemo/rocketmq/producerTest.java

+ 1 - 1
elab-alert/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.11-SNAPSHOT</version>
+        <version>2.0.4.12-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.11-SNAPSHOT</version>
+        <version>2.0.4.12-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.11-SNAPSHOT</version>
+        <version>2.0.4.12-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.11-SNAPSHOT</version>
+        <version>2.0.4.12-SNAPSHOT</version>
     </parent>
 
     <groupId>com.elab.core</groupId>

+ 1 - 1
elab-db/pom.xml

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

+ 0 - 4
elab-db/src/main/java/com/elab/core/aop/annotations/EnableElabDB.java

@@ -4,7 +4,6 @@ import com.elab.core.spring.config.DataSourceConfigBean;
 import com.elab.core.spring.config.JdbcBeanConfig;
 import com.elab.core.spring.config.TransactionConfigBean;
 import org.springframework.context.annotation.Import;
-import org.springframework.core.annotation.AliasFor;
 
 import java.lang.annotation.*;
 
@@ -14,7 +13,4 @@ import java.lang.annotation.*;
 @Import({DataSourceConfigBean.class, JdbcBeanConfig.class, TransactionConfigBean.class})
 public @interface EnableElabDB {
 
-    @AliasFor("basePackages")
-    String[] scanBasePackages() default {};
-
 }

+ 242 - 0
elab-es/README.md

@@ -0,0 +1,242 @@
+# Elab-ES使用手册
+
+## 环境配置
+
+### 加载依赖
+
+```xml
+<dependency>
+    <groupId>com.elab.core</groupId>
+    <artifactId>elab-es</artifactId>
+    <version>${project.version}</version>
+</dependency>
+```
+
+### 开启ES功能
+
+SpringBoot的启动类上加入`@EnableESTools`
+
+配置文件中加入
+
+
+
+```yml
+spring.elasticsearch.rest.uris=http://192.168.0.24:9200
+```
+
+如果有多个(集群情况)请用半角逗号```,```隔开
+
+
+
+### 索引映射
+
+```java
+import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
+import org.zxp.esclientrhl.annotation.ESMetaData;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户entity
+ *
+ * @author : liukx
+ * @time : 2019/8/1 - 11:40
+ */
+@ESMetaData(indexName = "索引名称", indexType = "类型名称", number_of_shards = 5, number_of_replicas = 0,
+        printLog = true)
+public class UserTable implements Serializable {
+	// 对应字段
+    private String doc_id;
+    private String title;
+    private String message;
+    private Date postDate;
+
+    private HighlightField highlightField;
+
+    public HighlightField getHighlightField() {
+        return highlightField;
+    }
+
+    public void setHighlightField(HighlightField highlightField) {
+        this.highlightField = highlightField;
+    }
+
+    public String getDoc_id() {
+        return doc_id;
+    }
+
+    public void setDoc_id(String doc_id) {
+        this.doc_id = doc_id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Date getPostDate() {
+        return postDate;
+    }
+
+    public void setPostDate(Date postDate) {
+        this.postDate = postDate;
+    }
+
+    @Override
+    public String toString() {
+        return "UserTable{" +
+                "doc_id='" + doc_id + '\'' +
+                ", title='" + title + '\'' +
+                ", message='" + message + '\'' +
+                ", postDate=" + postDate +
+                ", highlightField=" + highlightField +
+                '}';
+    }
+}
+```
+
+`indexName` : 类似于Mysql的数据库名称
+
+`indexType`: 类似于Mysql的表名称
+
+`printLog` : 是否打印日志,这个东西会将请求的参数转换成ES的文档搜索查询字符串打印出来
+
+### 业务中使用
+
+加入模版操作类
+
+```java
+@Autowired
+DefaultElasticSearchTemplate<Main2,String> elasticsearchTemplate;
+```
+
+这里是引入ES操作的模版类。
+
+**Main2** : 映射ES的实体类
+
+String : 主键
+
+```java
+@ESMetaData(indexName = "index",indexType = "main", number_of_shards = 5,number_of_replicas = 0)
+public class Main2 implements Serializable {
+    private static final long serialVersionUID = 1L;
+    @ESID
+    private String proposal_no;
+```
+
+
+
+
+
+
+
+#### 新增数据
+
+```java
+Main2 main = new Main2();
+main.setProposal_no("main2");
+main.setAppli_code("123");
+main.setAppli_name("456");
+elasticsearchTemplate.save(main);
+```
+
+#### 批量新增数据
+
+```java
+List<Main2> list = new ArrayList<>();
+Main2 main1 = new Main2();
+main1.setProposal_no("main1");
+main1.setAppli_code("123");
+main1.setAppli_name("456");
+Main2 main2 = new Main2();
+main2.setProposal_no("main2");
+main2.setAppli_code("123");
+main2.setAppli_name("456");
+Main2 main3 = new Main2();
+main3.setProposal_no("main3");
+main3.setAppli_code("123");
+main3.setAppli_name("456");
+list.add(main1);
+list.add(main2);
+list.add(main3);
+elasticsearchTemplate.save(list);
+```
+
+####  部分更新索引数据
+
+```java
+Main2 main1 = new Main2();
+main1.setProposal_no("main1");
+main1.setInsured_code("123");
+elasticsearchTemplate.update(main1);
+```
+
+#### 判断索引是否存在
+
+```java
+Main2 main1 = new Main2();
+main1.setProposal_no("main1");
+main1.setInsured_code("123");
+boolean exists = elasticsearchTemplate.exists("main1",Main2.class);
+System.out.println(exists);
+```
+
+原生查询
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+####  原生查询
+
+searchRequest是官方原生查询输入,此方法在工具无法满足需求时使用
+
+```java
+SearchRequest searchRequest = new SearchRequest(new String[]{"index"});
+SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
+searchSourceBuilder.query(new MatchAllQueryBuilder());
+searchSourceBuilder.from(0);
+searchSourceBuilder.size(10);
+searchRequest.source(searchSourceBuilder);
+SearchResponse searchResponse = elasticsearchTemplate.search(searchRequest);
+
+SearchHits hits = searchResponse.getHits();
+SearchHit[] searchHits = hits.getHits();
+for (SearchHit hit : searchHits) {
+    Main2 t = JsonUtils.string2Obj(hit.getSourceAsString(), Main2.class);
+    System.out.println(t);
+}
+```
+
+#### 高级查询
+
+[参考文档](https://gitee.com/zxporz/ESClientRHL)
+
+
+
+
+
+#### 高亮查询
+

+ 54 - 0
elab-es/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.4.12-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>elab-es</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <artifactId>elab-core</artifactId>
+            <groupId>com.elab.core</groupId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <artifactId>elab-spring</artifactId>
+            <groupId>com.elab.core</groupId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.zxp</groupId>
+            <artifactId>esclientrhl</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>org.springframework.boot</groupId>-->
+        <!--            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->
+        <!--            <version>2.1.6.RELEASE</version>-->
+        <!--        </dependency>-->
+        <!--        <dependency>-->
+        <!--            <groupId>org.elasticsearch.client</groupId>-->
+        <!--            <artifactId>elasticsearch-rest-client</artifactId>-->
+        <!--            <version>6.7.2</version>-->
+        <!--        </dependency>-->
+        <dependency>
+            <groupId>org.elasticsearch.client</groupId>
+            <artifactId>elasticsearch-rest-high-level-client</artifactId>
+            <version>6.7.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <version>2.1.6.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 15 - 0
elab-es/src/main/java/com/elab/es/client/DefaultElasticSearchTemplate.java

@@ -0,0 +1,15 @@
+package com.elab.es.client;
+
+import org.springframework.stereotype.Component;
+import org.zxp.esclientrhl.repository.ElasticsearchTemplateImpl;
+
+/**
+ * 默认的ES模版处理器
+ *
+ * @author : liukx
+ * @time : 2019/8/6 - 15:05
+ */
+@Component
+public class DefaultElasticSearchTemplate<K, V> extends ElasticsearchTemplateImpl<K, V> {
+
+}

+ 17 - 0
elab-es/src/main/java/com/elab/es/client/configuration/ESConfiguration.java

@@ -0,0 +1,17 @@
+package com.elab.es.client.configuration;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * es的配置类
+ *
+ * @author : liukx
+ * @time : 2019/8/6 - 15:48
+ */
+@Configuration
+@ComponentScan(basePackages = "com.elab.es.*")
+//@Import({DefaultElasticSearchTemplate.class})
+public class ESConfiguration {
+
+}

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

@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.elab.es.client.configuration.ESConfiguration

+ 29 - 0
elab-es/src/test/java/com/elab/es/App.java

@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.elab.es;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App {
+
+    public static void main(String[] args) {
+        SpringApplication.run(App.class, args);
+    }
+
+}

+ 563 - 0
elab-es/src/test/java/com/elab/es/data/DataTest.java

@@ -0,0 +1,563 @@
+package com.elab.es.data;
+
+import com.alibaba.fastjson.JSON;
+import com.elab.es.model.User;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.nio.entity.NStringEntity;
+import org.apache.http.util.EntityUtils;
+import org.elasticsearch.client.Response;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.transport.TransportClient;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.util.Collections;
+
+/**
+ * @author : liukx
+ * @time : 2019/7/31 - 14:02
+ */
+public class DataTest {
+    private static RestClient restClient;
+    private TransportClient transportClient;
+
+
+    /**
+     * 初始化RestClient
+     */
+    @Before
+    public void initRestClient() {
+        restClient = RestClient.builder(
+                new HttpHost("192.168.0.24", 9200, "http")).build();
+    }
+
+    /**
+     * 创建索引(id自己设置,PUT请求)
+     */
+    @Test
+    public void testCreateIndex() throws Exception {
+        User user = new User();
+        user.setId(100L);
+        user.setAge(20);
+        user.setName("张三100");
+        user.setSex(1);
+//        IndexRequest request = new IndexRequest("test", "index");
+//        request.source(user);
+//        request.timeout(TimeValue.timeValueSeconds(1));
+//        request.versionType(VersionType.EXTERNAL);
+//        request.routing()
+        HttpEntity entity = new NStringEntity(JSON.toJSONString(user), ContentType.APPLICATION_JSON);
+        Response indexResponse = restClient.performRequest(
+                "POST",
+                "/test/user",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(indexResponse.getEntity()));
+    }
+
+    /**
+     * 创建索引(id自动生成,POST请求)
+     */
+    @Test
+    public void testCreateIndex2() throws Exception {
+        User user = new User();
+        user.setAge(20);
+        user.setName("张三");
+        user.setSex(1);
+
+        HttpEntity entity = new NStringEntity(JSON.toJSONString(user), ContentType.APPLICATION_JSON);
+
+        Response indexResponse = restClient.performRequest(
+                "POST",
+                "test",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(indexResponse.getEntity()));
+    }
+
+    /**
+     * 根据id查询
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testFindById() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"match\" : {\n" +
+                " \"id\" : \"100\"\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "GET",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+
+        InputStream content = response.getEntity().getContent();
+        System.out.println("@@@liu" + content.toString());
+        Header[] headers = response.getHeaders();
+        for (Header header : headers) {
+            System.out.println("@@@name" + header.getName());
+            System.out.println("@@@value" + header.getValue());
+        }
+
+
+        /*byte[] b = new byte[1024];
+ int lenth = 0;
+ while ((lenth=content.read())!=-1){
+ int read = content.read(b, 0, lenth);
+ System.out.println("!!!"+new String(b,0,read));
+ }*/
+        System.out.println("!!!" + IOUtils.toString(content, "UTF-8"));
+    }
+
+    /**
+     * (查询特定字段用户)
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testFindByKey() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"match\" : {\n" +
+                " \"name\" : \"张1\"\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "GET",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+
+    }
+
+    /**
+     * 查询所有(默认返回10条记录)
+     */
+    @Test
+    public void findAll() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": { \"match_all\": {} }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "GET",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+
+    }
+
+    /**
+     * match_all & 返回11到20个文档信息
+     * from:指定文档索引从哪里开始,默认从0开始
+     * size:从from开始,返回多个文档
+     */
+    @Test
+    public void findByPage() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": { \"match_all\": {} },\n" +
+                " \"from\": 10,\n" +
+                " \"size\": 10\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+
+    }
+
+    /**
+     * 根据年龄降序排序查询.默认返回10条
+     */
+    @Test
+    public void findAllByAgeOderBy() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": { \"match_all\": {} },\n" +
+                " \"sort\": { \"age\": { \"order\": \"desc\" } }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 查询返回指定的字段(这样操作有点类似于SQL SELECT FROM field lis)
+     */
+    @Test
+    public void findByLimitField() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": { \"match_all\": {} },\n" +
+                " \"_source\": [\"name\", \"age\"]\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+
+    /**
+     * 布尔值(bool)查询(返回 匹配name=张1 & age=21)
+     */
+    @Test
+    public void findByMustBool() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"bool\": {\n" +
+                " \"must\": [\n" +
+                " { \"match\": { \"name\": \"张1\" } },\n" +
+                " { \"match\": { \"age\": \"21\" } }\n" +
+                " ]\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 布尔值(bool)查询(返回 匹配name=张1 || age=21)
+     */
+    @Test
+    public void findByOrBool() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"bool\": {\n" +
+                " \"should\": [\n" +
+                " { \"match\": { \"name\": \"张1\" } },\n" +
+                " { \"match\": { \"age\": \"21\" } }\n" +
+                " ]\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 布尔值(bool)查询(返回 不匹配name=张1 & age=21)
+     */
+    @Test
+    public void findByMachNotBool() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"bool\": {\n" +
+                " \"must_not\": [\n" +
+                " { \"match\": { \"name\": \"张1\" } },\n" +
+                " { \"match\": { \"age\": \"21\" } }\n" +
+                " ]\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 布尔值(bool)查询(返回 name=张1 & age!=21)
+     */
+    @Test
+    public void findByMachAndNotBool() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"bool\": {\n" +
+                " \"must\": [\n" +
+                " { \"match\": { \"name\": \"张1\" } }\n" +
+                " ],\n" +
+                " \"must_not\": [\n" +
+                " { \"match\": { \"age\": \"21\" } }\n" +
+                " ]\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+
+    /**
+     * 范围查询(age在25到28岁之间)
+     */
+    @Test
+    public void findByRang() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"range\" : {\n" +
+                " \"age\" : {\n" +
+                " \"gte\" : 25,\n" +
+                " \"lte\" : 28,\n" +
+                " \"boost\" : 2.0\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "GET",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 分组查询(按年龄分组查询,降序统计top 10)
+     * 类似 SELECT age, COUNT(*) FROM user GROUP BY age ORDER BY COUNT(*) DESC
+     */
+    @Test
+    public void findByGroup() throws Exception {
+        String DSL = "{\n" +
+                " \"size\": 0,\n" +
+                " \"aggs\": {\n" +
+                " \"group_by_age\": {\n" +
+                " \"terms\": {\n" +
+                " \"field\": \"age\"\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 分组查询(按年龄分组查询,查询组里其他字段的平均值)
+     * 类似 SELECT age, avg(age) FROM user GROUP BY age ORDER BY COUNT(*) DESC
+     */
+    @Test
+    public void findByGroupAndAvag() throws Exception {
+        String DSL = "{\n" +
+                " \"size\": 0,\n" +
+                " \"aggs\": {\n" +
+                " \"group_by_age\": {\n" +
+                " \"terms\": {\n" +
+                " \"field\": \"age\"\n" +
+                " },\n" +
+                " \"aggs\": {\n" +
+                " \"average_age\": {\n" +
+                " \"avg\": {\n" +
+                " \"field\": \"age\"\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 分组查询(按年龄分组查询,并且降序排序)
+     * 类似 SELECT age, avg(age) FROM user GROUP BY age ORDER BY avg(age) DESC
+     */
+    @Test
+    public void findByGroupAndOrderBy() throws Exception {
+        String DSL = "{\n" +
+                " \"size\": 0,\n" +
+                " \"aggs\": {\n" +
+                " \"group_by_age\": {\n" +
+                " \"terms\": {\n" +
+                " \"field\": \"age\",\n" +
+                " \"order\": {\n" +
+                " \"average_age\": \"desc\"\n" +
+                " }\n" +
+                " },\n" +
+                " \"aggs\": {\n" +
+                " \"average_age\": {\n" +
+                " \"avg\": {\n" +
+                " \"field\": \"age\"\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_search",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+
+    /**
+     * 删除操作
+     */
+    @Test
+    public void testDelete() throws Exception {
+        Response response = restClient.performRequest(
+                "DELETE",
+                "userindex/user/100",
+                Collections.<String, String>emptyMap());
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 根据条件删除(使用_delete_by_query,POST请求)
+     */
+    @Test
+    public void testDeleteByQuery() throws Exception {
+        String DSL = "{\n" +
+                " \"query\": {\n" +
+                " \"match\" : {\n" +
+                " \"name\" : \"张1\"\n" +
+                " }\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/_delete_by_query",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+
+    /**
+     * 跟新操作(1. 从旧文档中检索JSON
+     * 2. 修改它
+     * 3. 删除旧文档
+     * 4. 索引新文档)
+     */
+    @Test
+    public void testUpdate() throws Exception {
+        User user = new User();
+        user.setId(100L);
+        user.setAge(20);
+        user.setName("张三修改");
+        user.setSex(1);
+
+        HttpEntity entity = new NStringEntity(JSON.toJSONString(user), ContentType.APPLICATION_JSON);
+
+        Response indexResponse = restClient.performRequest(
+                "PUT",
+                "userindex/user/100",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(indexResponse.getEntity()));
+    }
+
+
+    /**
+     * 局部跟新字段(动态添加字段,添加tags和views字段)
+     */
+    @Test
+    public void testUpdateField() throws Exception {
+        String DSL = "{\n" +
+                " \"doc\" : {\n" +
+                " \"tags\" : [ \"testing\" ],\n" +
+                " \"views\": 0\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/100/_update",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 使用脚本部分跟新字段(将views字段数量加1)
+     */
+    @Test
+    public void testUpdateFieldByScript() throws Exception {
+        String DSL = "{\n" +
+                " \"script\" : \"ctx._source.views+=1\"\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/100/_update",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+    /**
+     * 将search 标签追加到 tags 数组中
+     */
+    @Test
+    public void testUpdateFieldAddByScript() throws Exception {
+        String DSL = "{\n" +
+                " \"script\" : \"ctx._source.tags+=new_tag\",\n" +
+                " \"params\" : {\n" +
+                " \"new_tag\" : \"search\"\n" +
+                " }\n" +
+                "}";
+        HttpEntity entity = new NStringEntity(DSL, ContentType.APPLICATION_JSON);
+        Response response = restClient.performRequest(
+                "POST",
+                "userindex/user/100/_update",
+                Collections.<String, String>emptyMap(),
+                entity);
+        System.out.println(EntityUtils.toString(response.getEntity()));
+    }
+
+
+    @After
+    public void closeRestClient() throws Exception {
+        restClient.close();
+    }
+}

+ 349 - 0
elab-es/src/test/java/com/elab/es/data/RestHighLevelClientTest.java

@@ -0,0 +1,349 @@
+package com.elab.es.data;
+
+import com.elab.core.utils.DateUtils;
+import org.apache.http.HttpHost;
+import org.elasticsearch.action.DocWriteResponse;
+import org.elasticsearch.action.bulk.BulkItemResponse;
+import org.elasticsearch.action.bulk.BulkRequest;
+import org.elasticsearch.action.bulk.BulkResponse;
+import org.elasticsearch.action.delete.DeleteRequest;
+import org.elasticsearch.action.delete.DeleteResponse;
+import org.elasticsearch.action.get.GetRequest;
+import org.elasticsearch.action.get.GetResponse;
+import org.elasticsearch.action.get.MultiGetRequest;
+import org.elasticsearch.action.get.MultiGetResponse;
+import org.elasticsearch.action.index.IndexRequest;
+import org.elasticsearch.action.index.IndexResponse;
+import org.elasticsearch.action.update.UpdateRequest;
+import org.elasticsearch.action.update.UpdateResponse;
+import org.elasticsearch.client.RequestOptions;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.client.core.TermVectorsRequest;
+import org.elasticsearch.client.core.TermVectorsResponse;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.index.query.TermQueryBuilder;
+import org.elasticsearch.index.reindex.ReindexRequest;
+import org.elasticsearch.index.reindex.UpdateByQueryRequest;
+import org.elasticsearch.rest.RestStatus;
+import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * es基本操作
+ *
+ * @author : liukx
+ * @time : 2019/7/31 - 17:01
+ */
+public class RestHighLevelClientTest {
+
+    private Logger logger = LoggerFactory.getLogger(RestHighLevelClientTest.class);
+    private RestHighLevelClient client;
+
+    @Before
+    public void before() {
+        client = new RestHighLevelClient(
+                RestClient.builder(
+//                        new HttpHost("localhost", 9200, "http"),
+                        new HttpHost("192.168.0.24", 9200, "http")));
+    }
+
+    @Test
+    public void indexAPI() throws IOException {
+        IndexRequest request = null;
+        // 下面是简单介绍的三种格式类型
+//        request = jsonData("周杰伦", "窗外的麻雀,在电线杆上多嘴。");
+//        request = mapData("林俊杰", "确认过眼神,我遇上对的人");
+        request = docData("某某某", "哈哈,终于成功了");
+
+        //设置超时时间
+        request.timeout(TimeValue.timeValueSeconds(1));
+
+        //设置版本号
+//        request.version(1);
+//        request.versionType(VersionType.EXTERNAL);
+//        request.opType(DocWriteRequest.OpType.CREATE);
+//        request.setPipeline("pipeline");
+
+
+        // 同步执行方式
+        IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
+
+        logger.info(" result : " + indexResponse.toString());
+//        String index = indexResponse.getIndex();
+//        String type = indexResponse.getType();
+//        String id = indexResponse.getId();
+//        long version = indexResponse.getVersion();
+
+
+        // 异步方式
+//        client.indexAsync(request, RequestOptions.DEFAULT, new ActionListener<IndexResponse>() {
+//            @Override
+//            public void onResponse(IndexResponse indexResponse) {
+//                RestStatus status = indexResponse.status();
+//                System.out.println(status.getStatus());
+//            }
+//
+//            @Override
+//            public void onFailure(Exception e) {
+//                System.out.println("执行失败.." + e.getMessage());
+//            }
+//        });
+    }
+
+
+    /**
+     * 根据id获取数据
+     *
+     * @throws IOException
+     */
+    @Test
+    public void getApi() throws IOException {
+        GetRequest request = new GetRequest(
+                "posts",
+                "doc",
+                "f5fd0129-0b02-4685-b9f0-024b7ed48868");
+//        request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
+
+//        String[] includes = new String[]{"message", "*Date"};
+//        String[] excludes = Strings.EMPTY_ARRAY;
+//        FetchSourceContext fetchSourceContext =
+//                new FetchSourceContext(true, includes, excludes);
+//        request.fetchSourceContext(fetchSourceContext);
+//        request.storedFields("message");
+        GetResponse getResponse = client.get(request, RequestOptions.DEFAULT);
+        // 批量获取
+        // GetResponse getResponse = client.mget()
+
+//        String message = getResponse.getField("message").getValue();
+        logger.info("--------" + getResponse.getSource().toString());
+    }
+
+    @Test
+    public void exists() throws IOException {
+        GetRequest getRequest = new GetRequest(
+                "posts",
+                "doc",
+                "f5fd0129-0b02-4685-b9f0-024b7ed48868");
+        getRequest.fetchSourceContext(new FetchSourceContext(false));
+        getRequest.storedFields("_none_");
+        boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
+        logger.info("result : " + exists);
+    }
+
+    @Test
+    public void delete() throws IOException {
+        DeleteRequest request = new DeleteRequest(
+                "posts",
+                "doc",
+                "0b31b14d-0f0e-44a6-9dbc-fb4dd60b0d68");
+        DeleteResponse deleteResponse = client.delete(
+                request, RequestOptions.DEFAULT);
+        RestStatus status = deleteResponse.status();
+
+        // deleteResponse.getShardInfo().getTotal()
+        logger.info(status.toString());
+    }
+
+    @Test
+    public void updateAPI() throws IOException {
+        Map<String, Object> jsonMap = new HashMap<>();
+        jsonMap.put("updated", new Date());
+        jsonMap.put("reason", "daily update");
+        UpdateRequest request = new UpdateRequest("posts", "doc", "af528f4f-53bc-4601-b677-f6e921e914a0")
+                .doc(jsonMap);
+        // 如果尝试更新的时候,发现其他线程也在更改该数据,这里会指定重试次数
+//        request.retryOnConflict(3);
+        // 当指定了版本号之后,会与ES中的文档数据进行比对,相同才会更改,不同则会异常。
+        request.version(4);
+        UpdateResponse updateResponse = client.update(
+                request, RequestOptions.DEFAULT);
+        updateResponse.getGetResult();
+        DocWriteResponse.Result result = updateResponse.getResult();
+        if (result == DocWriteResponse.Result.UPDATED) {
+            logger.info("ES 执行了 UPDATE 操作.");
+        }
+        logger.info(" =>> " + updateResponse.toString());
+    }
+
+    @Test
+    public void termVectorsApi() throws IOException {
+        // todo 待研究 1
+//        TermVectorsRequest request = new TermVectorsRequest("posts", "doc", "1");
+//        request.setFields("user");
+        XContentBuilder docBuilder = XContentFactory.jsonBuilder();
+        docBuilder.startObject().field("user", "guest-user").endObject();
+        TermVectorsRequest request = new TermVectorsRequest("posts",
+                "doc",
+                docBuilder);
+
+
+        // 可选参数
+        request.setFieldStatistics(false);
+        request.setTermStatistics(true);
+        request.setPositions(false);
+        request.setOffsets(false);
+        request.setPayloads(false);
+
+        Map<String, Integer> filterSettings = new HashMap<>();
+        filterSettings.put("max_num_terms", 3);
+        filterSettings.put("min_term_freq", 1);
+        filterSettings.put("max_term_freq", 10);
+        filterSettings.put("min_doc_freq", 1);
+        filterSettings.put("max_doc_freq", 100);
+        filterSettings.put("min_word_length", 1);
+        filterSettings.put("max_word_length", 10);
+
+        request.setFilterSettings(filterSettings);
+
+        Map<String, String> perFieldAnalyzer = new HashMap<>();
+        perFieldAnalyzer.put("user", "keyword");
+        request.setPerFieldAnalyzer(perFieldAnalyzer);
+
+        request.setRealtime(false);
+        request.setRouting("routing");
+        TermVectorsResponse response =
+                client.termvectors(request, RequestOptions.DEFAULT);
+    }
+
+
+    @Test
+    public void bulkApi() throws IOException {
+//        BulkRequest request = new BulkRequest();
+//        request.add(new IndexRequest("posts", "doc", "1")
+//                .source(XContentType.JSON,"field", "foo"));
+//        request.add(new IndexRequest("posts", "doc", "2")
+//                .source(XContentType.JSON,"field", "bar"));
+//        request.add(new IndexRequest("posts", "doc", "3")
+//                .source(XContentType.JSON,"field", "baz"));
+
+        // 混合使用
+        BulkRequest request = new BulkRequest();
+//        request.add(new DeleteRequest("posts", "doc", "3"));
+        request.add(new UpdateRequest("posts", "doc", "633b5f31-8cfd-47d4-bc9a-a151fb23633f")
+                .doc(XContentType.JSON, "user", "林俊杰1"));
+//        request.add(new IndexRequest("posts", "doc", "4")
+//                .source(XContentType.JSON,"field", "baz"));
+
+        BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
+        for (BulkItemResponse bulkItemResponse : bulkResponse) {
+            DocWriteResponse itemResponse = bulkItemResponse.getResponse();
+
+            switch (bulkItemResponse.getOpType()) {
+                case INDEX:
+                case CREATE:
+                    IndexResponse indexResponse = (IndexResponse) itemResponse;
+                    break;
+                case UPDATE:
+                    UpdateResponse updateResponse = (UpdateResponse) itemResponse;
+                    logger.info(updateResponse.toString());
+                    break;
+                case DELETE:
+                    DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
+            }
+        }
+    }
+
+    @Test
+    public void multiGetAPI() throws IOException {
+        MultiGetRequest request = new MultiGetRequest();
+        String[] includes = new String[]{"user", "*1"};
+        String[] excludes = Strings.EMPTY_ARRAY;
+        FetchSourceContext fetchSourceContext =
+                new FetchSourceContext(true, includes, excludes);
+        request.add(new MultiGetRequest.Item("posts", "doc", "633b5f31-8cfd-47d4-bc9a-a151fb23633f")
+                .fetchSourceContext(fetchSourceContext));
+        MultiGetResponse response = client.mget(request, RequestOptions.DEFAULT);
+        response.forEach((K) -> {
+            logger.info(K.toString());
+        });
+    }
+
+
+    @Test
+    public void reindexApi() {
+        ReindexRequest request = new ReindexRequest();
+        request.setSourceIndices("source1", "source2");
+        request.setDestIndex("dest");
+    }
+
+
+    @Test
+    public void updateByQueryAPI(){
+        UpdateByQueryRequest request =
+                new UpdateByQueryRequest("source1", "source2");
+
+
+        request.setConflicts("proceed");
+
+        request.setQuery(new TermQueryBuilder("user", "kimchy"));
+        request.setSize(10);
+
+        request.setPipeline("my_pipeline");
+
+
+    }
+
+
+    private IndexRequest jsonData(String user, String message) {
+        // 创建一个普通的数据对象
+        IndexRequest request = new IndexRequest(
+                "posts",
+                "doc",
+                UUID.randomUUID().toString());
+        String date = DateUtils.dateParseString(new Date());
+        String jsonString = "{" +
+                "\"user\":\"" + user + "\"," +
+                "\"postDate\":\"" + date + "\"," +
+                "\"message\":\"" + message + "\"" +
+                "}";
+        IndexRequest source = request.source(jsonString, XContentType.JSON);
+        return source;
+    }
+
+    private IndexRequest mapData(String user, String message) {
+        // 构建一个Map对象
+        Map<String, Object> jsonMap = new HashMap<>();
+        jsonMap.put("user", user);
+        jsonMap.put("postDate", new Date());
+        jsonMap.put("message", message);
+        IndexRequest indexRequest = new IndexRequest("posts", "doc", UUID.randomUUID().toString())
+                .source(jsonMap);
+        return indexRequest;
+    }
+
+    private IndexRequest docData(String user, String message) throws IOException {
+        XContentBuilder builder = XContentFactory.jsonBuilder();
+        builder.startObject();
+        {
+            builder.field("user", user);
+            builder.timeField("postDate", new Date());
+            builder.field("message", message);
+        }
+        builder.endObject();
+        IndexRequest indexRequest = new IndexRequest("posts", "doc", UUID.randomUUID().toString())
+                .source(builder);
+        return indexRequest;
+    }
+
+
+    @After
+    public void after() throws IOException {
+        client.close();
+    }
+
+}

+ 44 - 0
elab-es/src/test/java/com/elab/es/model/User.java

@@ -0,0 +1,44 @@
+package com.elab.es.model;
+
+/**
+ * @author : liukx
+ * @time : 2019/7/31 - 14:07
+ */
+public class User {
+    private long id;
+    private int age;
+    private String name;
+    private int sex;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getAge() {
+        return age;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getSex() {
+        return sex;
+    }
+
+    public void setSex(int sex) {
+        this.sex = sex;
+    }
+}

+ 4 - 0
elab-es/src/test/resources/application.yml

@@ -0,0 +1,4 @@
+spring:
+  elasticsearch:
+    rest:
+      uris: http://192.168.0.24:9100

+ 1 - 1
elab-log/pom.xml

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

+ 1 - 1
elab-mongodb/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>elab-parent</artifactId>
         <groupId>com.elab.core</groupId>
-        <version>2.0.4.11-SNAPSHOT</version>
+        <version>2.0.4.12-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.11-SNAPSHOT</version>
+        <version>2.0.4.12-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 116 - 0
elab-rocketMQ/REDERME.md

@@ -0,0 +1,116 @@
+# rocketMQ使用介绍
+
+
+
+## 引入依赖
+
+```xml
+<dependency>
+    <groupId>com.elab.core</groupId>
+    <artifactId>elab-rocketMQ</artifactId>
+    <version>${elab.version}</version>
+</dependency>
+```
+
+## 触发配置
+
+```java
+// 开启rocketmq配置
+@EnableRocketMQ
+```
+
+
+
+## 配置文件
+
+```yaml
+rocketmq:
+    name-server: 192.168.0.24:9876;192.168.0.25:9876
+    producer:
+        group: ${profiles.active}-${spring.application.name}
+        sendMessageTimeout: 300000
+```
+
+
+
+
+
+## SQL
+
+### 消息去重
+
+需要将消息进行存储,重试的时候可以方便查看对比
+
+```sql
+CREATE TABLE `rmq_consumer` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `msg_id` varchar(50) DEFAULT NULL COMMENT '消息编号',
+  `msg_key` varchar(50) DEFAULT NULL COMMENT '消息唯一编号',
+  `consuemr_group` varchar(300) DEFAULT NULL COMMENT '模块名称',
+  `consumer_ip` varchar(20) DEFAULT NULL COMMENT '生产者ip',
+  `topic` varchar(300) DEFAULT NULL COMMENT 'topic名称',
+  `consumer_status` int(11) DEFAULT NULL COMMENT '消费者状态1成功-1失败',
+  `retry_count` int(11) DEFAULT NULL COMMENT '重试次数',
+  `created` datetime DEFAULT NULL COMMENT '创建时间',
+  `updated` datetime DEFAULT NULL COMMENT '修改时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='消费者消息应用状态表';
+
+CREATE TABLE `rmq_producer` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `producer_status` int(11) DEFAULT NULL COMMENT '生产者状态1成功-1失败',
+  `producer_group` varchar(50) DEFAULT NULL COMMENT '生产者组',
+  `producer_ip` varchar(20) DEFAULT NULL COMMENT '生产者ip',
+  `topic` varchar(100) DEFAULT NULL COMMENT 'topic',
+  `tags` varchar(100) DEFAULT NULL COMMENT '标签',
+  `content` varchar(1000) DEFAULT NULL COMMENT '发送内容',
+  `created` datetime DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='生产者消息应用状态表';
+```
+
+
+
+## 消费者
+
+```java
+@Service
+public class StringConsumer implements TagRocketMQListener {
+    private Logger logger = LoggerFactory.getLogger(StringConsumer.class);
+
+    @Override
+    public String tag() {
+        return "*"; // 这里订阅你关注的tag消息,控制器会根据消息发送过来的tag转发给你定义的这个处理类中。
+    }
+
+    @Override
+    public void processMessage(String message) throws Exception {
+        logger.info("--------------------消费完成-->>>>" + message);
+    }
+}
+```
+
+这里需要注意两点:
+
+1. 如果没有抛出异常,那么MQ会认为消费成功了。
+2. 如果失败会执行重试机制,业务如果特别重要可以自行在验证一次。尽管抽象类中已经做了一次。
+
+
+
+## 生产者
+
+```java
+@Autowired
+private DefaultMQProducerExt rocketMQTemplate;
+
+SONObject jsonObject = new JSONObject();
+jsonObject.put("success", "true");
+jsonObject.put("msg", "my name is lkx");
+Message message = new Message();
+message.setBody(jsonObject.toJSONString().getBytes());
+message.setTopic(topic);
+message.setTags("");
+SendResult sendResult = rocketMQTemplate.send(topic, "tag", RandomUtils.randomString(5),
+                                              jsonObject.toJSONString().getBytes());
+```
+

+ 52 - 0
elab-rocketMQ/pom.xml

@@ -0,0 +1,52 @@
+<?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.4.12-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>elab-rocketMQ</artifactId>
+
+    <properties>
+        <springframework.version>5.0.9.RELEASE</springframework.version>
+        <rocketmq-spring-boot-starter-version>2.0.3</rocketmq-spring-boot-starter-version>
+        <springboot.version></springboot.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.elab.core</groupId>
+            <artifactId>elab-spring</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.elab.core</groupId>
+            <artifactId>elab-db</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-spring-boot-starter</artifactId>
+            <version>${rocketmq-spring-boot-starter-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <version>2.0.5.RELEASE</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 29 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/App.java

@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package com.elab.mq.rocket;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App {
+
+    public static void main(String[] args) {
+        SpringApplication.run(App.class, args);
+    }
+
+}

+ 19 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/anno/EnableRocketMQ.java

@@ -0,0 +1,19 @@
+package com.elab.mq.rocket.anno;
+
+import com.elab.core.aop.annotations.EnableElabDB;
+import com.elab.mq.rocket.configuration.RocketMQConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import({RocketMQConfiguration.class})
+@EnableElabDB
+@ComponentScan({"com.elab.mq.rocket.msg"})
+public @interface EnableRocketMQ {
+    String[] value() default {};
+}

+ 67 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/configuration/RocketMQConfiguration.java

@@ -0,0 +1,67 @@
+package com.elab.mq.rocket.configuration;
+
+import com.elab.mq.rocket.listener.DefaultRocketMQListener;
+import com.elab.mq.rocket.listener.TagInvokerListener;
+import com.elab.mq.rocket.listener.TagRocketMQListener;
+import com.elab.mq.rocket.msg.ConsumerDataStore;
+import com.elab.mq.rocket.msg.DefaultConsumeMessageHook;
+import com.elab.mq.rocket.msg.DefaultSendMessageHook;
+import com.elab.mq.rocket.msg.MysqlDataStore;
+import com.elab.mq.rocket.template.DefaultMQProducerExt;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 配置文件
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 13:49
+ */
+@Configuration
+public class RocketMQConfiguration {
+
+    @Bean
+    public DefaultSendMessageHook defaultSendMessageHook(@Autowired DefaultMQProducer defaultMQProducer) {
+        DefaultSendMessageHook defaultSendMessageHook = new DefaultSendMessageHook();
+        defaultMQProducer.getDefaultMQProducerImpl().registerSendMessageHook(defaultSendMessageHook);
+        return defaultSendMessageHook;
+    }
+
+    @Bean
+    @ConditionalOnBean(DefaultMQPushConsumer.class)
+    public DefaultConsumeMessageHook defaultConsumeMessageHook(@Autowired DefaultMQPushConsumer defaultMQPushConsumer) {
+        DefaultConsumeMessageHook defaultConsumeMessageHook = new DefaultConsumeMessageHook();
+        defaultMQPushConsumer.getDefaultMQPushConsumerImpl().registerConsumeMessageHook(defaultConsumeMessageHook);
+        return defaultConsumeMessageHook;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(value = {ConsumerDataStore.class})
+    public ConsumerDataStore consumerDataStore() {
+        MysqlDataStore mysqlDataStore = new MysqlDataStore();
+        return mysqlDataStore;
+    }
+
+    @Bean
+    public DefaultMQProducerExt rocketMQTemplateExt(@Autowired DefaultMQProducer defaultMQProducer) {
+        return new DefaultMQProducerExt(defaultMQProducer);
+    }
+
+    @Bean
+    @ConditionalOnBean(value = {TagRocketMQListener.class})
+    public TagInvokerListener tagInvokerListener() {
+        return new TagInvokerListener();
+    }
+
+    @Bean
+    @ConditionalOnBean(value = {TagRocketMQListener.class})
+    public DefaultRocketMQListener defaultRocketMQListener() {
+        return new DefaultRocketMQListener();
+    }
+
+}

+ 45 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/consumer/StringConsumer.java

@@ -0,0 +1,45 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one or more
+// * contributor license agreements.  See the NOTICE file distributed with
+// * this work for additional information regarding copyright ownership.
+// * The ASF licenses this file to You under the Apache License, Version 2.0
+// * (the "License"); you may not use this file except in compliance with
+// * the License.  You may obtain a copy of the License at
+// *
+// *     http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// */
+//
+//package com.elab.mq.rocket.consumer;
+//
+//import com.elab.mq.rocket.listener.DefaultRocketMQListener;
+//import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.stereotype.Service;
+//
+///**
+// * RocketMQMessageListener
+// * 普通消息
+// */
+//@Service
+//@RocketMQMessageListener(topic = "${demo.rocketmq.topic}", consumerGroup = "string_consumer")
+//public class StringConsumer extends DefaultRocketMQListener {
+//    private Logger logger = LoggerFactory.getLogger(StringConsumer.class);
+//
+//    @Override
+//    public String tag() {
+//        return "";
+//    }
+//
+//    @Override
+//    public void processMessage(String message) throws Exception {
+//        logger.info("--------------------消费完成-->>>>" + message);
+//
+//    }
+//}

+ 14 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/exception/MsgProcessException.java

@@ -0,0 +1,14 @@
+package com.elab.mq.rocket.exception;
+
+/**
+ * 处理消息消费异常
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 15:43
+ */
+public class MsgProcessException extends RuntimeException {
+
+    public MsgProcessException(String message) {
+        super(message);
+    }
+}

+ 14 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/exception/MsgRecurringException.java

@@ -0,0 +1,14 @@
+package com.elab.mq.rocket.exception;
+
+/**
+ * 处理重试消费异常
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 15:43
+ */
+public class MsgRecurringException extends RuntimeException {
+
+    public MsgRecurringException(String message) {
+        super(message);
+    }
+}

+ 14 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/exception/MsgWaitException.java

@@ -0,0 +1,14 @@
+package com.elab.mq.rocket.exception;
+
+/**
+ * 处理等待消息异常
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 15:43
+ */
+public class MsgWaitException extends RuntimeException {
+
+    public MsgWaitException(String message) {
+        super(message);
+    }
+}

+ 128 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/listener/DefaultRocketMQListener.java

@@ -0,0 +1,128 @@
+package com.elab.mq.rocket.listener;
+
+import com.elab.core.utils.StringUtils;
+import com.elab.mq.rocket.exception.MsgProcessException;
+import com.elab.mq.rocket.exception.MsgRecurringException;
+import com.elab.mq.rocket.exception.MsgWaitException;
+import com.elab.mq.rocket.msg.ConsumerDataStore;
+import com.elab.mq.rocket.msg.entity.RmqConsumerEntity;
+import com.elab.mq.rocket.utils.MsgConstants;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.util.Date;
+
+/**
+ * 公用抽象的消费者监听器
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 13:54
+ */
+@RocketMQMessageListener(topic = "topic-${rocketmq.producer.group}", consumerGroup = "group-${rocketmq.producer.group}")
+public class DefaultRocketMQListener implements RocketMQListener<MessageExt> {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired(required = false)
+    private ConsumerDataStore consumerDataStore;
+    @Value("${rocketmq.producer.group}")
+    private String group;
+    @Value("${spring.cloud.client.ipAddress:}")
+    private String ip;
+    @Autowired
+    private TagInvokerListener tagInvokerListener;
+
+    @Override
+    public void onMessage(MessageExt messageExt) {
+        RmqConsumerEntity entity = null;
+        String topic = messageExt.getTopic();
+        String keys = messageExt.getKeys();
+        String msgId = messageExt.getMsgId();
+        String tags = messageExt.getTags();
+        try {
+            if (StringUtils.isNotEmpty(keys)) {
+                entity = consumerDataStore.getMsgKey(group, keys);
+            } else {
+                entity = consumerDataStore.getMsgId(group, msgId);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        boolean isInsert = false;
+        // 1. 构建数据
+        if (entity == null) {
+            isInsert = true;
+            entity = new RmqConsumerEntity();
+            entity.setMsgId(msgId);
+            entity.setConsuemrGroup(group);
+            entity.setConsumerIp(ip);
+            entity.setConsumerStatus(MsgConstants.MSG_OK);
+            entity.setCreated(new Date());
+            entity.setMsgKey(keys);
+            entity.setRetryCount(0);
+            entity.setTopic(topic);
+        } else {
+            // 如果存在消息记录,开始做状态比较
+            Integer consumerStatus = entity.getConsumerStatus();
+            if (MsgConstants.MSG_OK == consumerStatus) {
+                logger.info(" topic : {} keys : {} id: {} 已经被消费过了.", topic, keys, msgId);
+                // 已经消费成功了,不做处理
+                return;
+            } else if (MsgConstants.MSG_WAIT == consumerStatus) {
+                // 还在处理中 ... 这个时候需要返回一个重新消费的状态
+                throw new MsgWaitException(" 该 key [" + keys + "] 还在消费中 ... ");
+            } else {
+                int count = entity.getRetryCount() + 1;
+                entity.setRetryCount(count);
+                entity.setUpdated(new Date());
+            }
+        }
+
+        String body = new String(messageExt.getBody());
+        try {
+            // 2. 具体执行消息
+            tagInvokerListener.process(tags, body);
+            // 3. 保存结果
+            saveData(entity, isInsert);
+        } catch (Exception e) {
+            logger.error(" 业务消息消费失败 topic : " + topic + " key : " + keys, e);
+            // 消息执行失败
+            e.printStackTrace();
+            try {
+                saveExceptionData(body, entity, isInsert);
+            } catch (Exception ex) {
+                logger.error(" 异常消费信息 存储数据库失败 ", ex);
+                ex.printStackTrace();
+
+            }
+        }
+    }
+    private void saveData(RmqConsumerEntity entity, boolean isInsert) throws Exception {
+        // 如果没有异常发生
+        entity.setConsumerStatus(MsgConstants.MSG_OK);
+        if (isInsert) {
+            consumerDataStore.add(entity);
+        } else {
+            consumerDataStore.update(entity);
+        }
+        logger.info("保存消费消息数据. {}", entity);
+    }
+
+    private void saveExceptionData(String message, RmqConsumerEntity entity, boolean isInsert) throws Exception {
+        if (isInsert) {
+            entity.setConsumerStatus(MsgConstants.MSG_FAILS);
+            consumerDataStore.add(entity);
+            logger.info(" 添加失败消息保存成功 " + message);
+            throw new MsgProcessException(" 消费消息执行失败 ... ");
+        } else {
+            consumerDataStore.update(entity);
+            logger.info(" 修改失败消息保存成功 " + message);
+            throw new MsgRecurringException(" 重试消息执行失败 ... ");
+        }
+    }
+}

+ 66 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/listener/TagInvokerListener.java

@@ -0,0 +1,66 @@
+package com.elab.mq.rocket.listener;
+
+import com.elab.mq.rocket.exception.MsgProcessException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * tag执行处理规则
+ *
+ * @author : liukx
+ * @time : 2019/9/16 - 16:51
+ */
+public class TagInvokerListener implements InitializingBean {
+
+    private Logger logger = LoggerFactory.getLogger(TagInvokerListener.class);
+
+    @Autowired
+    private List<TagRocketMQListener> topicList;
+
+    private Map<String, TagRocketMQListener> tagMap;
+
+    private TagRocketMQListener defaultTagRocketMQListener;
+
+    public TagInvokerListener() {
+        this.tagMap = new ConcurrentHashMap<>();
+    }
+
+
+    public void process(String tag, String body) throws Exception {
+        if (defaultTagRocketMQListener != null) {
+            tagMap.getOrDefault(tag, defaultTagRocketMQListener).processMessage(body);
+        } else {
+            TagRocketMQListener tagRocketMQListener = tagMap.get(tag);
+            if (tagRocketMQListener == null) {
+                throw new MsgProcessException(" 没有匹配到对应的tags : " + tag);
+            }
+            tagRocketMQListener.processMessage(body);
+        }
+    }
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        AtomicInteger allIndex = new AtomicInteger();
+        topicList.forEach((obj) -> {
+            String tag = obj.tag();
+            if (tag.equals("*")) {
+                defaultTagRocketMQListener = obj;
+                allIndex.getAndIncrement();
+            } else {
+                tagMap.put(tag, obj);
+            }
+        });
+
+        int count = allIndex.get();
+        if (count > 1) {
+            logger.warn(" 默认的AbstractRocketMQListener中的tag = * 出现了 {} 个 , 在匹配不上tag的时候 默认匹配 : {}", count, defaultTagRocketMQListener);
+        }
+    }
+}

+ 24 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/listener/TagRocketMQListener.java

@@ -0,0 +1,24 @@
+package com.elab.mq.rocket.listener;
+
+/**
+ * tag 分组监听处理
+ *
+ * @author : liukx
+ * @time : 2019/9/16 - 17:17
+ */
+public interface TagRocketMQListener {
+    /**
+     * 执行消息
+     *
+     * @param body
+     * @throws Exception
+     */
+    public void processMessage(String body) throws Exception;
+
+    /**
+     * 关注的tag
+     *
+     * @return
+     */
+    public String tag();
+}

+ 47 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/ConsumerDataStore.java

@@ -0,0 +1,47 @@
+package com.elab.mq.rocket.msg;
+
+import com.elab.mq.rocket.msg.entity.RmqConsumerEntity;
+
+/**
+ * 消费者数据存储
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 15:12
+ */
+public interface ConsumerDataStore {
+
+
+    /**
+     * 添加一条消息内容
+     *
+     * @param keyModel
+     * @return
+     */
+    public boolean add(RmqConsumerEntity keyModel) throws Exception;
+
+    /**
+     * 根据消息Key获取信息
+     *
+     * @param group 消费组
+     * @param key   消费key
+     * @return
+     */
+    public RmqConsumerEntity getMsgKey(String group, String key) throws Exception;
+
+    /**
+     * 修改消息数据
+     *
+     * @param entity 最终的实体
+     * @return
+     */
+    public boolean update(RmqConsumerEntity entity) throws Exception;
+
+    /**
+     * 根据消息编号获取信息
+     *
+     * @param group 消费组
+     * @param msgId 消费编号
+     * @return
+     */
+    public RmqConsumerEntity getMsgId(String group, String msgId) throws Exception;
+}

+ 114 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/DefaultConsumeMessageHook.java

@@ -0,0 +1,114 @@
+package com.elab.mq.rocket.msg;
+
+import org.apache.rocketmq.client.hook.ConsumeMessageContext;
+import org.apache.rocketmq.client.hook.ConsumeMessageHook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 默认消费者消费消息存储
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 16:52
+ */
+@Component
+public class DefaultConsumeMessageHook implements ConsumeMessageHook {
+    private Logger logger = LoggerFactory.getLogger(DefaultSendMessageHook.class);
+
+//    @Autowired
+//    private ConsumerDataStore consumerDataStore;
+//
+//    @Value("${spring.application.name}")
+//    private String group;
+//    @Value("${spring.cloud.client.ipAddress}:${server.port}")
+//    private String ip;
+
+    @Override
+    public String hookName() {
+        return DefaultConsumeMessageHook.class.getName();
+    }
+
+    @Override
+    public void consumeMessageBefore(ConsumeMessageContext context) {
+        logger.info("-----------------------------------DefaultConsumeMessageHook---------sendMessageBefore----------------");
+    }
+
+    @Override
+    public void consumeMessageAfter(ConsumeMessageContext context) {
+        // 查看消费是否成功
+        String status = context.getStatus();
+
+        logger.info("-----------------------------------DefaultConsumeMessageHook---------sendMessageBefore----------------");
+//        List<MessageExt> msgList = context.getMsgList();
+//        for (MessageExt messageExt : msgList) {
+//            RmqConsumerEntity entity = null;
+//            String topic = messageExt.getTopic();
+//            String keys = messageExt.getKeys();
+//            entity = consumerDataStore.getMsgKey(group, keys);
+//            boolean isInsert = false;
+//            // 1. 构建数据
+//            if (entity == null) {
+//                isInsert = true;
+//                entity = new RmqConsumerEntity();
+//                entity.setConsuemrGroup(group);
+//                entity.setConsumerIp(ip);
+//                entity.setConsumerStatus(MsgConstants.MSG_OK);
+//                entity.setCreated(new Date());
+//                entity.setMsgKey(keys);
+//                entity.setRetryCount(0);
+//                entity.setTopic(topic);
+//            } else {
+//                // 如果存在消息记录,开始做状态比较
+//                Integer consumerStatus = entity.getConsumerStatus();
+//                if (MsgConstants.MSG_OK == consumerStatus) {
+//                    // 已经消费成功了,不做处理
+//                    return;
+//                } else if (MsgConstants.MSG_WAIT == consumerStatus) {
+//                    // 还在处理中 ... 这个时候需要返回一个重新消费的状态
+//                    throw new MsgWaitException(" 该 key [" + keys + "] 还在消费中 ... ");
+//                } else {
+//                    int count = entity.getRetryCount() + 1;
+//                    entity.setRetryCount(count);
+//                    entity.setUpdated(new Date());
+//                }
+//            }
+//
+//            // 2. 具体执行消息
+//            try {
+//                processMessage(message);
+//                // 3. 保存结果
+//                saveData(entity, isInsert);
+//            } catch (Exception e) {
+//                logger.error(" 业务消息消费失败 topic : " + topic + " key : " + keys, e);
+//                // 消息执行失败
+//                e.printStackTrace();
+//                saveExceptionData(message, entity, isInsert);
+//            }
+//        }
+
+    }
+
+//    private void saveData(RmqConsumerEntity entity, boolean isInsert) {
+//        // 如果没有异常发生
+//        entity.setConsumerStatus(MsgConstants.MSG_OK);
+//        if (isInsert) {
+//            consumerDataStore.add(entity);
+//        } else {
+//            consumerDataStore.udpate(entity);
+//        }
+//    }
+//
+//    private void saveExceptionData(MessageExt message, RmqConsumerEntity entity, boolean isInsert) {
+//        if (isInsert) {
+//            entity.setConsumerStatus(MsgConstants.MSG_FAILS);
+//            consumerDataStore.add(entity);
+//            logger.info(" 添加失败消息保存成功 " + message.toString());
+//            throw new MsgProcessException(" 消费消息执行失败 ... ");
+//        } else {
+//            consumerDataStore.udpate(entity);
+//            logger.info(" 修改失败消息保存成功 " + message.toString());
+//            throw new MsgRecurringException(" 重试消息执行失败 ... ");
+//        }
+//    }
+}

+ 38 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/DefaultSendMessageHook.java

@@ -0,0 +1,38 @@
+package com.elab.mq.rocket.msg;
+
+import org.apache.rocketmq.client.hook.SendMessageContext;
+import org.apache.rocketmq.client.hook.SendMessageHook;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 默认的消息钩子
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 16:43
+ */
+@Component
+public class DefaultSendMessageHook implements SendMessageHook {
+
+    private Logger logger = LoggerFactory.getLogger(DefaultSendMessageHook.class);
+
+    @Override
+    public String hookName() {
+        return DefaultSendMessageHook.class.getName();
+    }
+
+    @Override
+    public void sendMessageBefore(SendMessageContext context) {
+        logger.info("-----------------------------------DefaultSendMessageHook---------sendMessageBefore----------------");
+    }
+
+    @Override
+    public void sendMessageAfter(SendMessageContext context) {
+        logger.info("-----------------------------------DefaultSendMessageHook---------sendMessageAfter----------------");
+        SendStatus sendStatus = context.getSendResult().getSendStatus();
+        String msgId = context.getSendResult().getMsgId();
+
+    }
+}

+ 18 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/IRmqConsumerDao.java

@@ -0,0 +1,18 @@
+package com.elab.mq.rocket.msg;
+
+
+import com.elab.core.aop.annotations.XmlGroupName;
+import com.elab.core.dao.IBaseDaoSupport;
+import com.elab.mq.rocket.msg.entity.RmqConsumerEntity;
+
+/**
+ * RmqConsumerDao
+ *
+ * @author liukx
+ * @Date 2019-07-18 15:04
+ */
+@XmlGroupName("rmq_consumer")
+public interface IRmqConsumerDao extends IBaseDaoSupport<RmqConsumerEntity> {
+    // 复杂业务自己写
+
+}

+ 17 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/IRmqProducerDao.java

@@ -0,0 +1,17 @@
+package com.elab.mq.rocket.msg;
+
+
+import com.elab.core.aop.annotations.XmlGroupName;
+import com.elab.core.dao.IBaseDaoSupport;
+import com.elab.mq.rocket.msg.entity.RmqProducerEntity;
+
+/**
+ * RmqProducerDao
+ *
+ * @author liukx
+ * @Date 2019-07-18 15:05
+ */
+@XmlGroupName("rmq_producer")
+public interface IRmqProducerDao extends IBaseDaoSupport<RmqProducerEntity> {
+    // 复杂业务自己写
+}

+ 67 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/MemoryDataStore.java

@@ -0,0 +1,67 @@
+package com.elab.mq.rocket.msg;
+
+import com.elab.mq.rocket.msg.entity.RmqConsumerEntity;
+import com.elab.mq.rocket.utils.MsgConstants;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 内存消息存储
+ *
+ * @author : liukx
+ * @time : 2019/7/22 - 14:32
+ */
+public class MemoryDataStore implements ConsumerDataStore {
+    private Map<String, RmqConsumerEntity> cacheMap = Maps.newConcurrentMap();
+    private LoadingCache<String, RmqConsumerEntity> cacheBuilder = CacheBuilder.newBuilder().expireAfterAccess(5l,
+            TimeUnit.SECONDS)
+            .build(new CacheLoader<String, RmqConsumerEntity>() {
+                @Override
+                public RmqConsumerEntity load(String key) throws Exception {
+                    return cacheMap.get(key);
+                }
+            });
+
+    @Override
+    public boolean add(RmqConsumerEntity keyModel) throws Exception{
+        Integer consumerStatus = keyModel.getConsumerStatus();
+        String key = getKey(keyModel.getConsuemrGroup(), keyModel.getMsgKey());
+        // 除了
+        if (MsgConstants.MSG_OK == consumerStatus) {
+            cacheBuilder.put(key, keyModel);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 存储的key
+     *
+     * @param group
+     * @param key
+     * @return
+     */
+    private String getKey(String group, String key) throws Exception{
+        return group + "_" + key;
+    }
+
+    @Override
+    public RmqConsumerEntity getMsgKey(String group, String key) throws Exception{
+        return cacheMap.get(getKey(group, key));
+    }
+
+    @Override
+    public boolean update(RmqConsumerEntity entity) throws Exception{
+        return false;
+    }
+
+    @Override
+    public RmqConsumerEntity getMsgId(String group, String msgId) throws Exception{
+        return null;
+    }
+}

+ 55 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/MysqlDataStore.java

@@ -0,0 +1,55 @@
+package com.elab.mq.rocket.msg;
+
+import com.elab.mq.rocket.msg.entity.RmqConsumerEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * 数据库存储
+ *
+ * @author : liukx
+ * @time : 2019/9/16 - 11:21
+ */
+public class MysqlDataStore implements ConsumerDataStore {
+
+    @Autowired
+    private IRmqConsumerDao consumerDao;
+
+    @Override
+    public boolean add(RmqConsumerEntity keyModel) throws Exception {
+        return consumerDao.insert(keyModel) > 0;
+    }
+
+    @Override
+    public RmqConsumerEntity getMsgKey(String group, String key) throws Exception {
+        RmqConsumerEntity entity = new RmqConsumerEntity();
+        entity.setConsuemrGroup(group);
+        entity.setMsgKey(key);
+        List<RmqConsumerEntity> rmqConsumerEntities = consumerDao.selectByList(entity);
+        if (rmqConsumerEntities.size() > 0) {
+            return rmqConsumerEntities.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public boolean update(RmqConsumerEntity entity) throws Exception {
+        return consumerDao.updateById(entity) > 0;
+    }
+
+    @Override
+    public RmqConsumerEntity getMsgId(String group, String msgId) throws Exception {
+        RmqConsumerEntity entity = new RmqConsumerEntity();
+        entity.setConsuemrGroup(group);
+        entity.setMsgId(msgId);
+        List<RmqConsumerEntity> rmqConsumerEntities = consumerDao.selectByList(entity);
+
+
+        if (rmqConsumerEntities.size() > 0) {
+            return rmqConsumerEntities.get(0);
+        }
+
+        return null;
+    }
+}

+ 36 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/ProducerDataStore.java

@@ -0,0 +1,36 @@
+package com.elab.mq.rocket.msg;
+
+import com.elab.mq.rocket.msg.entity.RmqProducerEntity;
+
+/**
+ * 唯一消息编号存储
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 14:16
+ */
+public interface ProducerDataStore {
+    /**
+     * 添加一条消息内容
+     *
+     * @param keyModel
+     * @return
+     */
+    public boolean add(RmqProducerEntity keyModel);
+
+    /**
+     * 根据消息Key获取信息
+     *
+     * @param key
+     * @return
+     */
+    public RmqProducerEntity getMsgKey(String key);
+
+    /**
+     * 根据消息编号获取信息
+     *
+     * @param key
+     * @return
+     */
+    public RmqProducerEntity getMsgId(String key);
+
+}

+ 241 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/entity/RmqConsumerEntity.java

@@ -0,0 +1,241 @@
+package com.elab.mq.rocket.msg.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Date;
+
+/**
+ * 消费者消息应用状态表
+ *
+ * @author liukx
+ * @Date 2019-07-18 15:04
+ */
+@Table(name = "rmq_consumer")
+@ApiModel(description = "消费者消息应用状态表 实体")
+public class RmqConsumerEntity {
+
+    /**
+     * Id
+     */
+    @Id
+    @ApiModelProperty(name = "id", value = "主键")
+    private Integer id;
+
+    /**
+     * 生产者消息id
+     */
+    @Column(name = "msg_id")
+    @ApiModelProperty(name = "msgId", value = "消息编号")
+    private String msgId;
+
+    /**
+     * 生产者消息id
+     */
+    @Column(name = "msg_key")
+    @ApiModelProperty(name = "msgKey", value = "唯一的消息key")
+    private String msgKey;
+
+    /**
+     * 模块名称
+     */
+    @Column(name = "consuemr_group")
+    @ApiModelProperty(name = "consuemrGroup", value = "模块名称")
+    private String consuemrGroup;
+
+    /**
+     * 生产者ip
+     */
+    @Column(name = "consumer_ip")
+    @ApiModelProperty(name = "consumerIp", value = "生产者ip")
+    private String consumerIp;
+
+    /**
+     * topic名称
+     */
+    @Column(name = "topic")
+    @ApiModelProperty(name = "topic", value = "topic名称")
+    private String topic;
+
+    /**
+     * 消费者状态1成功-1失败
+     */
+    @Column(name = "consumer_status")
+    @ApiModelProperty(name = "consumerStatus", value = "消费者状态1成功-1失败")
+    private Integer consumerStatus;
+
+    /**
+     * 重试次数
+     */
+    @Column(name = "retry_count")
+    @ApiModelProperty(name = "retryCount", value = "重试次数")
+    private Integer retryCount;
+
+    /**
+     * 创建时间
+     */
+    @Column(name = "created")
+    @ApiModelProperty(name = "created", value = "创建时间")
+    private Date created;
+
+    /**
+     * 修改时间
+     */
+    @Column(name = "updated")
+    @ApiModelProperty(name = "updated", value = "修改时间")
+    private Date updated;
+
+
+    /**
+     * 获取: Id
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * 设置: Id
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * 获取: 生产者消息id
+     */
+    public String getMsgKey() {
+        return msgKey;
+    }
+
+    /**
+     * 设置: 生产者消息id
+     */
+    public void setMsgKey(String msgKey) {
+        this.msgKey = msgKey;
+    }
+
+    /**
+     * 获取: 模块名称
+     */
+    public String getConsuemrGroup() {
+        return consuemrGroup;
+    }
+
+    /**
+     * 设置: 模块名称
+     */
+    public void setConsuemrGroup(String consuemrGroup) {
+        this.consuemrGroup = consuemrGroup;
+    }
+
+    /**
+     * 获取: 生产者ip
+     */
+    public String getConsumerIp() {
+        return consumerIp;
+    }
+
+    /**
+     * 设置: 生产者ip
+     */
+    public void setConsumerIp(String consumerIp) {
+        this.consumerIp = consumerIp;
+    }
+
+    /**
+     * 获取: topic名称
+     */
+    public String getTopic() {
+        return topic;
+    }
+
+    /**
+     * 设置: topic名称
+     */
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    /**
+     * 获取: 消费者状态1成功-1失败
+     */
+    public Integer getConsumerStatus() {
+        return consumerStatus;
+    }
+
+    /**
+     * 设置: 消费者状态1成功-1失败
+     */
+    public void setConsumerStatus(Integer consumerStatus) {
+        this.consumerStatus = consumerStatus;
+    }
+
+    /**
+     * 获取: 重试次数
+     */
+    public Integer getRetryCount() {
+        return retryCount;
+    }
+
+    /**
+     * 设置: 重试次数
+     */
+    public void setRetryCount(Integer retryCount) {
+        this.retryCount = retryCount;
+    }
+
+    /**
+     * 获取: 创建时间
+     */
+    public Date getCreated() {
+        return created;
+    }
+
+    /**
+     * 设置: 创建时间
+     */
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
+    /**
+     * 获取: 修改时间
+     */
+    public Date getUpdated() {
+        return updated;
+    }
+
+    /**
+     * 设置: 修改时间
+     */
+    public void setUpdated(Date updated) {
+        this.updated = updated;
+    }
+
+    public String getMsgId() {
+        return msgId;
+    }
+
+    public void setMsgId(String msgId) {
+        this.msgId = msgId;
+    }
+
+    @Override
+    public String toString() {
+        return "RmqConsumerEntity{" +
+                "id=" + id +
+                ", msgId='" + msgId + '\'' +
+                ", msgKey='" + msgKey + '\'' +
+                ", consuemrGroup='" + consuemrGroup + '\'' +
+                ", consumerIp='" + consumerIp + '\'' +
+                ", topic='" + topic + '\'' +
+                ", consumerStatus=" + consumerStatus +
+                ", retryCount=" + retryCount +
+                ", created=" + created +
+                ", updated=" + updated +
+                '}';
+    }
+}

+ 198 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/msg/entity/RmqProducerEntity.java

@@ -0,0 +1,198 @@
+package com.elab.mq.rocket.msg.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Date;
+
+/**
+ * 生产者消息应用状态表
+ *
+ * @author liukx
+ * @Date 2019-07-18 15:05
+ */
+@Table(name = "rmq_producer")
+@ApiModel(description = "生产者消息应用状态表 实体")
+public class RmqProducerEntity {
+
+     /**
+     * Id
+     * 
+     */
+    @Id
+    @ApiModelProperty(name = "id", value = "主键")
+    private Integer id;
+
+     /**
+     * 生产者状态1成功-1失败
+     * 
+     */
+    @Column(name = "producer_status")
+    @ApiModelProperty(name = "producerStatus", value = "生产者状态1成功-1失败")
+    private Integer producerStatus;
+
+     /**
+     * 生产者组
+     * 
+     */
+    @Column(name = "producer_group")
+    @ApiModelProperty(name = "producerGroup", value = "生产者组")
+    private String producerGroup;
+
+     /**
+     * 生产者ip
+     * 
+     */
+    @Column(name = "producer_ip")
+    @ApiModelProperty(name = "producerIp", value = "生产者ip")
+    private String producerIp;
+
+     /**
+     * topic
+     * 
+     */
+    @Column(name = "topic")
+    @ApiModelProperty(name = "topic", value = "topic")
+    private String topic;
+
+     /**
+     * 标签
+     * 
+     */
+    @Column(name = "tags")
+    @ApiModelProperty(name = "tags", value = "标签")
+    private String tags;
+
+     /**
+     * 发送内容
+     * 
+     */
+    @Column(name = "content")
+    @ApiModelProperty(name = "content", value = "发送内容")
+    private String content;
+
+     /**
+     * 创建时间
+     * 
+     */
+    @Column(name = "created")
+    @ApiModelProperty(name = "created", value = "创建时间")
+    private Date created;
+
+
+     /**
+     * 获取: Id
+     * 
+     */
+    public Integer getId() {
+    return id;
+    }
+     /**
+     * 设置: Id
+     * 
+     */
+    public void setId(Integer id) {
+    this.id = id;
+    }
+     /**
+     * 获取: 生产者状态1成功-1失败
+     * 
+     */
+    public Integer getProducerStatus() {
+    return producerStatus;
+    }
+     /**
+     * 设置: 生产者状态1成功-1失败
+     * 
+     */
+    public void setProducerStatus(Integer producerStatus) {
+    this.producerStatus = producerStatus;
+    }
+     /**
+     * 获取: 生产者组
+     * 
+     */
+    public String getProducerGroup() {
+    return producerGroup;
+    }
+     /**
+     * 设置: 生产者组
+     * 
+     */
+    public void setProducerGroup(String producerGroup) {
+    this.producerGroup = producerGroup;
+    }
+     /**
+     * 获取: 生产者ip
+     * 
+     */
+    public String getProducerIp() {
+    return producerIp;
+    }
+     /**
+     * 设置: 生产者ip
+     * 
+     */
+    public void setProducerIp(String producerIp) {
+    this.producerIp = producerIp;
+    }
+     /**
+     * 获取: topic
+     * 
+     */
+    public String getTopic() {
+    return topic;
+    }
+     /**
+     * 设置: topic
+     * 
+     */
+    public void setTopic(String topic) {
+    this.topic = topic;
+    }
+     /**
+     * 获取: 标签
+     * 
+     */
+    public String getTags() {
+    return tags;
+    }
+     /**
+     * 设置: 标签
+     * 
+     */
+    public void setTags(String tags) {
+    this.tags = tags;
+    }
+     /**
+     * 获取: 发送内容
+     * 
+     */
+    public String getContent() {
+    return content;
+    }
+     /**
+     * 设置: 发送内容
+     * 
+     */
+    public void setContent(String content) {
+    this.content = content;
+    }
+     /**
+     * 获取: 创建时间
+     * 
+     */
+    public Date getCreated() {
+    return created;
+    }
+     /**
+     * 设置: 创建时间
+     * 
+     */
+    public void setCreated(Date created) {
+    this.created = created;
+    }
+}

+ 17 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/producer/DefaultMQProducerExt.java

@@ -0,0 +1,17 @@
+package com.elab.mq.rocket.producer;
+
+/**
+ * 拓展消息发送者
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 16:21
+ */
+public class DefaultMQProducerExt {
+
+
+
+
+
+
+
+}

+ 47 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/template/DefaultMQProducerExt.java

@@ -0,0 +1,47 @@
+package com.elab.mq.rocket.template;
+
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+
+/**
+ * 消息发送模版拓展
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 16:14
+ */
+public class DefaultMQProducerExt {
+
+    private DefaultMQProducer defaultMQProducer;
+
+    public DefaultMQProducerExt(DefaultMQProducer defaultMQProducer) {
+        this.defaultMQProducer = defaultMQProducer;
+    }
+
+    public DefaultMQProducer getDefaultMQProducer() {
+        return defaultMQProducer;
+    }
+
+    public SendResult send(String topic, String tag, String key, byte[] body, int delayTimeLevel) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        Message message = new Message();
+        message.setBody(body);
+        message.setTopic(topic);
+        message.setTags(tag);
+        message.setKeys(key);
+        message.setDelayTimeLevel(delayTimeLevel);
+        return defaultMQProducer.send(message);
+    }
+
+    public SendResult send(String topic, String tag, String key, byte[] body) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        return send(topic, tag, key, body, 0);
+    }
+
+    public SendResult send(String topic, String key, byte[] body) throws InterruptedException, RemotingException,
+            MQClientException, MQBrokerException {
+        return send(topic, "*", key, body, 0);
+    }
+
+}

+ 25 - 0
elab-rocketMQ/src/main/java/com/elab/mq/rocket/utils/MsgConstants.java

@@ -0,0 +1,25 @@
+package com.elab.mq.rocket.utils;
+
+/**
+ * 枚举类
+ *
+ * @author : liukx
+ * @time : 2019/7/18 - 15:35
+ */
+public class MsgConstants {
+
+    /**
+     * 成功
+     */
+    public static int MSG_OK = 1;
+    /**
+     * 失败
+     */
+    public static int MSG_FAILS = -1;
+    /**
+     * 等待
+     */
+    public static int MSG_WAIT = 0;
+
+
+}

+ 43 - 0
elab-rocketMQ/src/test/java/com/elab/mq/rocket/msg/DefaultSendMessageHookTest.java

@@ -0,0 +1,43 @@
+package com.elab.mq.rocket.msg;
+
+import com.elab.mq.rocket.App;
+import org.apache.rocketmq.client.hook.ConsumeMessageHook;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.IOException;
+import java.util.Map;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {App.class})
+//@AutoConfigureMockMvc
+public class DefaultSendMessageHookTest {
+
+    @Autowired
+    private Map<String, ConsumeMessageHook> consumeMessageHookMap;
+
+    @Autowired
+    private RocketMQTemplate rocketMQTemplate;
+
+    @Value("${demo.rocketmq.topic}")
+    private String topic;
+
+
+    @Test
+    public void sendMessageBefore() throws IOException {
+        consumeMessageHookMap.forEach((K, V) -> {
+
+        });
+        System.out.println("-------------");
+        rocketMQTemplate.syncSend(topic, "aaaaaa");
+        System.in.read();
+    }
+
+    public void sendMessageAfter() {
+    }
+}

+ 16 - 0
elab-rocketMQ/src/test/resources/application.yml

@@ -0,0 +1,16 @@
+demo:
+    rocketmq:
+        extNameServer: 127.0.0.1:9876
+        msgExtTopic: demo-message-ext-topic
+        orderTopic: demo-order-paid-topic
+        topic: demo-string-topic
+        transTopic: demo-spring-transaction-topic
+rocketmq:
+    name-server: 192.168.0.24:9876;192.168.0.25:9876
+    producer:
+        group: my-group1
+        sendMessageTimeout: 300000
+spring:
+    application:
+        name: elab-rocketMQ
+

+ 1 - 1
elab-spring/pom.xml

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

+ 264 - 4
elab-spring/src/test/java/com/elab/spring/utils/RestTemplateUtilsTest.java

@@ -1,13 +1,14 @@
 package com.elab.spring.utils;
 
 import com.elab.core.utils.GzipUtils;
+import com.elab.core.utils.StringUtils;
 import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.web.client.RestTemplate;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.zip.GZIPInputStream;
 
 public class RestTemplateUtilsTest {
@@ -74,9 +75,268 @@ public class RestTemplateUtilsTest {
                 result = count;
                 System.out.println(count);
             } else {
-                result = result + count ;
+                result = result + count;
                 System.out.println(result);
             }
         }
     }
+
+
+    @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) {
+        URL url = null;
+        try {
+            url = new URL(urlList);
+            DataInputStream dataInputStream = new DataInputStream(url.openStream());
+
+            FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+            byte[] buffer = new byte[1024];
+            int length;
+
+            while ((length = dataInputStream.read(buffer)) > 0) {
+                output.write(buffer, 0, length);
+            }
+            fileOutputStream.write(output.toByteArray());
+            dataInputStream.close();
+            fileOutputStream.close();
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
 }

+ 4 - 3
pom.xml

@@ -7,7 +7,7 @@
     <groupId>com.elab.core</groupId>
     <artifactId>elab-parent</artifactId>
     <packaging>pom</packaging>
-    <version>2.0.4.11-SNAPSHOT</version>
+    <version>2.0.4.12-SNAPSHOT</version>
     <modules>
         <module>elab-core</module>
         <module>elab-cache</module>
@@ -19,6 +19,8 @@
         <module>elab-mongodb</module>
         <!--<module>elab-system-web</module>-->
         <module>elab-alert</module>
+        <module>elab-rocketMQ</module>
+        <module>elab-es</module>
     </modules>
 
 
@@ -139,7 +141,7 @@
             <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>
-                <version>18.0</version>
+                <version>27.0.1-jre</version>
             </dependency>
 
             <!-- xml解析 -->
@@ -167,7 +169,6 @@
                 <artifactId>slf4j-api</artifactId>
                 <version>1.7.25</version>
             </dependency>
-            <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
             <dependency>
                 <groupId>org.slf4j</groupId>
                 <artifactId>slf4j-log4j12</artifactId>

+ 45 - 0
springboot-demo/src/main/java/com/elab/example/springbootdemo/configuration/KafkaConfiguration.java

@@ -0,0 +1,45 @@
+//package com.elab.example.springbootdemo.configuration;
+//
+//import org.apache.kafka.clients.producer.KafkaProducer;
+//import org.apache.kafka.clients.producer.ProducerConfig;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//
+//import java.util.Properties;
+//
+///**
+// * kafka消息队列集成配置
+// *
+// * @author : liukx
+// * @time : 2019/8/7 - 13:48
+// */
+//@Configuration
+//public class KafkaConfiguration {
+//
+//    @Value("${kafka.bootstrap.servers}")
+//    private String bootstrapServers;
+//
+//    @Value("${kafka.topic}")
+//    private String topic;
+//
+//
+//    @Bean
+//    public KafkaProducer kafkaProducer() {
+//        Properties props = new Properties();
+//        //设置接入点,请通过控制台获取对应 Topic 的接入点
+//        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
+//        //消息队列 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);
+//
+//        //构造 Producer 对象,注意,该对象是线程安全的。
+//        //一般来说,一个进程内一个 Producer 对象即可。如果想提高性能,可构造多个对象,但最好不要超过 5 个
+//        KafkaProducer<String, String> producer = new KafkaProducer<String, String>(props);
+//        return producer;
+//    }
+//
+//
+//}

+ 39 - 0
springboot-demo/src/main/java/com/elab/example/springbootdemo/consumer/JSONConsumer.java

@@ -0,0 +1,39 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one or more
+// * contributor license agreements.  See the NOTICE file distributed with
+// * this work for additional information regarding copyright ownership.
+// * The ASF licenses this file to You under the Apache License, Version 2.0
+// * (the "License"); you may not use this file except in compliance with
+// * the License.  You may obtain a copy of the License at
+// *
+// *     http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// */
+//
+//package com.elab.example.springbootdemo.consumer;
+//
+//import com.elab.mq.rocket.listener.DefaultRocketMQListener;
+//import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.stereotype.Service;
+//
+///**
+// * RocketMQMessageListener
+// * 普通消息
+// */
+//@Service
+//@RocketMQMessageListener(topic = "${demo.rocketmq.jsonTopic}", consumerGroup = "string_consumer")
+//public class JSONConsumer extends DefaultRocketMQListener {
+//    private Logger logger = LoggerFactory.getLogger(JSONConsumer.class);
+//
+//    @Override
+//    public void processMessage(String message) throws Exception {
+//        logger.info("------------------json--消费完成-->>>>" + message);
+//    }
+//}

+ 43 - 0
springboot-demo/src/main/java/com/elab/example/springbootdemo/consumer/StringConsumer.java

@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.elab.example.springbootdemo.consumer;
+
+import com.elab.mq.rocket.listener.TagRocketMQListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ * RocketMQMessageListener
+ * 普通消息
+ */
+@Service
+public class StringConsumer implements TagRocketMQListener {
+    private Logger logger = LoggerFactory.getLogger(StringConsumer.class);
+
+    @Override
+    public String tag() {
+        return "*";
+    }
+
+    @Override
+    public void processMessage(String message) throws Exception {
+        logger.info("--------------------消费完成-->>>>" + message);
+
+    }
+}

+ 43 - 0
springboot-demo/src/main/java/com/elab/example/springbootdemo/consumer/StringTagConsumer.java

@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.elab.example.springbootdemo.consumer;
+
+import com.elab.mq.rocket.listener.TagRocketMQListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ * RocketMQMessageListener
+ * 普通消息
+ */
+@Service
+public class StringTagConsumer implements TagRocketMQListener {
+    private Logger logger = LoggerFactory.getLogger(StringTagConsumer.class);
+
+    @Override
+    public String tag() {
+        return "tag";
+    }
+
+    @Override
+    public void processMessage(String message) throws Exception {
+        logger.info("----------tag----------消费完成-->>>>" + message);
+
+    }
+}

+ 50 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/App.java

@@ -0,0 +1,50 @@
+package com.elab.example.springbootdemo.demo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * 是否死锁?
+ *
+ * @author : liukx
+ * @time : 2019/8/13 - 14:57
+ */
+public class App {
+
+    private Logger logger = LoggerFactory.getLogger(App.class);
+
+    public synchronized void demo() {
+        logger.info(" demo ");
+        demo2();
+    }
+
+    public void demo2() {
+        synchronized (this) {
+            logger.info("demo2");
+        }
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+//        App app = new App();
+//        for (int i = 0; i < 5; i++) {
+//            Thread thread = new Thread(() -> {
+//                app.demo();
+//            });
+//            thread.start();
+//        }
+
+        Lock lock = new ReentrantLock();
+        Condition condition = lock.newCondition();
+        new Thread(new ConditionSignal(lock, condition)).start();
+        Thread.sleep(2000);
+
+        new Thread(new ConditionWait(lock, condition)).start();
+
+
+    }
+
+}

+ 103 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/AxinBlockQueue.java

@@ -0,0 +1,103 @@
+package com.elab.example.springbootdemo.demo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class AxinBlockQueue {
+    //队列容器
+    private List<Integer> container = new ArrayList<>();
+    private volatile int size;
+    private volatile int capacity;
+    private Lock lock = new ReentrantLock();
+    //Condition
+    private final Condition isNull = lock.newCondition();
+    private final Condition isFull = lock.newCondition();
+
+    AxinBlockQueue(int cap) {
+        this.capacity = cap;
+    }
+
+    /**
+     * 添加方法
+     *
+     * @param data
+     */
+    public void add(int data) {
+        try {
+            lock.lock();
+            try {
+                if (size >= capacity) {
+                    System.out.println("阻塞队列满了");
+                    isFull.await();
+                }
+            } catch (InterruptedException e) {
+                isFull.signal();
+                e.printStackTrace();
+            }
+            ++size;
+            container.add(data);
+            isNull.signal();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * 取出元素
+     *
+     * @return
+     */
+    public int take() {
+        try {
+
+            lock.lock();
+            try {
+                if (size == 0) {
+                    System.out.println("阻塞队列空了");
+                    isNull.await();
+                }
+            } catch (InterruptedException e) {
+                isNull.signal();
+                e.printStackTrace();
+            }
+            --size;
+            int res = container.get(0);
+            container.remove(0);
+            isFull.signal();
+            return res;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public static void main(String[] args) {
+        AxinBlockQueue queue = new AxinBlockQueue(5);
+        Thread t1 = new Thread(() -> {
+            for (int i = 0; i < 100; i++) {
+                queue.add(i);
+                System.out.println("塞入" + i);
+//                try {
+////                    Thread.sleep(500);
+//                } catch (InterruptedException e) {
+//                    e.printStackTrace();
+//                }
+            }
+        });
+        Thread t2 = new Thread(() -> {
+            for (; ; ) {
+                System.out.println("消费" + queue.take());
+//                try {
+////                    Thread.sleep(800);
+//                } catch (InterruptedException e) {
+//                    e.printStackTrace();
+//                }
+            }
+
+        });
+        t1.start();
+        t2.start();
+    }
+}

+ 33 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/ConditionSignal.java

@@ -0,0 +1,33 @@
+package com.elab.example.springbootdemo.demo;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * 唤醒
+ *
+ * @author : liukx
+ * @time : 2019/8/14 - 14:47
+ */
+public class ConditionSignal implements Runnable {
+
+    private Lock lock;
+    private Condition condition;
+
+    public ConditionSignal(Lock lock, Condition condition) {
+        this.lock = lock;
+        this.condition = condition;
+    }
+
+    @Override
+    public void run() {
+        try {
+            this.lock.lock();
+            System.out.println("BEGIN - ConditionSignal");
+            condition.signal();
+            System.out.println("END - ConditionSignal");
+        } finally {
+            this.lock.unlock();
+        }
+    }
+}

+ 37 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/ConditionWait.java

@@ -0,0 +1,37 @@
+package com.elab.example.springbootdemo.demo;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * 等待
+ *
+ * @author : liukx
+ * @time : 2019/8/14 - 14:47
+ */
+public class ConditionWait implements Runnable {
+
+    private Lock lock;
+    private Condition condition;
+
+    public ConditionWait(Lock lock, Condition condition) {
+        this.lock = lock;
+        this.condition = condition;
+    }
+
+    @Override
+    public void run() {
+        try {
+            this.lock.lock();
+            try {
+                System.out.println("BEGIN - ConditionWait");
+                condition.await();
+                System.out.println("END - ConditionWait");
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        } finally {
+            this.lock.unlock();
+        }
+    }
+}

+ 109 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/MyBlockingArray.java

@@ -0,0 +1,109 @@
+package com.elab.example.springbootdemo.demo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Created by dengcheng on 2018/8/17.
+ */
+public class MyBlockingArray<E> {
+    private Logger logger = LoggerFactory.getLogger(MyBlockingArray.class);
+    E[] datas;
+    int takeIndex = -1;
+    int offerIndex = -1;
+    int count = 0;
+    int size;
+    private ReentrantLock lock = new ReentrantLock();
+    private Condition notEmpty = lock.newCondition();
+    private Condition notFull = lock.newCondition();
+
+    public MyBlockingArray(int size) {
+        datas = (E[]) new Object[size];
+        this.size = size;
+    }
+
+    public boolean offer(E e) {
+        try {
+            lock.lockInterruptibly();
+
+            if (count == size) {
+                logger.info(" 阻塞队列满啦.");
+                notFull.await();
+            }
+
+            if (datas.length > 0)
+                notEmpty.signal();
+
+            ++offerIndex;
+            datas[offerIndex] = e;
+            ++count;
+            if ((offerIndex + 1) == datas.length)
+                offerIndex = -1;
+
+            return true;
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            lock.unlock();
+        }
+        return false;
+    }
+
+    public E take() {
+        try {
+            lock.lockInterruptibly();
+
+            if (count == 0) {
+                logger.info(" 阻塞队列空了.");
+                notEmpty.await();
+            }
+            ++takeIndex;
+
+            E e = datas[takeIndex];
+            --count;
+            if ((takeIndex + 1) == datas.length)
+                takeIndex = -1;
+            return e;
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            lock.unlock();
+        }
+        return null;
+    }
+
+    public static void main(String[] args) {
+        final MyBlockingArray<Integer> array = new MyBlockingArray<Integer>(10);
+        new Thread(new Runnable() {
+            public void run() {
+                int i = 0;
+                while (true) {
+                    i++;
+                    array.offer(i);
+                    try {
+                        Thread.sleep(10);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+
+            }
+        }).start();
+
+        new Thread(new Runnable() {
+            public void run() {
+                while (true) {
+                    Integer data = array.take();
+                    if (data == null)
+                        break;
+                    System.out.println(data);
+                }
+
+            }
+        }).start();
+
+    }
+}

+ 114 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/demo/XBlockingQueue.java

@@ -0,0 +1,114 @@
+package com.elab.example.springbootdemo.demo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * 手写阻塞队列
+ *
+ * @author : liukx
+ * @time : 2019/8/14 - 17:10
+ */
+public class XBlockingQueue<T> {
+    private Logger logger = LoggerFactory.getLogger(XBlockingQueue.class);
+    public List<T> queue = new ArrayList<>();
+    public volatile int size;
+    public volatile int index = 0;
+
+    private Lock lock = new ReentrantLock();
+    private Condition isFull = lock.newCondition();
+    private Condition isNull = lock.newCondition();
+
+    public XBlockingQueue(int size) {
+        this.size = size;
+    }
+
+
+    public void add(T obj) throws Exception {
+        lock.lock();
+        try {
+            if (index == size) {
+                logger.info(" 阻塞队列满啦 ... ");
+                isFull.await();
+                index = -1;
+            }
+            queue.add(index, obj);
+            isNull.signal();
+            index++;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public T take() throws Exception {
+        lock.lock();
+        try {
+            if (index == 0) {
+                logger.info(" 阻塞队列中没有值...");
+                isNull.await();
+            }
+//            T t = queue.get(index);
+            T t = queue.get(index);
+            logger.info("take : " + t.toString());
+            isFull.signal();
+            --index;
+            return t;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        XBlockingQueue queue = new XBlockingQueue(10);
+
+        new Thread(() -> {
+            for (int i = 0; i < 100; i++) {
+                try {
+                    queue.add(i);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }).start();
+
+        Thread.sleep(1000);
+        new Thread(() -> {
+            for (int i = 0; i < 100; i++) {
+                try {
+                    queue.take();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }).start();
+
+
+//        for (int i = 0; i < 100; i++) {
+//            int finalI = i;
+//            new Thread(() -> {
+//                try {
+//                    queue.add(finalI);
+//                } catch (Exception e) {
+//                    e.printStackTrace();
+//                }
+//            }).start();
+//        }
+//        for (int i = 0; i < 100; i++) {
+//            new Thread(() -> {
+//                try {
+//                    Object take = queue.take();
+//                } catch (Exception e) {
+//                    e.printStackTrace();
+//                }
+//            }).start();
+//        }
+
+    }
+
+}

+ 256 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/es/EsTest.java

@@ -0,0 +1,256 @@
+package com.elab.example.springbootdemo.es;
+
+import com.elab.es.client.DefaultElasticSearchTemplate;
+import com.elab.example.springbootdemo.SpringbootDemoApplication;
+import com.elab.example.springbootdemo.es.entity.User;
+import com.elab.example.springbootdemo.es.entity.UserTable;
+import org.elasticsearch.action.bulk.BulkResponse;
+import org.elasticsearch.action.index.IndexRequest;
+import org.elasticsearch.action.search.SearchRequest;
+import org.elasticsearch.action.search.SearchResponse;
+import org.elasticsearch.index.query.*;
+import org.elasticsearch.rest.RestStatus;
+import org.elasticsearch.search.SearchHit;
+import org.elasticsearch.search.SearchHits;
+import org.elasticsearch.search.builder.SearchSourceBuilder;
+import org.elasticsearch.search.sort.SortOrder;
+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.test.context.junit4.SpringRunner;
+import org.zxp.esclientrhl.repository.HighLight;
+import org.zxp.esclientrhl.repository.PageList;
+import org.zxp.esclientrhl.repository.PageSortHighLight;
+import org.zxp.esclientrhl.repository.Sort;
+import org.zxp.esclientrhl.util.JsonUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author : liukx
+ * @time : 2019/8/1 - 11:40
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {SpringbootDemoApplication.class})
+public class EsTest {
+
+    private Logger logger = LoggerFactory.getLogger(EsTest.class);
+
+    @Autowired
+    private DefaultElasticSearchTemplate<User, String> elasticsearchTemplate;
+
+    @Autowired
+    private DefaultElasticSearchTemplate<UserTable, String> elasticsearchTemplate1;
+
+    @Test
+    public void save() throws Exception {
+        User user = new User();
+        user.setMessage("新的测试");
+        user.setPostDate(new Date());
+        user.setUser("某某某");
+        user.setId(UUID.randomUUID().toString());
+
+        IndexRequest request = new IndexRequest();
+        request.setPipeline("");
+
+        boolean save = elasticsearchTemplate.save(user);
+        logger.info(" 结果 : " + save);
+    }
+
+    @Test
+    public void update() throws Exception {
+        User user = getUser("新的测试1111", "周杰伦2");
+//        boolean save = elasticsearchTemplate.update(user);
+        boolean save = elasticsearchTemplate.updateCover(user);
+        logger.info(" 结果 : " + save);
+    }
+
+    private User getUser(String mesage, String username) {
+        User user = new User();
+        user.setMessage(mesage);
+        user.setPostDate(new Date());
+        user.setUser(username);
+        user.setId(UUID.randomUUID().toString());
+        return user;
+    }
+
+    private UserTable getUserTable(String mesage, String username) {
+        UserTable user = new UserTable();
+        user.setMessage(mesage);
+        user.setPostDate(new Date());
+        user.setTitle(mesage);
+        user.setDoc_id(UUID.randomUUID().toString());
+        return user;
+    }
+
+    @Test
+    public void delete() throws Exception {
+        boolean b = elasticsearchTemplate.deleteById("633b5f31-8cfd-47d4-bc9a-a151fb23633f", User.class);
+        logger.info(" result : " + b);
+    }
+
+    @Test
+    public void msave() throws Exception {
+        List<UserTable> list = new ArrayList<>();
+        int i = 1001;
+        list.add(getUserTable("双卧朝南向 高层视野开阔 客厅挂东窗 居住舒适", "周杰伦" + i++));
+        list.add(getUserTable("高层观三大公园三居室,安静不临街,精装修智能家居", "周杰伦" + i++));
+        list.add(getUserTable("馨莲茗园精装南北通透三居室 满五年唯一 看房方便", "周杰伦" + i++));
+        list.add(getUserTable("次顶层,视野好,人车分流,满五唯一,南北通透", "周杰伦" + i++));
+        list.add(getUserTable("万科星园南北3居2卫观奥森公园,满五年仅有住房", "周杰伦" + i++));
+        list.add(getUserTable("南北通透三居室   中间楼层  采光无遮挡", "周杰伦" + i++));
+        list.add(getUserTable("6号楼一梯两户安静位置南北向三居,金地物业", "周杰伦" + i++));
+        list.add(getUserTable("南北双通透两梯两户 眼睛户型中间楼层", "周杰伦" + i++));
+        list.add(getUserTable("南北正规三居 观花园 安静位置 板楼 带明卫 税费少", "周杰伦" + i++));
+        list.add(getUserTable("风格雅园 低密度社区 双卧朝南三居室", "周杰伦" + i++));
+        list.add(getUserTable("南北通透普通住宅正规三居,低密度封闭式管理", "周杰伦" + i++));
+        list.add(getUserTable("双井合生国际高层南北通透观景三居室", "周杰伦" + i++));
+        list.add(getUserTable("满五年唯一,业主自住房二次装修;双明卫户型!", "周杰伦" + i++));
+        list.add(getUserTable("70年产权东城区东直门桥东南角东方银座三居室", "周杰伦" + i++));
+        list.add(getUserTable("海淀金玉府 南北三居室 高楼层视野开阔", "周杰伦" + i++));
+        list.add(getUserTable("新上三居,南北通透不临街,满五年唯一", "周杰伦" + i++));
+        list.add(getUserTable("金都杭城东区 3室2厅 1090万", "周杰伦" + i++));
+        list.add(getUserTable("万科中粮假日风景 3室1厅 1050万", "周杰伦" + i++));
+        list.add(getUserTable("海淀2005年,中国房子,首套购房1.5%契税,南北3居室", "周杰伦" + i++));
+        list.add(getUserTable("一层带花园,不临街,满五年唯一,精装修,看房方便", "周杰伦" + i++));
+        list.add(getUserTable("中国房子 3室2厅 1025万", "周杰伦" + i++));
+        list.add(getUserTable("山水文园 三面采光 南北通透的三居室", "周杰伦" + i++));
+        list.add(getUserTable("带车位看房有钥匙前后不临街对花园", "周杰伦" + i++));
+        list.add(getUserTable("五星必看好房乐成国际270度采光三居金地物业满五唯一", "周杰伦" + i++));
+        list.add(getUserTable("九台东南三居 全明格局 随时看房", "周杰伦" + i++));
+        list.add(getUserTable("南北正规三居户型,带储藏间,精装修", "周杰伦" + i++));
+        list.add(getUserTable("千鹤家园正规西南向三居室,满五年唯一", "周杰伦" + i++));
+        list.add(getUserTable("二期园林!满五年唯一!只需契税!南北通透!板楼!", "周杰伦" + i++));
+        list.add(getUserTable("此房满五年唯一,配套齐全,交通便利,前后不临街", "周杰伦" + i++));
+        list.add(getUserTable("融科三期双卧朝南三居 双通透 满五唯一飘窗不算面积", "周杰伦" + i++));
+        list.add(getUserTable("西南北朝向,三居室,购房税费少", "周杰伦" + i++));
+        list.add(getUserTable("金星园南北通透三居室满五年唯一住房", "周杰伦" + i++));
+        list.add(getUserTable("2004年航天部分房,华润物业,西南北向,两卫,采光好", "周杰伦" + i++));
+        list.add(getUserTable("太阳公元南区A类全新三居  南北通透  百米楼间距", "周杰伦" + i++));
+        list.add(getUserTable("满五唯一东西通透三居室,业主诚心卖", "周杰伦" + i++));
+        list.add(getUserTable("金隅丽港城 低密板楼户型好带私密花园车位 品质住房", "周杰伦" + i++));
+        list.add(getUserTable("央产房次顶层 东观玉渊潭 西眺妙峰山 半个北京城视野", "周杰伦" + i++));
+        list.add(getUserTable("和平西桥 楼龄新 东南三居室 满五年唯一 无遮挡视野佳", "周杰伦" + i++));
+        list.add(getUserTable("南北通透3居 明厨明卫  精装修不临街", "周杰伦" + i++));
+        list.add(getUserTable("远中悦莱东南向大三居 满两年原值高税费少", "周杰伦" + i++));
+        BulkResponse save = elasticsearchTemplate1.save(list);
+        RestStatus status = save.status();
+        logger.info(status.toString());
+
+    }
+
+
+    @Test
+    public void search() throws Exception {
+        SearchRequest searchRequest = new SearchRequest(new String[]{"posts"});
+        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
+        searchSourceBuilder.query(new MatchAllQueryBuilder());
+        searchSourceBuilder.from(0);
+        searchSourceBuilder.size(10);
+        searchRequest.source(searchSourceBuilder);
+        SearchResponse searchResponse = elasticsearchTemplate.search(searchRequest);
+
+        SearchHits hits = searchResponse.getHits();
+        SearchHit[] searchHits = hits.getHits();
+        for (SearchHit hit : searchHits) {
+            User t = JsonUtils.string2Obj(hit.getSourceAsString(), User.class);
+            System.out.println(t + "\t" + hit.getId());
+        }
+    }
+
+
+    @Test
+    public void search1() throws Exception {
+        List<User> main2List = elasticsearchTemplate.search(new MatchAllQueryBuilder(), User.class);
+        main2List.forEach(main2 -> System.out.println(main2));
+    }
+
+
+    @Test
+    public void searchPage() throws Exception {
+        //定制分页信息
+        int currentPage = 1;
+        int pageSize = 2;
+        //分页
+        PageSortHighLight psh = new PageSortHighLight(currentPage, pageSize);
+        //排序字段,注意如果proposal_no是text类型会默认带有keyword性质,需要拼接.keyword
+        String sorter = "postDate.keyword";
+        Sort.Order order = new Sort.Order(SortOrder.ASC, sorter);
+        psh.setSort(new Sort(order));
+        //定制高亮,如果定制了高亮,返回结果会自动替换字段值为高亮内容
+        HighLight highLight = new HighLight();
+        //可以单独定义高亮的格式
+        highLight.setPreTag("<em>");
+        highLight.setPostTag("</em>");
+        highLight.field("title");
+        psh.setHighLight(highLight);
+        PageList<UserTable> pageList = new PageList<>();
+//        QueryBuilder queryBuilder = QueryBuilders.termQuery("user.keyword", "周杰伦2");
+//        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("_all", "唯一");
+
+        MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("wy","title","message");
+        pageList = elasticsearchTemplate1.search(matchQueryBuilder, psh, UserTable.class);
+        pageList.getList().forEach(main2 -> System.out.println(main2.toString()));
+
+    }
+
+    @Test
+    public void searchByField() throws Exception {
+        List<String> list = elasticsearchTemplate.completionSuggest("user", "周杰伦", User.class);
+        list.forEach(main2 -> System.out.println(main2));
+    }
+
+    @Test
+    public void searchById() throws Exception {
+        User main2 = elasticsearchTemplate.getById("f5fd0129-0b02-4685-b9f0-024b7ed48868", User.class);
+        System.out.println(main2);
+    }
+
+    @Test
+    public void searchByName() throws Exception {
+        // 精准查询
+        QueryBuilder queryBuilder = QueryBuilders.termQuery("user.keyword", "周杰伦2");
+        // 短语查询
+//        QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("user", "2");
+        // 移动匹配次数 slop设置为2,周[杰伦]2最多能移动两次并完成匹配
+//        QueryBuilder queryBuilder = QueryBuilders.matchPhraseQuery("user","周2").slop(2);
+        // 范围查询
+        //  QueryBuilder queryBuilder = QueryBuilders.rangeQuery("postDate").from(1564639725110l).to(1564640107682l);
+
+        //全文匹配
+//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("user", "周1");
+
+        // minimumShouldMatch最少匹配参数
+//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("message", "业主").minimumShouldMatch("100%");
+
+        // 纠错查询  需要集成fuzzy
+//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("message","明园");
+//        ((MatchQueryBuilder) queryBuilder).fuzziness(Fuzziness.AUTO);
+
+
+        // match设定逻辑关系,
+//        QueryBuilder queryBuilder = QueryBuilders.matchQuery("message","yezhu").operator(Operator.AND);
+//        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("message", "yezhu").analyzer("my_pinyin");
+
+        List<User> list = elasticsearchTemplate.search(queryBuilder, User.class);
+        list.forEach(main2 -> System.out.println(main2));
+    }
+
+    @Test
+    public void searchByName1() throws Exception {
+
+        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("message", "唯一").analyzer("my_pinyin");
+
+        List<UserTable> list = elasticsearchTemplate1.search(queryBuilder, UserTable.class);
+        list.forEach(main2 -> System.out.println(main2));
+
+    }
+
+
+}

+ 67 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/es/entity/User.java

@@ -0,0 +1,67 @@
+package com.elab.example.springbootdemo.es.entity;
+
+import org.zxp.esclientrhl.annotation.ESID;
+import org.zxp.esclientrhl.annotation.ESMapping;
+import org.zxp.esclientrhl.annotation.ESMetaData;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户entity
+ *
+ * @author : liukx
+ * @time : 2019/8/1 - 11:40
+ */
+@ESMetaData(indexName = "posts", indexType = "doc", number_of_shards = 5, number_of_replicas = 0,printLog = true)
+public class User implements Serializable {
+
+    @ESID
+    private String id;
+    @ESMapping(suggest = true)
+    private String user;
+    private String message;
+    private Date postDate;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Date getPostDate() {
+        return postDate;
+    }
+
+    public void setPostDate(Date postDate) {
+        this.postDate = postDate;
+    }
+
+    @Override
+    public String toString() {
+        return "User{" +
+                ", id='" + id + '\'' +
+                ", user='" + user + '\'' +
+                ", message='" + message + '\'' +
+                ", postDate=" + postDate +
+                '}';
+    }
+}

+ 76 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/es/entity/UserTable.java

@@ -0,0 +1,76 @@
+package com.elab.example.springbootdemo.es.entity;
+
+import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
+import org.zxp.esclientrhl.annotation.ESMetaData;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户entity
+ *
+ * @author : liukx
+ * @time : 2019/8/1 - 11:40
+ */
+@ESMetaData(indexName = "index_test", indexType = "user_table", number_of_shards = 5, number_of_replicas = 0,
+        printLog = true)
+public class UserTable implements Serializable {
+
+    private String doc_id;
+    private String title;
+    private String message;
+    private Date postDate;
+
+    private HighlightField highlightField;
+
+    public HighlightField getHighlightField() {
+        return highlightField;
+    }
+
+    public void setHighlightField(HighlightField highlightField) {
+        this.highlightField = highlightField;
+    }
+
+    public String getDoc_id() {
+        return doc_id;
+    }
+
+    public void setDoc_id(String doc_id) {
+        this.doc_id = doc_id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Date getPostDate() {
+        return postDate;
+    }
+
+    public void setPostDate(Date postDate) {
+        this.postDate = postDate;
+    }
+
+    @Override
+    public String toString() {
+        return "UserTable{" +
+                "doc_id='" + doc_id + '\'' +
+                ", title='" + title + '\'' +
+                ", message='" + message + '\'' +
+                ", postDate=" + postDate +
+                ", highlightField=" + highlightField +
+                '}';
+    }
+}

+ 46 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/kafka/KafkaSpringTest.java

@@ -0,0 +1,46 @@
+package com.elab.example.springbootdemo.kafka;
+
+import com.elab.example.springbootdemo.SpringbootDemoApplication;
+import org.apache.kafka.clients.producer.KafkaProducer;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.apache.kafka.clients.producer.RecordMetadata;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.concurrent.Future;
+
+/**
+ * @author : liukx
+ * @time : 2019/8/7 - 13:53
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {SpringbootDemoApplication.class})
+public class KafkaSpringTest {
+
+    @Autowired
+    private KafkaProducer<String, String> producer;
+
+    @Test
+    public void send() {
+        //构造一个消息队列 Kafka 消息
+        String topic = "api_log"; //消息所属的 Topic,请在控制台创建后,填写在这里
+        String value = "this is the message's value"; //消息的内容
+        ProducerRecord<String, String> kafkaMessage = new ProducerRecord<String, String>(topic, value);
+        try {
+            //发送消息,并获得一个 Future 对象
+            Future<RecordMetadata> metadataFuture = producer.send(kafkaMessage);
+            //同步获得 Future 对象的结果
+            RecordMetadata recordMetadata = metadataFuture.get();
+            System.out.println("Produce ok:" + recordMetadata.toString());
+        } catch (Exception e) {
+            //要考虑重试,参见常见问题: https://help.aliyun.com/document_detail/68168.html
+            System.out.println("error occurred");
+            e.printStackTrace();
+        }
+    }
+
+
+}

+ 152 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/kafka/KafkaTest.java

@@ -0,0 +1,152 @@
+package com.elab.example.springbootdemo.kafka;
+
+import com.elab.core.utils.DateUtils;
+import com.elab.spring.utils.RestTemplateUtils;
+import com.google.common.collect.Maps;
+import org.junit.Test;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.client.RestTemplate;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 卡夫卡测试
+ *
+ * @author : liukx
+ * @time : 2019/8/6 - 15:34
+ */
+public class KafkaTest {
+
+    @Test
+    public void test() {
+
+    }
+
+    private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+    private static final String ENCODING = "UTF-8";
+    private static final String HTTP_METHOD = "POST";
+    //购买的实例所在地域的 Region ID
+    private static final String REGION_ID = "cn-shanghai";
+    private static final String ACCESS_KEY = "LTAIWRlbq9unW05V";
+    private static final String ACCESS_KEY_SECRET = "6JXciPjrzfJGPWO1enoklG88GTo9DL";
+
+
+    public static void main(String[] args) {
+        try {
+            // 1. 设置参数
+            Map<String, String> parameters = buildCommonParams();
+            // 2. 排序请求参数: 根据字母排序
+            String[] sortedKeys = sortParamsToArray(parameters);
+            // 3. 构造 stringToSign 字符串
+            String stringToSign = buildSignString(parameters, sortedKeys);
+            // 4. 计算签名
+            String signature = calculateSignature(stringToSign);
+            // 5. 将签名设置到参数中
+            parameters.put("Signature", signature);
+            // 6. 发送 POST 请求
+            String result = post(String.format("http://alikafka.%s.aliyuncs.com/", REGION_ID), parameters);
+            // 7. 验证结果
+            System.out.println(result);
+        } catch (Throwable throwable) {
+            throwable.printStackTrace();
+        }
+    }
+
+    private static Map<String, String> buildCommonParams() {
+        Map<String, String> parameters = Maps.newLinkedHashMap();
+        // Action 为请求方法
+        // GetInstanceList:获取实例信息;GetConsumerList:获取消费组列表;GetTopicList:获取 Topic 列表;GetTopicStatus:获取 Topic 状态
+        // GetConsumerProgress:获取消费状态;CreateTopic:创建 Topic;CreateConsumerGroup:创建 Consumer Group
+        parameters.put("Action", "GetInstanceList");
+        // 接口版本:"2018-10-15"
+        parameters.put("Version", "V1.0.3");
+        // 请求参数:RegionId 为必填参数
+        // 如果接口有其他参数请都设置:比如 InstanceId/Topic/ConsumerId
+        // parameters.put("InstanceId", "cn-huhehaote");
+        // parameters.put("Topic", "cn-huhehaote");
+        // parameters.put("Remark", "cn-huhehaote");
+        // parameters.put("ConsumerId", "cn-huhehaote");
+        parameters.put("RegionId", REGION_ID);
+        parameters.put("AccessKeyId", ACCESS_KEY);
+        // 时间戳,注意格式:yyyy-MM-dd'T'HH:mm:ss'Z'
+        parameters.put("Timestamp", formatIso8601Date(new Date()));
+        parameters.put("SignatureMethod", "HMAC-SHA1");
+        parameters.put("SignatureVersion", "1.0");
+        parameters.put("SignatureNonce", UUID.randomUUID().toString());
+        parameters.put("Format", "json");
+        return parameters;
+    }
+
+    private static String[] sortParamsToArray(Map<String, String> parameters) {
+        String[] sortedKeys = parameters.keySet().toArray(new String[]{});
+        Arrays.sort(sortedKeys);
+        return sortedKeys;
+    }
+
+    private static String buildSignString(Map<String, String> parameters,
+                                          String[] sortedKeys) throws UnsupportedEncodingException {
+        StringBuilder stringToSign = new StringBuilder();
+        String SEPARATOR = "&";
+        stringToSign.append(HTTP_METHOD).append(SEPARATOR);
+        stringToSign.append(percentEncode("/")).append(SEPARATOR);
+        StringBuilder canonicalizedQueryString = new StringBuilder();
+        for (String key : sortedKeys) {
+            // 这里注意编码 key 和 value
+            canonicalizedQueryString.append("&")
+                    .append(percentEncode(key)).append("=")
+                    .append(percentEncode(parameters.get(key)));
+        }
+
+        // 这里注意编码 canonicalizedQueryString
+        stringToSign.append(percentEncode(canonicalizedQueryString.toString().substring(1)));
+        return stringToSign.toString();
+    }
+
+    private static String calculateSignature(String stringToSign)
+            throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
+        String ALGORITHM = "HmacSHA1";
+        String ENCODING = "UTF-8";
+        //对应账号的 AccessKeySecret
+        String accessKeySecret = ACCESS_KEY_SECRET + "&";
+        Mac mac = Mac.getInstance(ALGORITHM);
+        mac.init(new SecretKeySpec(accessKeySecret.getBytes(ENCODING), ALGORITHM));
+        byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
+        return new String(Base64.getEncoder().encode(signData));
+    }
+
+    private static String percentEncode(String value) throws UnsupportedEncodingException {
+        return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
+    }
+
+    private static String formatIso8601Date(Date date) {
+        SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
+        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
+        return df.format(date);
+    }
+
+    private static String post(String url, Map<String, String> paramMap) throws IOException {
+        RestTemplate restTemplate = new RestTemplate();
+        RestTemplateUtils restTemplateUtils = new RestTemplateUtils();
+        restTemplateUtils.setRestTemplate(restTemplate);
+        HttpHeaders httpHeaders = new HttpHeaders();
+        List<String> list = new ArrayList<>();
+        list.add(DateUtils.getStringOfTodayDate());
+        httpHeaders.put("Date", list );
+        String post = restTemplateUtils.post(url, paramMap, String.class);
+//        Form form = Form.form();
+//        for (String key : paramMap.keySet()) {
+//            form.add(key, paramMap.get(key));
+//        }
+//
+//        return Request.Post(url).bodyForm(form.build()).connectTimeout(10000).execute().returnContent().asString();
+        return post;
+    }
+}

+ 54 - 0
springboot-demo/src/test/java/com/elab/example/springbootdemo/rocketmq/producerTest.java

@@ -0,0 +1,54 @@
+package com.elab.example.springbootdemo.rocketmq;
+
+import com.alibaba.fastjson.JSONObject;
+import com.elab.core.utils.RandomUtils;
+import com.elab.example.springbootdemo.SpringbootDemoApplication;
+import com.elab.mq.rocket.template.DefaultMQProducerExt;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * 生产者发送消息
+ *
+ * @author : liukx
+ * @time : 2019/9/16 - 15:26
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {SpringbootDemoApplication.class})
+public class producerTest {
+
+    @Autowired
+    private DefaultMQProducerExt rocketMQTemplate;
+
+    @Value("${rocketmq.default.topic}")
+    private String topic;
+
+    @Test
+    public void sendJsonMsg() throws UnsupportedEncodingException, InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("success", "true");
+        jsonObject.put("msg", "my name is lkx");
+        Message message = new Message();
+        message.setBody(jsonObject.toJSONString().getBytes());
+        message.setTopic(topic);
+        message.setTags("");
+        SendResult sendResult = rocketMQTemplate.send(topic, "tag", RandomUtils.randomString(5),
+                jsonObject.toJSONString().getBytes());
+        SendStatus sendStatus = sendResult.getSendStatus();
+        System.out.println("--->" + sendResult.toString());
+    }
+
+
+}