wangweiqun 6 gadi atpakaļ
revīzija
fb72331a26
65 mainītis faili ar 7367 papildinājumiem un 0 dzēšanām
  1. 1159 0
      ehr-cloud/pom.xml
  2. 606 0
      ehr-ms-parent-pom/pom.xml
  3. 98 0
      pom.xml
  4. 42 0
      src/main/java/com/yihu/ehr/RedisServiceApp.java
  5. 79 0
      src/main/java/com/yihu/ehr/kafka/ConsumerRunner.java
  6. 52 0
      src/main/java/com/yihu/ehr/kafka/MessageManager.java
  7. 52 0
      src/main/java/com/yihu/ehr/listener/ApplicationReadyListener.java
  8. 66 0
      src/main/java/com/yihu/ehr/redis/RedisSubscribeMessageEndPoint.java
  9. 212 0
      src/main/java/com/yihu/ehr/redis/cache/CacheCommonBiz.java
  10. 75 0
      src/main/java/com/yihu/ehr/redis/cache/CacheResponseTimeAspect.java
  11. 168 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheAuthorizationEndPoint.java
  12. 219 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheCategoryEndPoint.java
  13. 221 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheKeyRuleEndPoint.java
  14. 150 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheOperationEndPoint.java
  15. 131 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheStatisticsEndPoint.java
  16. 262 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisEndPoint.java
  17. 100 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisInitEndPoint.java
  18. 59 0
      src/main/java/com/yihu/ehr/redis/cache/controller/RedisUpdateEndPoint.java
  19. 26 0
      src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheAuthorizationDao.java
  20. 22 0
      src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheCategoryDao.java
  21. 21 0
      src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheKeyMemoryDao.java
  22. 31 0
      src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheKeyRuleDao.java
  23. 19 0
      src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheResponseTimeLogDao.java
  24. 60 0
      src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheAuthorization.java
  25. 49 0
      src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheCategory.java
  26. 89 0
      src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheKeyMemory.java
  27. 102 0
      src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheKeyRule.java
  28. 49 0
      src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheResponseTimeLog.java
  29. 50 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheAuthorizationService.java
  30. 59 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheCategoryService.java
  31. 87 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheKeyMemoryService.java
  32. 74 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheKeyRuleService.java
  33. 34 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheResponseTimeLogService.java
  34. 244 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisInitService.java
  35. 250 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisService.java
  36. 106 0
      src/main/java/com/yihu/ehr/redis/cache/service/RedisUpdateService.java
  37. 27 0
      src/main/java/com/yihu/ehr/redis/config/RedisConfig.java
  38. 30 0
      src/main/java/com/yihu/ehr/redis/config/ScheduleConfig.java
  39. 46 0
      src/main/java/com/yihu/ehr/redis/pubsub/CustomMessageListenerAdapter.java
  40. 129 0
      src/main/java/com/yihu/ehr/redis/pubsub/DefaultMessageDelegate.java
  41. 46 0
      src/main/java/com/yihu/ehr/redis/pubsub/MessageCommonBiz.java
  42. 13 0
      src/main/java/com/yihu/ehr/redis/pubsub/MessageDelegate.java
  43. 182 0
      src/main/java/com/yihu/ehr/redis/pubsub/PubSubMessageJob.java
  44. 247 0
      src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqChannelEndPoint.java
  45. 43 0
      src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqOperationEndPoint.java
  46. 183 0
      src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqPublisherEndPoint.java
  47. 240 0
      src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqSubscriberEndPoint.java
  48. 24 0
      src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqChannelDao.java
  49. 25 0
      src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqMessageLogDao.java
  50. 25 0
      src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqPublisherDao.java
  51. 28 0
      src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqSubscriberDao.java
  52. 100 0
      src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqChannel.java
  53. 80 0
      src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqMessageLog.java
  54. 58 0
      src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqPublisher.java
  55. 58 0
      src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqSubscriber.java
  56. 145 0
      src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqChannelService.java
  57. 43 0
      src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqMessageLogService.java
  58. 56 0
      src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqPublisherService.java
  59. 78 0
      src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqSubscriberService.java
  60. 56 0
      src/main/resources/application.yml
  61. 29 0
      src/main/resources/banner.txt
  62. 23 0
      src/main/resources/bootstrap.yml
  63. 102 0
      src/main/resources/logback-spring.xml
  64. 45 0
      src/test/java/com/yihu/ehr/redis/cache/CacheTest.java
  65. 83 0
      src/test/java/com/yihu/ehr/redis/pubsub/PubSubTest.java

+ 1159 - 0
ehr-cloud/pom.xml

@ -0,0 +1,1159 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yihu.ehr</groupId>
    <artifactId>ehr-cloud</artifactId>
    <version>1.2.0</version>
    <packaging>pom</packaging>
    <name>ehr-cloud</name>
    <description>EHR parent pom for all</description>
    <url>http://ehr.yihu.com</url>
    <organization>
        <name>JKZL Software, Inc.</name>
        <url>http://www.yihu.com</url>
    </organization>
    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0</url>
        </license>
    </licenses>
    <developers>
        <developer>
            <id>sand</id>
            <name>Sand Wen</name>
            <email>sand.fj.wen@gmail.com</email>
            <organization>JKZL Software, Inc.</organization>
            <organizationUrl>http://www.yihu.com</organizationUrl>
            <roles>
                <role>Project lead</role>
                <role>Project designer</role>
                <role>Project programmer</role>
            </roles>
        </developer>
        <developer>
            <id>yzh</id>
            <name>叶泽华</name>
            <email>yzh@qq.com</email>
            <organization>JKZL Software, Inc.</organization>
            <organizationUrl>http://www.yihu.com</organizationUrl>
            <roles>
                <role>Project programmer</role>
            </roles>
        </developer>
        <developer>
            <id>cws</id>
            <name>陈维山</name>
            <email>hill9868@qq.com</email>
            <organization>JKZL Software, Inc.</organization>
            <organizationUrl>http://www.yihu.com</organizationUrl>
            <roles>
                <role>Project programmer</role>
            </roles>
        </developer>
        <developer>
            <id>hzy</id>
            <name>黄志勇</name>
            <email>hzy@qq.com</email>
            <organization>JKZL Software, Inc.</organization>
            <organizationUrl>http://www.yihu.com</organizationUrl>
            <roles>
                <role>Project programmer</role>
            </roles>
        </developer>
    </developers>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <version.spring-framework>4.3.13.RELEASE</version.spring-framework>
        <version.spring-boot>1.5.9.RELEASE</version.spring-boot>
        <version.spring-cloud-starter>1.3.2.RELEASE</version.spring-cloud-starter>
        <version.spring-cloud>1.4.2.RELEASE</version.spring-cloud>
        <version.spring-security>4.2.3.RELEASE</version.spring-security>
        <version.spring-oauth2>2.0.14.RELEASE</version.spring-oauth2>
        <version.spring-session>1.3.1.RELEASE</version.spring-session>
        <version.spring-session-hazelcast>2.0.1.RELEASE</version.spring-session-hazelcast>
        <version.spring-data-commons>1.13.9.RELEASE</version.spring-data-commons>
        <version.spring-data-hadoop>2.2.0.RELEASE</version.spring-data-hadoop>
        <version.spring-data-solr>2.1.3.RELEASE</version.spring-data-solr>
        <version.spring-data-redis>1.7.1.RELEASE</version.spring-data-redis>
        <version.spring-data-jpa>1.11.10.RELEASE</version.spring-data-jpa>
        <version.spring-kafka>1.0.5.RELEASE</version.spring-kafka>
        <version.commons-bean-utils>1.9.2</version.commons-bean-utils>
        <version.commons-codec>1.9</version.commons-codec>
        <version.commons-collections>3.2.1</version.commons-collections>
        <version.commons-compress>1.9</version.commons-compress>
        <version.commons-dbcp2>2.1.1</version.commons-dbcp2>
        <version.commons-dbutils>1.6</version.commons-dbutils>
        <version.commons-io>2.4</version.commons-io>
        <version.commons-lang3>3.2.1</version.commons-lang3>
        <version.commons-pool2>2.4.2</version.commons-pool2>
        <version.zookeeper>3.4.6</version.zookeeper>
        <version.hadoop-client>2.6.5</version.hadoop-client>
        <version.hbase-client>1.1.1</version.hbase-client>
        <version.solr>5.5.4</version.solr>
        <version.hibernate>4.3.11.Final</version.hibernate>
        <version.hibernate-validator>6.0.10.Final</version.hibernate-validator>
        <version.hibernate-jpa-api>1.0.0.Final</version.hibernate-jpa-api>
        <version.http-core>4.4.3</version.http-core>
        <version.http-client>4.5.1</version.http-client>
        <version.http-mime>4.5.1</version.http-mime>
        <version.io-dropwizard-metrics>3.1.2</version.io-dropwizard-metrics>
        <version.java>1.8</version.java>
        <version.jackson>2.6.6</version.jackson>
        <version.jedis>2.9.0</version.jedis>
        <version.jcl-over-slf4j>1.7.19</version.jcl-over-slf4j>
        <version.jul-over-slf4j>1.7.21</version.jul-over-slf4j>
        <version.joda-time>2.8.2</version.joda-time>
        <version.junit>4.12</version.junit>
        <version.logging>1.2</version.logging>
        <version.log4j>1.2.17</version.log4j>
        <version.log4j2>2.4.1</version.log4j2>
        <version.logback>1.1.7</version.logback>
        <version.mysql>5.1.45</version.mysql>
        <version.pinyin4j>2.5.0</version.pinyin4j>
        <version.quartz>2.2.3</version.quartz>
        <version.servlet-api>3.1.0</version.servlet-api>
        <version.slf4j>1.7.21</version.slf4j>
        <version.statsd-client>3.1.0</version.statsd-client>
        <version.swagger>2.7.0</version.swagger>
        <version.swagger-ui>2.7.0</version.swagger-ui>
        <version.thrift>0.9.1</version.thrift>
        <version.tomcat-embed>8.5.27</version.tomcat-embed>
        <version.websocket-api>1.1</version.websocket-api>
        <version.zip4j>1.3.2</version.zip4j>
        <version.poi>3.12</version.poi>
        <version.scala>2.10.6</version.scala>
        <version.elasticsearch>2.1.0</version.elasticsearch>
        <version.elasticsearch-sql>2.4.1.0</version.elasticsearch-sql>
        <version.jest>2.4.0</version.jest>
        <version.alibaba-druid>1.0.15</version.alibaba-druid>
        <version.feign>9.5.0</version.feign>
        <version.hystrix>1.5.10</version.hystrix>
        <version.archaius>0.7.5</version.archaius>
        <version.ehr>1.2.0</version.ehr>
        <version.eip>1.3.1</version.eip>
        <version.json>20160212</version.json>
        <version.json-lib>2.4</version.json-lib>
        <version.fastjson>1.2.17</version.fastjson>
        <version.commons-net>3.3</version.commons-net>
        <version.jxl>2.6</version.jxl>
        <version.fastdfs>1.27</version.fastdfs>
        <version.spring.boot.admin>1.5.7</version.spring.boot.admin>
        <version.jettison>1.3.7</version.jettison>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!--<dependency>-->
                <!--<groupId>org.springframework.boot</groupId>-->
                <!--<artifactId>spring-boot-dependencies</artifactId>-->
                <!--<version>1.5.9.RELEASE</version>-->
                <!--<type>pom</type>-->
                <!--<scope>import</scope>-->
            <!--</dependency>-->
            <!--<dependency>-->
                <!--<groupId>org.springframework.cloud</groupId>-->
                <!--<artifactId>spring-cloud-dependencies</artifactId>-->
                <!--<version>Finchley.M5</version>-->
                <!--<type>pom</type>-->
                <!--<scope>import</scope>-->
            <!--</dependency>-->
            <!-- Base library-->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${version.servlet-api}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${version.junit}</version>
                <scope>test</scope>
            </dependency>
            <!-- Spring framework family -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-messaging</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-oxm</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${version.spring-framework}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka -->
            <dependency>
                <groupId>org.springframework.kafka</groupId>
                <artifactId>spring-kafka</artifactId>
                <version>${version.spring-kafka}</version>
            </dependency>
            <!-- Spring boot family -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-actuator</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-autoconfigure</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-batch</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${version.spring-boot}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb</artifactId>
                <version>${version.spring-boot}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Spring cloud family -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter</artifactId>
                <version>${version.spring-cloud-starter}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-config-server</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-archaius</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka-server</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-netflix-eureka</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zuul</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
                <version>${version.spring-cloud}</version>
            </dependency>
            <!-- Feign -->
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-core</artifactId>
                <version>${version.feign}</version>
            </dependency>
            <!-- Hystrix -->
            <dependency>
                <groupId>com.netflix.hystrix</groupId>
                <artifactId>hystrix-core</artifactId>
                <version>${version.hystrix}</version>
            </dependency>
            <!-- Archaius -->
            <dependency>
                <groupId>com.netflix.archaius</groupId>
                <artifactId>archaius-core</artifactId>
                <version>${version.archaius}</version>
            </dependency>
            <!-- Spring data family -->
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-commons</artifactId>
                <version>${version.spring-data-commons}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-hadoop-hbase</artifactId>
                <version>${version.spring-data-hadoop}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-solr</artifactId>
                <version>${version.spring-data-solr}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Spring session family-->
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-hazelcast</artifactId>
                <version>${version.spring-session-hazelcast}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session</artifactId>
                <version>${version.spring-session}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.session</groupId>
                <artifactId>spring-session-data-redis</artifactId>
                <version>${version.spring-session}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Spring Security -->
            <!--<dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-config</artifactId>
                <version>${version.spring-security}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-core</artifactId>
                <version>${version.spring-security}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-crypto</artifactId>
                <version>${version.spring-security}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-web</artifactId>
                <version>${version.spring-security}</version>
                <scope>${dependency.scope}</scope>
            </dependency>-->
            <!-- Oauth2 -->
            <dependency>
                <groupId>org.springframework.security.oauth</groupId>
                <artifactId>spring-security-oauth2</artifactId>
                <version>${version.spring-oauth2}</version>
                <scope>${dependency.scope}</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.security</groupId>
                        <artifactId>*</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--Jackson library -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>${version.jackson}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>${version.jackson}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${version.jackson}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Http library -->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpcore</artifactId>
                <version>${version.http-core}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>${version.http-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpmime</artifactId>
                <version>${version.http-mime}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!--Apache commons library -->
            <dependency>
                <groupId>org.codehaus.woodstox</groupId>
                <artifactId>stax2-api</artifactId>
                <version>3.1.4</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.codehaus.woodstox</groupId>
                <artifactId>woodstox-core-asl</artifactId>
                <version>4.4.1</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.noggit</groupId>
                <artifactId>noggit</artifactId>
                <version>0.6</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${version.commons-lang3}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>${version.poi}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
                <version>${version.commons-bean-utils}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
                <version>${version.commons-pool2}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>commons-dbutils</groupId>
                <artifactId>commons-dbutils</artifactId>
                <version>${version.commons-dbutils}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-dbcp2</artifactId>
                <version>${version.commons-dbcp2}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${version.commons-io}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${version.commons-collections}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>${version.commons-codec}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-compress</artifactId>
                <version>${version.commons-compress}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Mysql library -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${version.mysql}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Hibernate framework library -->
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>${version.hibernate}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>${version.hibernate-validator}</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>${version.hibernate}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.hibernate.javax.persistence</groupId>
                <artifactId>hibernate-jpa-2.1-api</artifactId>
                <version>${version.hibernate-jpa-api}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Zookeeper library -->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>${version.zookeeper}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Hadoop library -->
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-annotations</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-auth</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-common</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-distcp</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-hdfs</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-mapreduce-client-common</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-mapreduce-client-core</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-mapreduce-client-shuffle</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-streaming</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-yarn-api</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-yarn-client</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-yarn-common</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-yarn-server-common</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-yarn-server-nodemanager</artifactId>
                <version>${version.hadoop-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.hbase</groupId>
                <artifactId>hbase-client</artifactId>
                <version>${version.hbase-client}</version>
                <scope>${dependency.scope}</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.hadoop</groupId>
                        <artifactId>*</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.hbase</groupId>
                <artifactId>hbase-common</artifactId>
                <version>${version.hbase-client}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.hbase</groupId>
                <artifactId>hbase-protocol</artifactId>
                <version>${version.hbase-client}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- export library -->
            <dependency>
                <groupId>net.sourceforge.jexcelapi</groupId>
                <artifactId>jxl</artifactId>
                <version>${version.jxl}</version>
            </dependency>
            <!-- Google library -->
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>18.0</version>
            </dependency>
            <dependency>
                <groupId>com.google.code.findbugs</groupId>
                <artifactId>jsr305</artifactId>
                <version>3.0.1</version>
            </dependency>
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.6.2</version>
            </dependency>
            <dependency>
                <groupId>com.google.protobuf</groupId>
                <artifactId>protobuf-java</artifactId>
                <version>2.5.0</version>
            </dependency>
            <dependency>
                <groupId>com.google.inject</groupId>
                <artifactId>guice</artifactId>
                <version>4.1.0</version>
            </dependency>
            <!-- Solr library -->
            <dependency>
                <groupId>org.apache.solr</groupId>
                <artifactId>solr-core</artifactId>
                <version>${version.solr}</version>
                <scope>${dependency.scope}</scope>
                <exclusions>
                    <exclusion>
                        <groupId>commons-lang</groupId>
                        <artifactId>commons-lang</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.solr</groupId>
                <artifactId>solr-solrj</artifactId>
                <version>${version.solr}</version>
                <exclusions>
                    <exclusion>
                        <groupId>commons-lang</groupId>
                        <artifactId>commons-lang</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- Elasticsearch -->
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>${version.elasticsearch}</version>
            </dependency>
            <dependency>
                <groupId>org.nlpcn</groupId>
                <artifactId>elasticsearch-sql</artifactId>
                <version>${version.elasticsearch-sql}</version>
            </dependency>
            <!-- Jest -->
            <dependency>
                <groupId>io.searchbox</groupId>
                <artifactId>jest</artifactId>
                <version>${version.jest}</version>
            </dependency>
            <!-- Redis library -->
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>${version.jedis}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- FastDFS library -->
            <dependency>
                <groupId>org.csource</groupId>
                <artifactId>fastdfs-client-java</artifactId>
                <version>${version.fastdfs}</version>
            </dependency>
            <!-- Quartz library -->
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>${version.quartz}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz-jobs</artifactId>
                <version>${version.quartz}</version>
            </dependency>
            <!-- Zip library -->
            <dependency>
                <groupId>net.lingala.zip4j</groupId>
                <artifactId>zip4j</artifactId>
                <version>${version.zip4j}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Pinyin library -->
            <dependency>
                <groupId>com.belerweb</groupId>
                <artifactId>pinyin4j</artifactId>
                <version>${version.pinyin4j}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Swagger-ui library -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${version.swagger}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${version.swagger-ui}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- date Time util library -->
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
                <version>${version.joda-time}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.thrift</groupId>
                <artifactId>libthrift</artifactId>
                <version>${version.thrift}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>com.timgroup</groupId>
                <artifactId>java-statsd-client</artifactId>
                <version>${version.statsd-client}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>io.dropwizard.metrics</groupId>
                <artifactId>metrics-core</artifactId>
                <version>${version.io-dropwizard-metrics}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Log framework library -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>${version.logging}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${version.log4j}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${version.slf4j}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>${version.logback}</version>
                <scope>${dependency.scope}</scope>
            </dependency>
            <!-- Alibaba -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${version.alibaba-druid}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${version.fastjson}</version>
            </dependency>
            <!-- Spring Boot Admin -->
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-starter-server</artifactId>
                <version>${version.spring.boot.admin}</version>
            </dependency>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-server-ui</artifactId>
                <version>${version.spring.boot.admin}</version>
            </dependency>
            <!-- Extend library-->
            <dependency>
                <groupId>org.codehaus.jettison</groupId>
                <artifactId>jettison</artifactId>
                <version>${version.jettison}</version>
            </dependency>
            <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
                <version>${version.json}</version>
            </dependency>
            <dependency>
                <groupId>net.sf.json-lib</groupId>
                <artifactId>json-lib</artifactId>
                <version>${version.json-lib}</version>
            </dependency>
            <dependency>
                <groupId>commons-net</groupId>
                <artifactId>commons-net</artifactId>
                <version>${version.commons-net}</version>
            </dependency>
            <!-- 个推相关 -->
            <dependency>
                <groupId>com.gexin.platform</groupId>
                <artifactId>gexin-rp-sdk-http</artifactId>
                <version>4.0.1.17</version>
            </dependency>
            <dependency>
                <groupId>com.gexin.platform</groupId>
                <artifactId>gexin-rp-fastjson</artifactId>
                <version>1.0.0.1</version>
            </dependency>
            <dependency>
                <groupId>com.gexin.platform</groupId>
                <artifactId>gexin-rp-sdk-base</artifactId>
                <version>4.0.0.22</version>
            </dependency>
            <dependency>
                <groupId>com.gexin.platform</groupId>
                <artifactId>gexin-rp-sdk-template</artifactId>
                <version>4.0.0.16</version>
            </dependency>
            <dependency>
                <groupId>com.gexin.platform</groupId>
                <artifactId>protobuf-java</artifactId>
                <version>2.5.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <repositories>
        <repository>
            <id>public</id>
            <name>public</name>
            <url>http://172.19.103.43:8081/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>public</name>
            <url>http://172.19.103.43:8081/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
    <build>
        <extensions>
            <extension>
                <groupId>org.apache.maven.wagon</groupId>
                <artifactId>wagon-ssh</artifactId>
                <version>2.10</version>
            </extension>
            <extension>
                <groupId>org.apache.maven.wagon</groupId>
                <artifactId>wagon-http-lightweight</artifactId>
                <version>2.10</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArguments>
                        <verbose/>
                        <bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar</bootclasspath>
                    </compilerArguments>
                </configuration>
                <version>3.1</version>
            </plugin>
        </plugins>
    </build>
</project>

+ 606 - 0
ehr-ms-parent-pom/pom.xml

@ -0,0 +1,606 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.yihu.ehr</groupId>
        <artifactId>ehr-cloud</artifactId>
        <version>1.2.0</version>
        <relativePath>../ehr-cloud/pom.xml</relativePath>
    </parent>
    <artifactId>ehr-ms-parent-pom</artifactId>
    <packaging>pom</packaging>
    <description>EHR micro service parent pom</description>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.jooq</groupId>
                    <artifactId>jooq-codegen-maven</artifactId>
                    <version>${jooq.version}</version>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <version>1.7</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.5.1</version>
                    <configuration>
                        <recompressZippedFiles>false</recompressZippedFiles>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>2.5</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.10</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-eclipse-plugin</artifactId>
                    <version>2.9</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>2.18</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-help-plugin</artifactId>
                    <version>2.2</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>2.5</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <version>2.10.1</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.7</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>2.3</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.3</version>
                    <dependencies>
                        <dependency>
                            <groupId>org.apache.maven.doxia</groupId>
                            <artifactId>doxia-module-markdown</artifactId>
                            <version>1.5</version>
                        </dependency>
                    </dependencies>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>2.4</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.18.1</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.5</version>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>build-helper-maven-plugin</artifactId>
                    <version>1.9.1</version>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.3.2</version>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>versions-maven-plugin</artifactId>
                    <version>2.2</version>
                </plugin>
                <plugin>
                    <groupId>pl.project13.maven</groupId>
                    <artifactId>git-commit-id-plugin</artifactId>
                    <version>2.1.11</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${version.spring-boot}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <version>2.17</version>
                <executions>
                    <execution>
                        <id>checkstyle-validation</id>
                        <phase>validate</phase>
                        <configuration>
                            <skip>true</skip>
                            <configLocation>src/checkstyle/checkstyle.xml</configLocation>
                            <suppressionsLocation>src/checkstyle/checkstyle-suppressions.xml</suppressionsLocation>
                            <headerLocation>src/checkstyle/checkstyle-header.txt</headerLocation>
                            <propertyExpansion>checkstyle.build.directory=${project.build.directory}</propertyExpansion>
                            <encoding>UTF-8</encoding>
                            <consoleOutput>true</consoleOutput>
                            <failsOnError>true</failsOnError>
                            <includeTestSourceDirectory>true</includeTestSourceDirectory>
                        </configuration>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${version.java}</source>
                    <target>${version.java}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <id>enforce-rules</id>
                        <goals>
                            <goal>enforce</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <requireJavaVersion>
                                    <version>[1.8,)</version>
                                </requireJavaVersion>
                                <!--<requireProperty>
                                    <property>main.basedir</property>
                                </requireProperty>-->
                                <!--<requireProperty>
                                    <property>project.organization.name</property>
                                </requireProperty>-->
                                <!--<requireProperty>
                                    <property>project.name</property>
                                </requireProperty>-->
                                <!--<requireProperty>
                                    <property>project.description</property>
                                </requireProperty>-->
                            </rules>
                            <fail>true</fail>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                            <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>**/*Tests.java</include>
                    </includes>
                    <excludes>
                        <exclude>**/Abstract*.java</exclude>
                    </excludes>
                    <!--<systemPropertyVariables>-->
                    <!--<java.security.egd>file:/dev/./urandom</java.security.egd>-->
                    <!--<java.awt.headless>true</java.awt.headless>-->
                    <!--</systemPropertyVariables>-->
                    <argLine>-Xmx1024m</argLine>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <!--<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>animal-sniffer-maven-plugin</artifactId>
                <configuration>
                    <skip>${disable.checks}</skip>
                    <signature>
                        <groupId>org.codehaus.mojo.signature</groupId>
                        <artifactId>java16</artifactId>
                        <version>1.0</version>
                    </signature>
                    <annotations>
                        <annotation>org.springframework.lang.UsesJava8</annotation>
                        <annotation>org.springframework.lang.UsesJava7</annotation>
                        <annotation>org.springframework.boot.lang.UsesUnsafeJava</annotation>
                    </annotations>
                </configuration>
                <executions>
                    <execution>
                        <id>enforce-java-6</id>
                        <phase>test</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>-->
        </plugins>
    </build>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-admin-gateway-model</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-data-elasticsearch</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-data-fastdfs</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-data-hbase</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-data-mysql</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-data-query</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-data-redis</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-data-solr</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-ehr-constants</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-entity</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <!--<dependency>-->
            <!--<groupId>com.yihu.ehr</groupId>-->
            <!--<artifactId>commons-metrics</artifactId>-->
            <!--<version>${version.ehr}</version>-->
            <!--</dependency>-->
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-profile-core</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-redis-mq</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-rest-model</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.hos</groupId>
                <artifactId>common-rest-model</artifactId>
                <version>${version.eip}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-ui-swagger</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-util</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-web</artifactId>
                <version>${version.ehr}</version>
            </dependency>
            <!--<dependency>
                <groupId>com.yihu.ehr</groupId>
                <artifactId>commons-metrics</artifactId>
                <version>${version.ehr}</version>
            </dependency>-->
        </dependencies>
    </dependencyManagement>
    <!--
    profiles分为三种场景(dev,test,prod),三种部署模式(jar,war,docker).预计是9种模式,
    但目前仅使用到dev,test,prod的jar,test的war.若有需要可以组合配置这些部署模式.
    - dev的可执行jar包,在本机调试,不需要配置wagon参数。
    - test,prod的可执行jar包,需要在编译后传送到服务器上部署,故需配置wagon参数,参数可根据服务需要自行配置。
    - dev,test,prod的war包,编译后使用tomcat api部署,故需配置tomcat参数,参数可根据服务需要自行配置。
    -->
    <profiles>
        <profile>
            <id>dev-jar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <skipTests>true</skipTests>
                <packaging.type>jar</packaging.type>
                <dependency.scope>compile</dependency.scope>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </dependency>
                <!--<dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-devtools</artifactId>
                    <scope>${dependency.scope}</scope>
                </dependency>-->
            </dependencies>
        </profile>
        <profile>
            <id>test-jar</id>
            <properties>
                <skipTests>true</skipTests>
                <packaging.type>jar</packaging.type>
                <dependency.scope>compile</dependency.scope>
                <wagonServerId/>
                <wagonUrl/>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>wagon-maven-plugin</artifactId>
                        <version>1.0</version>
                        <configuration>
                            <serverId>${wagonServerId}</serverId>
                            <fromFile>${project.build.directory}/${project.build.finalName}.jar</fromFile>
                            <url>${wagonUrl}</url>
                            <commands>
                                <command>pkill -f ${project.build.finalName}.jar</command>
                                <command>nohub java -Djava.security.egd=file:/dev/./urandom -jar
                                    ${project.build.finalName}.jar &amp;
                                </command>
                            </commands>
                            <displayCommandOutputs>true</displayCommandOutputs>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                    <exclusions>
                        <exclusion>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-starter-logging</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-devtools</artifactId>
                    <scope>${dependency.scope}</scope>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>test-war</id>
            <activation>
                <property>
                    <name>spring.profiles.active</name>
                    <value>default,test</value>
                </property>
            </activation>
            <properties>
                <skipTests>true</skipTests>
                <packaging.type>war</packaging.type>
                <dependency.scope>provided</dependency.scope>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                    <scope>${dependency.scope}</scope>
                    <exclusions>
                        <exclusion>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-starter-logging</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <scope>${dependency.scope}</scope>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-devtools</artifactId>
                    <scope>${dependency.scope}</scope>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.tomcat.maven</groupId>
                        <artifactId>tomcat7-maven-plugin</artifactId>
                        <version>2.2</version>
                        <configuration>
                            <url>http://localhost:8080/manager/text</url>
                            <server>tomcat8</server>
                            <username>deployer</username>
                            <password>jkzldeployer</password>
                            <path>/${project.artifactId}</path>
                            <update>true</update>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>prod-jar</id>
            <activation>
                <property>
                    <name>spring.profiles.active</name>
                    <value>default,prod</value>
                </property>
            </activation>
            <properties>
                <skipTests>true</skipTests>
                <packaging.type>war</packaging.type>
                <dependency.scope>compile</dependency.scope>
                <wagonServerId>11.1.2.21</wagonServerId>
                <wagonUrl>scp://user:password@11.1.2.21/home/root/ehr-release</wagonUrl>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                    <scope>${dependency.scope}</scope>
                    <exclusions>
                        <exclusion>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-starter-logging</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>prod-war</id>
            <properties>
                <skipTests>true</skipTests>
                <packaging.type>war</packaging.type>
                <dependency.scope>provided</dependency.scope>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                    <scope>${dependency.scope}</scope>
                    <exclusions>
                        <exclusion>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-starter-logging</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <scope>${dependency.scope}</scope>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-devtools</artifactId>
                    <scope>${dependency.scope}</scope>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

+ 98 - 0
pom.xml

@ -0,0 +1,98 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.yihu.ehr</groupId>
        <artifactId>ehr-ms-parent-pom</artifactId>
        <version>1.2.0</version>
        <relativePath>ehr-ms-parent-pom/pom.xml</relativePath>
    </parent>
    <artifactId>svr-redis</artifactId>
    <!--<packaging>${packaging.type}</packaging>-->
    <packaging>war</packaging>
    <properties>
        <wagonServerId>192.168.1.220</wagonServerId>
        <wagonUrl>scp://sand:timeneverstop@192.168.1.221/home/sand/ehr-release</wagonUrl>
    </properties>
    <dependencies>
        <!-- true -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>${dependency.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <scope>${dependency.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
            <scope>${dependency.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <scope>${dependency.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>${dependency.scope}</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-ehr-constants</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-util</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-data-mysql</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-rest-model</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-data-redis</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-ui-swagger</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-web</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.yihu.ehr</groupId>
            <artifactId>commons-entity</artifactId>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

+ 42 - 0
src/main/java/com/yihu/ehr/RedisServiceApp.java

@ -0,0 +1,42 @@
package com.yihu.ehr;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;
@Configuration
@EnableAutoConfiguration(exclude = {
        SecurityAutoConfiguration.class})
@ComponentScan
@EnableDiscoveryClient
@EnableFeignClients
@EnableScheduling
public class RedisServiceApp extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication();
        app.run(RedisServiceApp.class, args);
    }
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(RedisServiceApp.class);
    }
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

+ 79 - 0
src/main/java/com/yihu/ehr/kafka/ConsumerRunner.java

@ -0,0 +1,79 @@
package com.yihu.ehr.kafka;
import com.yihu.ehr.lang.SpringContext;
import com.yihu.ehr.redis.pubsub.entity.RedisMqSubscriber;
import com.yihu.ehr.redis.pubsub.service.RedisMqSubscriberService;
import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
 * Created by progr1mmer on 2018/8/2.
 */
public class ConsumerRunner implements Runnable {
    private KafkaConsumer<String, String> consumer;
    private List<RedisMqSubscriber> redisMqSubscribers;
    private RestTemplate restTemplate;
    public ConsumerRunner(String groupId, Set<String> topics) throws Exception {
        Assert.notEmpty(topics, "Topic cannot be empty");
        init(groupId, topics);
    }
    private void init(String groupId, Set<String> topics) throws Exception {
        Properties props = new Properties();
        Environment environment = SpringContext.getService(Environment.class);
        props.put("bootstrap.servers", environment.getProperty("spring.kafka.bootstrap-servers", "localhost:9092"));
        props.put("group.id", groupId);
        props.put("enable.auto.commit", "false");
        props.put("auto.commit.interval.ms", "1000");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        List<String> _topics = new ArrayList<>();
        _topics.addAll(topics);
        consumer = new KafkaConsumer<>(props);
        consumer.subscribe(_topics);
        RedisMqSubscriberService redisMqSubscriberService = SpringContext.getService(RedisMqSubscriberService.class);
        redisMqSubscribers = redisMqSubscriberService.search("appId=" + groupId + ";channel=" + StringUtils.join(_topics, ","));
        restTemplate = SpringContext.getService("restTemplate");
    }
    @Override
    public void run() {
        while (true) {
            ConsumerRecords<String, String> records = consumer.poll(1000);
            for (ConsumerRecord<String, String> record : records) {
                System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
                for (RedisMqSubscriber subscriber : redisMqSubscribers) {
                    if (record.topic().equals(subscriber.getChannel())) {
                        String subscribedUrl = subscriber.getSubscribedUrl();
                        try {
                            // 推送消息到指定服务地址
                            HttpHeaders headers = new HttpHeaders();
                            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                            HttpEntity<String> entity = new HttpEntity<>(record.offset() + ":" + record.key() + ":" + record.value(), headers);
                            restTemplate.postForObject(subscribedUrl, entity, String.class);
                            consumer.commitSync();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                    }
                }
            }
        }
    }
}

+ 52 - 0
src/main/java/com/yihu/ehr/kafka/MessageManager.java

@ -0,0 +1,52 @@
package com.yihu.ehr.kafka;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import com.yihu.ehr.redis.pubsub.entity.RedisMqSubscriber;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import com.yihu.ehr.redis.pubsub.service.RedisMqSubscriberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * Created by progr1mmer on 2018/8/2.
 */
//@Component
public class MessageManager {
    private ExecutorService executorService;
    @Autowired
    private RedisMqChannelService redisMqChannelService;
    @Autowired
    private RedisMqSubscriberService redisMqSubscriberService;
    public void initConsumer () {
        try {
            Map<String, Set<String>> groups = new HashMap<>();
            List<RedisMqChannel> channels = redisMqChannelService.search("");
            for (RedisMqChannel channel : channels) {
                List<RedisMqSubscriber> redisMqSubscribers = redisMqSubscriberService.search("channel=" + channel.channel);
                redisMqSubscribers.forEach(item -> {
                    if (groups.containsKey(item.getAppId())) {
                        groups.get(item.getAppId()).add(item.getChannel());
                    } else {
                        Set<String> topics = new HashSet<>();
                        topics.add(item.getChannel());
                        groups.put(item.getAppId(), topics);
                    }
                });
            }
            executorService = Executors.newFixedThreadPool(groups.size());
            for (String key : groups.keySet()) {
                executorService.execute(new ConsumerRunner(key, groups.get(key)));
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

+ 52 - 0
src/main/java/com/yihu/ehr/listener/ApplicationReadyListener.java

@ -0,0 +1,52 @@
package com.yihu.ehr.listener;
import com.yihu.ehr.redis.pubsub.CustomMessageListenerAdapter;
import com.yihu.ehr.redis.pubsub.MessageCommonBiz;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.util.List;
/**
 * SpringBoot 启动完成的监听器
 *
 * @author 张进军
 * @date 2017/11/14 17:48
 */
@Component
public class ApplicationReadyListener implements ApplicationListener<ApplicationReadyEvent> {
    @Autowired
    private RedisMessageListenerContainer redisMessageListenerContainer;
    @Autowired
    private RedisMqChannelService redisMqChannelService;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        try {
            // 添加消息队列的监听器
            List<RedisMqChannel> channelList = redisMqChannelService.search("");
            for (RedisMqChannel channel : channelList) {
                ChannelTopic topic = new ChannelTopic(channel.getChannel());
                CustomMessageListenerAdapter messageListener = MessageCommonBiz.newCustomMessageListenerAdapter(channel.getChannel());
                redisMessageListenerContainer.addMessageListener(messageListener, topic);
                try {
                    // 每次添加channel监听器都会flush,这需要点时间。
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

+ 66 - 0
src/main/java/com/yihu/ehr/redis/RedisSubscribeMessageEndPoint.java

@ -0,0 +1,66 @@
package com.yihu.ehr.redis;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.redis.cache.CacheCommonBiz;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyRule;
import com.yihu.ehr.redis.cache.entity.RedisCacheResponseTimeLog;
import com.yihu.ehr.redis.cache.service.RedisCacheKeyRuleService;
import com.yihu.ehr.redis.cache.service.RedisCacheResponseTimeLogService;
import com.yihu.ehr.util.id.UuidUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
 * @author 张进军
 * @date 2017/12/4 15:19
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "接收消息队列的消息订阅接口", tags = {"缓存服务管理--接收消息队列的消息订阅接口"})
public class RedisSubscribeMessageEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisCacheResponseTimeLogService responseTimeLogService;
    @Autowired
    private RedisCacheKeyRuleService keyRuleService;
    @ApiOperation("记录缓存获取接口的响应时间")
    @RequestMapping(value = ServiceApi.Redis.SubscribeMessage.ReceiveResponseTime, method = RequestMethod.POST)
    public void receiveResponseTime(
            @ApiParam(value = "消息", required = true)
            @RequestBody String message) {
        try {
            Map<String, Object> messageMap = objectMapper.readValue(message, Map.class);
            String keyRuleCode = messageMap.get("keyRuleCode").toString();
            String ruleParams = messageMap.get("ruleParams") == null ? "" : messageMap.get("ruleParams").toString();
            int responseTime = (Integer) messageMap.get("responseTime");
            RedisCacheKeyRule redisCacheKeyRule = keyRuleService.findByCode(keyRuleCode);
            if (redisCacheKeyRule != null) {
                String categoryCode = redisCacheKeyRule.getCategoryCode();
                String keyRuleExpression = redisCacheKeyRule.getExpression();
                String key = CacheCommonBiz.generateKey(keyRuleExpression, ruleParams, categoryCode);
                RedisCacheResponseTimeLog responseTimeLog = new RedisCacheResponseTimeLog();
                responseTimeLog.setId(UuidUtil.randomUUID());
                responseTimeLog.setCacheKey(key);
                responseTimeLog.setCategoryCode(categoryCode);
                responseTimeLog.setResponseTime(responseTime);
                responseTimeLogService.save(responseTimeLog);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

+ 212 - 0
src/main/java/com/yihu/ehr/redis/cache/CacheCommonBiz.java

@ -0,0 +1,212 @@
package com.yihu.ehr.redis.cache;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.constants.ErrorCode;
import com.yihu.ehr.exception.ApiException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * 缓存服务共通类
 *
 * @author 张进军
 * @date 2017/12/1 14:00
 */
public class CacheCommonBiz {
    /**
     * 制造缓存Key前缀 = 缓存分类编码 + :
     *
     * @param categoryCode 缓存分类编码
     * @return 缓存Key前缀
     */
    public static String makeKeyPrefix(String categoryCode) {
        return categoryCode + ":";
    }
    /**
     * 生成Redis缓存的唯一key
     * 最终生成的key = 前缀 + 填充值的Key规则
     *
     * @param keyRule       Key规则表达式
     * @param keyRuleParams Key规则命名参数的值
     * @param categoryCode  缓存分类编码
     * @return 缓存的 key
     * @throws Exception
     */
    public static String generateKey(String keyRule, String keyRuleParams, String categoryCode) throws Exception {
        String errorMsg = "";
        ObjectMapper objectMapper = new ObjectMapper();
        List<String> paramNames = parseParamNames(keyRule);
        String key = keyRule;
        if (paramNames.size() != 0) {
            if (StringUtils.isEmpty(keyRuleParams)) {
                errorMsg = "Key规则表达式中有命名参数,则Key规则命名参数的值必传。";
                throw new ApiException(ErrorCode.BAD_REQUEST, errorMsg);
            }
            Map<String, Object> paramValues = objectMapper.readValue(keyRuleParams, Map.class);
            for (int i = 0, length = paramNames.size(); i < length; i++) {
                String paramName = paramNames.get(i);
                Object paramValue = paramValues.get(paramName);
                if (paramValue == null) {
                    errorMsg = "命名参数 " + paramName + " 缺少值,或参数名错误。";
                    throw new ApiException(ErrorCode.BAD_REQUEST, errorMsg);
                } else {
                    key = key.replace("{" + paramName + "}", paramValue.toString());
                }
            }
        }
        key = makeKeyPrefix(categoryCode) + key;
        return key;
    }
    /**
     * 校验缓存Key规则表达式
     * <p>
     * 例:规则 xxx{a}xx{b}{c}
     * 说明:
     * 1.a、b、c 代表三个命名参数,参数用"{}"包含起来。是否需要定义参数,根据业务而定。
     * 2.x 代表任意字符,可有可无,根据业务自行定义。
     *
     * @param keyRule
     * @return
     */
    public static boolean validateKeyRule(String keyRule) throws ApiException {
        String errorMsg = "";
        if (!keyRule.contains("{") && !keyRule.contains("}")) {
            return true;
        }
        int leftBraceNum = countLeftBrace(keyRule);
        int rightBraceNum = countRightBrace(keyRule);
        int preIndex = 0;
        while (preIndex != -1) {
            int start = keyRule.indexOf("{", preIndex);
            int end = keyRule.indexOf("}", preIndex);
            // 大括号只用于包含参数名
            int innerStart = keyRule.indexOf("{", start + 1);
            if (leftBraceNum != rightBraceNum || (innerStart != -1 && innerStart < end)) {
                errorMsg = "大括号\"{\"、\"}\"只能用于包裹参数名,参数名中或其他地方不能使用。";
                throw new ApiException(ErrorCode.BAD_REQUEST, errorMsg);
            }
            // 参数名不能为空
            if (start == end - 1) {
                errorMsg = "大括号中参数名不能为空。";
                throw new ApiException(ErrorCode.BAD_REQUEST, errorMsg);
            }
            preIndex = keyRule.indexOf("{", end + 1);
        }
        return true;
    }
    /**
     * 解析Key规则中的占位参数名
     *
     * @param keyRule Key规则表达式
     * @return 占位参数名集合
     */
    public static List<String> parseParamNames(String keyRule) {
        List<String> paramNames = new ArrayList<>();
        if (!keyRule.contains("{") && !keyRule.contains("}")) {
            return paramNames;
        }
        int preIndex = 0;
        while (preIndex != -1) {
            int start = keyRule.indexOf("{", preIndex);
            int end = keyRule.indexOf("}", preIndex);
            String paramName = keyRule.substring(start + 1, end);
            paramNames.add(paramName);
            preIndex = keyRule.indexOf("{", end + 1);
        }
        return paramNames;
    }
    /**
     * 将缓存Key规则中的参数名(包括大括号)替换为指定字符串
     *
     * @param keyRule     Key规则
     * @param replacement 代替的字符串
     * @return 替换后的字符串
     */
    public static String replaceParams(String keyRule, String replacement) {
        if (!keyRule.contains("{") && !keyRule.contains("}")) {
            return keyRule;
        }
        int preIndex = 0;
        while (preIndex != -1) {
            int start = keyRule.indexOf("{", preIndex);
            int end = keyRule.indexOf("}", preIndex);
            int len = end - start - 1;
            String regex = "\\{.{1," + len + "}\\}";
            keyRule = keyRule.replaceFirst(regex, replacement);
            preIndex = keyRule.indexOf("{", start + replacement.length());
        }
        return keyRule;
    }
    /**
     * 统计Key规则中左大括号个数
     *
     * @param keyRule Key规则
     * @return 左大括号个数
     */
    private static int countLeftBrace(String keyRule) {
        int sum = 0;
        while (keyRule.contains("{")) {
            keyRule = keyRule.replaceFirst("\\{", "");
            sum += 1;
        }
        return sum;
    }
    /**
     * 统计Key规则中右大括号个数
     *
     * @param keyRule Key规则
     * @return 右大括号个数
     */
    private static int countRightBrace(String keyRule) {
        int sum = 0;
        while (keyRule.contains("}")) {
            keyRule = keyRule.replaceFirst("\\}", "");
            sum += 1;
        }
        return sum;
    }
    // 测试
    /*public static void main(String[] args) {
//        String keyRule = "zjj"; // yes
        String keyRule = "zjj.{aa}xx{b}xx"; // yes
//        String keyRule = "zjj.{aa{a}a}"; // no
//        String keyRule = "zjj.{aa{a}"; // no
//        String keyRule = "zjj.{a}{"; // no
//        String keyRule = "zjj.{a}{"; // no
//        String keyRule = "zjj.{}{a}"; // no
//        validateKeyRule(keyRule);
        String newKeyRule = replaceParams(keyRule, "*");
//        System.out.println(newKeyRule);
    }*/
}

+ 75 - 0
src/main/java/com/yihu/ehr/redis/cache/CacheResponseTimeAspect.java

@ -0,0 +1,75 @@
package com.yihu.ehr.redis.cache;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import com.yihu.ehr.util.rest.Envelop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * 记录缓存获取的响应时间
 *
 * @author 张进军
 * @date 2017/12/1 14:23
 */
@Aspect
@Component
public class CacheResponseTimeAspect {
    @Value("${ehr-redis.mq.pubsub.publisherAppId}")
    private String publisherAppId;
    @Value("${ehr-redis.mq.pubsub.responseTimeChannel}")
    private String responseTimeChannel;
    @Autowired
    private RedisMqChannelService redisMqChannelService;
    @Autowired
    private ObjectMapper objectMapper;
    private long startTime;
    private long endTime;
    private boolean resultFlag;
    @Before("execution(* com.yihu.ehr.redis.cache.controller.RedisCacheOperationEndPoint.get(..))")
    public void doBefore(JoinPoint point) {
        startTime = System.currentTimeMillis();
    }
    @Around("execution(* com.yihu.ehr.redis.cache.controller.RedisCacheOperationEndPoint.get(..))")
    public void doAround(ProceedingJoinPoint point) throws Throwable {
        Envelop backEnvelop = (Envelop) point.proceed();
        resultFlag = backEnvelop.isSuccessFlg();
    }
    @After("execution(* com.yihu.ehr.redis.cache.controller.RedisCacheOperationEndPoint.get(..))")
    public void doAfter(JoinPoint point) throws Throwable {
        try {
            if (resultFlag) {
                endTime = System.currentTimeMillis();
                String keyRuleCode = point.getArgs()[0].toString();
                String ruleParams = point.getArgs()[1] == null ? "" : point.getArgs()[1].toString();
                Map<String, Object> messageMap = new HashMap<>();
                messageMap.put("keyRuleCode", keyRuleCode);
                messageMap.put("ruleParams", ruleParams);
                messageMap.put("responseTime", endTime - startTime);
                String message = objectMapper.writeValueAsString(messageMap);
                redisMqChannelService.sendMessage(publisherAppId, responseTimeChannel, message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

+ 168 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheAuthorizationEndPoint.java

@ -0,0 +1,168 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.model.redis.MRedisCacheAuthorization;
import com.yihu.ehr.redis.cache.entity.RedisCacheAuthorization;
import com.yihu.ehr.redis.cache.service.RedisCacheAuthorizationService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
 * 缓存授权 接口
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "缓存授权接口", tags = {"缓存服务管理--缓存授权接口"})
public class RedisCacheAuthorizationEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisCacheAuthorizationService redisCacheAuthorizationService;
    @ApiOperation("根据ID获取缓存授权")
    @RequestMapping(value = ServiceApi.Redis.CacheAuthorization.GetById, method = RequestMethod.GET)
    public Envelop getById(
            @ApiParam(name = "id", value = "主键", required = true)
            @PathVariable(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            MRedisCacheAuthorization mRedisCacheAuthorization = convertToModel(redisCacheAuthorizationService.getById(id), MRedisCacheAuthorization.class);
            envelop.setObj(mRedisCacheAuthorization);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取缓存授权。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存授权发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "根据条件获取缓存授权")
    @RequestMapping(value = ServiceApi.Redis.CacheAuthorization.Search, method = RequestMethod.GET)
    public Envelop search(
            @ApiParam(name = "fields", value = "返回的字段,为空则返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "筛选条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "页码", defaultValue = "1")
            @RequestParam(value = "page", required = false) int page,
            @ApiParam(name = "size", value = "分页大小", defaultValue = "15")
            @RequestParam(value = "size", required = false) int size) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            List<RedisCacheAuthorization> redisCacheAuthorization = redisCacheAuthorizationService.search(fields, filters, sorts, page, size);
            int count = (int) redisCacheAuthorizationService.getCount(filters);
            List<MRedisCacheAuthorization> mRedisCacheAuthorization = (List<MRedisCacheAuthorization>) convertToModels(redisCacheAuthorization, new ArrayList<MRedisCacheAuthorization>(), MRedisCacheAuthorization.class, fields);
            envelop = getPageResult(mRedisCacheAuthorization, count, page, size);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取缓存授权列表。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存授权发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("新增缓存授权")
    @RequestMapping(value = ServiceApi.Redis.CacheAuthorization.Save, method = RequestMethod.POST)
    public Envelop add(
            @ApiParam(value = "缓存授权JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheAuthorization newEntity = objectMapper.readValue(entityJson, RedisCacheAuthorization.class);
            newEntity = redisCacheAuthorizationService.save(newEntity);
            MRedisCacheAuthorization mRedisCacheAuthorization = convertToModel(newEntity, MRedisCacheAuthorization.class);
            envelop.setObj(mRedisCacheAuthorization);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功新增缓存授权。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("新增缓存授权发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("更新缓存授权")
    @RequestMapping(value = ServiceApi.Redis.CacheAuthorization.Save, method = RequestMethod.PUT)
    public Envelop update(
            @ApiParam(value = "缓存授权JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheAuthorization updateEntity = objectMapper.readValue(entityJson, RedisCacheAuthorization.class);
            updateEntity = redisCacheAuthorizationService.save(updateEntity);
            MRedisCacheAuthorization mRedisCacheAuthorization = convertToModel(updateEntity, MRedisCacheAuthorization.class);
            envelop.setObj(mRedisCacheAuthorization);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功更新缓存授权。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("更新缓存授权发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("删除缓存授权")
    @RequestMapping(value = ServiceApi.Redis.CacheAuthorization.Delete, method = RequestMethod.DELETE)
    public Envelop delete(
            @ApiParam(name = "id", value = "缓存授权ID", required = true)
            @RequestParam(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            redisCacheAuthorizationService.delete(id);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功删除缓存授权。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("删除缓存授权发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证指定缓存分类下应用ID是否唯一")
    @RequestMapping(value = ServiceApi.Redis.CacheAuthorization.IsUniqueAppId, method = RequestMethod.GET)
    public Envelop isUniqueAppId(
            @ApiParam(name = "id", value = "缓存授权ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "categoryCode", value = "缓存分类编码", required = true)
            @RequestParam(value = "categoryCode") String categoryCode,
            @ApiParam(name = "appId", value = "应用ID", required = true)
            @RequestParam(value = "appId") String appId) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisCacheAuthorizationService.isUniqueAppId(id, categoryCode, appId);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("当前缓存分类下的当前应用ID已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
}

+ 219 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheCategoryEndPoint.java

@ -0,0 +1,219 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.model.redis.MRedisCacheCategory;
import com.yihu.ehr.redis.cache.entity.RedisCacheCategory;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyRule;
import com.yihu.ehr.redis.cache.service.RedisCacheCategoryService;
import com.yihu.ehr.redis.cache.service.RedisCacheKeyRuleService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
 * 缓存分类 接口
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "缓存分类接口", tags = {"缓存服务管理--缓存分类接口"})
public class RedisCacheCategoryEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisCacheCategoryService redisCacheCategoryService;
    @Autowired
    private RedisCacheKeyRuleService redisCacheKeyRuleService;
    @ApiOperation("根据ID获取缓存分类")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.GetById, method = RequestMethod.GET)
    public Envelop getById(
            @ApiParam(name = "id", value = "主键", required = true)
            @PathVariable(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            MRedisCacheCategory mRedisCacheCategory = convertToModel(redisCacheCategoryService.getById(id), MRedisCacheCategory.class);
            envelop.setObj(mRedisCacheCategory);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取缓存分类。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存分类发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "根据条件获取缓存分类")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.Search, method = RequestMethod.GET)
    public Envelop search(
            @ApiParam(name = "fields", value = "返回的字段,为空则返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "筛选条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "页码", defaultValue = "1")
            @RequestParam(value = "page", required = false) int page,
            @ApiParam(name = "size", value = "分页大小", defaultValue = "15")
            @RequestParam(value = "size", required = false) int size) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            List<RedisCacheCategory> redisCacheCategoryList = redisCacheCategoryService.search(fields, filters, sorts, page, size);
            int count = (int) redisCacheCategoryService.getCount(filters);
            List<MRedisCacheCategory> mRedisCacheCategoryList = (List<MRedisCacheCategory>) convertToModels(redisCacheCategoryList, new ArrayList<MRedisCacheCategory>(), MRedisCacheCategory.class, fields);
            envelop = getPageResult(mRedisCacheCategoryList, count, page, size);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取缓存分类列表。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存分类发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "根据条件获取缓存分类(不分页)")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.SearchNoPage, method = RequestMethod.GET)
    public Envelop searchNoPage(
            @ApiParam(name = "filters", value = "筛选条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序")
            @RequestParam(value = "sorts", required = false) String sorts) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            List<RedisCacheCategory> redisCacheCategoryList = redisCacheCategoryService.search(filters, sorts);
            envelop.setDetailModelList(redisCacheCategoryList);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取缓存分类列表。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存分类发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("新增缓存分类")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.Save, method = RequestMethod.POST)
    public Envelop add(
            @ApiParam(value = "缓存分类JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheCategory newEntity = objectMapper.readValue(entityJson, RedisCacheCategory.class);
            newEntity = redisCacheCategoryService.save(newEntity);
            MRedisCacheCategory mRedisCacheCategory = convertToModel(newEntity, MRedisCacheCategory.class);
            envelop.setObj(mRedisCacheCategory);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功新增缓存分类。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("新增缓存分类发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("更新缓存分类")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.Save, method = RequestMethod.PUT)
    public Envelop update(
            @ApiParam(value = "缓存分类JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheCategory updateEntity = objectMapper.readValue(entityJson, RedisCacheCategory.class);
            updateEntity = redisCacheCategoryService.save(updateEntity);
            MRedisCacheCategory mRedisCacheCategory = convertToModel(updateEntity, MRedisCacheCategory.class);
            envelop.setObj(mRedisCacheCategory);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功更新缓存分类。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("更新缓存分类发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("删除缓存分类")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.Delete, method = RequestMethod.DELETE)
    public Envelop delete(
            @ApiParam(name = "id", value = "缓存分类ID", required = true)
            @RequestParam(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheCategory category = redisCacheCategoryService.getById(id);
            List<RedisCacheKeyRule> redisCacheKeyRuleList = redisCacheKeyRuleService.findByCategoryCode(category.getCode());
            if (redisCacheKeyRuleList.size() > 0) {
                envelop.setSuccessFlg(false);
                envelop.setErrorMsg("该缓存分类已有 Key 规则在使用,请确认清理对应 Key 规则之后,再来删除该缓存分类。");
            } else {
                redisCacheCategoryService.delete(id, category.getCode());
                envelop.setSuccessFlg(true);
                envelop.setErrorMsg("成功删除缓存分类。");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("删除缓存分类发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证缓存分类名称是否唯一")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.IsUniqueName, method = RequestMethod.GET)
    public Envelop isUniqueName(
            @ApiParam(name = "id", value = "缓存分类ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "name", value = "缓存分类名称", required = true)
            @RequestParam(value = "name") String name) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisCacheCategoryService.isUniqueName(id, name);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该缓存分类名称已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证缓存分类编码是否唯一")
    @RequestMapping(value = ServiceApi.Redis.CacheCategory.IsUniqueCode, method = RequestMethod.GET)
    public Envelop isUniqueCode(
            @ApiParam(name = "id", value = "缓存分类ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "code", value = "缓存分类编码", required = true)
            @RequestParam(value = "code") String code) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisCacheCategoryService.isUniqueCode(id, code);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该缓存分类编码已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
}

+ 221 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheKeyRuleEndPoint.java

@ -0,0 +1,221 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.model.redis.MRedisCacheKeyRule;
import com.yihu.ehr.redis.cache.CacheCommonBiz;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyRule;
import com.yihu.ehr.redis.cache.service.RedisCacheKeyRuleService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
 * 缓存Key规则 接口
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "缓存Key规则接口", tags = {"缓存服务管理--缓存Key规则接口"})
public class RedisCacheKeyRuleEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisCacheKeyRuleService redisCacheKeyRuleService;
    @ApiOperation("根据ID获取缓存Key规则")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.GetById, method = RequestMethod.GET)
    public Envelop getById(
            @ApiParam(name = "id", value = "主键", required = true)
            @PathVariable(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            MRedisCacheKeyRule mRedisCacheKeyRule = convertToModel(redisCacheKeyRuleService.getById(id), MRedisCacheKeyRule.class);
            envelop.setObj(mRedisCacheKeyRule);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取缓存Key规则。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存Key规则发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "根据条件获取缓存Key规则")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.Search, method = RequestMethod.GET)
    public Envelop search(
            @ApiParam(name = "fields", value = "返回的字段,为空则返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "筛选条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "页码", defaultValue = "1")
            @RequestParam(value = "page", required = false) int page,
            @ApiParam(name = "size", value = "分页大小", defaultValue = "15")
            @RequestParam(value = "size", required = false) int size) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            List<RedisCacheKeyRule> redisCacheKeyRuleList = redisCacheKeyRuleService.search(fields, filters, sorts, page, size);
            int count = (int) redisCacheKeyRuleService.getCount(filters);
            List<MRedisCacheKeyRule> mRedisCacheKeyRule = (List<MRedisCacheKeyRule>) convertToModels(redisCacheKeyRuleList, new ArrayList<MRedisCacheKeyRule>(), MRedisCacheKeyRule.class, fields);
            envelop = getPageResult(mRedisCacheKeyRule, count, page, size);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取缓存Key规则列表。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存Key规则发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("新增缓存Key规则")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.Save, method = RequestMethod.POST)
    public Envelop add(
            @ApiParam(value = "缓存Key规则JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheKeyRule newEntity = objectMapper.readValue(entityJson, RedisCacheKeyRule.class);
            CacheCommonBiz.validateKeyRule(newEntity.getExpression());
            String simpleExpression = CacheCommonBiz.replaceParams(newEntity.getExpression(), "{}");
            newEntity.setSimpleExpression(simpleExpression);
            newEntity = redisCacheKeyRuleService.save(newEntity);
            MRedisCacheKeyRule mRedisCacheKeyRule = convertToModel(newEntity, MRedisCacheKeyRule.class);
            envelop.setObj(mRedisCacheKeyRule);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功新增缓存Key规则。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("新增缓存Key规则发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("更新缓存Key规则")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.Save, method = RequestMethod.PUT)
    public Envelop update(
            @ApiParam(value = "缓存Key规则JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheKeyRule updateEntity = objectMapper.readValue(entityJson, RedisCacheKeyRule.class);
            CacheCommonBiz.validateKeyRule(updateEntity.getExpression());
            String simpleExpression = CacheCommonBiz.replaceParams(updateEntity.getExpression(), "{}");
            updateEntity.setSimpleExpression(simpleExpression);
            updateEntity = redisCacheKeyRuleService.save(updateEntity);
            MRedisCacheKeyRule mRedisCacheKeyRule = convertToModel(updateEntity, MRedisCacheKeyRule.class);
            envelop.setObj(mRedisCacheKeyRule);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功更新缓存Key规则。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("更新缓存Key规则发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("删除缓存Key规则")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.Delete, method = RequestMethod.DELETE)
    public Envelop delete(
            @ApiParam(name = "id", value = "缓存Key规则ID", required = true)
            @RequestParam(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            redisCacheKeyRuleService.delete(id);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功删除缓存Key规则。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("删除缓存Key规则发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证缓存Key规则名称是否唯一")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.IsUniqueName, method = RequestMethod.GET)
    public Envelop isUniqueName(
            @ApiParam(name = "id", value = "缓存Key规则ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "name", value = "缓存Key规则名称", required = true)
            @RequestParam(value = "name") String name) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisCacheKeyRuleService.isUniqueName(id, name);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该缓存Key规则名称已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证缓存Key规则编码是否唯一")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.IsUniqueCode, method = RequestMethod.GET)
    public Envelop isUniqueCode(
            @ApiParam(name = "id", value = "缓存Key规则ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "code", value = "缓存Key规则编码", required = true)
            @RequestParam(value = "code") String code) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisCacheKeyRuleService.isUniqueCode(id, code);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该缓存Key规则编码已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证类似的缓存Key规则表达式是否已经存在")
    @RequestMapping(value = ServiceApi.Redis.CacheKeyRule.IsUniqueExpression, method = RequestMethod.GET)
    public Envelop isUniqueExpression(
            @ApiParam(name = "id", value = "缓存Key规则ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "categoryCode", value = "缓存分类编码", required = true)
            @RequestParam(value = "categoryCode") String categoryCode,
            @ApiParam(name = "expression", value = "缓存Key规则表达式", required = true)
            @RequestParam(value = "expression") String expression) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            CacheCommonBiz.validateKeyRule(expression);
            String simpleExpression = CacheCommonBiz.replaceParams(expression, "{}");
            boolean result = redisCacheKeyRuleService.isUniqueExpression(id, categoryCode, simpleExpression);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("当前分类下类似的缓存Key规则表达式已经定义过,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
}

+ 150 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheOperationEndPoint.java

@ -0,0 +1,150 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.redis.cache.CacheCommonBiz;
import com.yihu.ehr.redis.cache.entity.RedisCacheAuthorization;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyRule;
import com.yihu.ehr.redis.cache.service.RedisCacheAuthorizationService;
import com.yihu.ehr.redis.cache.service.RedisCacheKeyRuleService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
 * 缓存操作
 *
 * @author 张进军
 * @date 2017/11/23 15:09
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "缓存操作接口", tags = {"缓存服务管理--缓存操作接口"})
public class RedisCacheOperationEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisCacheKeyRuleService redisCacheKeyRuleService;
    @Autowired
    private RedisCacheAuthorizationService redisCacheAuthorizationService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @ApiOperation("根据Key规则,获取指定key的缓存值")
    @RequestMapping(value = ServiceApi.Redis.CacheOperation.Get, method = RequestMethod.GET)
    public Envelop get(
            @ApiParam(name = "keyRuleCode", value = "Key规则编码", required = true)
            @RequestParam("keyRuleCode") String keyRuleCode,
            @ApiParam(name = "ruleParams", value = "规则参数,JSON字符串")
            @RequestParam(value = "ruleParams", required = false) String ruleParams) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheKeyRule redisCacheKeyRule = redisCacheKeyRuleService.findByCode(keyRuleCode);
            if (redisCacheKeyRule == null) {
                envelop.setErrorMsg("Key规则 " + keyRuleCode + " 不存在。");
                return envelop;
            }
            String categoryCode = redisCacheKeyRule.getCategoryCode();
            String keyRuleExpression = redisCacheKeyRule.getExpression();
            // 获取缓存值
            ValueOperations<String, Object> valOps = redisTemplate.opsForValue();
            String key = CacheCommonBiz.generateKey(keyRuleExpression, ruleParams, categoryCode);
            Object value = valOps.get(key);
            envelop.setSuccessFlg(true);
            envelop.setObj(value);
            envelop.setErrorMsg("成功获取缓存。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("根据Key规则,设置指定key的缓存值")
    @RequestMapping(value = ServiceApi.Redis.CacheOperation.Set, method = RequestMethod.POST)
    public Envelop set(
            @ApiParam(name = "appId", value = "应用ID", required = true)
            @RequestParam("appId") String appId,
            @ApiParam(name = "value", value = "值", required = true)
            @RequestParam("value") String value,
            @ApiParam(name = "keyRuleCode", value = "Key规则编码", required = true)
            @RequestParam("keyRuleCode") String keyRuleCode,
            @ApiParam(name = "ruleParams", value = "规则参数,JSON字符串")
            @RequestParam(value = "ruleParams", required = false) String ruleParams) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheKeyRule redisCacheKeyRule = redisCacheKeyRuleService.findByCode(keyRuleCode);
            if (redisCacheKeyRule == null) {
                envelop.setErrorMsg("Key规则 " + keyRuleCode + " 不存在。");
                return envelop;
            }
            String categoryCode = redisCacheKeyRule.getCategoryCode();
            String keyRuleExpression = redisCacheKeyRule.getExpression();
            RedisCacheAuthorization redisCacheAuthorization = redisCacheAuthorizationService.findByCategoryCodeAndAppId(categoryCode, appId);
            // 判断应用ID是否在缓存分类上绑定
            if (redisCacheAuthorization == null) {
                envelop.setErrorMsg("该应用ID还未绑定到缓存分类 " + categoryCode + "上,请先绑定。");
                return envelop;
            }
            // 设置缓存值
            ValueOperations<String, Object> valOps = redisTemplate.opsForValue();
            String key = CacheCommonBiz.generateKey(keyRuleExpression, ruleParams, categoryCode);
            valOps.set(key, value);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功设置缓存。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("设置缓存发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("根据Key规则,移除指定key的缓存值")
    @RequestMapping(value = ServiceApi.Redis.CacheOperation.Remove, method = RequestMethod.POST)
    public Envelop remove(
            @ApiParam(name = "keyRuleCode", value = "Key规则编码", required = true)
            @RequestParam("keyRuleCode") String keyRuleCode,
            @ApiParam(name = "ruleParams", value = "规则参数,JSON字符串")
            @RequestParam(value = "ruleParams", required = false) String ruleParams) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisCacheKeyRule redisCacheKeyRule = redisCacheKeyRuleService.findByCode(keyRuleCode);
            if (redisCacheKeyRule == null) {
                envelop.setErrorMsg("Key规则 " + keyRuleCode + " 不存在。");
                return envelop;
            }
            String categoryCode = redisCacheKeyRule.getCategoryCode();
            String keyRuleExpression = redisCacheKeyRule.getExpression();
            // 移除缓存值
            String key = CacheCommonBiz.generateKey(keyRuleExpression, ruleParams, categoryCode);
            redisTemplate.delete(key);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功移除缓存。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取缓存发生异常:" + e.getMessage());
        }
        return envelop;
    }
}

+ 131 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisCacheStatisticsEndPoint.java

@ -0,0 +1,131 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.redis.cache.CacheCommonBiz;
import com.yihu.ehr.redis.cache.entity.RedisCacheCategory;
import com.yihu.ehr.redis.cache.service.RedisCacheCategoryService;
import com.yihu.ehr.redis.cache.service.RedisCacheKeyMemoryService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 缓存统计
 *
 * @author 张进军
 * @date 2017/11/30 17:07
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "缓存统计接口", tags = {"缓存服务管理--缓存统计接口"})
public class RedisCacheStatisticsEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisCacheCategoryService redisCacheCategoryService;
    @Autowired
    private RedisCacheKeyMemoryService redisCacheKeyMemoryService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @ApiOperation("统计缓存分类的缓存数量")
    @RequestMapping(value = ServiceApi.Redis.CacheStatistics.GetCategoryKeys, method = RequestMethod.GET)
    public Envelop getCategoryKeys() {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            Map<String, Object> result = new HashMap<>();
            List<String> categoryNameList = new ArrayList<>();
            List<Integer> categoryNumList = new ArrayList<>();
            List<RedisCacheCategory> categoryList = redisCacheCategoryService.search("");
            for (RedisCacheCategory category : categoryList) {
                categoryNameList.add(category.getName());
                String keysPattern = CacheCommonBiz.makeKeyPrefix(category.getCode()) + "*";
                categoryNumList.add(redisTemplate.keys(keysPattern).size());
            }
            result.put("categoryNameList", categoryNameList);
            result.put("categoryNumList", categoryNumList);
            envelop.setObj(result);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取数据。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("统计缓存分类的缓存内存比率(近似值,比实际略小)")
    @RequestMapping(value = ServiceApi.Redis.CacheStatistics.GetCategoryMemory, method = RequestMethod.GET)
    public Envelop getCategoryMemory() {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            Map<String, Object> result = new HashMap<>();
            List<String> categoryNameList = new ArrayList<>();
            List<Map<String, Object>> categoryMemoryList = new ArrayList<>();
            // Redis使用的总内存
            long redisUsedMemory = (long) redisTemplate.execute(new RedisCallback() {
                @Override
                public Object doInRedis(RedisConnection connection) throws DataAccessException {
                    return Long.parseLong(connection.info("memory").get("used_memory").toString());
                }
            });
            List<RedisCacheCategory> categoryList = redisCacheCategoryService.search("");
            long categoryMemoryTotal = 0;
            for (RedisCacheCategory category : categoryList) {
                categoryNameList.add(category.getName());
                String keyPrefix = CacheCommonBiz.makeKeyPrefix(category.getCode());
                Long categoryMemory = redisCacheKeyMemoryService.sumCategoryMemory(keyPrefix);
                Map<String, Object> rateMap = new HashMap<>();
                rateMap.put("name", category.getName());
                rateMap.put("value", categoryMemory);
                categoryMemoryList.add(rateMap);
                categoryMemoryTotal += categoryMemory;
            }
            String noCategoryName = "未分类";
            categoryNameList.add(noCategoryName);
            Map<String, Object> noCategoryMemMap = new HashMap<>();
            Long noCategoryMemory = redisCacheKeyMemoryService.sumNotCategoryMemory();
            noCategoryMemMap.put("name", noCategoryName);
            noCategoryMemMap.put("value", noCategoryMemory);
            categoryMemoryList.add(noCategoryMemMap);
            String idleMemoryName = "闲置内存";
            categoryNameList.add(idleMemoryName);
            Map<String, Object> idleMemoryMap = new HashMap<>();
            idleMemoryMap.put("name", idleMemoryName);
            idleMemoryMap.put("value", redisUsedMemory - categoryMemoryTotal - noCategoryMemory);
            categoryMemoryList.add(idleMemoryMap);
            result.put("categoryNameList", categoryNameList);
            result.put("categoryMemoryList", categoryMemoryList);
            envelop.setObj(result);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取数据。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
}

+ 262 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisEndPoint.java

@ -0,0 +1,262 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.redis.cache.service.RedisService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * @author hzp add at 20170425
 * @modified Airhead 2018.01.21
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(value = "RedisEndPoint", description = "Redis数据缓存服务", tags = {"缓存服务-数据获取接口"})
public class RedisEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisService redisService;
    @ApiOperation("通过HP编码取健康问题名称")
    @RequestMapping(value = ServiceApi.Redis.HealthProblem, method = RequestMethod.GET)
    public String getHealthProblem(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getHealthProblem(key);
    }
    @ApiOperation("通过ICD10编码获取ICD10名称")
    @RequestMapping(value = ServiceApi.Redis.Icd10Name, method = RequestMethod.GET)
    public String getIcd10Name(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getIcd10Name(key);
    }
    @ApiOperation("通过ICD10编码获取HP健康问题编码")
    @RequestMapping(value = ServiceApi.Redis.Icd10HpCode, method = RequestMethod.GET)
    public String getHpCodeByIcd10(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getHpCodeByIcd10(key);
    }
    @ApiOperation("通过ICD10编码获取ICD10慢病信息")
    @RequestMapping(value = ServiceApi.Redis.Icd10ChronicInfo, method = RequestMethod.GET)
    public String cacheIcd10ChronicInfo(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) throws Exception {
        return redisService.getChronicInfo(key);
    }
    @ApiOperation("通过机构编码获取机构名称")
    @RequestMapping(value = ServiceApi.Redis.OrgName, method = RequestMethod.GET)
    public String getOrgName(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getOrgName(key);
    }
    @ApiOperation("通过机构编码获取机构区域")
    @RequestMapping(value = ServiceApi.Redis.OrgArea, method = RequestMethod.GET)
    public String getOrgArea(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getOrgArea(key);
    }
    @ApiOperation("通过机构编码获取机构SAAS区域权限范围")
    @RequestMapping(value = ServiceApi.Redis.OrgSaasArea, method = RequestMethod.GET)
    public String getOrgSaasArea(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getOrgSaasArea(key);
    }
    @ApiOperation("通过机构编码获取机构SAAS机构权限范围")
    @RequestMapping(value = ServiceApi.Redis.OrgSaasOrg, method = RequestMethod.GET)
    public String getOrgSaasOrg(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getOrgSaasOrg(key);
    }
    //------------------------------------ 资源化相关 START -------------------------------------------------------
    @ApiOperation("通过StdDataSet版本、编码和标准数据元内部编码获取资源化数据元ID(rs_adapter_metadata)")
    @RequestMapping(value = ServiceApi.Redis.RsAdapterMetadata, method = RequestMethod.GET)
    public String getRsAdapterMetaData(
            @ApiParam(value = "cdaVersion")
            @RequestParam(value = "cdaVersion") String cdaVersion,
            @ApiParam(value = "srcDataSetCode")
            @RequestParam(value = "srcDataSetCode") String srcDataSetCode,
            @ApiParam(value = "srcMetadataCode")
            @RequestParam(value = "srcMetadataCode") String srcMetadataCode) {
        return redisService.getRsAdapterMetaData(cdaVersion, srcDataSetCode, srcMetadataCode);
    }
    @ApiOperation("通过资源化数据元ID获取标准数据元字典编码")
    @RequestMapping(value = ServiceApi.Redis.RsMetadataDict, method = RequestMethod.GET)
    public String getRsMetaData(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key") String key) {
        return redisService.getRsMetadataDict(key);
    }
    //------------------------------------ 资源化相关 END -------------------------------------------------------
    //------------------------------------ 标准相关 START -------------------------------------------------------
    @ApiOperation("通过version值获取版本名")
    @RequestMapping(value = ServiceApi.Redis.StdVersion, method = RequestMethod.GET)
    public String getStdVersion(
            @ApiParam(value = "key", defaultValue = "59083976eebd")
            @RequestParam(value = "key") String key) {
        return redisService.getStdVersion(key);
    }
    @ApiOperation("通过StdDataSet版本和id获取标准数据集编码")
    @RequestMapping(value = ServiceApi.Redis.StdDataSetCode, method = RequestMethod.GET)
    public String getDataSetCode(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
             @ApiParam(value = "id")
             @RequestParam(value = "id") String id) {
        return redisService.getDataSetCode(version, id);
    }
    @ApiOperation("通过StdDataSet版本和id获取标准数据集名称")
    @RequestMapping(value = ServiceApi.Redis.StdDataSetName, method = RequestMethod.GET)
    public String getDataSetName(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "id")
            @RequestParam(value = "id") String id) {
        return redisService.getDataSetName(version, id);
    }
    @ApiOperation("通过StdDataSet版本和编码获取标准数据集名称")
    @RequestMapping(value = ServiceApi.Redis.StdDataSetNameByCode, method = RequestMethod.GET)
    public String getDataSetNameByCode(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "code")
            @RequestParam(value = "code") String code) {
        return redisService.getDataSetNameByCode(version, code);
    }
    @ApiOperation("通过StdDataSet版本和编码获取标准数据集主从表信息")
    @RequestMapping(value = ServiceApi.Redis.StdDataSetMultiRecord, method = RequestMethod.GET)
    public Boolean getDataSetMultiRecord(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "code")
            @RequestParam(value = "code") String code) {
        return redisService.getDataSetMultiRecord(version, code);
    }
    @ApiOperation("通过StdDataSet版本、编码以及标准数据元的内部编码获取标准数据元对应类型")
    @RequestMapping(value = ServiceApi.Redis.StdMetadataType, method = RequestMethod.GET)
    public String getMetaDataType(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "dataSetCode")
            @RequestParam(value = "dataSetCode") String dataSetCode,
            @ApiParam(value = "innerCode")
            @RequestParam(value = "innerCode") String innerCode) {
        return redisService.getMetaDataType(version, dataSetCode, innerCode);
    }
    @ApiOperation("通过StdDataSet版本、编码以及标准数据元的内部编码获取标准数据元的格式")
    @RequestMapping(value = ServiceApi.Redis.StdMetadataFormat, method = RequestMethod.GET)
    public String getMetaDataFormat(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "dataSetCode")
            @RequestParam(value = "dataSetCode") String dataSetCode,
            @ApiParam(value = "innerCode")
            @RequestParam(value = "innerCode") String innerCode) {
        return redisService.getMetaDataFormat(version, dataSetCode, innerCode);
    }
    @ApiOperation("通过StdDataSet版本、编码以及标准数据元的内部编码获取标准数据元的是否可为空")
    @RequestMapping(value = ServiceApi.Redis.StdMetadataNullable, method = RequestMethod.GET)
    public Boolean isMetaDataNullable(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "dataSetCode")
            @RequestParam(value = "dataSetCode") String dataSetCode,
            @ApiParam(value = "innerCode")
            @RequestParam(value = "innerCode") String innerCode) {
        return redisService.isMetaDataNullable(version, dataSetCode, innerCode);
    }
    @ApiOperation("通过StdDataSet版本、编码以及标准数据元的内部编码获取标准数据元字典ID")
    @RequestMapping(value = ServiceApi.Redis.StdMetadataDict, method = RequestMethod.GET)
    public String getMetaDataDict(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "dataSetCode")
            @RequestParam(value = "dataSetCode") String dataSetCode,
            @ApiParam(value = "innerCode")
            @RequestParam(value = "innerCode") String innerCode) {
        return redisService.getMetaDataDict(version, dataSetCode, innerCode);
    }
    @ApiOperation("通过StdDataSet版本、标准数据元字典ID以及标准数据元字典项编码获取标准数据元字典项值")
    @RequestMapping(value = ServiceApi.Redis.StdDictEntryValue, method = RequestMethod.GET)
    public String getDictEntryValue(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "dictId")
            @RequestParam(value = "dictId") String dictId,
            @ApiParam(value = "entryCode")
            @RequestParam(value = "entryCode") String entryCode) {
        return redisService.getDictEntryValue(version, dictId, entryCode);
    }
    @ApiOperation("通过StdDataSet版本、标准数据元字典ID以及标准数据元字典项编码判断值是否存在")
    @RequestMapping(value = ServiceApi.Redis.StdDictEntryValueExist, method = RequestMethod.GET)
    public Boolean isDictValueExist(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "dictId")
            @RequestParam(value = "dictId") String dictId,
            @ApiParam(value = "entryValue")
            @RequestParam(value = "entryValue") String entryValue) {
        return redisService.isDictValueExist(version, dictId, entryValue);
    }
    @ApiOperation("通过StdDataSet版本、标准数据元字典ID以及标准数据元字典项编码判断编码是否存在")
    @RequestMapping(value = ServiceApi.Redis.StdDictEntryCodeExist, method = RequestMethod.GET)
    public Boolean isDictCodeExist(
            @ApiParam(value = "version")
            @RequestParam(value = "version") String version,
            @ApiParam(value = "dictId")
            @RequestParam(value = "dictId") String dictId,
            @ApiParam(value = "entryCode")
            @RequestParam(value = "entryCode") String entryCode) {
        return redisService.isDictCodeExist(version, dictId, entryCode);
    }
    //------------------------------------ 标准相关 END -------------------------------------------------------
    /*@ApiOperation("通过指标编码获取指标相关数据")
    @RequestMapping(value = ServiceApi.Redis.IndicatorsDict, method = RequestMethod.GET)
    public String getIndicators(
            @ApiParam(value = "key")
            @RequestParam(value = "key") String key) {
        return redisService.getIndicators(key);
    }*/
}

+ 100 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisInitEndPoint.java

@ -0,0 +1,100 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.redis.cache.service.RedisInitService;
import com.yihu.ehr.redis.client.RedisClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
/**
 * @author hzp add at 20170425
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(value = "RedisInitEndPoint", description = "Redis初始化服务", tags = {"缓存服务-数据初始化接口"})
public class RedisInitEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisInitService redisInitService;
    @Autowired
    private RedisClient redis;
    @ApiOperation("清除Redis缓存")
    @RequestMapping(value = ServiceApi.Redis.Delete, method = RequestMethod.POST)
    @ApiIgnore
    public String deleteRedis(
            @ApiParam(name = "key", value = "机构编码、ICD10编码、健康问题编码等")
            @RequestParam(value = "key") String key) throws Exception {
        redis.delete(key);
        return "缓存清除成功!";
    }
    @ApiOperation("Redis缓存HP健康问题名称")
    @RequestMapping(value = ServiceApi.Redis.InitHealthProblem, method = RequestMethod.POST)
    public int cacheHpName() throws Exception {
        return redisInitService.cacheHpName();
    }
    @ApiOperation("1.Redis缓存ICD10名称 2.对应HP健康问题编码 3.慢病信息")
    @RequestMapping(value = ServiceApi.Redis.InitIcd10, method = RequestMethod.POST)
    public int cacheIcd10() throws Exception {
        return redisInitService.cacheIcd10();
    }
    @ApiOperation("Redis缓存机构名称")
    @RequestMapping(value = ServiceApi.Redis.InitOrgName, method = RequestMethod.POST)
    public int cacheOrgName() throws Exception {
        return redisInitService.cacheOrgName();
    }
    @ApiOperation("Redis缓存机构区域")
    @RequestMapping(value = ServiceApi.Redis.InitOrgArea, method = RequestMethod.POST)
    public int cacheOrgArea() throws Exception {
        return redisInitService.cacheOrgArea();
    }
    @ApiOperation("Redis缓存机构Saas区域")
    @RequestMapping(value = ServiceApi.Redis.InitOrgSaasArea, method = RequestMethod.POST)
    public int cacheOrgSaasArea() throws Exception {
        return redisInitService.cacheOrgSaasArea();
    }
    @ApiOperation("Redis缓存机构Saas机构")
    @RequestMapping(value = ServiceApi.Redis.InitOrgSaasOrg, method = RequestMethod.POST)
    public int cacheOrgSaasOrg() throws Exception {
        return redisInitService.cacheOrgSaasOrg();
    }
    @RequestMapping(value= ServiceApi.Redis.InitRsAdapterMeta, method = RequestMethod.POST)
    @ApiOperation("Redis缓存适配数据元数据")
    public int cacheAdapterMetadata(
            @ApiParam(name = "id", value = "rs_adapter_scheme.id")
            @PathVariable(value = "id") String id,
            @ApiParam(name = "deleteAll", defaultValue = "false", required = true)
            @RequestParam(value = "deleteAll") boolean deleteAll) throws Exception {
       return redisInitService.cacheAdapterMetadata(id, deleteAll);
    }
    @RequestMapping(value= ServiceApi.Redis.InitRsMetadataDict, method = RequestMethod.POST)
    @ApiOperation("Redis缓存资源化数据元字典(dict_code不为空)")
    public int cacheMetadataDict() throws Exception {
        return redisInitService.cacheMetadataDict();
    }
    //TODO ------------------- 未知用途 --------------------------
    /*@ApiOperation("Redis缓存指标(-1)")
    @RequestMapping(value = ServiceApi.Redis.InitIndicatorsDict, method = RequestMethod.POST)
    public String cacheIndicatorsDict() throws Exception {
        redisInitService.cacheIndicatorsDict();
        return "Redis缓存指标完成!";
    }*/
}

+ 59 - 0
src/main/java/com/yihu/ehr/redis/cache/controller/RedisUpdateEndPoint.java

@ -0,0 +1,59 @@
package com.yihu.ehr.redis.cache.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.redis.cache.service.RedisUpdateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * Created by Sxy on 2017/08/28.
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(value = "RedisUpdateEndPoint", description = "Redis更新服务", tags = {"缓存服务-缓存更新接口"})
public class RedisUpdateEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisUpdateService redisUpdateService;
    @ApiOperation("Redis更新机构名称")
    @RequestMapping(value = ServiceApi.Redis.UpdateOrgName, method = RequestMethod.POST)
    public Boolean updateOrgName(
            @ApiParam(name = "orgCode", value = "机构编码(orgCode)")
            @RequestParam(value = "orgCode") String orgCode) {
        return redisUpdateService.updateOrgName(orgCode);
    }
    @ApiOperation("Redis更新机构区域")
    @RequestMapping(value = ServiceApi.Redis.UpdateOrgArea, method = RequestMethod.POST)
    public Boolean updateOrgArea(
            @ApiParam(name = "orgCode", value = "机构编码(orgCode)")
            @RequestParam(value = "orgCode") String orgCode) {
        return redisUpdateService.updateOrgArea(orgCode);
    }
    @ApiOperation("Redis更新机构Saas区域")
    @RequestMapping(value = ServiceApi.Redis.UpdateOrgSaasArea, method = RequestMethod.POST)
    public Boolean updateOrgSaasArea(
            @ApiParam(name = "orgCode", value = "机构编码(orgCode)")
            @RequestParam(value = "orgCode") String orgCode) {
        return redisUpdateService.updateOrgSaasArea(orgCode);
    }
    @ApiOperation("Redis更新机构Saas机构")
    @RequestMapping(value = ServiceApi.Redis.UpdateOrgSaasOrg, method = RequestMethod.POST)
    public Boolean updateOrgSaasOrg(
            @ApiParam(name = "orgCode", value = "机构编码(orgCode)")
            @RequestParam(value = "orgCode") String orgCode) {
        return redisUpdateService.updateOrgSaasOrg(orgCode);
    }
}

+ 26 - 0
src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheAuthorizationDao.java

@ -0,0 +1,26 @@
package com.yihu.ehr.redis.cache.dao;
import com.yihu.ehr.redis.cache.entity.RedisCacheAuthorization;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
/**
 * 缓存授权 DAO
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
public interface RedisCacheAuthorizationDao extends PagingAndSortingRepository<RedisCacheAuthorization, Integer> {
    RedisCacheAuthorization findByCategoryCodeAndAppId(@Param("categoryCode") String categoryCode, @Param("appId") String appId);
    @Query(" FROM RedisCacheAuthorization a WHERE a.id <> :id AND a.categoryCode = :categoryCode AND a.appId = :appId ")
    RedisCacheAuthorization isUniqueAppId(@Param("id") Integer id, @Param("categoryCode") String categoryCode, @Param("appId") String appId);
    @Modifying
    @Query(" DELETE RedisCacheAuthorization WHERE categoryCode = :categoryCode")
    void deleteByCategoryCode(@Param("categoryCode") String categoryCode);
}

+ 22 - 0
src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheCategoryDao.java

@ -0,0 +1,22 @@
package com.yihu.ehr.redis.cache.dao;
import com.yihu.ehr.redis.cache.entity.RedisCacheCategory;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
/**
 * 缓存分类 DAO
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
public interface RedisCacheCategoryDao extends PagingAndSortingRepository<RedisCacheCategory, Integer> {
    @Query(" FROM RedisCacheCategory a WHERE a.id <> :id AND a.name = :name ")
    RedisCacheCategory isUniqueName(@Param("id") Integer id, @Param("name") String name);
    @Query(" FROM RedisCacheCategory a WHERE a.id <> :id AND a.code = :code ")
    RedisCacheCategory isUniqueCode(@Param("id") Integer id, @Param("code") String code);
}

+ 21 - 0
src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheKeyMemoryDao.java

@ -0,0 +1,21 @@
package com.yihu.ehr.redis.cache.dao;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyMemory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
/**
 * 缓存Key值占用内存分析 DAO
 *
 * @author 张进军
 * @date 2017/12/6 14:58
 */
public interface RedisCacheKeyMemoryDao extends JpaRepository<RedisCacheKeyMemory, Integer> {
    RedisCacheKeyMemory findByCacheKey(@Param("cacheKey") String cacheKey);
    @Query(value = "SELECT SUM(a.size_in_bytes) FROM redis_cache_key_memory a WHERE a.cache_key LIKE :keyPrefix%", nativeQuery = true)
    Long sumCategoryMemory(@Param("keyPrefix") String keyPrefix);
}

+ 31 - 0
src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheKeyRuleDao.java

@ -0,0 +1,31 @@
package com.yihu.ehr.redis.cache.dao;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyRule;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
 * 缓存Key生成规则 DAO
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
public interface RedisCacheKeyRuleDao extends PagingAndSortingRepository<RedisCacheKeyRule, Integer> {
    RedisCacheKeyRule findByCode(@Param("code") String code);
    List<RedisCacheKeyRule> findByCategoryCode(@Param("categoryCode") String categoryCode);
    @Query(" FROM RedisCacheKeyRule a WHERE a.id <> :id AND a.name = :name ")
    RedisCacheKeyRule isUniqueName(@Param("id") Integer id, @Param("name") String name);
    @Query(" FROM RedisCacheKeyRule a WHERE a.id <> :id AND a.code = :code ")
    RedisCacheKeyRule isUniqueCode(@Param("id") Integer id, @Param("code") String code);
    @Query(" FROM RedisCacheKeyRule a WHERE a.id <> :id AND a.categoryCode = :categoryCode AND a.simpleExpression = :simpleExpression ")
    RedisCacheKeyRule isUniqueExpression(@Param("id") Integer id, @Param("categoryCode") String categoryCode, @Param("simpleExpression") String simpleExpression);
}

+ 19 - 0
src/main/java/com/yihu/ehr/redis/cache/dao/RedisCacheResponseTimeLogDao.java

@ -0,0 +1,19 @@
package com.yihu.ehr.redis.cache.dao;
import com.yihu.ehr.redis.cache.entity.RedisCacheResponseTimeLog;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
 * 缓存获取的响应时间日志 DAO
 *
 * @author 张进军
 * @date 2017/12/4 08:56
 */
public interface RedisCacheResponseTimeLogDao extends PagingAndSortingRepository<RedisCacheResponseTimeLog, String> {
    List<RedisCacheResponseTimeLog> findByCacheKeyOrderByCreateDateAsc(@Param("cacheKey") String cacheKey);
}

+ 60 - 0
src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheAuthorization.java

@ -0,0 +1,60 @@
package com.yihu.ehr.redis.cache.entity;
import com.yihu.ehr.entity.BaseIdentityEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 缓存授权 entity
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@Entity
@Table(name = "redis_cache_authorization")
public class RedisCacheAuthorization extends BaseIdentityEntity {
    private String categoryCode; // 缓存分类编码
    private String appId; // 应用ID
    private String authorizedCode; // 授权码
    private String remark; // 备注
    @Column(name = "category_code", nullable = false)
    public String getCategoryCode() {
        return categoryCode;
    }
    public void setCategoryCode(String categoryCode) {
        this.categoryCode = categoryCode;
    }
    @Column(name = "app_id", nullable = false)
    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }
    @Column(name = "authorized_code", nullable = false)
    public String getAuthorizedCode() {
        return authorizedCode;
    }
    public void setAuthorizedCode(String authorizedCode) {
        this.authorizedCode = authorizedCode;
    }
    @Column(name = "remark")
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

+ 49 - 0
src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheCategory.java

@ -0,0 +1,49 @@
package com.yihu.ehr.redis.cache.entity;
import com.yihu.ehr.entity.BaseIdentityEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 缓存分类 entity
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@Entity
@Table(name = "redis_cache_category")
public class RedisCacheCategory extends BaseIdentityEntity {
    private String name; // 缓存分类名称
    private String code; // 缓存分类编码
    private String remark; // 备注
    @Column(name = "name", nullable = false, unique = true)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Column(name = "code", nullable = false, unique = true)
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    @Column(name = "remark")
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

+ 89 - 0
src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheKeyMemory.java

@ -0,0 +1,89 @@
package com.yihu.ehr.redis.cache.entity;
import com.yihu.ehr.entity.BaseAssignedEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 缓存Key值占用内存分析 entity
 *
 * @author 张进军
 * @date 2017/12/6 14:58
 */
@Entity
@Table(name = "redis_cache_key_memory")
public class RedisCacheKeyMemory extends BaseAssignedEntity {
    private int databaseNo; // Redis数据库编号
    private String type; // 数据类型
    private String cacheKey; // Redis Key编码
    private long sizeInBytes; // Key值内存字节大小
    private String encoding; // RDB编码类型
    private int numElements;
    private int lenLargestElement;
    @Column(name = "database_no", nullable = false)
    public int getDatabaseNo() {
        return databaseNo;
    }
    public void setDatabaseNo(int databaseNo) {
        this.databaseNo = databaseNo;
    }
    @Column(name = "type", nullable = false)
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    @Column(name = "cache_key", nullable = false)
    public String getCacheKey() {
        return cacheKey;
    }
    public void setCacheKey(String cacheKey) {
        this.cacheKey = cacheKey;
    }
    @Column(name = "size_in_bytes", nullable = false)
    public long getSizeInBytes() {
        return sizeInBytes;
    }
    public void setSizeInBytes(long sizeInBytes) {
        this.sizeInBytes = sizeInBytes;
    }
    @Column(name = "encoding", nullable = false)
    public String getEncoding() {
        return encoding;
    }
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }
    @Column(name = "num_elements", nullable = false)
    public int getNumElements() {
        return numElements;
    }
    public void setNumElements(int numElements) {
        this.numElements = numElements;
    }
    @Column(name = "len_largest_element", nullable = false)
    public int getLenLargestElement() {
        return lenLargestElement;
    }
    public void setLenLargestElement(int lenLargestElement) {
        this.lenLargestElement = lenLargestElement;
    }
}

+ 102 - 0
src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheKeyRule.java

@ -0,0 +1,102 @@
package com.yihu.ehr.redis.cache.entity;
import com.yihu.ehr.entity.BaseIdentityEntity;
import org.hibernate.annotations.Formula;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 缓存Key生成规则 entity
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@Entity
@Table(name = "redis_cache_key_rule")
public class RedisCacheKeyRule extends BaseIdentityEntity {
    private String name; // 规则名称
    private String code; // 规则编码
    private String categoryCode; // 缓存分类编码
    private String expression; // 规则表达式
    private String simpleExpression; // 精简规则表达式
    private String expireTime; // 过期时间,单位秒
    private String remark; // 备注
    // 临时字段
    private String categoryName; // 缓存分类名称
    @Column(name = "name", nullable = false)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Column(name = "code", nullable = false)
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    @Column(name = "category_code", nullable = false)
    public String getCategoryCode() {
        return categoryCode;
    }
    public void setCategoryCode(String categoryCode) {
        this.categoryCode = categoryCode;
    }
    @Column(name = "expression", nullable = false)
    public String getExpression() {
        return expression;
    }
    public void setExpression(String expression) {
        this.expression = expression;
    }
    @Column(name = "simple_expression", nullable = false)
    public String getSimpleExpression() {
        return simpleExpression;
    }
    public void setSimpleExpression(String simpleExpression) {
        this.simpleExpression = simpleExpression;
    }
    @Column(name = "expire_time")
    public String getExpireTime() {
        return expireTime;
    }
    public void setExpireTime(String expireTime) {
        this.expireTime = expireTime;
    }
    @Column(name = "remark")
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
    @Formula("( SELECT c.name FROM redis_cache_category c WHERE c.code = category_code )")
    public String getCategoryName() {
        return categoryName;
    }
    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }
}

+ 49 - 0
src/main/java/com/yihu/ehr/redis/cache/entity/RedisCacheResponseTimeLog.java

@ -0,0 +1,49 @@
package com.yihu.ehr.redis.cache.entity;
import com.yihu.ehr.entity.BaseAssignedEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 缓存获取的响应时间日志 entity
 *
 * @author 张进军
 * @date 2017/12/4 08:56
 */
@Entity
@Table(name = "redis_cache_response_time_log")
public class RedisCacheResponseTimeLog extends BaseAssignedEntity {
    private String cacheKey; // 缓存Key
    private String categoryCode; // 缓存分类编码
    private long responseTime; // 响应时长,单位毫秒
    @Column(name = "cache_key", nullable = false)
    public String getCacheKey() {
        return cacheKey;
    }
    public void setCacheKey(String cacheKey) {
        this.cacheKey = cacheKey;
    }
    @Column(name = "category_code", nullable = false)
    public String getCategoryCode() {
        return categoryCode;
    }
    public void setCategoryCode(String categoryCode) {
        this.categoryCode = categoryCode;
    }
    @Column(name = "response_time", nullable = false)
    public long getResponseTime() {
        return responseTime;
    }
    public void setResponseTime(long responseTime) {
        this.responseTime = responseTime;
    }
}

+ 50 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheAuthorizationService.java

@ -0,0 +1,50 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.cache.dao.RedisCacheAuthorizationDao;
import com.yihu.ehr.redis.cache.entity.RedisCacheAuthorization;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * 缓存授权 Service
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@Service
@Transactional
public class RedisCacheAuthorizationService extends BaseJpaService<RedisCacheAuthorization, RedisCacheAuthorizationDao> {
    @Autowired
    RedisCacheAuthorizationDao redisCacheAuthorizationDao;
    
    public RedisCacheAuthorization getById(Integer id) {
        return redisCacheAuthorizationDao.findOne(id);
    }
    public RedisCacheAuthorization findByCategoryCodeAndAppId(String categoryCode, String appId) {
        return redisCacheAuthorizationDao.findByCategoryCodeAndAppId(categoryCode, appId);
    }
    @Transactional(readOnly = false)
    public RedisCacheAuthorization save(RedisCacheAuthorization redisCacheAuthorization) {
        return redisCacheAuthorizationDao.save(redisCacheAuthorization);
    }
    @Transactional(readOnly = false)
    public void delete(Integer id) {
        redisCacheAuthorizationDao.delete(id);
    }
    public Boolean isUniqueAppId(Integer id, String categoryCode, String appId) {
        RedisCacheAuthorization redisCacheAuthorization = redisCacheAuthorizationDao.isUniqueAppId(id, categoryCode, appId);
        if (redisCacheAuthorization == null) {
            return true;
        } else {
            return false;
        }
    }
}

+ 59 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheCategoryService.java

@ -0,0 +1,59 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.cache.dao.RedisCacheAuthorizationDao;
import com.yihu.ehr.redis.cache.dao.RedisCacheCategoryDao;
import com.yihu.ehr.redis.cache.entity.RedisCacheCategory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * 缓存分类 Service
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@Service
@Transactional
public class RedisCacheCategoryService extends BaseJpaService<RedisCacheCategory, RedisCacheCategoryDao> {
    @Autowired
    RedisCacheCategoryDao redisCacheCategoryDao;
    @Autowired
    RedisCacheAuthorizationDao redisCacheAuthorizationDao;
    public RedisCacheCategory getById(Integer id) {
        return redisCacheCategoryDao.findOne(id);
    }
    @Transactional(readOnly = false)
    public RedisCacheCategory save(RedisCacheCategory redisCacheCategory) {
        return redisCacheCategoryDao.save(redisCacheCategory);
    }
    @Transactional(readOnly = false)
    public void delete(Integer id, String code) {
        redisCacheAuthorizationDao.deleteByCategoryCode(code);
        redisCacheCategoryDao.delete(id);
    }
    public Boolean isUniqueName(Integer id, String name) {
        RedisCacheCategory redisCacheCategory = redisCacheCategoryDao.isUniqueName(id, name);
        if (redisCacheCategory == null) {
            return true;
        } else {
            return false;
        }
    }
    public Boolean isUniqueCode(Integer id, String code) {
        RedisCacheCategory redisCacheCategory = redisCacheCategoryDao.isUniqueCode(id, code);
        if (redisCacheCategory == null) {
            return true;
        } else {
            return false;
        }
    }
}

+ 87 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheKeyMemoryService.java

@ -0,0 +1,87 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.cache.CacheCommonBiz;
import com.yihu.ehr.redis.cache.dao.RedisCacheCategoryDao;
import com.yihu.ehr.redis.cache.dao.RedisCacheKeyMemoryDao;
import com.yihu.ehr.redis.cache.entity.RedisCacheCategory;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyMemory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
/**
 * 缓存Key值占用内存分析 Service
 *
 * @author 张进军
 * @date 2017/12/6 14:58
 */
@Service
@Transactional
public class RedisCacheKeyMemoryService extends BaseJpaService<RedisCacheKeyMemory, RedisCacheKeyMemoryDao> {
    @Autowired
    RedisCacheKeyMemoryDao redisCacheKeyMemoryDao;
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    RedisCacheCategoryDao redisCacheCategoryDao;
    public RedisCacheKeyMemory findByCacheKey(String cacheKey) {
        return redisCacheKeyMemoryDao.findByCacheKey(cacheKey);
    }
    /**
     * 合计指定分类的占用内存大小
     *
     * @param keyPrefix
     * @return
     */
    public Long sumCategoryMemory(String keyPrefix) {
        Long mem = redisCacheKeyMemoryDao.sumCategoryMemory(keyPrefix);
        return mem == null ? 0 : mem;
    }
    /**
     * 合计未分类的占用内存大小
     *
     * @return
     */
    public Long sumNotCategoryMemory() {
        StringBuffer sql = new StringBuffer("SELECT SUM(size_in_bytes) AS sumSize FROM redis_cache_key_memory WHERE ");
        List<RedisCacheCategory> categoryList = (List<RedisCacheCategory>) redisCacheCategoryDao.findAll();
        for (int i = 0, len = categoryList.size(); i < len; i++) {
            String keyPrefix = CacheCommonBiz.makeKeyPrefix(categoryList.get(i).getCode());
            if (i != 0) sql.append(" AND ");
            sql.append(" cache_key NOT LIKE '" + keyPrefix + "%' ");
        }
        Map<String, Object> result = jdbcTemplate.queryForMap(sql.toString());
        Object memObj = result.get("sumSize");
        return memObj == null ? 0 : Long.parseLong(memObj.toString());
    }
    @Transactional(readOnly = false)
    public RedisCacheKeyMemory save(RedisCacheKeyMemory redisCacheKeyMemory) {
        return redisCacheKeyMemoryDao.save(redisCacheKeyMemory);
    }
    @Transactional(readOnly = false)
    public Iterable<RedisCacheKeyMemory> save(List<RedisCacheKeyMemory> list) {
        return redisCacheKeyMemoryDao.save(list);
    }
    @Transactional(readOnly = false)
    public void delete(Integer id) {
        redisCacheKeyMemoryDao.delete(id);
    }
    @Transactional(readOnly = false)
    public void deleteAllInBatch() {
        redisCacheKeyMemoryDao.deleteAllInBatch();
    }
}

+ 74 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheKeyRuleService.java

@ -0,0 +1,74 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.cache.dao.RedisCacheKeyRuleDao;
import com.yihu.ehr.redis.cache.entity.RedisCacheKeyRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * 缓存Key规则 Service
 *
 * @author 张进军
 * @date 2017/11/23 11:28
 */
@Service
@Transactional
public class RedisCacheKeyRuleService extends BaseJpaService<RedisCacheKeyRule, RedisCacheKeyRuleDao> {
    @Autowired
    RedisCacheKeyRuleDao redisCacheKeyRuleDao;
    public RedisCacheKeyRule getById(Integer id) {
        return redisCacheKeyRuleDao.findOne(id);
    }
    public RedisCacheKeyRule findByCode(String code) {
        return redisCacheKeyRuleDao.findByCode(code);
    }
    public List<RedisCacheKeyRule> findByCategoryCode(String categoryCode) {
        return redisCacheKeyRuleDao.findByCategoryCode(categoryCode);
    }
    @Transactional(readOnly = false)
    public RedisCacheKeyRule save(RedisCacheKeyRule redisCacheKeyRule) {
        return redisCacheKeyRuleDao.save(redisCacheKeyRule);
    }
    @Transactional(readOnly = false)
    public void delete(Integer id) {
        redisCacheKeyRuleDao.delete(id);
    }
    public Boolean isUniqueName(Integer id, String name) {
        RedisCacheKeyRule redisCacheKeyRule = redisCacheKeyRuleDao.isUniqueName(id, name);
        if (redisCacheKeyRule == null) {
            return true;
        } else {
            return false;
        }
    }
    public Boolean isUniqueCode(Integer id, String code) {
        RedisCacheKeyRule redisCacheKeyRule = redisCacheKeyRuleDao.isUniqueCode(id, code);
        if (redisCacheKeyRule == null) {
            return true;
        } else {
            return false;
        }
    }
    public Boolean isUniqueExpression(Integer id, String categoryCode, String simpleExpression) {
        RedisCacheKeyRule redisCacheKeyRule = redisCacheKeyRuleDao.isUniqueExpression(id, categoryCode, simpleExpression);
        if (redisCacheKeyRule == null) {
            return true;
        } else {
            return false;
        }
    }
}

+ 34 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisCacheResponseTimeLogService.java

@ -0,0 +1,34 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.cache.dao.RedisCacheResponseTimeLogDao;
import com.yihu.ehr.redis.cache.entity.RedisCacheResponseTimeLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * 缓存获取的响应时间日志 Service
 *
 * @author 张进军
 * @date 2017/12/4 08:56
 */
@Service
@Transactional
public class RedisCacheResponseTimeLogService extends BaseJpaService<RedisCacheResponseTimeLog, RedisCacheResponseTimeLogDao> {
    @Autowired
    RedisCacheResponseTimeLogDao redisCacheResponseTimeLogDao;
    public List<RedisCacheResponseTimeLog> findByCacheKey(String key) {
        return redisCacheResponseTimeLogDao.findByCacheKeyOrderByCreateDateAsc(key);
    }
    @Transactional(readOnly = false)
    public RedisCacheResponseTimeLog save(RedisCacheResponseTimeLog redisCacheResponseTimeLog) {
        return redisCacheResponseTimeLogDao.save(redisCacheResponseTimeLog);
    }
}

+ 244 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisInitService.java

@ -0,0 +1,244 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.schema.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
/**
 * Redis初始化管理
 * @author hzp add at 20170425
 */
@Service
public class RedisInitService extends BaseJpaService {
    @Autowired
    private JdbcTemplate jdbc;
    @Autowired
    private HealthProblemDictKeySchema healthProblemDictKeySchema;
    @Autowired
    private Icd10KeySchema icd10KeySchema;
    @Autowired
    private OrgKeySchema orgKeySchema;
    @Autowired
    private RsAdapterMetaKeySchema rsAdapterMetaKeySchema;
    @Autowired
    private RsMetadataKeySchema rsMetadataKeySchema;
    /**
     * 缓存健康问题名称Redis
     */
    public int cacheHpName() {
        String sql = "select code, name from health_problem_dict";
        List<Map<String,Object>> list = jdbc.queryForList(sql);
        //清空相关Redis
        healthProblemDictKeySchema.deleteAll();
        for (Map<String,Object> map : list){
            healthProblemDictKeySchema.set((String) map.get("code"), (String)map.get("name"));
        }
        return list.size();
    }
    /**
     * 缓存ICD10 Redis
     */
    public int cacheIcd10() {
        String sql = "select t.hp_code, d.code, d.name, d.chronic_flag, d.type from\n" +
                "(select r.icd10_id, group_concat(p.`code` separator ';') hp_code \n" +
                "from icd10_hp_relation r\n" +
                "left join health_problem_dict p on p.id = r.hp_id \n" +
                "group by icd10_id) t\n" +
                "left join icd10_dict d on t.icd10_id = d.id" ;
        List<Map<String,Object>> list = jdbc.queryForList(sql);
        //清空相关Redis
        icd10KeySchema.deleteAll();
        icd10KeySchema.deleteHpCode();
        icd10KeySchema.deleteChronic();
        list.forEach(item -> {
            icd10KeySchema.set((String) item.get("code"), (String)item.get("name"));
            icd10KeySchema.setHpCode((String) item.get("code"), (String)item.get("hp_code"));
            if (item.get("chronic_flag") != null) {
                if (item.get("type") != null) {
                    icd10KeySchema.setChronicInfo((String) item.get("code"), item.get("chronic_flag") + "-" + item.get("type"));
                } else {
                    icd10KeySchema.setChronicInfo((String) item.get("code"), item.get("chronic_flag") + "-0");
                }
            }
        });
        return list.size();
    }
    /**
     * 缓存机构名称Redis
     */
    public int cacheOrgName() {
        String sql = "select org_code, full_name from organizations";
        List<Map<String, Object>> list = jdbc.queryForList(sql);
        //清空相关Redis
        orgKeySchema.deleteAll();
        for (Map<String,Object> map : list){
            orgKeySchema.set(String.valueOf(map.get("org_code")), String.valueOf(map.get("full_name")));
        }
        return list.size();
    }
    /**
     * 缓存机构区域Redis
     */
    public int cacheOrgArea() {
        String sql = "select org_code, administrative_division from organizations";
        List<Map<String,Object>> list = jdbc.queryForList(sql);
        //清空相关Redis
        orgKeySchema.deleteOrgArea();
        for (Map<String,Object> map : list){
            orgKeySchema.setOrgArea(String.valueOf(map.get("org_code")), String.valueOf(map.get("administrative_division")));
        }
        return list.size();
    }
    /**
     * 缓存机构Saas区域Redis
     */
    public int cacheOrgSaasArea() {
        String sql = "select org_code, saas_code from org_saas where type='1' order by org_code";
        List<Map<String,Object>> list = jdbc.queryForList(sql);
        //清空相关Redis
        orgKeySchema.deleteOrgSaasArea();
        String orgCode = "";
        String val = "";
        for (Map<String,Object> map:list){
            String orgCodeCurrent =  String.valueOf(map.get("org_code"));
            String saasCodeCurrent =  String.valueOf(map.get("saas_code"));
            if (!orgCode.equals(orgCodeCurrent) && !StringUtils.isEmpty(orgCode)) {
                orgKeySchema.setOrgSaasArea(orgCode,val);
                val = saasCodeCurrent;
                orgCode = orgCodeCurrent;
            } else {
                if (StringUtils.isEmpty(val)) {
                    orgCode = orgCodeCurrent;
                    val =  saasCodeCurrent;
                } else {
                    orgCode = orgCodeCurrent;
                    val += "," + saasCodeCurrent;
                }
            }
        }
        if (!StringUtils.isEmpty(orgCode)) {
            orgKeySchema.setOrgSaasArea(orgCode,val);
        }
        return list.size();
    }
    /**
     * 缓存机构Saas机构Redis
     */
    public int cacheOrgSaasOrg() {
        String sql = "select org_code, saas_code from org_saas where type='2' order by org_code";
        List<Map<String, Object>> list = jdbc.queryForList(sql);
        //清空相关Redis
        orgKeySchema.deleteOrgSaasOrg();
        String orgCode = "";
        String val = "";
        for (Map<String,Object> map:list){
            String orgCodeCurrent =  String.valueOf(map.get("org_code"));
            String saasCodeCurrent =  String.valueOf(map.get("saas_code"));
            if (!orgCode.equals(orgCodeCurrent) && !StringUtils.isEmpty(orgCode)) {
                orgKeySchema.setOrgSaasOrg(orgCode,val);
                val = saasCodeCurrent;
                orgCode = orgCodeCurrent;
            } else {
                if (StringUtils.isEmpty(val)) {
                    orgCode = orgCodeCurrent;
                    val =  saasCodeCurrent;
                } else {
                    orgCode = orgCodeCurrent;
                    val += "," + saasCodeCurrent;
                }
            }
        }
        if (!StringUtils.isEmpty(orgCode)) {
            orgKeySchema.setOrgSaasOrg(orgCode,val);
        }
        return list.size();
    }
    /**
     * 缓存适配数据元数据
     * @param id
     * @return
     */
    public int cacheAdapterMetadata (String id, boolean deleteAll){
        String schemaSql = "SELECT adapter_version FROM rs_adapter_scheme WHERE id = " + id;
        String metaSql = "SELECT src_dataset_code, src_metadata_code, metadata_id FROM rs_adapter_metadata WHERE scheme_id = " + id;
        Map<String, Object> schemaMap = jdbc.queryForMap(schemaSql);
        List<Map<String, Object>> metaList = jdbc.queryForList(metaSql);
        //清空相关Redis
        if (deleteAll) {
            rsAdapterMetaKeySchema.deleteAll();
        } else {
            rsAdapterMetaKeySchema.deleteVersion(schemaMap.get("adapter_version").toString());
        }
        for (Map<String, Object> metaMap : metaList) {
            if (StringUtils.isEmpty(metaMap.get("src_dataset_code")) || StringUtils.isEmpty(metaMap.get("metadata_id"))) {
                continue;
            }
            rsAdapterMetaKeySchema.setMetaData(schemaMap.get("adapter_version").toString(), metaMap.get("src_dataset_code").toString(),
                    metaMap.get("src_metadata_code").toString(), metaMap.get("metadata_id").toString());
        }
        return metaList.size();
    }
    /**
     * 缓存数据元字典(Dict_code不为空)
     * @return
     */
    public int cacheMetadataDict() {
        String sql = "SELECT id, dict_code FROM rs_metadata WHERE dict_code != NULL OR dict_code != ''";
        //String sql1 = "SELECT a FROM RsMetadata a WHERE a.dictCode <> NULL AND a.dictCode <> ''";
        List<Map<String, Object>> metaList = jdbc.queryForList(sql);
        //清空相关Redis
        rsMetadataKeySchema.deleteAll();
        for (Map<String, Object> tempMap : metaList) {
            if (StringUtils.isEmpty(tempMap.get("dict_code"))) {
                continue;
            }
            rsMetadataKeySchema.set((String) tempMap.get("id"), (String) tempMap.get("dict_code"));
        }
        return metaList.size();
    }
    //TODO ------------------- 未知用途 --------------------------
    @Autowired
    private IndicatorsDictKeySchema indicatorsDictKeySchema;
    /**
     * 缓存指标
     * @return
     */
    /*public boolean cacheIndicatorsDict() {
        String sql = "SELECT * FROM indicators_dict";
        List<Map<String, Object>> list = jdbc.queryForList(sql);
        indicatorsDictKeySchema.deleteAll();
        for (Map<String, Object> tempMap : list) {
            HashMap<String, String> map = new HashMap<>();
            map.put("id", String.valueOf(tempMap.get("id")));
            map.put("code", String.valueOf(tempMap.get("code")));
            map.put("name", String.valueOf(tempMap.get("name")));
            map.put("PhoneticCode", String.valueOf(tempMap.get("phonetic_code")));
            map.put("type", String.valueOf(tempMap.get("type")));
            map.put("unit", String.valueOf(tempMap.get("unit")));
            map.put("LowerLimit", String.valueOf(tempMap.get("lower_limit")));
            map.put("UpperLimit", String.valueOf(tempMap.get("upper_limit")));
            map.put("Description", String.valueOf(tempMap.get("description")));
            indicatorsDictKeySchema.set(String.valueOf(tempMap.get("code")), map);
        }
        return true;
    }*/
}

+ 250 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisService.java

@ -0,0 +1,250 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.redis.schema.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
 * Redis管理
 *
 * @author hzp add at 20170425
 */
@Service
public class RedisService {
    @Autowired
    private HealthProblemDictKeySchema healthProblemDictKeySchema;
    @Autowired
    private Icd10KeySchema icd10KeySchema;
    @Autowired
    private OrgKeySchema orgKeySchema;
    @Autowired
    private RsAdapterMetaKeySchema rsAdapterMetaKeySchema;
    @Autowired
    private RsMetadataKeySchema rsMetadataKeySchema;
    @Autowired
    private StdCdaVersionKeySchema stdVersionKeySchema;
    @Autowired
    private StdDataSetKeySchema stdDataSetKeySchema;
    @Autowired
    private StdMetaDataKeySchema stdMetaDataKeySchema;
   /* @Autowired
    private IndicatorsDictKeySchema indicatorsDictKeySchema;*/
    /**
     * 获取健康问题redis
     *
     * @return
     */
    public String getHealthProblem(String key) {
        return healthProblemDictKeySchema.get(key);
    }
    /**
     * 获取ICD10名称 redis
     */
    public String getIcd10Name(String key) {
        return icd10KeySchema.get(key);
    }
    /**
     * 获取ICD10对应健康问题 redis
     */
    public String getHpCodeByIcd10(String key) {
        return icd10KeySchema.getHpCode(key);
    }
    /**
     * 获取ICD10慢病信息 redis
     */
    public String getChronicInfo(String key) {
        return icd10KeySchema.getChronicInfo(key);
    }
    /**
     * 获取机构名称redis
     *
     * @return
     */
    public String getOrgName(String key) {
        return orgKeySchema.get(key);
    }
    /**
     * 获取机构区域redis
     *
     * @return
     */
    public String getOrgArea(String key) {
        return orgKeySchema.getOrgArea(key);
    }
    /**
     * 获取机构Saas区域权限范围redis
     *
     * @return
     */
    public String getOrgSaasArea(String key) {
        return orgKeySchema.getOrgSaasArea(key);
    }
    /**
     * 获取机构Saas机构权限范围redis
     *
     * @return
     */
    public String getOrgSaasOrg(String key) {
        String saasOrg = orgKeySchema.getOrgSaasOrg(key);
        //未设置权限,默认自身机构
        if (StringUtils.isEmpty(saasOrg)) {
            saasOrg = key;
        }
        return saasOrg;
    }
    //------------------------------------ 资源化相关 START -------------------------------------------------------
    /**
     * 获取资源化数据元映射 redis
     *
     * @return
     */
    public String getRsAdapterMetaData(String cdaVersion, String srcDataSetCode, String srcMetadataCode) {
        return rsAdapterMetaKeySchema.getMetaData(cdaVersion, srcDataSetCode, srcMetadataCode);
    }
    /**
     * 获取资源化数据元映射 redis
     *
     * @return
     */
    public String getRsMetadataDict(String key) {
        return rsMetadataKeySchema.get(key);
    }
    //------------------------------------ 资源化相关 END -------------------------------------------------------
    //------------------------------------ 标准相关 START -------------------------------------------------------
    /**
     * 获取标准版本 redis
     */
    public String getStdVersion(String key) {
        return stdVersionKeySchema.get(key);
    }
    /**
     * 获取标准数据集代码 redis
     */
    public String getDataSetCode(String version, String id) {
        return stdDataSetKeySchema.dataSetCode(version, id);
    }
    /**
     * 获取标准数据集名称 redis
     */
    public String getDataSetName(String version, String id) {
        return stdDataSetKeySchema.dataSetName(version, id);
    }
    /**
     * 获取标准数据集名称 redis
     */
    public String getDataSetNameByCode(String version, String code) {
        return stdDataSetKeySchema.dataSetNameByCode(version, code);
    }
    /**
     * 获取标准数据集--主从表 redis
     */
    public Boolean getDataSetMultiRecord(String version, String code) {
        return stdDataSetKeySchema.dataSetMultiRecord(version, code);
    }
    /**
     * 获取标准数据元对应类型 redis
     */
    public String getMetaDataType(String version, String dataSetCode, String innerCode) {
        return stdMetaDataKeySchema.metaDataType(version, dataSetCode, innerCode);
    }
    /**
     * 获取数据元格式
     *
     * @param version
     * @param dataSetCode
     * @param innerCode
     * @return
     */
    public String getMetaDataFormat(String version, String dataSetCode, String innerCode) {
        return stdMetaDataKeySchema.metaDataFormat(version, dataSetCode, innerCode);
    }
    /**
     * 获取数据元是否为空
     *
     * @param version
     * @param dataSetCode
     * @param innerCode
     * @return
     */
    public Boolean isMetaDataNullable(String version, String dataSetCode, String innerCode) {
        return stdMetaDataKeySchema.metaDataNullable(version, dataSetCode, innerCode);
    }
    /**
     * 获取标准数据元对应字典 redis
     */
    public String getMetaDataDict(String version, String dataSetCode, String innerCode) {
        return stdMetaDataKeySchema.metaDataDict(version, dataSetCode, innerCode);
    }
    /**
     * 获取标准数据字典对应值 redis
     */
    public String getDictEntryValue(String version, String dictId, String entryCode) {
        return stdMetaDataKeySchema.dictEntryValue(version, dictId, entryCode);
    }
    /**
     * 判断值域编码是否存在
     *
     * @param version
     * @param dictId
     * @param entryCode
     * @return
     */
    public Boolean isDictCodeExist(String version, String dictId, String entryCode) {
        return stdMetaDataKeySchema.isDictCodeExist(version, dictId, entryCode);
    }
    /**
     * 判断值域编码是否存在
     *
     * @param version
     * @param dictId
     * @param entryValue
     * @return
     */
    public Boolean isDictValueExist(String version, String dictId, String entryValue) {
        return stdMetaDataKeySchema.isDictValueExist(version, dictId, entryValue);
    }
    //------------------------------------ 标准相关 END -------------------------------------------------------
    /**
     * 获取指标 redis
     *
     * @return
     */
    /*public String getIndicators(String key) {
        return indicatorsDictKeySchema.get(key);
    }*/
}

+ 106 - 0
src/main/java/com/yihu/ehr/redis/cache/service/RedisUpdateService.java

@ -0,0 +1,106 @@
package com.yihu.ehr.redis.cache.service;
import com.yihu.ehr.redis.schema.OrgKeySchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * Created by Sxy on 2017/08/28.
 * Redis更新服务
 */
@Service
public class RedisUpdateService {
    @Autowired
    private OrgKeySchema orgKeySchema;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    /**
     * 更新机构名称缓存
     * @param orgCode
     * @return
     */
    public boolean updateOrgName(String orgCode) {
        String sql = "select full_name from organizations where org_code = '" + orgCode + "'";
        try {
            Map<String, Object> resultMap = jdbcTemplate.queryForMap(sql);
            orgKeySchema.set(orgCode, String.valueOf(resultMap.get("full_name")));
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 更新机构区域缓存
     * @param orgCode
     * @return
     */
    public boolean updateOrgArea(String orgCode) {
        String sql = "select administrative_division from organizations where org_code = '" +  orgCode + "'";
        try {
            Map<String, Object> resultMap = jdbcTemplate.queryForMap(sql);
            orgKeySchema.setOrgArea(orgCode, String.valueOf(resultMap.get("administrative_division")));
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 更新机构Saas区域缓存
     * @param orgCode
     * @return
     */
    public boolean updateOrgSaasArea(String orgCode) {
        String sql = "select saas_code from org_saas where type='1' and org_code = '" + orgCode  + "' order by saas_code";
        try {
            List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql);
            String value = "";
            for(Map<String, Object> tempMap : resultList) {
                String saasCode = String.valueOf(tempMap.get("saas_code"));
                value += saasCode + ",";
            }
            if(value.equals("")) {
                return false;
            }
            orgKeySchema.setOrgSaasArea(orgCode, value.substring(0, value.length() - 1));
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 更新机构Saas机构缓存
     * @param orgCode
     * @return
     */
    public boolean updateOrgSaasOrg(String orgCode) {
        String sql = "select saas_code from org_saas where type='2' and org_code = '" + orgCode  + "' order by saas_code";
        try {
            List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql);
            String value = "";
            for(Map<String, Object> tempMap : resultList) {
                String saasCode = String.valueOf(tempMap.get("saas_code"));
                value += saasCode + ",";
            }
            if(value.equals("")) {
                return false;
            }
            orgKeySchema.setOrgSaasOrg(orgCode, value.substring(0, value.length() - 1));
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

+ 27 - 0
src/main/java/com/yihu/ehr/redis/config/RedisConfig.java

@ -0,0 +1,27 @@
package com.yihu.ehr.redis.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
 * redis 配置
 *
 * @author 张进军
 * @date 2017/11/2 11:15
 */
@Configuration
public class RedisConfig {
    @Bean
    RedisMessageListenerContainer redisMessageListenerContainer(JedisConnectionFactory jedisConnectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(jedisConnectionFactory);
        return container;
    }
}

+ 30 - 0
src/main/java/com/yihu/ehr/redis/config/ScheduleConfig.java

@ -0,0 +1,30 @@
package com.yihu.ehr.redis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
 * 配置 @Scheduled 支持并发处理
 *
 * @author 张进军
 * @date 2018/5/29 18:33
 */
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }
    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }
}

+ 46 - 0
src/main/java/com/yihu/ehr/redis/pubsub/CustomMessageListenerAdapter.java

@ -0,0 +1,46 @@
package com.yihu.ehr.redis.pubsub;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
/**
 * 重写父类 MessageListenerAdapter 的 equals() 方法
 *
 * @author 张进军
 * @date 2017/11/16 17:33
 */
public class CustomMessageListenerAdapter extends MessageListenerAdapter {
    // 消息队列编码
    private String channel;
    public CustomMessageListenerAdapter(DefaultMessageDelegate delegate) {
        super.setDelegate(delegate);
        this.channel = super.getDelegate().toString();
    }
    public int hashCode() {
        return this.channel.hashCode();
    }
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (!(obj instanceof CustomMessageListenerAdapter)) {
            return false;
        } else {
            CustomMessageListenerAdapter other = (CustomMessageListenerAdapter) obj;
            if (this.channel == null) {
                if (other.channel != null) {
                    return false;
                }
            } else if (!this.channel.equals(other.channel)) {
                return false;
            }
            return true;
        }
    }
}

+ 129 - 0
src/main/java/com/yihu/ehr/redis/pubsub/DefaultMessageDelegate.java

@ -0,0 +1,129 @@
package com.yihu.ehr.redis.pubsub;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.profile.queue.RedisCollection;
import com.yihu.ehr.redis.pubsub.entity.RedisMqMessageLog;
import com.yihu.ehr.redis.pubsub.entity.RedisMqSubscriber;
import com.yihu.ehr.redis.pubsub.service.RedisMqSubscriberService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
 * Redis 订阅发布的消息代理
 *
 * @author 张进军
 * @date 2017/11/3 10:51
 */
public class DefaultMessageDelegate implements MessageDelegate {
    private static final Logger logger = Logger.getLogger(DefaultMessageDelegate.class);
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private RedisMqSubscriberService redisMqSubscriberService;
    @Override
    public void handleMessage(String message, String channel) {
        try {
            Map<String, Object> messageMap = objectMapper.readValue(message, Map.class);
            String messageId = messageMap.get("messageId").toString();
            String publisherAppId = messageMap.get("publisherAppId").toString();
            String messageContent = messageMap.get("messageContent").toString();
            List<RedisMqSubscriber> subscriberList = redisMqSubscriberService.findByChannel(channel);
            if (subscriberList.size() == 0) {
                // 收集订阅成功的消息,定时任务里累计出列数
                RedisMqMessageLog messageLog = MessageCommonBiz.newMessageLog(channel, publisherAppId, messageContent);
                redisTemplate.opsForList().leftPush(RedisCollection.SUB_SUCCESSFUL_MESSAGES, objectMapper.writeValueAsString(messageLog));
            } else {
                // 遍历消息队列的订阅者,并推送消息
                for (RedisMqSubscriber subscriber : subscriberList) {
                    String subscribedUrl = subscriber.getSubscribedUrl();
                    try {
                        // 推送消息到指定服务地址
                        HttpHeaders headers = new HttpHeaders();
                        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                        HttpEntity<String> entity = new HttpEntity<>(messageContent, headers);
                        restTemplate.postForObject(subscribedUrl, entity, String.class);
                        // 收集订阅成功的消息,定时任务里累计出列数
                        RedisMqMessageLog messageLog = MessageCommonBiz.newMessageLog(channel, publisherAppId, messageContent);
                        if (!StringUtils.isEmpty(messageId)) {
                            // 首次订阅失败,但重试订阅成功场合
                            messageLog.setId(messageId);
                        }
                        redisTemplate.opsForList().leftPush(RedisCollection.SUB_SUCCESSFUL_MESSAGES, objectMapper.writeValueAsString(messageLog));
                    } catch (Exception e) {
                        e.printStackTrace();
                        // 收集订阅失败的消息
                        RedisMqMessageLog messageLog = MessageCommonBiz.newMessageLog(channel, publisherAppId, messageContent);
                        messageLog.setErrorMsg(e.toString());
                        if (!StringUtils.isEmpty(messageId)) {
                            // 非头次订阅失败
                            messageLog.setId(messageId);
                            // 通过 -1 标记为非头次订阅失败,定时任务里累计更新失败次数。
                            messageLog.setFailedNum(-1);
                        }
                        redisTemplate.opsForList().leftPush(RedisCollection.SUB_FAILED_MESSAGES, objectMapper.writeValueAsString(messageLog));
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 消息队列编码
    private String channel;
    public DefaultMessageDelegate(String channel) {
        this.channel = channel;
    }
    public int hashCode() {
        return this.channel.hashCode();
    }
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (!(obj instanceof DefaultMessageDelegate)) {
            return false;
        } else {
            DefaultMessageDelegate other = (DefaultMessageDelegate) obj;
            if (this.channel == null) {
                if (other.channel != null) {
                    return false;
                }
            } else if (!this.channel.equals(other.channel)) {
                return false;
            }
            return true;
        }
    }
    public String toString() {
        return this.channel;
    }
}

+ 46 - 0
src/main/java/com/yihu/ehr/redis/pubsub/MessageCommonBiz.java

@ -0,0 +1,46 @@
package com.yihu.ehr.redis.pubsub;
import com.yihu.ehr.lang.SpringContext;
import com.yihu.ehr.redis.pubsub.entity.RedisMqMessageLog;
import com.yihu.ehr.util.id.UuidUtil;
/**
 * 消息发布订阅共通业务方法
 *
 * @author 张进军
 * @date 2017/11/20 17:03
 */
public class MessageCommonBiz {
    /**
     *  实例化一个 RedisMqMessageLog
     * @param channel 消息队列编码
     * @param publisherAppId 发布者应用ID
     * @param message 要发布的消息
     * @return RedisMqMessageLog
     */
    public static RedisMqMessageLog newMessageLog(String channel, String publisherAppId, String message) {
        RedisMqMessageLog redisMqMessageLog = new RedisMqMessageLog();
        redisMqMessageLog.setId(UuidUtil.randomUUID());
        redisMqMessageLog.setChannel(channel);
        redisMqMessageLog.setPublisherAppId(publisherAppId);
        redisMqMessageLog.setMessage(message);
        redisMqMessageLog.setStatus(0);
        redisMqMessageLog.setFailedNum(0);
        return redisMqMessageLog;
    }
    /**
     *  实例化一个 CustomMessageListenerAdapter
     * @param channel 消息队列编码
     * @return CustomMessageListenerAdapter
     */
    public static CustomMessageListenerAdapter newCustomMessageListenerAdapter(String channel) {
        DefaultMessageDelegate defaultMessageDelegate = new DefaultMessageDelegate(channel);
        SpringContext.autowiredBean(defaultMessageDelegate);
        CustomMessageListenerAdapter messageListener = new CustomMessageListenerAdapter(defaultMessageDelegate);
        SpringContext.autowiredBean(messageListener);
        return messageListener;
    }
}

+ 13 - 0
src/main/java/com/yihu/ehr/redis/pubsub/MessageDelegate.java

@ -0,0 +1,13 @@
package com.yihu.ehr.redis.pubsub;
/**
 * Redis 订阅发布的消息代理接口
 *
 * @author 张进军
 * @date 2017/11/2 13:43
 */
public interface MessageDelegate {
    void handleMessage(String message, String channel);
}

+ 182 - 0
src/main/java/com/yihu/ehr/redis/pubsub/PubSubMessageJob.java

@ -0,0 +1,182 @@
package com.yihu.ehr.redis.pubsub;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.profile.queue.RedisCollection;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import com.yihu.ehr.redis.pubsub.entity.RedisMqMessageLog;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import com.yihu.ehr.redis.pubsub.service.RedisMqMessageLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;
/**
 * 定时定量处理消息,包括:
 * - 发送消息。
 * - 重试订阅失败的消息。
 * - 处理订阅成功的消息。
 *
 * @author 张进军
 * @date 2018/5/7 14:01
 */
@Component
public class PubSubMessageJob {
    private Logger logger = LoggerFactory.getLogger(PubSubMessageJob.class);
    // 最大次数尝试重发订阅失败消息
    private final int maxFailedNum = 3;
    // 每次定时最多操作的消息数量
    private final int onceNum = 1000;
    @Autowired
    RedisMqChannelService redisMqChannelService;
    @Autowired
    RedisMqMessageLogService redisMqMessageLogService;
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    ObjectMapper objectMapper;
    /*
     * 发送消息
     */
    @Scheduled(initialDelay = 1000, fixedDelay = 5000)
    public void send() {
        try {
            int num = 0;
            while (true) {
                Object msgObj = redisTemplate.opsForList().rightPop(RedisCollection.PUB_WAITING_MESSAGES);
                if (msgObj == null) {
                    break;
                }
                Map<String, Object> messageMap = objectMapper.readValue(String.valueOf(msgObj), Map.class);
                String channel = messageMap.get("channel").toString();
                // 发布消息
                redisTemplate.convertAndSend(channel, objectMapper.writeValueAsString(messageMap));
                // 累计入列数
                RedisMqChannel afterChannel = updateChannelQueueNumber(channel, "Enqueued");
                num++;
                if (num == onceNum) {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
     * 重试订阅失败的消息
     */
    @Scheduled(initialDelay = 1000, fixedDelay = 5000)
    public void resend() {
        try {
            int num = 0;
            while (true) {
                Object msgObj = redisTemplate.opsForList().rightPop(RedisCollection.SUB_FAILED_MESSAGES);
                if (msgObj == null) {
                    break;
                }
                boolean valid = true;
                RedisMqMessageLog cacheMessageLog = objectMapper.readValue(String.valueOf(msgObj), RedisMqMessageLog.class);
                if (cacheMessageLog.getFailedNum() == 0) {
                    // 头次订阅失败,则保存到数据库中
                    cacheMessageLog.setFailedNum(1);
                    redisMqMessageLogService.save(cacheMessageLog);
                } else if (cacheMessageLog.getFailedNum() == -1) {
                    // 累计订阅失败次数
                    RedisMqMessageLog dbMessageLog = redisMqMessageLogService.getById(cacheMessageLog.getId());
                    if (dbMessageLog.getFailedNum() >= maxFailedNum) {
                        // 大于等于最大尝试失败数,则不再重试。
                        valid = false;
                    } else {
                        dbMessageLog.setFailedNum(dbMessageLog.getFailedNum() + 1);
                        dbMessageLog.setErrorMsg(cacheMessageLog.getErrorMsg());
                        redisMqMessageLogService.save(dbMessageLog);
                    }
                }
                if (valid) {
                    // 将消息加入到待发缓存集合中
                    redisMqChannelService.addToPubWaitingMessage(cacheMessageLog.getPublisherAppId(),
                            cacheMessageLog.getChannel(), cacheMessageLog.getMessage(), cacheMessageLog.getId());
                    num++;
                    if (num == onceNum) {
                        break;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
     * 处理订阅成功的消息。
     * 累计出列数、更新重试成功的订阅失败消息的状态。
     */
    @Scheduled(initialDelay = 1000, fixedDelay = 5000)
    public void update() {
        try {
            int num = 0;
            while (true) {
                Object msgObj = redisTemplate.opsForList().rightPop(RedisCollection.SUB_SUCCESSFUL_MESSAGES);
                if (msgObj == null) {
                    break;
                }
                RedisMqMessageLog cacheMessageLog = objectMapper.readValue(String.valueOf(msgObj), RedisMqMessageLog.class);
                RedisMqMessageLog dbMessageLog = redisMqMessageLogService.getById(cacheMessageLog.getId());
                if (dbMessageLog != null && dbMessageLog.getStatus() == 0) {
                    // 更新重试成功的订阅失败消息的状态
                    redisMqMessageLogService.updateStatus(cacheMessageLog.getId(), 1);
                }
                // 累计出列数
                RedisMqChannel afterChannel = updateChannelQueueNumber(cacheMessageLog.getChannel(), "Dequeued");
                num++;
                if (num == onceNum) {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 累计 channel 的出入列数
     *
     * @param channel 队列编码
     * @param type    出入列类型标识符
     * @return RedisMqChannel
     */
    private synchronized RedisMqChannel updateChannelQueueNumber(String channel, String type) {
        RedisMqChannel mqChannelAfter = null;
        RedisMqChannel mqChannel = redisMqChannelService.findByChannel(channel);
        if ("Dequeued".equals(type)) {
            // 累计出列数
            mqChannel.setDequeuedNum(mqChannel.getDequeuedNum() + 1);
            mqChannelAfter = redisMqChannelService.save(mqChannel);
        } else if ("Enqueued".equals(type)) {
            // 累计入列数
            mqChannel.setEnqueuedNum(mqChannel.getEnqueuedNum() + 1);
            mqChannelAfter = redisMqChannelService.save(mqChannel);
        }
        return mqChannelAfter;
    }
}

+ 247 - 0
src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqChannelEndPoint.java

@ -0,0 +1,247 @@
package com.yihu.ehr.redis.pubsub.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.model.redis.MRedisCacheCategory;
import com.yihu.ehr.model.redis.MRedisMqChannel;
import com.yihu.ehr.redis.pubsub.CustomMessageListenerAdapter;
import com.yihu.ehr.redis.pubsub.MessageCommonBiz;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import com.yihu.ehr.redis.pubsub.entity.RedisMqMessageLog;
import com.yihu.ehr.redis.pubsub.entity.RedisMqPublisher;
import com.yihu.ehr.redis.pubsub.entity.RedisMqSubscriber;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import com.yihu.ehr.redis.pubsub.service.RedisMqMessageLogService;
import com.yihu.ehr.redis.pubsub.service.RedisMqPublisherService;
import com.yihu.ehr.redis.pubsub.service.RedisMqSubscriberService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
 * Redis消息队列 接口
 *
 * @author 张进军
 * @date 2017/11/10 11:45
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "消息队列接口", tags = {"Redis消息发布订阅--消息队列接口"})
public class RedisMqChannelEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisMqChannelService redisMqChannelService;
    @Autowired
    private RedisMqMessageLogService redisMqMessageLogService;
    @Autowired
    private RedisMqSubscriberService redisMqSubscriberService;
    @Autowired
    private RedisMqPublisherService redisMqPublisherService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private RedisMessageListenerContainer redisMessageListenerContainer;
    @ApiOperation("根据ID获取消息队列")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.GetById, method = RequestMethod.GET)
    public Envelop getById(
            @ApiParam(name = "id", value = "主键", required = true)
            @PathVariable(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            MRedisMqChannel mRedisMqChannel = convertToModel(redisMqChannelService.getById(id), MRedisMqChannel.class);
            envelop.setObj(mRedisMqChannel);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取消息队列。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取消息队列发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "根据条件获取消息队列")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.Search, method = RequestMethod.GET)
    public Envelop search(
            @ApiParam(name = "fields", value = "返回的字段,为空则返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "筛选条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "页码", defaultValue = "1")
            @RequestParam(value = "page", required = false) int page,
            @ApiParam(name = "size", value = "分页大小", defaultValue = "15")
            @RequestParam(value = "size", required = false) int size) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            List<RedisMqChannel> redisMqChannelList = redisMqChannelService.search(fields, filters, sorts, page, size);
            int count = (int) redisMqChannelService.getCount(filters);
            List<MRedisMqChannel> mRedisMqChannelList = (List<MRedisMqChannel>) convertToModels(redisMqChannelList, new ArrayList<MRedisMqChannel>(), MRedisMqChannel.class, fields);
            envelop = getPageResult(mRedisMqChannelList, count, page, size);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取消息队列列表。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取消息队列发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("新增消息队列")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.Save, method = RequestMethod.POST)
    public Envelop add(
            @ApiParam(value = "消息队列JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqChannel newEntity = objectMapper.readValue(entityJson, RedisMqChannel.class);
            newEntity.setDequeuedNum(0);
            newEntity.setEnqueuedNum(0);
            newEntity.setPublisherNum(0);
            newEntity.setSubscriberNum(0);
            newEntity = redisMqChannelService.save(newEntity);
            // 开启该订阅者的消息队列的消息监听
            String channel = newEntity.getChannel();
            CustomMessageListenerAdapter messageListener = MessageCommonBiz.newCustomMessageListenerAdapter(channel);
            redisMessageListenerContainer.addMessageListener(messageListener, new ChannelTopic(channel));
            MRedisCacheCategory mRedisCacheCategory = convertToModel(newEntity, MRedisCacheCategory.class);
            envelop.setObj(mRedisCacheCategory);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功新增消息队列。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("新增消息队列发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("更新消息队列")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.Save, method = RequestMethod.PUT)
    public Envelop update(
            @ApiParam(value = "消息队列JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqChannel updateEntity = objectMapper.readValue(entityJson, RedisMqChannel.class);
            updateEntity = redisMqChannelService.save(updateEntity);
            MRedisMqChannel mRedisMqChannel = convertToModel(updateEntity, MRedisMqChannel.class);
            envelop.setObj(mRedisMqChannel);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功更新消息队列。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("更新消息队列发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("删除消息队列")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.Delete, method = RequestMethod.DELETE)
    public Envelop delete(
            @ApiParam(name = "id", value = "消息队列ID", required = true)
            @RequestParam(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        RedisMqChannel redisMqChannel = redisMqChannelService.getById(id);
        String channel = redisMqChannel.getChannel();
        List<RedisMqMessageLog> messageLogList = redisMqMessageLogService.findByChannel(channel);
        if (messageLogList.size() != 0) {
            envelop.setSuccessFlg(false);
            envelop.setErrorMsg("该消息队列存在订阅失败的消息,不能删除。");
            return envelop;
        }
        List<RedisMqSubscriber> subscriberList = redisMqSubscriberService.findByChannel(channel);
        if (subscriberList.size() != 0) {
            envelop.setSuccessFlg(false);
            envelop.setErrorMsg("该消息队列存在订阅者,不能删除。");
            return envelop;
        }
        List<RedisMqPublisher> publisherList = redisMqPublisherService.findByChannel(channel);
        if (publisherList.size() != 0) {
            envelop.setSuccessFlg(false);
            envelop.setErrorMsg("该消息队列存在发布者,不能删除。");
            return envelop;
        }
        redisMqChannelService.delete(id);
        // 删除该消息队列的消息监听
        CustomMessageListenerAdapter messageListener = MessageCommonBiz.newCustomMessageListenerAdapter(channel);
        redisMessageListenerContainer.removeMessageListener(messageListener, new ChannelTopic(channel));
        envelop.setSuccessFlg(true);
        return envelop;
    }
    @ApiOperation("验证消息队列编码是否唯一")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.IsUniqueChannel, method = RequestMethod.GET)
    public Envelop isUniqueChannel(
            @ApiParam(name = "id", value = "消息队列ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "channel", value = "消息队列编码", required = true)
            @RequestParam(value = "channel") String channel) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisMqChannelService.isUniqueChannel(id, channel);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该消息队列编码已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证消息队列名称是否唯一")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.IsUniqueChannelName, method = RequestMethod.GET)
    public Envelop isUniqueChannelName(
            @ApiParam(name = "id", value = "消息队列ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "channelName", value = "消息队列名称", required = true)
            @RequestParam(value = "channelName") String channelName) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisMqChannelService.isUniqueChannelName(id, channelName);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该消息队列名称已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证消息队列是否已存在")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.IsExist, method = RequestMethod.GET)
    public Boolean isExist(
            @ApiParam(name = "channel", value = "消息队列", required = true)
            @RequestParam(value = "channel") String channel) {
        return redisMqChannelService.isExist(channel);
    }
}

+ 43 - 0
src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqOperationEndPoint.java

@ -0,0 +1,43 @@
package com.yihu.ehr.redis.pubsub.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * Redis消息队列操作 接口
 *
 * @author 张进军
 * @date 2017/12/27 16:09
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "消息队列操作接口", tags = {"Redis消息发布订阅--消息队列操作接口"})
public class RedisMqOperationEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisMqChannelService redisMqChannelService;
    @ApiOperation("发布消息")
    @RequestMapping(value = ServiceApi.Redis.MqChannel.SendMessage, method = RequestMethod.POST)
    public Envelop sendMessage(
            @ApiParam(name = "publisherAppId", value = "发布者应用ID", required = true)
            @RequestParam(value = "publisherAppId") String publisherAppId,
            @ApiParam(name = "channel", value = "消息队列编码", required = true)
            @RequestParam(value = "channel") String channel,
            @ApiParam(name = "message", value = "消息", required = true)
            @RequestParam(value = "message") String message) {
        return redisMqChannelService.sendMessage(publisherAppId, channel, message);
    }
}

+ 183 - 0
src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqPublisherEndPoint.java

@ -0,0 +1,183 @@
package com.yihu.ehr.redis.pubsub.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.model.redis.MRedisMqPublisher;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import com.yihu.ehr.redis.pubsub.entity.RedisMqPublisher;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import com.yihu.ehr.redis.pubsub.service.RedisMqPublisherService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
 * Redis消息发布者 接口
 *
 * @author 张进军
 * @date 2017/11/20 09:35
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "消息发布者接口", tags = {"Redis消息发布订阅--消息发布者接口"})
public class RedisMqPublisherEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisMqPublisherService redisMqPublisherService;
    @Autowired
    private RedisMqChannelService redisMqChannelService;
    @ApiOperation("根据ID获取消息发布者")
    @RequestMapping(value = ServiceApi.Redis.MqPublisher.GetById, method = RequestMethod.GET)
    public Envelop getById(
            @ApiParam(name = "id", value = "主键", required = true)
            @PathVariable(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            MRedisMqPublisher mRedisMqPublisher = convertToModel(redisMqPublisherService.getById(id), MRedisMqPublisher.class);
            envelop.setObj(mRedisMqPublisher);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取消息发布者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取消息发布者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "根据条件获取消息发布者")
    @RequestMapping(value = ServiceApi.Redis.MqPublisher.Search, method = RequestMethod.GET)
    public Envelop search(
            @ApiParam(name = "fields", value = "返回的字段,为空则返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "筛选条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "页码", defaultValue = "1")
            @RequestParam(value = "page", required = false) int page,
            @ApiParam(name = "size", value = "分页大小", defaultValue = "15")
            @RequestParam(value = "size", required = false) int size) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            List<RedisMqPublisher> list = redisMqPublisherService.search(fields, filters, sorts, page, size);
            int count = (int) redisMqPublisherService.getCount(filters);
            List<MRedisMqPublisher> mList = (List<MRedisMqPublisher>) convertToModels(list, new ArrayList<MRedisMqPublisher>(), MRedisMqPublisher.class, fields);
            envelop = getPageResult(mList, count, page, size);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取消息发布者列表。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取消息发布者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("新增消息发布者")
    @RequestMapping(value = ServiceApi.Redis.MqPublisher.Save, method = RequestMethod.POST)
    public Envelop add(
            @ApiParam(value = "消息发布者JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqPublisher newEntity = objectMapper.readValue(entityJson, RedisMqPublisher.class);
            newEntity = redisMqPublisherService.save(newEntity);
            // 累计发布者数
            RedisMqChannel channel = redisMqChannelService.findByChannel(newEntity.getChannel());
            channel.setPublisherNum(channel.getPublisherNum() + 1);
            redisMqChannelService.save(channel);
            MRedisMqPublisher mRedisMqPublisher = convertToModel(newEntity, MRedisMqPublisher.class);
            envelop.setObj(mRedisMqPublisher);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功新增消息发布者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("新增消息发布者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("更新消息发布者")
    @RequestMapping(value = ServiceApi.Redis.MqPublisher.Save, method = RequestMethod.PUT)
    public Envelop update(
            @ApiParam(value = "消息发布者JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqPublisher updateEntity = objectMapper.readValue(entityJson, RedisMqPublisher.class);
            updateEntity = redisMqPublisherService.save(updateEntity);
            MRedisMqPublisher mRedisMqPublisher = convertToModel(updateEntity, MRedisMqPublisher.class);
            envelop.setObj(mRedisMqPublisher);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功更新消息发布者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("更新消息发布者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("删除消息发布者")
    @RequestMapping(value = ServiceApi.Redis.MqPublisher.Delete, method = RequestMethod.DELETE)
    public Envelop delete(
            @ApiParam(name = "id", value = "消息发布者ID", required = true)
            @RequestParam(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqPublisher publisher = redisMqPublisherService.getById(id);
            redisMqPublisherService.delete(id);
            // 扣减发布者数
            RedisMqChannel channel = redisMqChannelService.findByChannel(publisher.getChannel());
            channel.setPublisherNum(channel.getPublisherNum() - 1);
            redisMqChannelService.save(channel);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功删除消息发布者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("删除消息发布者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证指定队列中发布者应用ID是否唯一")
    @RequestMapping(value = ServiceApi.Redis.MqPublisher.IsUniqueAppId, method = RequestMethod.GET)
    public Envelop isUniqueAppId(
            @ApiParam(name = "id", value = "消息订阅者ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "channel", value = "消息队列编码", required = true)
            @RequestParam(value = "channel") String channel,
            @ApiParam(name = "appId", value = "发布者应用ID", required = true)
            @RequestParam(value = "appId") String appId) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisMqPublisherService.isUniqueAppId(id, channel, appId);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该指定队列的发布者应用ID已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
}

+ 240 - 0
src/main/java/com/yihu/ehr/redis/pubsub/controller/RedisMqSubscriberEndPoint.java

@ -0,0 +1,240 @@
package com.yihu.ehr.redis.pubsub.controller;
import com.yihu.ehr.constants.ApiVersion;
import com.yihu.ehr.constants.ServiceApi;
import com.yihu.ehr.controller.EnvelopRestEndPoint;
import com.yihu.ehr.model.redis.MRedisMqSubscriber;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import com.yihu.ehr.redis.pubsub.entity.RedisMqSubscriber;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
import com.yihu.ehr.redis.pubsub.service.RedisMqSubscriberService;
import com.yihu.ehr.util.rest.Envelop;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
 * Redis消息订阅者 接口
 *
 * @author 张进军
 * @date 2017/11/13 15:14
 */
@RestController
@RequestMapping(value = ApiVersion.Version1_0)
@Api(description = "消息订阅者接口", tags = {"Redis消息发布订阅--消息订阅者接口"})
public class RedisMqSubscriberEndPoint extends EnvelopRestEndPoint {
    @Autowired
    private RedisMqSubscriberService redisMqSubscriberService;
    @Autowired
    private RedisMqChannelService redisMqChannelService;
    @Autowired
    private RedisMessageListenerContainer redisMessageListenerContainer;
    @ApiOperation("根据ID获取消息订阅者")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.GetById, method = RequestMethod.GET)
    public Envelop getById(
            @ApiParam(name = "id", value = "主键", required = true)
            @PathVariable(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            MRedisMqSubscriber mRedisMqSubscriber = convertToModel(redisMqSubscriberService.getById(id), MRedisMqSubscriber.class);
            envelop.setObj(mRedisMqSubscriber);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取消息订阅者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取消息订阅者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "根据条件获取消息订阅者")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.Search, method = RequestMethod.GET)
    public Envelop search(
            @ApiParam(name = "fields", value = "返回的字段,为空则返回全部字段")
            @RequestParam(value = "fields", required = false) String fields,
            @ApiParam(name = "filters", value = "筛选条件")
            @RequestParam(value = "filters", required = false) String filters,
            @ApiParam(name = "sorts", value = "排序")
            @RequestParam(value = "sorts", required = false) String sorts,
            @ApiParam(name = "page", value = "页码", defaultValue = "1")
            @RequestParam(value = "page", required = false) int page,
            @ApiParam(name = "size", value = "分页大小", defaultValue = "15")
            @RequestParam(value = "size", required = false) int size) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            List<RedisMqSubscriber> list = redisMqSubscriberService.search(fields, filters, sorts, page, size);
            int count = (int) redisMqSubscriberService.getCount(filters);
            List<MRedisMqSubscriber> mList = (List<MRedisMqSubscriber>) convertToModels(list, new ArrayList<MRedisMqSubscriber>(), MRedisMqSubscriber.class, fields);
            envelop = getPageResult(mList, count, page, size);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功获取消息订阅者列表。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("获取消息订阅者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation(value = "获取消息订阅者列表,不分页")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.Prefix, method = RequestMethod.GET)
    public Collection<MRedisMqSubscriber> getSubscriberList(
            @ApiParam(name = "filters", value = "过滤器,为空检索所有条件", defaultValue = "")
            @RequestParam(value = "filters") String filters) throws Exception {
        List<RedisMqSubscriber> subscriberList = redisMqSubscriberService.search(filters);
        return convertToModels(subscriberList, new ArrayList<>(subscriberList.size()), MRedisMqSubscriber.class, "");
    }
    @ApiOperation("新增消息订阅者")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.Save, method = RequestMethod.POST)
    public Envelop add(
            @ApiParam(value = "消息订阅者JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqSubscriber newEntity = objectMapper.readValue(entityJson, RedisMqSubscriber.class);
            newEntity = redisMqSubscriberService.save(newEntity);
            // 累计订阅者数
            RedisMqChannel channel = redisMqChannelService.findByChannel(newEntity.getChannel());
            channel.setSubscriberNum(channel.getSubscriberNum() + 1);
            redisMqChannelService.save(channel);
            MRedisMqSubscriber mRedisMqSubscriber = convertToModel(newEntity, MRedisMqSubscriber.class);
            envelop.setObj(mRedisMqSubscriber);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功新增消息订阅者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("新增消息订阅者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("更新消息订阅者")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.Save, method = RequestMethod.PUT)
    public Envelop update(
            @ApiParam(value = "消息订阅者JSON", required = true)
            @RequestBody String entityJson) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqSubscriber updateEntity = objectMapper.readValue(entityJson, RedisMqSubscriber.class);
            updateEntity = redisMqSubscriberService.save(updateEntity);
            MRedisMqSubscriber mRedisMqSubscriber = convertToModel(updateEntity, MRedisMqSubscriber.class);
            envelop.setObj(mRedisMqSubscriber);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功更新消息订阅者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("更新消息订阅者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("删除消息订阅者")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.Delete, method = RequestMethod.DELETE)
    public Envelop delete(
            @ApiParam(name = "id", value = "消息订阅者ID", required = true)
            @RequestParam(value = "id") Integer id) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            RedisMqSubscriber subscriber = redisMqSubscriberService.getById(id);
            redisMqSubscriberService.delete(id);
            // 扣减订阅者数
            RedisMqChannel channel = redisMqChannelService.findByChannel(subscriber.getChannel());
            channel.setSubscriberNum(channel.getSubscriberNum() - 1);
            redisMqChannelService.save(channel);
            envelop.setSuccessFlg(true);
            envelop.setErrorMsg("成功删除消息订阅者。");
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("删除消息订阅者发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证指定消息队列中订阅者应用ID是否唯一")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.IsUniqueAppId, method = RequestMethod.GET)
    public Envelop isUniqueAppId(
            @ApiParam(name = "id", value = "消息订阅者ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "channel", value = "消息队列编码", required = true)
            @RequestParam(value = "channel") String channel,
            @ApiParam(name = "appId", value = "消息订阅者应用ID", required = true)
            @RequestParam(value = "appId") String appId) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisMqSubscriberService.isUniqueAppId(id, channel, appId);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该指定消息队列中订阅者应用ID已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证指定消息队列中订阅者服务地址是否唯一")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.IsUniqueSubscribedUrl, method = RequestMethod.GET)
    public Envelop isUniqueSubscribedUrl(
            @ApiParam(name = "id", value = "消息订阅者ID", required = true)
            @RequestParam(value = "id") Integer id,
            @ApiParam(name = "channel", value = "消息队列编码", required = true)
            @RequestParam(value = "channel") String channel,
            @ApiParam(name = "subscriberUrl", value = "消息订阅者服务地址", required = true)
            @RequestParam(value = "subscriberUrl") String subscriberUrl) {
        Envelop envelop = new Envelop();
        envelop.setSuccessFlg(false);
        try {
            boolean result = redisMqSubscriberService.isUniqueSubscribedUrl(id, channel, subscriberUrl);
            envelop.setSuccessFlg(result);
            if (!result) {
                envelop.setErrorMsg("该指定消息队列中订阅者服务地址已被使用,请重新填写!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setErrorMsg("发生异常:" + e.getMessage());
        }
        return envelop;
    }
    @ApiOperation("验证消息队列的订阅者服务地址是否存在")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.IsExist, method = RequestMethod.GET)
    public Boolean isExist(
            @ApiParam(name = "channel", value = "消息队列编码", required = true)
            @RequestParam(value = "channel") String channel,
            @ApiParam(name = "subscriber", value = "消息订阅者服务地址", required = true)
            @RequestParam(value = "subscriber") String subscriber) {
        return redisMqSubscriberService.isExist(channel, subscriber);
    }
    @ApiOperation("取消队列的订阅者")
    @RequestMapping(value = ServiceApi.Redis.MqSubscriber.Unsubscribe, method = RequestMethod.POST)
    public void unsubscribe(
            @ApiParam(name = "channel", value = "消息队列编码", required = true)
            @RequestParam(value = "channel") String channel,
            @ApiParam(name = "subscriber", value = "消息订阅者服务地址", required = false)
            @RequestParam(value = "subscriber", required = false) String subscriber) {
        redisMqSubscriberService.unsubscribe(channel, subscriber);
    }
}

+ 24 - 0
src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqChannelDao.java

@ -0,0 +1,24 @@
package com.yihu.ehr.redis.pubsub.dao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
/**
 * redis消息队列 DAO
 *
 * @author 张进军
 * @date 2017/11/10 11:45
 */
public interface RedisMqChannelDao extends PagingAndSortingRepository<RedisMqChannel, Integer> {
    RedisMqChannel findByChannel(@Param("channel") String channel);
    @Query(" FROM RedisMqChannel rmc WHERE rmc.id <> :id AND rmc.channel = :channel ")
    RedisMqChannel isUniqueChannel(@Param("id") Integer id, @Param("channel") String channel);
    @Query(" FROM RedisMqChannel rmc WHERE rmc.id <> :id AND rmc.channelName = :channelName ")
    RedisMqChannel isUniqueChannelName(@Param("id") Integer id, @Param("channelName") String channelName);
}

+ 25 - 0
src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqMessageLogDao.java

@ -0,0 +1,25 @@
package com.yihu.ehr.redis.pubsub.dao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqMessageLog;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
 * redis消息记录 DAO
 *
 * @author 张进军
 * @date 2017/11/10 11:45
 */
public interface RedisMqMessageLogDao extends PagingAndSortingRepository<RedisMqMessageLog, String> {
    List<RedisMqMessageLog> findByChannel(@Param("channel") String channel);
    @Modifying
    @Query("update RedisMqMessageLog set status=:status where id=:id")
    void updateStatus(@Param("id") String id, @Param("status") Integer status);
}

+ 25 - 0
src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqPublisherDao.java

@ -0,0 +1,25 @@
package com.yihu.ehr.redis.pubsub.dao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqPublisher;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
 * redis消息发布者 DAO
 *
 * @author 张进军
 * @date 2017/11/20 09:35
 */
public interface RedisMqPublisherDao extends PagingAndSortingRepository<RedisMqPublisher, Integer> {
    List<RedisMqPublisher> findByChannel(@Param("channel") String channel);
    RedisMqPublisher findByChannelAndAppId(@Param("channel") String channel, @Param("appId") String appId);
    @Query(" FROM RedisMqPublisher rmp WHERE rmp.id <> :id AND rmp.channel = :channel AND rmp.appId = :appId ")
    RedisMqPublisher isUniqueAppId(@Param("id") Integer id, @Param("channel") String channel, @Param("appId") String appId);
}

+ 28 - 0
src/main/java/com/yihu/ehr/redis/pubsub/dao/RedisMqSubscriberDao.java

@ -0,0 +1,28 @@
package com.yihu.ehr.redis.pubsub.dao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqSubscriber;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
 * redis消息订阅者 DAO
 *
 * @author 张进军
 * @date 2017/11/10 11:45
 */
public interface RedisMqSubscriberDao extends PagingAndSortingRepository<RedisMqSubscriber, Integer> {
    List<RedisMqSubscriber> findByChannel(@Param("channel") String channel);
    RedisMqSubscriber findByChannelAndAndSubscribedUrl(String channel, String subscribedUrl);
    @Query(" FROM RedisMqSubscriber rms WHERE rms.id <> :id AND rms.channel = :channel AND rms.appId = :appId ")
    RedisMqSubscriber isUniqueAppId(@Param("id") Integer id, @Param("channel") String channel, @Param("appId") String appId);
    @Query(" FROM RedisMqSubscriber rms WHERE rms.id <> :id AND rms.channel = :channel AND rms.subscribedUrl = :subscribedUrl ")
    RedisMqSubscriber isUniqueSubscribedUrl(@Param("id") Integer id, @Param("channel") String channel, @Param("subscribedUrl") String subscribedUrl);
}

+ 100 - 0
src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqChannel.java

@ -0,0 +1,100 @@
package com.yihu.ehr.redis.pubsub.entity;
import com.yihu.ehr.entity.BaseIdentityEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * redis消息队列 Entity
 *
 * @author 张进军
 * @date 2017/11/10 11:14
 */
@Entity
@Table(name = "redis_mq_channel")
public class RedisMqChannel extends BaseIdentityEntity {
    public String channel; // 消息队列编码
    public String channelName; // 消息队列名称
    public String messageTemplate; // 消息模版
    public String remark; // 备注
    public Integer enqueuedNum; // 入列数
    public Integer dequeuedNum; // 出列数
    public Integer subscriberNum; // 订阅者数
    public Integer publisherNum; // 发布者数
    @Column(name = "channel")
    public String getChannel() {
        return channel;
    }
    public void setChannel(String channel) {
        this.channel = channel;
    }
    @Column(name = "channel_name")
    public String getChannelName() {
        return channelName;
    }
    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }
    @Column(name = "message_template")
    public String getMessageTemplate() {
        return messageTemplate;
    }
    public void setMessageTemplate(String messageTemplate) {
        this.messageTemplate = messageTemplate;
    }
    @Column(name = "remark")
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
    @Column(name = "enqueued_num")
    public Integer getEnqueuedNum() {
        return enqueuedNum;
    }
    public void setEnqueuedNum(Integer enqueuedNum) {
        this.enqueuedNum = enqueuedNum;
    }
    @Column(name = "dequeued_num")
    public Integer getDequeuedNum() {
        return dequeuedNum;
    }
    public void setDequeuedNum(Integer dequeuedNum) {
        this.dequeuedNum = dequeuedNum;
    }
    @Column(name = "subscriber_num")
    public Integer getSubscriberNum() {
        return subscriberNum;
    }
    public void setSubscriberNum(Integer subscriberNum) {
        this.subscriberNum = subscriberNum;
    }
    @Column(name = "publisher_num")
    public Integer getPublisherNum() {
        return publisherNum;
    }
    public void setPublisherNum(Integer publisherNum) {
        this.publisherNum = publisherNum;
    }
}

+ 80 - 0
src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqMessageLog.java

@ -0,0 +1,80 @@
package com.yihu.ehr.redis.pubsub.entity;
import com.yihu.ehr.entity.BaseAssignedEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
 * 消费失败的消息记录 Entity
 *
 * @author 张进军
 * @date 2017/11/10 11:14
 */
@Entity
@Table(name = "redis_mq_message_log")
public class RedisMqMessageLog extends BaseAssignedEntity {
    public String message; // 消息
    public String channel; // 消息队列编码
    public String publisherAppId; // 发布者应用ID
    public Integer status; // 消费状态,1:已消费,未消费
    public String errorMsg; // 异常消息
    public Integer failedNum; // 订阅失败次数
    @Column(name = "message")
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Column(name = "channel")
    public String getChannel() {
        return channel;
    }
    public void setChannel(String channel) {
        this.channel = channel;
    }
    @Column(name = "publisher_app_id")
    public String getPublisherAppId() {
        return publisherAppId;
    }
    public void setPublisherAppId(String publisherAppId) {
        this.publisherAppId = publisherAppId;
    }
    @Column(name = "status")
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    @Column(name = "error_msg")
    public String getErrorMsg() {
        return errorMsg;
    }
    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
    @Column(name = "failed_num")
    public Integer getFailedNum() {
        return failedNum;
    }
    public void setFailedNum(Integer failedNum) {
        this.failedNum = failedNum;
    }
}

+ 58 - 0
src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqPublisher.java

@ -0,0 +1,58 @@
package com.yihu.ehr.redis.pubsub.entity;
import com.yihu.ehr.entity.BaseIdentityEntity;
import javax.persistence.*;
/**
 * redis消息发布者 Entity
 *
 * @author 张进军
 * @date 2017/11/20 09:35
 */
@Entity
@Table(name = "redis_mq_publisher")
public class RedisMqPublisher extends BaseIdentityEntity {
    public String appId; // 应用ID
    public String authorizedCode; // 授权码
    public String channel; // 消息队列编码
    public String remark; // 备注
    @Column(name = "app_id")
    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }
    @Column(name = "authorized_code")
    public String getAuthorizedCode() {
        return authorizedCode;
    }
    public void setAuthorizedCode(String authorizedCode) {
        this.authorizedCode = authorizedCode;
    }
    @Column(name = "channel")
    public String getChannel() {
        return channel;
    }
    public void setChannel(String channel) {
        this.channel = channel;
    }
    @Column(name = "remark")
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

+ 58 - 0
src/main/java/com/yihu/ehr/redis/pubsub/entity/RedisMqSubscriber.java

@ -0,0 +1,58 @@
package com.yihu.ehr.redis.pubsub.entity;
import com.yihu.ehr.entity.BaseIdentityEntity;
import javax.persistence.*;
/**
 * redis消息订阅者 Entity
 *
 * @author 张进军
 * @date 2017/11/10 11:14
 */
@Entity
@Table(name = "redis_mq_subscriber")
public class RedisMqSubscriber extends BaseIdentityEntity {
    public String appId; // 应用ID
    public String subscribedUrl; // 订阅者服务地址
    public String channel; // 消息队列编码
    public String remark; // 备注
    @Column(name = "app_id")
    public String getAppId() {
        return appId;
    }
    public void setAppId(String appId) {
        this.appId = appId;
    }
    @Column(name = "subscribed_url")
    public String getSubscribedUrl() {
        return subscribedUrl;
    }
    public void setSubscribedUrl(String subscribedUrl) {
        this.subscribedUrl = subscribedUrl;
    }
    @Column(name = "channel")
    public String getChannel() {
        return channel;
    }
    public void setChannel(String channel) {
        this.channel = channel;
    }
    @Column(name = "remark")
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

+ 145 - 0
src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqChannelService.java

@ -0,0 +1,145 @@
package com.yihu.ehr.redis.pubsub.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.profile.queue.RedisCollection;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.pubsub.dao.RedisMqChannelDao;
import com.yihu.ehr.redis.pubsub.dao.RedisMqPublisherDao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqChannel;
import com.yihu.ehr.redis.pubsub.entity.RedisMqPublisher;
import com.yihu.ehr.util.rest.Envelop;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
 * redis消息队列 Service
 *
 * @author 张进军
 * @date 2017/11/10 11:45
 */
@Service
public class RedisMqChannelService extends BaseJpaService<RedisMqChannel, RedisMqChannelDao> {
    private static final Logger logger = Logger.getLogger(RedisMqChannelService.class);
    @Autowired
    RedisMqChannelDao redisMqChannelDao;
    @Autowired
    RedisMqPublisherDao redisMqPublisherDao;
    @Autowired
    RedisMqMessageLogService redisMqMessageLogService;
    @Autowired
    RedisMqChannelService redisMqChannelService;
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    ObjectMapper objectMapper;
    public RedisMqChannel getById(Integer id) {
        return redisMqChannelDao.findOne(id);
    }
    public RedisMqChannel findByChannel(String channel) {
        return redisMqChannelDao.findByChannel(channel);
    }
    @Transactional(readOnly = false)
    public RedisMqChannel save(RedisMqChannel redisMqChannel) {
        return redisMqChannelDao.save(redisMqChannel);
    }
    @Transactional(readOnly = false)
    public void delete(Integer id) {
        redisMqChannelDao.delete(id);
    }
    public Boolean isUniqueChannel(Integer id, String channel) {
        RedisMqChannel redisMqChannel = redisMqChannelDao.isUniqueChannel(id, channel);
        if (redisMqChannel == null) {
            return true;
        } else {
            return false;
        }
    }
    public Boolean isUniqueChannelName(Integer id, String channelName) {
        RedisMqChannel redisMqChannel = redisMqChannelDao.isUniqueChannelName(id, channelName);
        if (redisMqChannel == null) {
            return true;
        } else {
            return false;
        }
    }
    public Boolean isExist(String channel) {
        RedisMqChannel channels = redisMqChannelDao.findByChannel(channel);
        return channels != null;
    }
    /**
     * 发布消息
     *
     * @param publisherAppId 发布者应用ID
     * @param channel        消息队列编码
     * @param message        消息
     * @return Envelop
     */
    public Envelop sendMessage(String publisherAppId, String channel, String message) {
        Envelop envelop = new Envelop();
        try {
            // 判断消息队列是否注册
            RedisMqChannel redisMqChannel = redisMqChannelDao.findByChannel(channel);
            if (redisMqChannel == null) {
                envelop.setSuccessFlg(false);
                envelop.setErrorMsg("消息队列 " + channel + " 还未注册,需要先注册才能往队列发布消息。");
                return envelop;
            }
            // 判断队列是否绑定发布者
            RedisMqPublisher redisMqPublisher = redisMqPublisherDao.findByChannelAndAppId(channel, publisherAppId);
            if (redisMqPublisher == null) {
                envelop.setSuccessFlg(false);
                envelop.setErrorMsg("消息队列 " + channel + " 中没绑定过应用ID为 " + publisherAppId + " 的发布者,需要先绑定才能发布消息。");
                return envelop;
            }
            // 将消息加入到待发缓存集合中
            addToPubWaitingMessage(publisherAppId, channel, message, "");
            envelop.setSuccessFlg(true);
        } catch (Exception e) {
            e.printStackTrace();
            envelop.setSuccessFlg(false);
            envelop.setErrorMsg("发布消息发生异常:" + e.getMessage());
        }
        return envelop;
    }
    /**
     * 将消息加入到待发缓存集合中
     *
     * @param publisherAppId 发布者应用ID
     * @param channel        消息队列编码
     * @param message        消息
     * @param messageId      消息ID,订阅失败重发时才有值,不然为空字符串,即首次发送必为空字符串。
     * @throws JsonProcessingException
     */
    public void addToPubWaitingMessage(String publisherAppId, String channel, String message, String messageId)
            throws JsonProcessingException {
        Map<String, Object> messageMap = new HashMap<>();
        messageMap.put("messageId", messageId);
        messageMap.put("channel", channel);
        messageMap.put("publisherAppId", publisherAppId);
        messageMap.put("messageContent", message);
        redisTemplate.opsForList().leftPush(RedisCollection.PUB_WAITING_MESSAGES, objectMapper.writeValueAsString(messageMap));
    }
}

+ 43 - 0
src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqMessageLogService.java

@ -0,0 +1,43 @@
package com.yihu.ehr.redis.pubsub.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.pubsub.dao.RedisMqMessageLogDao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqMessageLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * redis消息记录 Service
 *
 * @author 张进军
 * @date 2017/11/10 11:45
 */
@Service
@Transactional
public class RedisMqMessageLogService extends BaseJpaService<RedisMqMessageLog, RedisMqMessageLogDao> {
    @Autowired
    RedisMqMessageLogDao redisMqMessageLogDao;
    public RedisMqMessageLog getById(String id) {
        return redisMqMessageLogDao.findOne(id);
    }
    public List<RedisMqMessageLog> findByChannel(String channel) {
        return redisMqMessageLogDao.findByChannel(channel);
    }
    @Transactional(readOnly = false)
    public RedisMqMessageLog save(RedisMqMessageLog redisMqMessageLog) {
        return redisMqMessageLogDao.save(redisMqMessageLog);
    }
    @Transactional(readOnly = false)
    public void updateStatus(String id, Integer status) {
        redisMqMessageLogDao.updateStatus(id, status);
    }
}

+ 56 - 0
src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqPublisherService.java

@ -0,0 +1,56 @@
package com.yihu.ehr.redis.pubsub.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.pubsub.dao.RedisMqPublisherDao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * redis消息发布者 Service
 *
 * @author 张进军
 * @date 2017/11/20 09:35
 */
@Service
@Transactional
public class RedisMqPublisherService extends BaseJpaService<RedisMqPublisher, RedisMqPublisherDao> {
    @Autowired
    RedisMqPublisherDao redisMqPublisherDao;
    public RedisMqPublisher getById(Integer id) {
        return redisMqPublisherDao.findOne(id);
    }
    public List<RedisMqPublisher> findByChannel(String channel) {
        return redisMqPublisherDao.findByChannel(channel);
    }
    public RedisMqPublisher findByChannelAndAppId(String channel, String appId) {
        return redisMqPublisherDao.findByChannelAndAppId(channel, appId);
    }
    @Transactional(readOnly = false)
    public RedisMqPublisher save(RedisMqPublisher redisMqChannel) {
        return redisMqPublisherDao.save(redisMqChannel);
    }
    @Transactional(readOnly = false)
    public void delete(Integer id) {
        redisMqPublisherDao.delete(id);
    }
    public Boolean isUniqueAppId(Integer id, String channel, String appId) {
        RedisMqPublisher redisMqPublisher = redisMqPublisherDao.isUniqueAppId(id, channel, appId);
        if (redisMqPublisher == null) {
            return true;
        } else {
            return false;
        }
    }
}

+ 78 - 0
src/main/java/com/yihu/ehr/redis/pubsub/service/RedisMqSubscriberService.java

@ -0,0 +1,78 @@
package com.yihu.ehr.redis.pubsub.service;
import com.yihu.ehr.query.BaseJpaService;
import com.yihu.ehr.redis.pubsub.dao.RedisMqSubscriberDao;
import com.yihu.ehr.redis.pubsub.entity.RedisMqSubscriber;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * redis消息订阅者 Service
 *
 * @author 张进军
 * @date 2017/11/10 11:45
 */
@Service
@Transactional
public class RedisMqSubscriberService extends BaseJpaService<RedisMqSubscriber, RedisMqSubscriberDao> {
    @Autowired
    RedisMqSubscriberDao redisMqSubscriberDao;
    public RedisMqSubscriber getById(Integer id) {
        return redisMqSubscriberDao.findOne(id);
    }
    public List<RedisMqSubscriber> findByChannel(String channel) {
        return redisMqSubscriberDao.findByChannel(channel);
    }
    @Transactional(readOnly = false)
    public RedisMqSubscriber save(RedisMqSubscriber redisMqChannel) {
        return redisMqSubscriberDao.save(redisMqChannel);
    }
    @Transactional(readOnly = false)
    public void delete(Integer id) {
        redisMqSubscriberDao.delete(id);
    }
    public Boolean isUniqueAppId(Integer id, String channel, String appId) {
        RedisMqSubscriber redisMqSubscriber = redisMqSubscriberDao.isUniqueAppId(id, channel, appId);
        if (redisMqSubscriber == null) {
            return true;
        } else {
            return false;
        }
    }
    public Boolean isUniqueSubscribedUrl(Integer id, String channel, String subscriberUrl) {
        RedisMqSubscriber redisMqSubscriber = redisMqSubscriberDao.isUniqueSubscribedUrl(id, channel, subscriberUrl);
        if (redisMqSubscriber == null) {
            return true;
        } else {
            return false;
        }
    }
    public Boolean isExist(String channel, String subscriber) {
        RedisMqSubscriber redisMqSubscriber = redisMqSubscriberDao.findByChannelAndAndSubscribedUrl(channel, subscriber);
        return redisMqSubscriber != null;
    }
    public void unsubscribe(String channel, String subscriber) {
        List<RedisMqSubscriber> subscriberList = redisMqSubscriberDao.findByChannel(channel);
        subscriberList.forEach(redisMqSubscriber -> {
            if (StringUtils.isEmpty(subscriber)) {//取消所有订阅者
                redisMqSubscriberDao.delete(redisMqSubscriber);
            } else if (subscriber.equals(redisMqSubscriber.getSubscribedUrl())) {
                redisMqSubscriberDao.delete(redisMqSubscriber);//取消指定订阅者
            }
        });
    }
}

+ 56 - 0
src/main/resources/application.yml

@ -0,0 +1,56 @@
server:
  port: ${svr-redis.server.port}
info:
  app:
    name: SVR-REDIS
    description: EHR Platform Microservice.
    version: 1.0.0
spring:
  # REDIS
  redis:
    database: 0 # Database index used by the connection factory.
    #password:  # Login password of the redis server.
    timeout: 0 # Connection timeout in milliseconds.
    #sentinel:
    #  master: # Name of Redis server.
    #  nodes: # Comma-separated list of host:port pairs.
    pool:
      max-active: 8 # Max number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
      max-idle: 8 # Max number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
      max-wait: -1 # Maximum amount of time (in milliseconds) a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
      min-idle: 1 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    max-active: 20
    max-idle: 8
    min-idle: 8
    validation-query: SELECT 1
    test-on-borrow: true
hystrix:
  threadpool:
    default:
      coreSize: 60 #并发执行的最大线程数,默认10
      maxQueueSize: 100 #LinkedBlockingQueue的最大队列数,默认-1,使用SynchronousQueue
      #queueSizeRejectionThreshold: 50 #配置该值后,即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝
---
spring:
  profiles: dev
  datasource:
    url: jdbc:mysql://172.19.103.50:3306/healtharchive?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: chenweishan
    password: chenweishan
  redis:
    host: 172.19.103.47
    port: 6379
    password: redis!@456
  kafka:
    bootstrap-servers: node4.hde.h3c.com:6667
ehr-redis:
  mq:
    pubsub:
      publisherAppId: svr-redis
      responseTimeChannel: redis.cache.reponse-time

+ 29 - 0
src/main/resources/banner.txt

@ -0,0 +1,29 @@
                                   _oo8oo_
                                  o8888888o
                                  88" . "88
                                  (| -_- |)
                                  0\  =  /0
                                ___/'==='\___
                              .' \\|     |// '.
                             / \\|||  :  |||// \
                            / _||||| -:- |||||_ \
                           |   | \\\  -  /// |   |
                           | \_|  ''\---/''  |_/ |
                           \  .-\__  '-'  __/-.  /
                         ___'. .'  /--.--\  '. .'___
                      ."" '<  '.___\_<|>_/___.'  >' "".
                     | | :  `- \`.:`\ _ /`:.`/ -`  : | |
                     \  \ `-.   \_ __\ /__ _/   .-` /  /
                 =====`-.____`.___ \_____/ ___.`____.-`=====
                                   `=---=`
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      佛祖保佑     永不宕机     永无Bug
                   __   _      ___       ___   ____  ___   _   __
                  ( (` \ \  / | |_)     | |_) | |_  | | \ | | ( (`
                  _)_)  \_\/  |_| \     |_| \ |_|__ |_|_/ |_| _)_)

+ 23 - 0
src/main/resources/bootstrap.yml

@ -0,0 +1,23 @@
spring:
  application:
    name: svr-redis
  cloud:
    config:
      username: user
      password: configuration
---
spring:
  profiles: dev
  cloud:
    config:
      uri: ${spring.config.uri:http://172.19.103.73:1221}
      label: ${spring.config.label:dev}
---
spring:
  profiles: prod
  cloud:
    config:
      uri: ${spring.config.uri}
      label: ${spring.config.label}

+ 102 - 0
src/main/resources/logback-spring.xml

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
	<springProperty scope="context" name="appName" source="spring.application.name"/>
	<property name="log_home" value="/ehr-logs/${appName}" />
	<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
	<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
	<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
	<!-- 彩色日志格式 -->
	<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr([${appName}]){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
	<!-- 文件日志格式 -->
	<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [${appName}] %-5level --- [%thread] - %logger{36}: %msg%n" />
	<!-- Standard output -->
	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>${CONSOLE_LOG_PATTERN}</pattern>
			<charset class="java.nio.charset.Charset">UTF-8</charset>
		</encoder>
	</appender>
    <!-- Api Log Start -->
    <appender name="ApiInfoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log_home}/api/info/%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
			<pattern>${FILE_LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <appender name="ApiWarnFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log_home}/api/warn/%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
			<pattern>${FILE_LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <appender name="ApiErrorFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log_home}/api/error/%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
			<pattern>${FILE_LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <logger name="com.yihu.ehr.exception.GlobalExceptionHandler" level="WARN" additivity="false">
        <appender-ref ref="console" />
        <appender-ref ref="ApiInfoFile" />
        <appender-ref ref="ApiWarnFile" />
        <appender-ref ref="ApiErrorFile" />
    </logger>
    <!-- Api Log End -->
    <!-- 如果微服务纳入全局异常处理,请勿修改以上代码,有新的日志处理请在以下追加!!! -->
	<!-- 开发环境配置 -->
	<springProfile name="dev">
		<root level="INFO">
			<appender-ref ref="console"/>
		</root>
	</springProfile>
	<!-- 测试环境配置 -->
	<springProfile name="test">
		<root level="WARN">
			<appender-ref ref="console"/>
		</root>
	</springProfile>
    <!-- 上饶正式环境配置 -->
    <springProfile name="prod">
        <root level="WARN">
            <appender-ref ref="console"/>
        </root>
    </springProfile>
</configuration>

+ 45 - 0
src/test/java/com/yihu/ehr/redis/cache/CacheTest.java

@ -0,0 +1,45 @@
package com.yihu.ehr.redis.cache;
import com.yihu.ehr.RedisServiceApp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
 * @author 张进军
 * @date 2018/5/30 09:28
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RedisServiceApp.class)
public class CacheTest {
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Test
    public void listTest() {
        ListOperations<String, Object> listOps = redisTemplate.opsForList();
        long num = 100000;
        redisTemplate.delete("list_test");
        for (int i = 1; i <= num; i++) {
            listOps.leftPush("list_test", "test-" + i);
        }
        long start = System.currentTimeMillis();
        while (true) {
            Object obj = listOps.rightPop("list_test");
            if (obj == null) {
                break;
            }
            System.out.println(obj.toString());
        }
        long time = System.currentTimeMillis() - start;
        System.out.println("条数:" + num + ",用时:" + time);
    }
}

+ 83 - 0
src/test/java/com/yihu/ehr/redis/pubsub/PubSubTest.java

@ -0,0 +1,83 @@
package com.yihu.ehr.redis.pubsub;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.ehr.RedisServiceApp;
import com.yihu.ehr.redis.pubsub.service.RedisMqChannelService;
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.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
 * Redis消息发布订阅测试
 *
 * @author 张进军
 * @date 2017/11/2 14:17
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RedisServiceApp.class)
public class PubSubTest {
    @Autowired
    JedisConnectionFactory jedisConnectionFactory;
    @Autowired
    RedisMessageListenerContainer redisMessageListenerContainer;
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    RedisMqChannelService redisMqChannelService;
    @Test
    public void redisPubSubTest() throws InterruptedException, JsonProcessingException {
        String channel_01 = "zjj.test.01";
        for (int i = 0; i < 20000; i++) {
            String channel = channel_01 + i;
            ChannelTopic topic = new ChannelTopic(channel);
            CustomMessageListenerAdapter messageListener = MessageCommonBiz.newCustomMessageListenerAdapter(channel);
            redisMessageListenerContainer.addMessageListener(messageListener, topic);
            // 每次添加channel监听器都会flush,这需要点时间。
            Thread.sleep(5);
        }
//        Map<String, Object> message = new HashMap<>();
//        message.put("messageLogId", "");
//        message.put("messageContent", "a test message.");
//        redisTemplate.convertAndSend(channel_01, objectMapper.writeValueAsString(message));
    }
    @Test
    public void sendMessageTest() throws InterruptedException {
        PubRunnable r = new PubRunnable("svr-zjj", "test1");
        for (int i = 0; i < 2; i++) {
            new Thread(r, "r" + i).start();
        }
    }
    public class PubRunnable implements Runnable {
        private String appId;
        private String channel;
        PubRunnable (String appId, String channel) {
            this.appId = appId;
            this.channel = channel;
        }
        @Override
        public void run() {
            for (int i = 0; i < 1; i++){
                redisMqChannelService.sendMessage(appId, channel, Thread.currentThread().getName() + ": test message.");
            }
        }
    }
}