yangyoupeng

第一次提交

Showing 183 changed files with 4786 additions and 0 deletions
File mode changed
1 +zhaoonline-coupen
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="ProjectCodeStyleSettingsManager">
4 + <option name="PER_PROJECT_SETTINGS">
5 + <value>
6 + <XML>
7 + <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
8 + </XML>
9 + </value>
10 + </option>
11 + <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default copy" />
12 + </component>
13 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="CompilerConfiguration">
4 + <resourceExtensions />
5 + <wildcardResourcePatterns>
6 + <entry name="!?*.java" />
7 + <entry name="!?*.form" />
8 + <entry name="!?*.class" />
9 + <entry name="!?*.groovy" />
10 + <entry name="!?*.scala" />
11 + <entry name="!?*.flex" />
12 + <entry name="!?*.kt" />
13 + <entry name="!?*.clj" />
14 + <entry name="!?*.aj" />
15 + </wildcardResourcePatterns>
16 + <annotationProcessing>
17 + <profile default="true" name="Default" enabled="false">
18 + <processorPath useClasspath="true" />
19 + </profile>
20 + <profile default="false" name="Annotation profile for coupen-dispatcher" enabled="true">
21 + <sourceOutputDir name="target/generated-sources/annotations" />
22 + <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
23 + <outputRelativeToContentRoot value="true" />
24 + <processorPath useClasspath="true" />
25 + <module name="coupen-dispatcher" />
26 + </profile>
27 + <profile default="false" name="Annotation profile for coupen-generator" enabled="true">
28 + <sourceOutputDir name="target/generated-sources/annotations" />
29 + <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
30 + <outputRelativeToContentRoot value="true" />
31 + <processorPath useClasspath="true" />
32 + <module name="coupen-generator" />
33 + </profile>
34 + <profile default="false" name="Annotation profile for coupen-processor" enabled="true">
35 + <sourceOutputDir name="target/generated-sources/annotations" />
36 + <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
37 + <outputRelativeToContentRoot value="true" />
38 + <processorPath useClasspath="true" />
39 + <module name="coupen-processor" />
40 + </profile>
41 + <profile default="false" name="Annotation profile for coupen-core" enabled="true">
42 + <sourceOutputDir name="target/generated-sources/annotations" />
43 + <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
44 + <outputRelativeToContentRoot value="true" />
45 + <processorPath useClasspath="true" />
46 + <module name="coupen-core" />
47 + </profile>
48 + <profile default="false" name="Annotation profile for coupen-dispatcher-api" enabled="true">
49 + <sourceOutputDir name="target/generated-sources/annotations" />
50 + <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
51 + <outputRelativeToContentRoot value="true" />
52 + <processorPath useClasspath="true" />
53 + <module name="coupen-dispatcher-api" />
54 + </profile>
55 + </annotationProcessing>
56 + <bytecodeTargetLevel>
57 + <module name="coupen-core" target="1.8" />
58 + <module name="coupen-dispatcher" target="1.8" />
59 + <module name="coupen-dispatcher-api" target="1.8" />
60 + <module name="coupen-generator" target="1.8" />
61 + <module name="coupen-processor" target="1.8" />
62 + <module name="zhaoonline-coupen" target="1.8" />
63 + </bytecodeTargetLevel>
64 + </component>
65 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="CopyrightManager">
2 + <settings default="" />
3 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="Encoding">
4 + <file url="file://$PROJECT_DIR$" charset="UTF-8" />
5 + <file url="file://$PROJECT_DIR$/coupen-core" charset="UTF-8" />
6 + <file url="file://$PROJECT_DIR$/coupen-dispatcher" charset="UTF-8" />
7 + <file url="file://$PROJECT_DIR$/coupen-dispatcher-api" charset="UTF-8" />
8 + <file url="file://$PROJECT_DIR$/coupen-generator" charset="UTF-8" />
9 + <file url="file://$PROJECT_DIR$/coupen-processor" charset="UTF-8" />
10 + <file url="PROJECT" charset="UTF-8" />
11 + </component>
12 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: aopalliance:aopalliance:1.0">
3 + <CLASSES>
4 + <root url="jar://D:/maven/aopalliance/aopalliance/1.0/aopalliance-1.0.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/aopalliance/aopalliance/1.0/aopalliance-1.0-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: ch.qos.logback:logback-core:1.1.7">
3 + <CLASSES>
4 + <root url="jar://D:/maven/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: com.auth0:java-jwt:3.0.1">
3 + <CLASSES>
4 + <root url="jar://D:/maven/com/auth0/java-jwt/3.0.1/java-jwt-3.0.1.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/com/auth0/java-jwt/3.0.1/java-jwt-3.0.1-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/com/auth0/java-jwt/3.0.1/java-jwt-3.0.1-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0">
3 + <CLASSES>
4 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.1">
3 + <CLASSES>
4 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-core/2.8.1/jackson-core-2.8.1.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-core/2.8.1/jackson-core-2.8.1-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-core/2.8.1/jackson-core-2.8.1-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.1">
3 + <CLASSES>
4 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-databind/2.8.1/jackson-databind-2.8.1.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-databind/2.8.1/jackson-databind-2.8.1-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/com/fasterxml/jackson/core/jackson-databind/2.8.1/jackson-databind-2.8.1-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: com.google.guava:guava:18.0">
3 + <CLASSES>
4 + <root url="jar://D:/maven/com/google/guava/guava/18.0/guava-18.0.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/com/google/guava/guava/18.0/guava-18.0-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/com/google/guava/guava/18.0/guava-18.0-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: com.zhaoonline:microservice-redis:1.0.0-SNAPSHOT">
3 + <CLASSES>
4 + <root url="jar://D:/maven/com/zhaoonline/microservice-redis/1.0.0-SNAPSHOT/microservice-redis-1.0.0-SNAPSHOT.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/com/zhaoonline/microservice-redis/1.0.0-SNAPSHOT/microservice-redis-1.0.0-SNAPSHOT-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/com/zhaoonline/microservice-redis/1.0.0-SNAPSHOT/microservice-redis-1.0.0-SNAPSHOT-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: commons-codec:commons-codec:1.10">
3 + <CLASSES>
4 + <root url="jar://D:/maven/commons-codec/commons-codec/1.10/commons-codec-1.10.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/commons-codec/commons-codec/1.10/commons-codec-1.10-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/commons-codec/commons-codec/1.10/commons-codec-1.10-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: commons-logging:commons-logging:1.2">
3 + <CLASSES>
4 + <root url="jar://D:/maven/commons-logging/commons-logging/1.2/commons-logging-1.2.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/commons-logging/commons-logging/1.2/commons-logging-1.2-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/commons-logging/commons-logging/1.2/commons-logging-1.2-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: io.jsonwebtoken:jjwt:0.7.0">
3 + <CLASSES>
4 + <root url="jar://D:/maven/io/jsonwebtoken/jjwt/0.7.0/jjwt-0.7.0.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/io/jsonwebtoken/jjwt/0.7.0/jjwt-0.7.0-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/io/jsonwebtoken/jjwt/0.7.0/jjwt-0.7.0-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: javax.validation:validation-api:1.1.0.Final">
3 + <CLASSES>
4 + <root url="jar://D:/maven/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: joda-time:joda-time:2.9.4">
3 + <CLASSES>
4 + <root url="jar://D:/maven/joda-time/joda-time/2.9.4/joda-time-2.9.4.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/joda-time/joda-time/2.9.4/joda-time-2.9.4-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/joda-time/joda-time/2.9.4/joda-time-2.9.4-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: junit:junit:4.12">
3 + <CLASSES>
4 + <root url="jar://D:/maven/junit/junit/4.12/junit-4.12.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/junit/junit/4.12/junit-4.12-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/junit/junit/4.12/junit-4.12-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.apache.commons:commons-pool2:2.4.2">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.bitbucket.b_c:jose4j:0.5.2">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/bitbucket/b_c/jose4j/0.5.2/jose4j-0.5.2.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/bitbucket/b_c/jose4j/0.5.2/jose4j-0.5.2-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/bitbucket/b_c/jose4j/0.5.2/jose4j-0.5.2-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.bouncycastle:bcprov-jdk15on:1.55">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/bouncycastle/bcprov-jdk15on/1.55/bcprov-jdk15on-1.55.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/bouncycastle/bcprov-jdk15on/1.55/bcprov-jdk15on-1.55-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/bouncycastle/bcprov-jdk15on/1.55/bcprov-jdk15on-1.55-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.hamcrest:hamcrest-core:1.3">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.mockito:mockito-all:1.10.19">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/mockito/mockito-all/1.10.19/mockito-all-1.10.19.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/mockito/mockito-all/1.10.19/mockito-all-1.10.19-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/mockito/mockito-all/1.10.19/mockito-all-1.10.19-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.slf4j:jcl-over-slf4j:1.7.21">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.slf4j:slf4j-api:1.7.21">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework.data:spring-data-commons:1.12.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/data/spring-data-commons/1.12.2.RELEASE/spring-data-commons-1.12.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/data/spring-data-commons/1.12.2.RELEASE/spring-data-commons-1.12.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/data/spring-data-commons/1.12.2.RELEASE/spring-data-commons-1.12.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework.data:spring-data-keyvalue:1.1.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/data/spring-data-keyvalue/1.1.2.RELEASE/spring-data-keyvalue-1.1.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/data/spring-data-keyvalue/1.1.2.RELEASE/spring-data-keyvalue-1.1.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/data/spring-data-keyvalue/1.1.2.RELEASE/spring-data-keyvalue-1.1.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework.data:spring-data-redis:1.7.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/data/spring-data-redis/1.7.2.RELEASE/spring-data-redis-1.7.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/data/spring-data-redis/1.7.2.RELEASE/spring-data-redis-1.7.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/data/spring-data-redis/1.7.2.RELEASE/spring-data-redis-1.7.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-aop:4.2.6.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-aop/4.2.6.RELEASE/spring-aop-4.2.6.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-aop/4.2.6.RELEASE/spring-aop-4.2.6.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-aop/4.2.6.RELEASE/spring-aop-4.2.6.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-beans:4.3.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-beans/4.3.2.RELEASE/spring-beans-4.3.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-beans/4.3.2.RELEASE/spring-beans-4.3.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-beans/4.3.2.RELEASE/spring-beans-4.3.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-context:4.3.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-context/4.3.2.RELEASE/spring-context-4.3.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-context/4.3.2.RELEASE/spring-context-4.3.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-context/4.3.2.RELEASE/spring-context-4.3.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-context-support:4.3.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-context-support/4.3.2.RELEASE/spring-context-support-4.3.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-context-support/4.3.2.RELEASE/spring-context-support-4.3.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-context-support/4.3.2.RELEASE/spring-context-support-4.3.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-core:4.3.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-core/4.3.2.RELEASE/spring-core-4.3.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-core/4.3.2.RELEASE/spring-core-4.3.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-core/4.3.2.RELEASE/spring-core-4.3.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-expression:4.3.2.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-expression/4.3.2.RELEASE/spring-expression-4.3.2.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-expression/4.3.2.RELEASE/spring-expression-4.3.2.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-expression/4.3.2.RELEASE/spring-expression-4.3.2.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-oxm:4.2.6.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-oxm/4.2.6.RELEASE/spring-oxm-4.2.6.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-oxm/4.2.6.RELEASE/spring-oxm-4.2.6.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-oxm/4.2.6.RELEASE/spring-oxm-4.2.6.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: org.springframework:spring-tx:4.2.6.RELEASE">
3 + <CLASSES>
4 + <root url="jar://D:/maven/org/springframework/spring-tx/4.2.6.RELEASE/spring-tx-4.2.6.RELEASE.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/org/springframework/spring-tx/4.2.6.RELEASE/spring-tx-4.2.6.RELEASE-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/org/springframework/spring-tx/4.2.6.RELEASE/spring-tx-4.2.6.RELEASE-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<component name="libraryTable">
2 + <library name="Maven: redis.clients:jedis:2.9.0">
3 + <CLASSES>
4 + <root url="jar://D:/maven/redis/clients/jedis/2.9.0/jedis-2.9.0.jar!/" />
5 + </CLASSES>
6 + <JAVADOC>
7 + <root url="jar://D:/maven/redis/clients/jedis/2.9.0/jedis-2.9.0-javadoc.jar!/" />
8 + </JAVADOC>
9 + <SOURCES>
10 + <root url="jar://D:/maven/redis/clients/jedis/2.9.0/jedis-2.9.0-sources.jar!/" />
11 + </SOURCES>
12 + </library>
13 +</component>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="EntryPointsManager">
4 + <entry_points version="2.0" />
5 + </component>
6 + <component name="MavenProjectsManager">
7 + <option name="originalFiles">
8 + <list>
9 + <option value="$PROJECT_DIR$/pom.xml" />
10 + </list>
11 + </option>
12 + </component>
13 + <component name="ProjectLevelVcsManager" settingsEditedManually="false">
14 + <OptionsSetting value="true" id="Add" />
15 + <OptionsSetting value="true" id="Remove" />
16 + <OptionsSetting value="true" id="Checkout" />
17 + <OptionsSetting value="true" id="Update" />
18 + <OptionsSetting value="true" id="Status" />
19 + <OptionsSetting value="true" id="Edit" />
20 + <ConfirmationsSetting value="0" id="Add" />
21 + <ConfirmationsSetting value="0" id="Remove" />
22 + </component>
23 + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
24 + <output url="file://$PROJECT_DIR$/out" />
25 + </component>
26 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="ProjectModuleManager">
4 + <modules>
5 + <module fileurl="file://$PROJECT_DIR$/coupen-core/coupen-core.iml" filepath="$PROJECT_DIR$/coupen-core/coupen-core.iml" />
6 + <module fileurl="file://$PROJECT_DIR$/coupen-dispatcher/coupen-dispatcher.iml" filepath="$PROJECT_DIR$/coupen-dispatcher/coupen-dispatcher.iml" />
7 + <module fileurl="file://$PROJECT_DIR$/coupen-dispatcher-api/coupen-dispatcher-api.iml" filepath="$PROJECT_DIR$/coupen-dispatcher-api/coupen-dispatcher-api.iml" />
8 + <module fileurl="file://$PROJECT_DIR$/coupen-generator/coupen-generator.iml" filepath="$PROJECT_DIR$/coupen-generator/coupen-generator.iml" />
9 + <module fileurl="file://$PROJECT_DIR$/coupen-processor/coupen-processor.iml" filepath="$PROJECT_DIR$/coupen-processor/coupen-processor.iml" />
10 + <module fileurl="file://$PROJECT_DIR$/zhaoonline-coupen.iml" filepath="$PROJECT_DIR$/zhaoonline-coupen.iml" />
11 + </modules>
12 + </component>
13 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="Palette2">
4 + <group name="Swing">
5 + <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
6 + <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
7 + </item>
8 + <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
9 + <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
10 + </item>
11 + <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
12 + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
13 + </item>
14 + <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
15 + <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
16 + </item>
17 + <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
18 + <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
19 + <initial-values>
20 + <property name="text" value="Button" />
21 + </initial-values>
22 + </item>
23 + <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
24 + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
25 + <initial-values>
26 + <property name="text" value="RadioButton" />
27 + </initial-values>
28 + </item>
29 + <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
30 + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
31 + <initial-values>
32 + <property name="text" value="CheckBox" />
33 + </initial-values>
34 + </item>
35 + <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
36 + <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
37 + <initial-values>
38 + <property name="text" value="Label" />
39 + </initial-values>
40 + </item>
41 + <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
42 + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
43 + <preferred-size width="150" height="-1" />
44 + </default-constraints>
45 + </item>
46 + <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
47 + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
48 + <preferred-size width="150" height="-1" />
49 + </default-constraints>
50 + </item>
51 + <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
52 + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
53 + <preferred-size width="150" height="-1" />
54 + </default-constraints>
55 + </item>
56 + <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
57 + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
58 + <preferred-size width="150" height="50" />
59 + </default-constraints>
60 + </item>
61 + <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
62 + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
63 + <preferred-size width="150" height="50" />
64 + </default-constraints>
65 + </item>
66 + <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
67 + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
68 + <preferred-size width="150" height="50" />
69 + </default-constraints>
70 + </item>
71 + <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
72 + <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
73 + </item>
74 + <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
75 + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
76 + <preferred-size width="150" height="50" />
77 + </default-constraints>
78 + </item>
79 + <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
80 + <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
81 + <preferred-size width="150" height="50" />
82 + </default-constraints>
83 + </item>
84 + <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
85 + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
86 + <preferred-size width="150" height="50" />
87 + </default-constraints>
88 + </item>
89 + <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
90 + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
91 + <preferred-size width="200" height="200" />
92 + </default-constraints>
93 + </item>
94 + <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
95 + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
96 + <preferred-size width="200" height="200" />
97 + </default-constraints>
98 + </item>
99 + <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
100 + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
101 + </item>
102 + <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
103 + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
104 + </item>
105 + <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
106 + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
107 + </item>
108 + <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
109 + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
110 + </item>
111 + <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
112 + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
113 + <preferred-size width="-1" height="20" />
114 + </default-constraints>
115 + </item>
116 + <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
117 + <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
118 + </item>
119 + <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
120 + <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
121 + </item>
122 + </group>
123 + </component>
124 +</project>
...\ No newline at end of file ...\ No newline at end of file
This diff could not be displayed because it is too large.
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
3 + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
4 + <output url="file://$MODULE_DIR$/target/classes" />
5 + <output-test url="file://$MODULE_DIR$/target/test-classes" />
6 + <content url="file://$MODULE_DIR$">
7 + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
8 + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
9 + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
10 + <excludeFolder url="file://$MODULE_DIR$/target" />
11 + </content>
12 + <orderEntry type="inheritedJdk" />
13 + <orderEntry type="sourceFolder" forTests="false" />
14 + <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
15 + <orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
16 + <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.4" level="project" />
17 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.1" level="project" />
18 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
19 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.1" level="project" />
20 + <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.21" level="project" />
21 + <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.7" level="project" />
22 + <orderEntry type="library" name="Maven: com.zhaoonline:microservice-redis:1.0.0-SNAPSHOT" level="project" />
23 + <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.0" level="project" />
24 + <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.2" level="project" />
25 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:1.7.2.RELEASE" level="project" />
26 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:1.1.2.RELEASE" level="project" />
27 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.12.2.RELEASE" level="project" />
28 + <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.2.6.RELEASE" level="project" />
29 + <orderEntry type="library" name="Maven: org.springframework:spring-oxm:4.2.6.RELEASE" level="project" />
30 + <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.2.6.RELEASE" level="project" />
31 + <orderEntry type="library" name="Maven: aopalliance:aopalliance:1.0" level="project" />
32 + <orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.21" level="project" />
33 + <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.2.RELEASE" level="project" />
34 + <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.2.RELEASE" level="project" />
35 + <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.2.RELEASE" level="project" />
36 + <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.2.RELEASE" level="project" />
37 + <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.2.RELEASE" level="project" />
38 + <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
39 + <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.10.19" level="project" />
40 + <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
41 + <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
42 + <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.0.1" level="project" />
43 + <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
44 + <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.55" level="project" />
45 + <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.7.0" level="project" />
46 + <orderEntry type="library" name="Maven: org.bitbucket.b_c:jose4j:0.5.2" level="project" />
47 + </component>
48 +</module>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 + <parent>
6 + <artifactId>parent</artifactId>
7 + <groupId>com.zhaoonline.coupen</groupId>
8 + <version>1.0-SNAPSHOT</version>
9 + </parent>
10 + <modelVersion>4.0.0</modelVersion>
11 + <artifactId>coupen-core</artifactId>
12 +
13 + <dependencies>
14 +
15 + <dependency>
16 + <groupId>javax.validation</groupId>
17 + <artifactId>validation-api</artifactId>
18 + </dependency>
19 +
20 + <dependency>
21 + <groupId>com.google.guava</groupId>
22 + <artifactId>guava</artifactId>
23 + </dependency>
24 +
25 + <dependency>
26 + <groupId>joda-time</groupId>
27 + <artifactId>joda-time</artifactId>
28 + </dependency>
29 +
30 + <dependency>
31 + <groupId>com.fasterxml.jackson.core</groupId>
32 + <artifactId>jackson-databind</artifactId>
33 + </dependency>
34 +
35 + <dependency>
36 + <groupId>org.slf4j</groupId>
37 + <artifactId>slf4j-api</artifactId>
38 + </dependency>
39 +
40 + <dependency>
41 + <groupId>ch.qos.logback</groupId>
42 + <artifactId>logback-core</artifactId>
43 + </dependency>
44 +
45 + <dependency>
46 + <groupId>com.zhaoonline</groupId>
47 + <artifactId>microservice-redis</artifactId>
48 + <exclusions>
49 + <exclusion>
50 + <groupId>com.zhaoonline</groupId>
51 + <artifactId>alpaca-config-zookeeper</artifactId>
52 + </exclusion>
53 + </exclusions>
54 + </dependency>
55 +
56 + <!-- test相关 -->
57 + <dependency>
58 + <groupId>org.mockito</groupId>
59 + <artifactId>mockito-all</artifactId>
60 + <version>1.10.19</version>
61 + <scope>test</scope>
62 + </dependency>
63 + <dependency>
64 + <groupId>junit</groupId>
65 + <artifactId>junit</artifactId>
66 + <scope>test</scope>
67 + </dependency>
68 +
69 + <!-- jwt相关 -->
70 + <dependency>
71 + <groupId>com.auth0</groupId>
72 + <artifactId>java-jwt</artifactId>
73 + </dependency>
74 + <dependency>
75 + <groupId>io.jsonwebtoken</groupId>
76 + <artifactId>jjwt</artifactId>
77 + </dependency>
78 + <dependency>
79 + <groupId>org.bitbucket.b_c</groupId>
80 + <artifactId>jose4j</artifactId>
81 + </dependency>
82 + </dependencies>
83 +
84 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.bean;
2 +
3 +import org.joda.time.DateTime;
4 +
5 +/**
6 + * Created by ZhaoOnline<br/>
7 + * User: yangyoupeng<br/>
8 + * Date: 2016/12/14<br/>
9 + * Time: 11:13<br/>
10 + * Description:活动
11 + */
12 +public class Activity {
13 + private String activityName;
14 + private Integer activityID;
15 + //活动开启时间
16 + protected DateTime startDate;
17 + //活动结束时间
18 + protected DateTime endDate;
19 + public Activity(){
20 + }
21 +
22 + public Activity(Integer ID,String name){
23 + this.activityName = name;
24 + this.activityID=ID;
25 + }
26 +
27 + public String getActivityName() {
28 + return activityName;
29 + }
30 +
31 + public void setActivityName(String activityName) {
32 + this.activityName = activityName;
33 + }
34 +
35 + public Integer getActivityID() {
36 + return activityID;
37 + }
38 +
39 + public void setActivityID(Integer activityID) {
40 + this.activityID = activityID;
41 + }
42 +
43 + public DateTime getStartDate() {
44 + return startDate;
45 + }
46 +
47 + public void setStartDate(DateTime startDate) {
48 + this.startDate = startDate;
49 + }
50 +
51 + public DateTime getEndDate() {
52 + return endDate;
53 + }
54 +
55 + public void setEndDate(DateTime endDate) {
56 + this.endDate = endDate;
57 + }
58 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/14<br/>
7 + * Time: 11:06<br/>
8 + * Description:业务类型:投资币、自营等
9 + */
10 +public class BizType {
11 + private Integer bizTypeID;
12 + private String bizTypeName;
13 +
14 + public BizType(){
15 + }
16 + public BizType(Integer ID,String name){
17 + this.bizTypeName = name;
18 + this.bizTypeID=ID;
19 + }
20 +
21 + public Integer getBizTypeID() {
22 + return bizTypeID;
23 + }
24 +
25 + public void setBizTypeID(Integer bizTypeID) {
26 + this.bizTypeID = bizTypeID;
27 + }
28 +
29 + public String getBizTypeName() {
30 + return bizTypeName;
31 + }
32 +
33 + public void setBizTypeName(String bizTypeName) {
34 + this.bizTypeName = bizTypeName;
35 + }
36 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +import org.joda.time.DateTime;
4 +
5 +import java.math.BigDecimal;
6 +
7 +/**
8 + * Created by ZhaoOnline<br/>
9 + * User: yangyoupeng<br/>
10 + * Date: 2016/12/14<br/>
11 + * Time: 19:16<br/>
12 + * Description:please descript you class
13 + */
14 +public class CommonCoupenEntity {
15 + protected CommonCoupenSeed seed;
16 + protected BigDecimal amount;
17 + protected String coupenID;
18 + protected OwnerUser ownerUser;
19 + //预定分发日期。
20 + protected DateTime distributeDate;
21 +
22 + public CommonCoupenSeed getSeed() {
23 + return seed;
24 + }
25 +
26 + public void setSeed(CommonCoupenSeed seed) {
27 + this.seed = seed;
28 + }
29 +
30 + public BigDecimal getAmount() {
31 + return amount;
32 + }
33 +
34 + public void setAmount(BigDecimal amount) {
35 + this.amount = amount;
36 + }
37 +
38 + public String getCoupenID() {
39 + return coupenID;
40 + }
41 +
42 + public void setCoupenID(String coupenID) {
43 + this.coupenID = coupenID;
44 + }
45 +
46 + public DateTime getDistributeDate() {
47 + return distributeDate;
48 + }
49 +
50 + public void setDistributeDate(DateTime distributeDate) {
51 + this.distributeDate = distributeDate;
52 + }
53 +
54 + public OwnerUser getOwnerUser() {
55 + return ownerUser;
56 + }
57 +
58 + public void setOwnerUser(OwnerUser ownerUser) {
59 + this.ownerUser = ownerUser;
60 + }
61 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +import org.joda.time.DateTime;
4 +
5 +import javax.validation.constraints.NotNull;
6 +import java.math.BigDecimal;
7 +
8 +/**
9 + * Created by ZhaoOnline<br/>
10 + * User: yangyoupeng<br/>
11 + * Date: 2016/12/14<br/>
12 + * Time: 10:41<br/>
13 + * Description:please descript you class
14 + */
15 +public class CommonCoupenSeed {
16 +
17 + protected Activity activity;
18 +
19 + protected String seedID;
20 +
21 + protected CoupenCatagory catagory;
22 +
23 + protected BizType bizType;
24 +
25 + protected BigDecimal totalAmount=new BigDecimal(0);
26 +
27 + //红包的个数至少为1;
28 + protected @NotNull Integer coupenCount=new Integer(1);
29 +
30 + //validStartDate和validEndDate为有效期
31 + protected DateTime validStartDate;
32 +
33 + protected DateTime validEndDate;
34 +
35 + //最后领取时间
36 + protected DateTime drawDeadlineDate;
37 +
38 + protected DistributeType distributeStrategy;
39 +
40 + protected DrawType drawType;
41 +
42 +
43 + public Activity getActivity() {
44 + return activity;
45 + }
46 +
47 + public void setActivity(Activity activity) {
48 + this.activity = activity;
49 + }
50 +
51 + public String getSeedID() {
52 + return seedID;
53 + }
54 +
55 + public void setSeedID(String seedID) {
56 + this.seedID = seedID;
57 + }
58 +
59 + public CoupenCatagory getCatagory() {
60 + return catagory;
61 + }
62 +
63 + public void setCatagory(CoupenCatagory catagory) {
64 + this.catagory = catagory;
65 + }
66 +
67 + public BizType getBizType() {
68 + return bizType;
69 + }
70 +
71 + public void setBizType(BizType bizType) {
72 + this.bizType = bizType;
73 + }
74 +
75 + public BigDecimal getTotalAmount() {
76 + return totalAmount;
77 + }
78 +
79 + public void setTotalAmount(BigDecimal totalAmount) {
80 + this.totalAmount = totalAmount;
81 + }
82 +
83 + public Integer getCoupenCount() {
84 + return coupenCount;
85 + }
86 +
87 + public void setCoupenCount(Integer coupenCount) {
88 + this.coupenCount = coupenCount;
89 + }
90 +
91 + public DateTime getDrawDeadlineDate() {
92 + return drawDeadlineDate;
93 + }
94 +
95 + public void setDrawDeadlineDate(DateTime drawDeadlineDate) {
96 + this.drawDeadlineDate = drawDeadlineDate;
97 + }
98 +
99 + public DateTime getValidStartDate() {
100 + return validStartDate;
101 + }
102 +
103 + public void setValidStartDate(DateTime validStartDate) {
104 + this.validStartDate = validStartDate;
105 + }
106 +
107 + public DateTime getValidEndDate() {
108 + return validEndDate;
109 + }
110 +
111 + public void setValidEndDate(DateTime validEndDate) {
112 + this.validEndDate = validEndDate;
113 + }
114 +
115 + public DistributeType getDistributeStrategy() {
116 + return distributeStrategy;
117 + }
118 +
119 + public void setDistributeStrategy(DistributeType distributeStrategy) {
120 + this.distributeStrategy = distributeStrategy;
121 + }
122 +
123 + public DrawType getDrawType() {
124 + return drawType;
125 + }
126 +
127 + public void setDrawType(DrawType drawType) {
128 + this.drawType = drawType;
129 + }
130 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/14<br/>
7 + * Time: 11:03<br/>
8 + * Description:分类:可以是红包、可以优惠券
9 + */
10 +public class CoupenCatagory {
11 + private Integer catagoryID;
12 + private String catagoryName;
13 +
14 + public CoupenCatagory(){
15 + }
16 +
17 + public CoupenCatagory(Integer ID,String name){
18 + this.catagoryName = name;
19 + this.catagoryID=ID;
20 + }
21 +
22 + public Integer getCatagoryID() {
23 + return catagoryID;
24 + }
25 +
26 + public void setCatagoryID(Integer catagoryID) {
27 + this.catagoryID = catagoryID;
28 + }
29 +
30 + public String getCatagoryName() {
31 + return catagoryName;
32 + }
33 +
34 + public void setCatagoryName(String catagoryName) {
35 + this.catagoryName = catagoryName;
36 + }
37 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +import java.util.ArrayList;
4 +import java.util.List;
5 +
6 +/**
7 + * Created by ZhaoOnline<br/>
8 + * User: yangyoupeng<br/>
9 + * Date: 2016/12/14<br/>
10 + * Time: 19:14<br/>
11 + * Description:Context表示上下文的意思,其中可以包括CoupenEnttity
12 + */
13 +public class CoupenContext<T extends CommonCoupenEntity,R extends CommonCoupenSeed> {
14 +
15 + private R seed=null;
16 +
17 + private List<T> coupens =new ArrayList<T>(0);
18 +
19 + public List<T> getCoupens() {
20 + return coupens;
21 + }
22 +
23 + public void setCoupens(List<T> coupens) {
24 + this.coupens = coupens;
25 + }
26 +
27 + public R getSeed() {
28 + return seed;
29 + }
30 +
31 + public void setSeed(R seed) {
32 + this.seed = seed;
33 + }
34 +
35 + public static CoupenContext empty() {
36 + CoupenContext context =new CoupenContext();
37 + return context;
38 + }
39 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/14<br/>
7 + * Time: 11:18<br/>
8 + * Description:分配类型。该类作为元数据。
9 + */
10 +public class DistributeType {
11 + private Integer typeID;
12 + private String typeName;
13 +
14 + public Integer getTypeID() {
15 + return typeID;
16 + }
17 +
18 + public void setTypeID(Integer typeID) {
19 + this.typeID = typeID;
20 + }
21 +
22 + public String getTypeName() {
23 + return typeName;
24 + }
25 +
26 + public void setTypeName(String typeName) {
27 + this.typeName = typeName;
28 + }
29 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/14<br/>
7 + * Time: 11:14<br/>
8 + * Description:领取类型,该类作为元数据
9 + */
10 +public class DrawType {
11 + private Integer typeID;
12 +
13 + private String typeName;
14 +
15 + public Integer getTypeID() {
16 + return typeID;
17 + }
18 +
19 + public void setTypeID(Integer typeID) {
20 + this.typeID = typeID;
21 + }
22 +
23 + public String getTypeName() {
24 + return typeName;
25 + }
26 +
27 + public void setTypeName(String typeName) {
28 + this.typeName = typeName;
29 + }
30 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 10:45<br/>
8 + * Description:HelpOpenCoupenSeed即 帮拆红包。
9 + * 用户在领取红包后,红包并不能立刻生效。用户必须邀请一定数目的好友进行帮拆
10 + * 帮拆的红包,也可以分为:1)满足全部帮拆好友数目后,红包才生效。
11 + * 2)即拆即用,好友每帮忙拆一个红包。其帮拆的一部分立刻生效,红包的主人可以立即使用该红包。
12 + */
13 +public class HelpOpenCoupenSeed extends CommonCoupenSeed {
14 + //帮拆的数目
15 + private Integer helperCount=new Integer(0);
16 +
17 + private HelpOpenType helpOpenType=HelpOpenType.VALIDE_LAST_TIME;
18 +
19 +
20 + public Integer getHelperCount() {
21 + return helperCount;
22 + }
23 +
24 + public void setHelperCount(Integer helperCount) {
25 + this.helperCount = helperCount;
26 + }
27 +
28 + public HelpOpenType getHelpOpenType() {
29 + return helpOpenType;
30 + }
31 +
32 + public void setHelpOpenType(HelpOpenType helpOpenType) {
33 + this.helpOpenType = helpOpenType;
34 + }
35 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by 杨有鹏 on 2016/12/15.
5 + * 帮拆类型
6 + */
7 +public enum HelpOpenType {
8 + UNKNOWN(0),//未知
9 + VALIDE_LAST_TIME(1),//最后时刻生效即帮拆
10 + VALIDE_ON_TIME(2);//帮拆就生效
11 +
12 + private final int type;
13 +
14 + HelpOpenType(int type){
15 + this.type=type;
16 + }
17 +
18 + public static HelpOpenType build(int type){
19 + switch (type){
20 + case 1:return VALIDE_LAST_TIME;
21 + case 2:return VALIDE_ON_TIME;
22 + default:return UNKNOWN;
23 + }
24 + }
25 +
26 + public boolean is(HelpOpenType helpOpenType) {
27 + return this.type == helpOpenType.type;
28 + }
29 +
30 + public boolean isNot(HelpOpenType helpOpenType){
31 + return !is(helpOpenType);
32 + }
33 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 10:29<br/>
8 + * Description:该红包类型。主要服务对象是好友帮拆的即拆即用的Counpen
9 + * 所谓即拆即用的Coupen:用户在领取红包后,红包并不能立刻生效。用户必须邀请一定数目的好友进行帮拆,
10 + * 每个好友帮拆之后,红包中其中一部分就生效,用户在这部分红包生效之后立刻使用该红包。可使用的额度只是好友帮拆的内容
11 + */
12 +public class LeafCoupenEntity extends CommonCoupenEntity {
13 +
14 + private CommonCoupenEntity parentCoupen;
15 +
16 +
17 + public CommonCoupenEntity getParentCoupen() {
18 + return parentCoupen;
19 + }
20 +
21 + public void setParentCoupen(CommonCoupenEntity parentCoupen) {
22 + this.parentCoupen = parentCoupen;
23 + }
24 +}
1 +package com.zhaoonline.coupen.bean;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 14:33<br/>
8 + * Description:用户信息
9 + */
10 +public class OwnerUser {
11 + private String ownerUserID;
12 + private String ownerUserType;
13 +
14 + public String getOwnerUserID() {
15 + return ownerUserID;
16 + }
17 +
18 + public void setOwnerUserID(String ownerUserID) {
19 + this.ownerUserID = ownerUserID;
20 + }
21 +
22 + public String getOwnerUserType() {
23 + return ownerUserType;
24 + }
25 +
26 + public void setOwnerUserType(String ownerUserType) {
27 + this.ownerUserType = ownerUserType;
28 + }
29 +}
1 +package com.zhaoonline.coupen.cache;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 17:55<br/>
8 + * Description:please descript you class
9 + */
10 +public class CacheEntry<T> {
11 + String key;
12 + T value;
13 + CacheEntry pre;
14 + CacheEntry next;
15 +}
1 +package com.zhaoonline.coupen.cache;
2 +
3 +import java.util.HashSet;
4 +import java.util.Iterator;
5 +import java.util.Set;
6 +import java.util.concurrent.ConcurrentHashMap;
7 +
8 +/**
9 + * Created by ZhaoOnline<br/>
10 + * User: yangyoupeng<br/>
11 + * Date: 2016/12/15<br/>
12 + * Time: 17:54<br/>
13 + * Description:
14 + */
15 +public class LRUCache<T> {
16 + private ConcurrentHashMap<String, T> caches = null;
17 +
18 + private CacheEntry<T> first;
19 + private CacheEntry<T> last;
20 + private int capacity = 0;
21 +
22 + public LRUCache() {
23 + this(200);
24 + }
25 + public LRUCache(int capacity) {
26 + this.capacity=capacity;
27 + this.caches = new ConcurrentHashMap<String,T>(capacity);
28 + }
29 +
30 +
31 + public synchronized T put(String key, T value) {
32 + CacheEntry<T> entry = getEntry(key);
33 + if (entry == null) {
34 + if (caches.size() >= capacity) {
35 + caches.remove(last.key);
36 + removeLast();
37 + }
38 + entry = new CacheEntry<T>();
39 + entry.key = key;
40 + }else{
41 + entry.value=null;
42 + }
43 + entry.value = value;
44 + moveToFirst(entry);
45 + return caches.put(key, value);
46 + }
47 +
48 + public int getSize() {
49 + return caches.size();
50 + }
51 +
52 + public synchronized T get(String key) {
53 + CacheEntry<T> entry = getEntry(key);
54 + if (entry == null){
55 + return null;
56 + }
57 + moveToFirst(entry);
58 + return entry.value;
59 + }
60 +
61 +
62 + public synchronized void remove(String key) {
63 + CacheEntry<T> entry = getEntry(key);
64 + if (entry != null) {
65 + if (entry.pre != null)
66 + entry.pre.next = entry.next;
67 + if (entry.next != null)
68 + entry.next.pre = entry.pre;
69 + if (entry == first)
70 + first = entry.next;
71 + if (entry == last)
72 + last = entry.pre;
73 + }
74 + caches.remove(key);
75 + }
76 +
77 + private void removeLast() {
78 + if (last != null) {
79 + last = last.pre;
80 + if (last == null)
81 + first = null;
82 + else
83 + last.next = null;
84 + }
85 + }
86 +
87 + private void moveToFirst(CacheEntry<T> entry) {
88 + if (entry == first)
89 + return;
90 + if (entry.pre != null)
91 + entry.pre.next = entry.next;
92 + if (entry.next != null)
93 + entry.next.pre = entry.pre;
94 + if (entry == last)
95 + last = last.pre;
96 + if (first == null || last == null) {
97 + first = last = entry;
98 + return;
99 + }
100 + entry.next = first;
101 + first.pre = entry;
102 + first = entry;
103 + entry.pre = null;
104 + }
105 +
106 +
107 + private CacheEntry<T> getEntry(String key) {
108 + T item = caches.get(key);
109 + if (item == null) {
110 + return null;
111 + }
112 + CacheEntry<T> entry = new CacheEntry<T>();
113 + entry.key = key;
114 + entry.value = item;
115 + return entry;
116 + }
117 +
118 +
119 +
120 + @Override
121 + public String toString() {
122 + StringBuilder sb = new StringBuilder();
123 + CacheEntry<T> entry = first;
124 + while (entry != null) {
125 + sb.append(String.format("%s:%s ", entry.key, entry.value));
126 + entry = entry.next;
127 + }
128 + return sb.toString();
129 + }
130 +
131 +
132 +
133 + public Set<String> keySet(){
134 + Set<String> keSet=new HashSet<String>();
135 + ConcurrentHashMap.KeySetView<String, T> keysSetView= caches.keySet();
136 + Iterator<String> iter=keysSetView.iterator();
137 + while(iter.hasNext()){
138 + String key=iter.next();
139 + keSet.add(key);
140 + }
141 + return keSet;
142 + }
143 +}
1 +package com.zhaoonline.coupen.cache;
2 +
3 +import java.util.*;
4 +import java.util.concurrent.ConcurrentHashMap;
5 +
6 +/**
7 + * Created by ZhaoOnline<br/>
8 + * User: yangyoupeng<br/>
9 + * Date: 2016/12/15<br/>
10 + * Time: 18:13<br/>
11 + * Description:随机缓存
12 + */
13 +public class RandomCache<K,V> {
14 + private ConcurrentHashMap<K,V> caches = null;
15 + private int capacity = 0;
16 + private List<K> keys=null;
17 + public RandomCache() {
18 + this(200);
19 + }
20 + public RandomCache(int capacity) {
21 + this.capacity=capacity;
22 + this.caches = new ConcurrentHashMap<K,V>(capacity);
23 + this.keys= Collections.synchronizedList(new ArrayList<K>(capacity));
24 + }
25 +
26 + public synchronized void put(K key,V value){
27 + caches.put(key, value);
28 + keys.add(key);
29 + }
30 +
31 + public synchronized void remove(K key){
32 + caches.remove(key);
33 + keys.remove(key);
34 + }
35 +
36 + public K randomKey(){
37 + Random random = new Random();
38 + if(keys.size() == 0){
39 + return null;
40 + }
41 + int keyIndex=random.nextInt(keys.size());
42 + K key=keys.get(keyIndex);
43 + return key;
44 + }
45 +
46 +
47 + public synchronized K shuffledRandomKey(){
48 + List<K> clonedKeys=new ArrayList<>(keys);
49 + Collections.shuffle(clonedKeys);
50 + if(clonedKeys.size() == 0){
51 + return null;
52 + }
53 + return clonedKeys.get(0);
54 + }
55 +
56 + public int size(){
57 + return caches.size();
58 + }
59 +
60 + public boolean isEmpty(){
61 + return caches.isEmpty();
62 + }
63 +
64 + public List<K> allKeys(){
65 + return keys;
66 + }
67 +
68 + public V getCache(String key){
69 + if(key == null){
70 + return null;
71 + }
72 + return caches.get(key);
73 + }
74 +
75 + public synchronized void clear() {
76 + this.caches = new ConcurrentHashMap<K,V>(capacity);
77 + this.keys= Collections.synchronizedList(new ArrayList<K>(capacity));
78 + }
79 +}
1 +package com.zhaoonline.coupen.concurrent;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/16<br/>
7 + * Time: 17:48<br/>
8 + * Description:please descript you class
9 + */
10 +public interface ConcurrentStrategy {
11 +
12 + public boolean proceeding();
13 +
14 + public boolean proceeding(long timeout);
15 +
16 +
17 +}
1 +package com.zhaoonline.coupen.concurrent;
2 +
3 +import com.zhaoonline.coupen.concurrent.tokenbucket.TokenBucket;
4 +import com.zhaoonline.coupen.concurrent.tokenbucket.TokenBuckets;
5 +
6 +import java.util.concurrent.TimeUnit;
7 +
8 +/**
9 + * Created by ZhaoOnline<br/>
10 + * User: yangyoupeng<br/>
11 + * Date: 2016/12/16<br/>
12 + * Time: 17:49<br/>
13 + * Description:please descript you class
14 + */
15 +public class TokenBucktStrategy implements ConcurrentStrategy {
16 +
17 + TokenBucket bucket = null;
18 + public TokenBucktStrategy(){
19 + bucket = TokenBuckets.builder()
20 + .withCapacity(1000)
21 + .withFixedIntervalRefillStrategy(400, 1, TimeUnit.SECONDS)
22 + .build();
23 + }
24 +
25 + /**
26 + * 立即返回
27 + * @return
28 + */
29 + @Override
30 + public boolean proceeding() {
31 + return bucket.tryConsume();
32 + }
33 +
34 + /**
35 + * @param 令牌桶的timemout等同于从令牌桶里面获取多少个令牌。
36 + * @return
37 + */
38 + @Override
39 + public boolean proceeding(long timeout) {
40 + bucket.consume(timeout);
41 + return true;
42 + }
43 +
44 +
45 +}
1 +package com.zhaoonline.coupen.concurrent.tokenbucket;
2 +
3 +
4 +import com.google.common.base.Ticker;
5 +
6 +import java.util.concurrent.TimeUnit;
7 +
8 +/**
9 + * A token bucket refill strategy that will provide N tokens for a token bucket to consume every T units of time.
10 + * The tokens are refilled in bursts rather than at a fixed rate. This refill strategy will never allow more than
11 + * N tokens to be consumed during a window of time T.
12 + */
13 +public class FixedIntervalRefillStrategy implements TokenBucketImpl.RefillStrategy {
14 + private final Ticker ticker;
15 + private final long numTokensPerPeriod;
16 + private final long periodDurationInNanos;
17 + private long lastRefillTime;
18 + private long nextRefillTime;
19 +
20 + /**
21 + * Create a FixedIntervalRefillStrategy.
22 + *
23 + * @param ticker A ticker to use to measure time.
24 + * @param numTokensPerPeriod The number of tokens to add to the bucket every period.
25 + * @param period How often to refill the bucket.
26 + * @param unit Unit for period.
27 + */
28 + public FixedIntervalRefillStrategy(Ticker ticker, long numTokensPerPeriod, long period, TimeUnit unit) {
29 + this.ticker = ticker;
30 + this.numTokensPerPeriod = numTokensPerPeriod;
31 + this.periodDurationInNanos = unit.toNanos(period);
32 + this.lastRefillTime = -periodDurationInNanos;
33 + this.nextRefillTime = -periodDurationInNanos;
34 + }
35 +
36 + @Override
37 + public synchronized long refill() {
38 + long now = ticker.read();
39 + if (now < nextRefillTime) {
40 + return 0;
41 + }
42 +
43 + // We now know that we need to refill the bucket with some tokens, the question is how many. We need to count how
44 + // many periods worth of tokens we've missed.
45 + long numPeriods = Math.max(0, (now - lastRefillTime) / periodDurationInNanos);
46 +
47 + // Move the last refill time forward by this many periods.
48 + lastRefillTime += numPeriods * periodDurationInNanos;
49 +
50 + // ...and we'll refill again one period after the last time we refilled.
51 + nextRefillTime = lastRefillTime + periodDurationInNanos;
52 +
53 + return numPeriods * numTokensPerPeriod;
54 + }
55 +
56 + @Override
57 + public long getDurationUntilNextRefill(TimeUnit unit) {
58 + long now = ticker.read();
59 + return unit.convert(Math.max(0, nextRefillTime - now), TimeUnit.NANOSECONDS);
60 + }
61 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.concurrent.tokenbucket;
2 +
3 +import java.util.concurrent.TimeUnit;
4 +
5 +/**
6 + * A token bucket is used for rate limiting access to a portion of code.
7 + *
8 + * @see <a href="http://en.wikipedia.org/wiki/Token_bucket">Token Bucket on Wikipedia</a>
9 + * @see <a href="http://en.wikipedia.org/wiki/Leaky_bucket">Leaky Bucket on Wikipedia</a>
10 + */
11 +public interface TokenBucket {
12 + /**
13 + * Returns the capacity of this token bucket. This is the maximum number of tokens that the bucket can hold at
14 + * any one time.
15 + *
16 + * @return The capacity of the bucket.
17 + */
18 + long getCapacity();
19 +
20 + /**
21 + * Returns the current number of tokens in the bucket. If the bucket is empty then this method will return 0.
22 + *
23 + * @return The current number of tokens in the bucket.
24 + */
25 + long getNumTokens();
26 +
27 + /**
28 + * Returns the amount of time in the specified time unit until the next group of tokens can be added to the token
29 + * bucket.
30 + *
31 + * @param unit The time unit to express the return value in.
32 + * @return The amount of time until the next group of tokens can be added to the token bucket.
33 + * @see org.isomorphism.util.TokenBucket.RefillStrategy#getDurationUntilNextRefill(java.util.concurrent.TimeUnit)
34 + */
35 + long getDurationUntilNextRefill(TimeUnit unit) throws UnsupportedOperationException;
36 +
37 + /**
38 + * Attempt to consume a single token from the bucket. If it was consumed then {@code true} is returned, otherwise
39 + * {@code false} is returned.
40 + *
41 + * @return {@code true} if a token was consumed, {@code false} otherwise.
42 + */
43 + boolean tryConsume();
44 +
45 + /**
46 + * Attempt to consume a specified number of tokens from the bucket. If the tokens were consumed then {@code true}
47 + * is returned, otherwise {@code false} is returned.
48 + *
49 + * @param numTokens The number of tokens to consume from the bucket, must be a positive number.
50 + * @return {@code true} if the tokens were consumed, {@code false} otherwise.
51 + */
52 + boolean tryConsume(long numTokens);
53 +
54 + /**
55 + * Consume a single token from the bucket. If no token is currently available then this method will block until a
56 + * token becomes available.
57 + */
58 + void consume();
59 +
60 + /**
61 + * Consumes multiple tokens from the bucket. If enough tokens are not currently available then this method will block
62 + * until
63 + *
64 + * @param numTokens The number of tokens to consume from teh bucket, must be a positive number.
65 + */
66 + void consume(long numTokens);
67 +
68 + /**
69 + * Refills the bucket with the specified number of tokens. If the bucket is currently full or near capacity then
70 + * fewer than {@code numTokens} may be added.
71 + *
72 + * @param numTokens The number of tokens to add to the bucket.
73 + */
74 + void refill(long numTokens);
75 +
76 + /**
77 + * Encapsulation of a refilling strategy for a token bucket.
78 + */
79 + static interface RefillStrategy {
80 + /**
81 + * Returns the number of tokens to add to the token bucket.
82 + *
83 + * @return The number of tokens to add to the token bucket.
84 + */
85 + long refill();
86 +
87 + /**
88 + * Returns the amount of time in the specified time unit until the next group of tokens can be added to the token
89 + * bucket. Please note, depending on the {@code SleepStrategy} used by the token bucket, tokens may not actually
90 + * be added until much after the returned duration. If for some reason the implementation of
91 + * {@code RefillStrategy} doesn't support knowing when the next batch of tokens will be added, then an
92 + * {@code UnsupportedOperationException} may be thrown. Lastly, if the duration until the next time tokens will
93 + * be added to the token bucket is less than a single unit of the passed in time unit then this method will
94 + * return 0.
95 + *
96 + * @param unit The time unit to express the return value in.
97 + * @return The amount of time until the next group of tokens can be added to the token bucket.
98 + */
99 + long getDurationUntilNextRefill(TimeUnit unit) throws UnsupportedOperationException;
100 + }
101 +
102 + /**
103 + * Encapsulation of a strategy for relinquishing control of the CPU.
104 + */
105 + static interface SleepStrategy {
106 + /**
107 + * Sleep for a short period of time to allow other threads and system processes to execute.
108 + */
109 + void sleep();
110 + }
111 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.concurrent.tokenbucket;
2 +
3 +import java.util.concurrent.TimeUnit;
4 +
5 +import static com.google.common.base.Preconditions.checkArgument;
6 +import static com.google.common.base.Preconditions.checkNotNull;
7 +
8 +/**
9 + * A token bucket implementation that is of a leaky bucket in the sense that it has a finite capacity and any added
10 + * tokens that would exceed this capacity will "overflow" out of the bucket and are lost forever.
11 + * <p>
12 + * In this implementation the rules for refilling the bucket are encapsulated in a provided {@code RefillStrategy}
13 + * instance. Prior to attempting to consume any tokens the refill strategy will be consulted to see how many tokens
14 + * should be added to the bucket.
15 + * <p>
16 + * In addition in this implementation the method of yielding CPU control is encapsulated in the provided
17 + * {@code SleepStrategy} instance. For high performance applications where tokens are being refilled incredibly quickly
18 + * and an accurate bucket implementation is required, it may be useful to never yield control of the CPU and to instead
19 + * busy wait. This strategy allows the caller to make this decision for themselves instead of the library forcing a
20 + * decision.
21 + */
22 +
23 +/**
24 + * Created by ZhaoOnline<br/>
25 + * User: yangyoupeng<br/>
26 + * Date: 2016/12/16<br/>
27 + * Time: 17:42<br/>
28 + * Description:please descript you class
29 + */
30 +public class TokenBucketImpl implements TokenBucket {
31 + private final long capacity;
32 + private final RefillStrategy refillStrategy;
33 + private final SleepStrategy sleepStrategy;
34 + private long size;
35 +
36 + TokenBucketImpl(long capacity, long initialTokens, RefillStrategy refillStrategy, SleepStrategy sleepStrategy) {
37 + checkArgument(capacity > 0);
38 + checkArgument(initialTokens <= capacity);
39 +
40 + this.capacity = capacity;
41 + this.refillStrategy = checkNotNull(refillStrategy);
42 + this.sleepStrategy = checkNotNull(sleepStrategy);
43 + this.size = initialTokens;
44 + }
45 +
46 + /**
47 + * Returns the capacity of this token bucket. This is the maximum number of tokens that the bucket can hold at
48 + * any one time.
49 + *
50 + * @return The capacity of the bucket.
51 + */
52 + @Override
53 + public long getCapacity() {
54 + return capacity;
55 + }
56 +
57 + /**
58 + * Returns the current number of tokens in the bucket. If the bucket is empty then this method will return 0.
59 + *
60 + * @return The current number of tokens in the bucket.
61 + */
62 + @Override
63 + public synchronized long getNumTokens() {
64 + // Give the refill strategy a chance to add tokens if it needs to so that we have an accurate
65 + // count.
66 + refill(refillStrategy.refill());
67 +
68 + return size;
69 + }
70 +
71 + /**
72 + * Returns the amount of time in the specified time unit until the next group of tokens can be added to the token
73 + * bucket.
74 + *
75 + * @see org.isomorphism.util.TokenBucket.RefillStrategy#getDurationUntilNextRefill(java.util.concurrent.TimeUnit)
76 + * @param unit The time unit to express the return value in.
77 + * @return The amount of time until the next group of tokens can be added to the token bucket.
78 + */
79 + @Override
80 + public long getDurationUntilNextRefill(TimeUnit unit) throws UnsupportedOperationException {
81 + return refillStrategy.getDurationUntilNextRefill(unit);
82 + }
83 +
84 + /**
85 + * Attempt to consume a single token from the bucket. If it was consumed then {@code true} is returned, otherwise
86 + * {@code false} is returned.
87 + *
88 + * @return {@code true} if a token was consumed, {@code false} otherwise.
89 + */
90 + public boolean tryConsume() {
91 + return tryConsume(1);
92 + }
93 +
94 + /**
95 + * Attempt to consume a specified number of tokens from the bucket. If the tokens were consumed then {@code true}
96 + * is returned, otherwise {@code false} is returned.
97 + *
98 + * @param numTokens The number of tokens to consume from the bucket, must be a positive number.
99 + * @return {@code true} if the tokens were consumed, {@code false} otherwise.
100 + */
101 + public synchronized boolean tryConsume(long numTokens) {
102 + checkArgument(numTokens > 0, "Number of tokens to consume must be positive");
103 + checkArgument(numTokens <= capacity, "Number of tokens to consume must be less than the capacity of the bucket.");
104 +
105 + refill(refillStrategy.refill());
106 +
107 + // Now try to consume some tokens
108 + if (numTokens <= size) {
109 + size -= numTokens;
110 + return true;
111 + }
112 +
113 + return false;
114 + }
115 +
116 + /**
117 + * Consume a single token from the bucket. If no token is currently available then this method will block until a
118 + * token becomes available.
119 + */
120 + public void consume() {
121 + consume(1);
122 + }
123 +
124 + /**
125 + * Consumes multiple tokens from the bucket. If enough tokens are not currently available then this method will block
126 + * until
127 + *
128 + * @param numTokens The number of tokens to consume from teh bucket, must be a positive number.
129 + */
130 + public void consume(long numTokens) {
131 + while (true) {
132 + if (tryConsume(numTokens)) {
133 + break;
134 + }
135 +
136 + sleepStrategy.sleep();
137 + }
138 + }
139 +
140 + /**
141 + * Refills the bucket with the specified number of tokens. If the bucket is currently full or near capacity then
142 + * fewer than {@code numTokens} may be added.
143 + *
144 + * @param numTokens The number of tokens to add to the bucket.
145 + */
146 + public synchronized void refill(long numTokens) {
147 + long newTokens = Math.min(capacity, Math.max(0, numTokens));
148 + size = Math.max(0, Math.min(size + newTokens, capacity));
149 + }
150 +}
1 +package com.zhaoonline.coupen.concurrent.tokenbucket;
2 +
3 +
4 +import com.google.common.base.Ticker;
5 +import com.google.common.util.concurrent.Uninterruptibles;
6 +
7 +import java.util.concurrent.TimeUnit;
8 +
9 +import static com.google.common.base.Preconditions.checkArgument;
10 +import static com.google.common.base.Preconditions.checkNotNull;
11 +/**
12 + * Created by ZhaoOnline<br/>
13 + * User: yangyoupeng<br/>
14 + * Date: 2016/12/16<br/>
15 + * Time: 17:42<br/>
16 + * Description:please descript you class
17 + */
18 +
19 +/**
20 + * Static utility methods pertaining to creating {@link TokenBucketImpl} instances.
21 + */
22 +public final class TokenBuckets {
23 + private TokenBuckets() {
24 + }
25 +
26 + /**
27 + * Create a new builder for token buckets.
28 + */
29 + public static Builder builder() {
30 + return new Builder();
31 + }
32 +
33 + public static class Builder {
34 + private Long capacity = null;
35 + private long initialTokens = 0;
36 + private TokenBucketImpl.RefillStrategy refillStrategy = null;
37 + private TokenBucketImpl.SleepStrategy sleepStrategy = YIELDING_SLEEP_STRATEGY;
38 + private final Ticker ticker = Ticker.systemTicker();
39 +
40 + /**
41 + * Specify the overall capacity of the token bucket.
42 + */
43 + public Builder withCapacity(long numTokens) {
44 + checkArgument(numTokens > 0, "Must specify a positive number of tokens");
45 + capacity = numTokens;
46 + return this;
47 + }
48 +
49 + /**
50 + * Initialize the token bucket with a specific number of tokens.
51 + */
52 + public Builder withInitialTokens(long numTokens) {
53 + checkArgument(numTokens > 0, "Must specify a positive number of tokens");
54 + initialTokens = numTokens;
55 + return this;
56 + }
57 +
58 + /**
59 + * Refill tokens at a fixed interval.
60 + */
61 + public Builder withFixedIntervalRefillStrategy(long refillTokens, long period, TimeUnit unit) {
62 + return withRefillStrategy(new FixedIntervalRefillStrategy(ticker, refillTokens, period, unit));
63 + }
64 +
65 + /**
66 + * Use a user defined refill strategy.
67 + */
68 + public Builder withRefillStrategy(TokenBucket.RefillStrategy refillStrategy) {
69 + this.refillStrategy = checkNotNull(refillStrategy);
70 + return this;
71 + }
72 +
73 + /**
74 + * Use a sleep strategy that will always attempt to yield the CPU to other processes.
75 + */
76 + public Builder withYieldingSleepStrategy() {
77 + return withSleepStrategy(YIELDING_SLEEP_STRATEGY);
78 + }
79 +
80 + /**
81 + * Use a sleep strategy that will not yield the CPU to other processes. It will busy wait until more tokens become
82 + * available.
83 + */
84 + public Builder withBusyWaitSleepStrategy() {
85 + return withSleepStrategy(BUSY_WAIT_SLEEP_STRATEGY);
86 + }
87 +
88 + /**
89 + * Use a user defined sleep strategy.
90 + */
91 + public Builder withSleepStrategy(TokenBucket.SleepStrategy sleepStrategy) {
92 + this.sleepStrategy = checkNotNull(sleepStrategy);
93 + return this;
94 + }
95 +
96 + /**
97 + * Build the token bucket.
98 + */
99 + public TokenBucket build() {
100 + checkNotNull(capacity, "Must specify a capacity");
101 + checkNotNull(refillStrategy, "Must specify a refill strategy");
102 +
103 + return new TokenBucketImpl(capacity, initialTokens, refillStrategy, sleepStrategy);
104 + }
105 + }
106 +
107 + private static final TokenBucketImpl.SleepStrategy YIELDING_SLEEP_STRATEGY = new TokenBucketImpl.SleepStrategy() {
108 + @Override
109 + public void sleep() {
110 + // Sleep for the smallest unit of time possible just to relinquish control
111 + // and to allow other threads to run.
112 + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.NANOSECONDS);
113 + }
114 + };
115 +
116 + private static final TokenBucketImpl.SleepStrategy BUSY_WAIT_SLEEP_STRATEGY = new TokenBucketImpl.SleepStrategy() {
117 + @Override
118 + public void sleep() {
119 + // Do nothing, don't sleep.
120 + }
121 + };
122 +}
1 +package com.zhaoonline.coupen.jwt;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/14<br/>
7 + * Time: 14:58<br/>
8 + * Description:please descript you class
9 + */
10 +public class JWTConfig {
11 + private String issuer;
12 + private String password;
13 +
14 + private String encodeKeyName;
15 +
16 + public String getIssuer() {
17 + return issuer;
18 + }
19 +
20 + public void setIssuer(String issuer) {
21 + this.issuer = issuer;
22 + }
23 +
24 + public String getPassword() {
25 + return password;
26 + }
27 +
28 + public void setPassword(String password) {
29 + this.password = password;
30 + }
31 +
32 + public String getEncodeKeyName() {
33 + return encodeKeyName;
34 + }
35 +
36 + public void setEncodeKeyName(String encodeKeyName) {
37 + this.encodeKeyName = encodeKeyName;
38 + }
39 +}
1 +package com.zhaoonline.coupen.jwt;
2 +
3 +import com.auth0.jwt.JWT;
4 +import com.auth0.jwt.JWTVerifier;
5 +import com.auth0.jwt.algorithms.Algorithm;
6 +import com.auth0.jwt.interfaces.DecodedJWT;
7 +import com.fasterxml.jackson.databind.ObjectMapper;
8 +
9 +import java.io.IOException;
10 +import java.io.UnsupportedEncodingException;
11 +
12 +/**
13 + * Created by ZhaoOnline<br/>
14 + * User: yangyoupeng<br/>
15 + * Date: 2016/12/14<br/>
16 + * Time: 10:38<br/>
17 + * Description:please descript you class
18 + */
19 +public class JWTDecoder {
20 + private static ObjectMapper objectMapper =new ObjectMapper();
21 + JWTVerifier verifier = null;
22 + JWTConfig config =new JWTConfig();
23 + public JWTDecoder(JWTConfig config) throws UnsupportedEncodingException {
24 + this.config= config;
25 + verifier =JWT.require(Algorithm.HMAC256(config.getPassword()))
26 + .withIssuer(config.getIssuer())
27 + .build();
28 + }
29 +
30 + public <T> T decode(String jwtToken,Class<T> clazz ) throws IOException {
31 + DecodedJWT jwt = verifier.verify(jwtToken);
32 + java.lang.String coupenJsonString= jwt.getClaim(config.getEncodeKeyName()).asString();
33 + T decodeCoupen= objectMapper.readValue(coupenJsonString,clazz);
34 + return decodeCoupen;
35 + }
36 +}
1 +package com.zhaoonline.coupen.jwt;
2 +
3 +import com.auth0.jwt.JWT;
4 +import com.auth0.jwt.algorithms.Algorithm;
5 +import com.fasterxml.jackson.core.JsonProcessingException;
6 +import com.fasterxml.jackson.databind.ObjectMapper;
7 +
8 +import java.io.UnsupportedEncodingException;
9 +
10 +/**
11 + * Created by ZhaoOnline<br/>
12 + * User: yangyoupeng<br/>
13 + * Date: 2016/12/14<br/>
14 + * Time: 10:38<br/>
15 + * Description:please descript you class
16 + */
17 +public class JWTEncoder {
18 + private static ObjectMapper objectMapper =new ObjectMapper();
19 + JWTConfig config =new JWTConfig();
20 + public JWTEncoder(JWTConfig config){
21 + this.config= config;
22 + }
23 + public String encode(Object object) throws JsonProcessingException, UnsupportedEncodingException {
24 + String coupenSeedString =objectMapper.writeValueAsString(object);
25 + String token = JWT.create()
26 + .withIssuer(config.getIssuer())
27 + .withClaim(config.getEncodeKeyName(),coupenSeedString)
28 + .sign(Algorithm.HMAC256(config.getPassword()));
29 + return token;
30 + }
31 +}
1 +package com.zhaoonline.coupen.lifecycle;
2 +
3 +import java.util.concurrent.atomic.AtomicBoolean;
4 +
5 +/**
6 + * Created by ZhaoOnline<br/>
7 + * User: yangyoupeng<br/>
8 + * Date: 2016/12/16<br/>
9 + * Time: 15:22<br/>
10 + * Description:please descript you class
11 + */
12 +public class LifeCycle {
13 + private AtomicBoolean start=new AtomicBoolean(false);
14 + private AtomicBoolean needReload=new AtomicBoolean(false);
15 +
16 + public void markNeedReload(){
17 + needReload.set(true);
18 + }
19 + public void resetNeedReload(){
20 + needReload.set(false);
21 + }
22 + public boolean checkNeedReload(){
23 + return needReload.get();
24 + }
25 + public void markStart(){
26 + start.compareAndSet(false,true);
27 + }
28 + public void markShutDown(){
29 + start.set(false);
30 + }
31 + public void resetAll(){
32 + needReload.set(false);
33 + start.set(false);
34 + }
35 +}
1 +package com.zhaoonline.coupen.repository;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 16:06<br/>
8 + * Description:活动的增删改查
9 + */
10 +public class ActivityRepository {
11 +
12 +}
1 +package com.zhaoonline.coupen.repository;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 16:08<br/>
8 + * Description:CoupenEntity(具体的Counpen实体)的增删改查
9 + */
10 +public class CoupenEntityRepository {
11 +}
1 +package com.zhaoonline.coupen.repository;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 16:07<br/>
8 + * Description:CoupenSeed的增删改查
9 + */
10 +public class CoupenSeedRepository {
11 +}
1 +package com.zhaoonline.coupen.repository;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/15<br/>
7 + * Time: 16:36<br/>
8 + * Description:用户与Coupen之间映射关系的增删改查
9 + */
10 +public class UserCoupenMappingRepository {
11 +}
1 +package com.zhaoonline.coupen.utils;
2 +
3 +import com.fasterxml.jackson.core.JsonParseException;
4 +import com.fasterxml.jackson.core.JsonProcessingException;
5 +import com.fasterxml.jackson.databind.JsonMappingException;
6 +import com.fasterxml.jackson.databind.ObjectMapper;
7 +
8 +import java.io.IOException;
9 +import java.io.InputStream;
10 +import java.util.Map;
11 +
12 +/**
13 + * Created by ZhaoOnline<br/>
14 + * User: yangyoupeng<br/>
15 + * Date: 2016/12/15<br/>
16 + * Time: 20:00<br/>
17 + * Description:please descript you class
18 + */
19 +public class JsonUtils {
20 + private static ObjectMapper mapper= new ObjectMapper();
21 +
22 +
23 + /**
24 + * Method name: toObject <BR>
25 + * Description: 读取失败就返回null <BR>
26 + * Remark: <BR>
27 + * @param inputStram
28 + * @param clazz
29 + * @return T<BR>
30 + * @throws IOException
31 + * @throws JsonMappingException
32 + * @throws JsonParseException
33 + */
34 + public static <T> T toObject(InputStream inputStram , Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
35 + return mapper.readValue(inputStram, clazz);
36 + }
37 +
38 + public static String toJson(Object object) throws JsonProcessingException {
39 + return mapper.writeValueAsString(object);
40 + }
41 +
42 + public static <T> T toObject(String jsonString,Class<T> clazz) throws IOException {
43 + return mapper.readValue(jsonString, clazz);
44 + }
45 + public static Map toMap(String jsonString) throws IOException {
46 + return toObject(jsonString,Map.class);
47 + }
48 +
49 +}
1 +package com.zhaoonline.coupen.utils;
2 +
3 +import java.io.Closeable;
4 +import java.io.IOException;
5 +import java.text.SimpleDateFormat;
6 +import java.util.Date;
7 +import java.util.Random;
8 +
9 +/**
10 + * Created by ZhaoOnline<br/>
11 + * User: yangyoupeng<br/>
12 + * Date: 2016/12/14<br/>
13 + * Time: 19:57<br/>
14 + * Description:please descript you class
15 + */
16 +public class Utils {
17 +
18 + public static void closeStream(Closeable stream){
19 + if(stream!=null){
20 + try {
21 + stream.close();
22 + } catch (IOException e) {
23 + e.printStackTrace();
24 + }
25 + }
26 + }
27 + public static String getRandomForDate(String param){
28 + SimpleDateFormat simpleDateFormat;
29 + simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
30 + Date date = new Date();
31 + String str = simpleDateFormat.format(date);
32 + Random random = new Random();
33 + int rannum = (int) (random.nextDouble() * (9999 - 100 + 1)) + 100;// 获取5位随机数
34 + return param + str + rannum;
35 + }
36 +}
1 +package com.zhaoonline.coupen.concurrent.tokenbucket;
2 +
3 +
4 +import com.google.common.base.Ticker;
5 +import org.junit.Test;
6 +
7 +import java.util.concurrent.TimeUnit;
8 +
9 +import static org.junit.Assert.assertEquals;
10 +
11 +public class FixedIntervalRefillStrategyTest {
12 + private static final long N = 5; // 5 tokens
13 + private static final long P = 10; // every 10
14 + private static final TimeUnit U = TimeUnit.SECONDS; // seconds
15 +
16 + private final MockTicker ticker = new MockTicker();
17 + private final FixedIntervalRefillStrategy strategy = new FixedIntervalRefillStrategy(ticker, N, P, U);
18 +
19 + @Test
20 + public void testFirstRefill() {
21 + assertEquals(N, strategy.refill());
22 + }
23 +
24 + @Test
25 + public void testNoRefillUntilPeriodUp() {
26 + strategy.refill();
27 +
28 + // Another refill shouldn't come for P time units.
29 + for (int i = 0; i < P - 1; i++) {
30 + ticker.advance(1, U);
31 + assertEquals(0, strategy.refill());
32 + }
33 + }
34 +
35 + @Test
36 + public void testRefillEveryPeriod() {
37 + strategy.refill();
38 +
39 + ticker.advance(P, U);
40 + assertEquals(N, strategy.refill());
41 +
42 + ticker.advance(P, U);
43 + assertEquals(N, strategy.refill());
44 +
45 + ticker.advance(P, U);
46 + assertEquals(N, strategy.refill());
47 + }
48 +
49 + @Test
50 + public void testRefillEveryOtherPeriod() {
51 + strategy.refill();
52 +
53 + // Move time forward two periods, since we're skipping a period next time we should add double the tokens.
54 + ticker.advance(2 * P, U);
55 + assertEquals(2 * N, strategy.refill());
56 +
57 + ticker.advance(2 * P, U);
58 + assertEquals(2 * N, strategy.refill());
59 + }
60 +
61 + @Test
62 + public void testRefillOnNonEvenPeriods() {
63 + // The strategy is configured to refill tokens every P time units. So we should only get refills at 0, P, 2P, 3P,
64 + // etc. Any other time should return 0 tokens.
65 +
66 + // t = 0
67 + assertEquals(N, strategy.refill());
68 +
69 + // t = P+1
70 + ticker.advance(P + 1, U);
71 + assertEquals(N, strategy.refill());
72 +
73 + // t = 2P+1
74 + ticker.advance(P, U);
75 + assertEquals(N, strategy.refill());
76 +
77 + // t = 3P
78 + ticker.advance(P - 1, U);
79 + assertEquals(N, strategy.refill());
80 +
81 + // t = 4P-1
82 + ticker.advance(P - 1, U);
83 + assertEquals(0, strategy.refill());
84 +
85 + // t = 4P
86 + ticker.advance(1, U);
87 + assertEquals(N, strategy.refill());
88 + }
89 +
90 + @Test
91 + public void testDurationUntilFirstRefill() {
92 + // A refill has never happened, so one is supposed to happen immediately.
93 + assertEquals(0, strategy.getDurationUntilNextRefill(TimeUnit.SECONDS));
94 + }
95 +
96 + @Test
97 + public void testDurationAfterFirstRefill() {
98 + strategy.refill();
99 +
100 + for (int i = 0; i < P - 1; i++) {
101 + assertEquals(P - i, strategy.getDurationUntilNextRefill(TimeUnit.SECONDS));
102 + ticker.advance(1, U);
103 + }
104 + }
105 +
106 + @Test
107 + public void testDurationAtSecondRefillTime() {
108 + strategy.refill();
109 + ticker.advance(P, U);
110 +
111 + assertEquals(0, strategy.getDurationUntilNextRefill(TimeUnit.SECONDS));
112 + }
113 +
114 + @Test
115 + public void testDurationInProperUnits() {
116 + strategy.refill();
117 +
118 + assertEquals(10000, strategy.getDurationUntilNextRefill(TimeUnit.MILLISECONDS));
119 + }
120 +
121 + private static final class MockTicker extends Ticker {
122 + private long now = 0;
123 +
124 + @Override
125 + public long read() {
126 + return now;
127 + }
128 +
129 + public void advance(long delta, TimeUnit unit) {
130 + now += unit.toNanos(delta);
131 + }
132 + }
133 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.concurrent.tokenbucket;
2 +
3 +
4 +import org.junit.Test;
5 +
6 +public class TokenBucketBuilderTest {
7 + private final TokenBuckets.Builder builder = TokenBuckets.builder();
8 +
9 + @Test(expected = IllegalArgumentException.class)
10 + public void testNegativeCapacity() {
11 + builder.withCapacity(-1);
12 + }
13 +
14 + @Test(expected = IllegalArgumentException.class)
15 + public void testZeroCapacity() {
16 + builder.withCapacity(0);
17 + }
18 +
19 + @Test(expected = IllegalArgumentException.class)
20 + public void testNegativeInitialTokens() {
21 + builder.withInitialTokens(-1);
22 + }
23 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.concurrent.tokenbucket;
2 +
3 +import org.junit.Test;
4 +
5 +import java.util.concurrent.TimeUnit;
6 +
7 +import static org.junit.Assert.assertEquals;
8 +import static org.junit.Assert.assertFalse;
9 +import static org.junit.Assert.assertTrue;
10 +import static org.mockito.Mockito.mock;
11 +
12 +public class TokenBucketImplTest {
13 + private static final long CAPACITY = 10;
14 +
15 + private final MockRefillStrategy refillStrategy = new MockRefillStrategy();
16 + private final TokenBucket.SleepStrategy sleepStrategy = mock(TokenBucket.SleepStrategy.class);
17 + private final TokenBucketImpl bucket = new TokenBucketImpl(CAPACITY, 0, refillStrategy, sleepStrategy);
18 +
19 + @Test(expected = IllegalArgumentException.class)
20 + public void testNegativeCapacity() {
21 + new TokenBucketImpl(-1, 0, refillStrategy, sleepStrategy);
22 + }
23 +
24 + @Test(expected = IllegalArgumentException.class)
25 + public void testZeroCapacity() {
26 + new TokenBucketImpl(0, 0, refillStrategy, sleepStrategy);
27 + }
28 +
29 + @Test(expected = IllegalArgumentException.class)
30 + public void testMoreInitialTokensThanCapacity() {
31 + new TokenBucketImpl(1, 2, refillStrategy, sleepStrategy);
32 + }
33 +
34 + @Test
35 + public void testGetCapacity() {
36 + assertEquals(CAPACITY, bucket.getCapacity());
37 + }
38 +
39 + @Test
40 + public void testEmptyBucketHasZeroTokens() {
41 + assertEquals(0, bucket.getNumTokens());
42 + }
43 +
44 + @Test
45 + public void testBucketWithInitialTokens() {
46 + TokenBucketImpl bucket = new TokenBucketImpl(CAPACITY, CAPACITY, refillStrategy, sleepStrategy);
47 + assertEquals(CAPACITY, bucket.getNumTokens());
48 + }
49 +
50 + @Test
51 + public void testAddingTokenIncreasesNumTokens() {
52 + refillStrategy.addToken();
53 + assertEquals(1, bucket.getNumTokens());
54 + }
55 +
56 + @Test
57 + public void testAddingMultipleTokensIncreasesNumTokens() {
58 + refillStrategy.addTokens(2);
59 + assertEquals(2, bucket.getNumTokens());
60 + }
61 +
62 + @Test
63 + public void testAtCapacityNumTokens() {
64 + refillStrategy.addTokens(CAPACITY);
65 + assertEquals(CAPACITY, bucket.getNumTokens());
66 + }
67 +
68 + @Test
69 + public void testOverCapacityNumTokens() {
70 + refillStrategy.addTokens(CAPACITY + 1);
71 + assertEquals(CAPACITY, bucket.getNumTokens());
72 + }
73 +
74 + @Test
75 + public void testConsumingTokenDecreasesNumTokens() {
76 + refillStrategy.addTokens(1);
77 + bucket.consume();
78 + assertEquals(0, bucket.getNumTokens());
79 + }
80 +
81 + @Test
82 + public void testConsumingMultipleTokensDecreasesNumTokens() {
83 + refillStrategy.addTokens(CAPACITY);
84 + bucket.consume(2);
85 + assertEquals(CAPACITY - 2, bucket.getNumTokens());
86 + }
87 +
88 + @Test
89 + public void testEmptyNumTokens() {
90 + refillStrategy.addTokens(CAPACITY);
91 + bucket.consume(CAPACITY);
92 + assertEquals(0, bucket.getNumTokens());
93 + }
94 +
95 + @Test
96 + public void testFailedConsumeKeepsNumTokens() {
97 + refillStrategy.addTokens(1);
98 + bucket.tryConsume(2);
99 + assertEquals(1, bucket.getNumTokens());
100 + }
101 +
102 + @Test(expected = IllegalArgumentException.class)
103 + public void testTryConsumeZeroTokens() {
104 + bucket.tryConsume(0);
105 + }
106 +
107 + @Test(expected = IllegalArgumentException.class)
108 + public void testTryConsumeNegativeTokens() {
109 + bucket.tryConsume(-1);
110 + }
111 +
112 + @Test(expected = IllegalArgumentException.class)
113 + public void testTryConsumeMoreThanCapacityTokens() {
114 + bucket.tryConsume(100);
115 + }
116 +
117 + @Test
118 + public void testTryConsumeOnEmptyBucket() {
119 + assertFalse(bucket.tryConsume());
120 + }
121 +
122 + @Test
123 + public void testTryConsumeOneToken() {
124 + refillStrategy.addToken();
125 + assertTrue(bucket.tryConsume());
126 + }
127 +
128 + @Test
129 + public void testTryConsumeMoreTokensThanAreAvailable() {
130 + refillStrategy.addToken();
131 + assertFalse(bucket.tryConsume(2));
132 + }
133 +
134 + @Test
135 + public void testTryManuallyRefillOneToken() {
136 + bucket.refill(1);
137 + assertTrue(bucket.tryConsume());
138 + }
139 +
140 + @Test
141 + public void testTryManuallyRefillCapacityTokens() {
142 + bucket.refill(CAPACITY);
143 + assertTrue(bucket.tryConsume(CAPACITY));
144 + assertFalse(bucket.tryConsume(1));
145 + }
146 +
147 + @Test
148 + public void testTryManuallyRefillMoreThanCapacityTokens() {
149 + bucket.refill(CAPACITY + 1);
150 + assertTrue(bucket.tryConsume(CAPACITY));
151 + assertFalse(bucket.tryConsume(1));
152 + }
153 +
154 + @Test
155 + public void testTryManualRefillAndStrategyRefill() {
156 + bucket.refill(CAPACITY);
157 + refillStrategy.addTokens(CAPACITY);
158 + assertTrue(bucket.tryConsume(CAPACITY));
159 + assertFalse(bucket.tryConsume(1));
160 + }
161 +
162 + @Test
163 + public void testTryRefillMoreThanCapacityTokens() {
164 + refillStrategy.addTokens(CAPACITY + 1);
165 + assertTrue(bucket.tryConsume(CAPACITY));
166 + assertFalse(bucket.tryConsume(1));
167 + }
168 +
169 + @Test
170 + public void testTryRefillWithTooManyTokens() {
171 + refillStrategy.addTokens(CAPACITY);
172 + assertTrue(bucket.tryConsume());
173 +
174 + refillStrategy.addTokens(Long.MAX_VALUE);
175 + assertTrue(bucket.tryConsume(CAPACITY));
176 + assertFalse(bucket.tryConsume(1));
177 + }
178 +
179 + private static final class MockRefillStrategy implements TokenBucketImpl.RefillStrategy {
180 + private long numTokensToAdd = 0;
181 +
182 + public long refill() {
183 + long numTokens = numTokensToAdd;
184 + numTokensToAdd = 0;
185 + return numTokens;
186 + }
187 +
188 + @Override
189 + public long getDurationUntilNextRefill(TimeUnit unit) throws UnsupportedOperationException {
190 + throw new UnsupportedOperationException();
191 + }
192 +
193 + public void addToken() {
194 + numTokensToAdd++;
195 + }
196 +
197 + public void addTokens(long numTokens) {
198 + numTokensToAdd += numTokens;
199 + }
200 + }
201 +}
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.jwt;
2 +
3 +import com.auth0.jwt.JWT;
4 +import com.auth0.jwt.JWTVerifier;
5 +import com.auth0.jwt.algorithms.Algorithm;
6 +
7 +import com.auth0.jwt.interfaces.DecodedJWT;
8 +import com.fasterxml.jackson.databind.ObjectMapper;
9 +import com.zhaoonline.coupen.bean.Activity;
10 +import com.zhaoonline.coupen.bean.BizType;
11 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
12 +import org.junit.Assert;
13 +import org.junit.Test;
14 +
15 +import java.io.IOException;
16 +import java.math.BigDecimal;
17 +
18 +/**
19 + * Created by ZhaoOnline<br/>
20 + * User: yangyoupeng<br/>
21 + * Date: 2016/12/14<br/>
22 + * Time: 10:42<br/>
23 + * Description:please descript you class
24 + */
25 +public class TestJWTEncoder {
26 + ObjectMapper objectMapper = new ObjectMapper();
27 +
28 + /**
29 + * 测试使用原生的JWT来对对象进行编码和解码
30 + * @throws IOException
31 + */
32 + @Test
33 + public void testEncodeAndDecodeWithoriginalJWT() throws IOException {
34 + CommonCoupenSeed coupenSeed =new CommonCoupenSeed();
35 + Activity activity= new Activity(1,"新年大礼包");
36 + BigDecimal totalAmount = new BigDecimal(8880);
37 + Integer coupenCount = 10;
38 +
39 + coupenSeed.setActivity(activity);
40 + coupenSeed.setTotalAmount(totalAmount);
41 + coupenSeed.setBizType(new BizType(1,"TZB"));
42 +
43 +
44 + coupenSeed.setCoupenCount(coupenCount);
45 +
46 + JWTConfig config =new JWTConfig();
47 + config.setIssuer("zhaoonline");
48 + config.setPassword("hellowwolrd");
49 +
50 + String coupenSeedString =objectMapper.writeValueAsString(coupenSeed);
51 + String token = JWT.create()
52 + .withIssuer(config.getIssuer())
53 + .withClaim("counpen",coupenSeedString)
54 + .sign(Algorithm.HMAC256(config.getPassword()));
55 +
56 + System.out.println(token);
57 +
58 +
59 +
60 + JWTVerifier verifier = JWT.require(Algorithm.HMAC256(config.getPassword()))
61 + .withIssuer(config.getIssuer())
62 + .build();
63 + DecodedJWT jwt = verifier.verify(token);
64 +
65 + String coupenJsonString= jwt.getClaim("counpen").asString();
66 +
67 +
68 +
69 + CommonCoupenSeed decodeCoupen= objectMapper.readValue(coupenJsonString,CommonCoupenSeed.class);
70 +
71 +
72 + Assert.assertEquals(activity.getActivityName(), decodeCoupen.getActivity().getActivityName());
73 + Assert.assertEquals(coupenCount, decodeCoupen.getCoupenCount());
74 + }
75 +
76 +
77 + /**
78 + * 使用我们封装过得getCoupenCountJWTEncoder和JWTDecoder来测试编码和解码
79 + */
80 + @Test
81 + public void testEncodeAndDecodeWithWrappedJWT() throws IOException {
82 +
83 + CommonCoupenSeed coupenSeed =new CommonCoupenSeed();
84 + Activity activity= new Activity(1,"新年大礼包");
85 + BigDecimal totalAmount = new BigDecimal(8880);
86 + Integer coupenCount = 10;
87 +
88 + coupenSeed.setActivity(activity);
89 + coupenSeed.setTotalAmount(totalAmount);
90 + coupenSeed.setBizType(new BizType(1,"TZB"));
91 +
92 +
93 + coupenSeed.setCoupenCount(coupenCount);
94 +
95 + JWTConfig config =new JWTConfig();
96 + config.setIssuer("zhaoonline");
97 + config.setPassword("hellowwolrd");
98 + config.setEncodeKeyName("coupen");
99 +
100 +
101 + JWTEncoder encoder= new JWTEncoder(config);
102 +
103 + String token= encoder.encode(coupenSeed);
104 +
105 +
106 + JWTDecoder decoder=new JWTDecoder(config);
107 +
108 + CommonCoupenSeed decodeCoupen= decoder.decode(token,CommonCoupenSeed.class);
109 +
110 + Assert.assertEquals(activity.getActivityName(), decodeCoupen.getActivity().getActivityName());
111 + Assert.assertEquals(coupenCount, decodeCoupen.getCoupenCount());
112 + }
113 +}
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
3 + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
4 + <output url="file://$MODULE_DIR$/target/classes" />
5 + <output-test url="file://$MODULE_DIR$/target/test-classes" />
6 + <content url="file://$MODULE_DIR$">
7 + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
8 + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
9 + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
10 + <excludeFolder url="file://$MODULE_DIR$/target" />
11 + </content>
12 + <orderEntry type="inheritedJdk" />
13 + <orderEntry type="sourceFolder" forTests="false" />
14 + <orderEntry type="module" module-name="coupen-core" />
15 + <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
16 + <orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
17 + <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.4" level="project" />
18 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.1" level="project" />
19 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
20 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.1" level="project" />
21 + <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.21" level="project" />
22 + <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.7" level="project" />
23 + <orderEntry type="library" name="Maven: com.zhaoonline:microservice-redis:1.0.0-SNAPSHOT" level="project" />
24 + <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.0" level="project" />
25 + <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.2" level="project" />
26 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:1.7.2.RELEASE" level="project" />
27 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:1.1.2.RELEASE" level="project" />
28 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.12.2.RELEASE" level="project" />
29 + <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.2.6.RELEASE" level="project" />
30 + <orderEntry type="library" name="Maven: org.springframework:spring-oxm:4.2.6.RELEASE" level="project" />
31 + <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.2.6.RELEASE" level="project" />
32 + <orderEntry type="library" name="Maven: aopalliance:aopalliance:1.0" level="project" />
33 + <orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.21" level="project" />
34 + <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.10.19" level="project" />
35 + <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.2.RELEASE" level="project" />
36 + <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.2.RELEASE" level="project" />
37 + <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.2.RELEASE" level="project" />
38 + <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.2.RELEASE" level="project" />
39 + <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.2.RELEASE" level="project" />
40 + <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
41 + <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.0.1" level="project" />
42 + <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
43 + <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.55" level="project" />
44 + <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.7.0" level="project" />
45 + <orderEntry type="library" name="Maven: org.bitbucket.b_c:jose4j:0.5.2" level="project" />
46 + </component>
47 +</module>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 + <parent>
6 + <artifactId>parent</artifactId>
7 + <groupId>com.zhaoonline.coupen</groupId>
8 + <version>1.0-SNAPSHOT</version>
9 + </parent>
10 + <modelVersion>4.0.0</modelVersion>
11 +
12 + <artifactId>coupen-dispatcher-api</artifactId>
13 + <dependencies>
14 + <dependency>
15 + <groupId>com.zhaoonline.coupen</groupId>
16 + <artifactId>coupen-core</artifactId>
17 + <version>1.0-SNAPSHOT</version>
18 + </dependency>
19 + </dependencies>
20 +
21 +
22 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.dispatcher;
2 +
3 +
4 +import com.zhaoonline.coupen.bean.Activity;
5 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
6 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
7 +
8 +import java.util.List;
9 +
10 +
11 +/**
12 + * Created by ZhaoOnline<br/>
13 + * User: yangyoupeng<br/>
14 + * Date: 2016/12/15<br/>
15 + * Time: 15:38<br/>
16 + * Description:红包派发器
17 + */
18 +public interface CoupenDispatchHandler {
19 +
20 + /**根据活动来获取一个红包种子
21 + * @param activity
22 + * @return
23 + */
24 + public List<CommonCoupenEntity> dispatchCoupenEntityUsingActivity(Activity activity);
25 +
26 + /**根据活动来获取一个红包种子
27 + * @param activity
28 + * @return
29 + */
30 + public List<CommonCoupenSeed> dispatchCoupenSeedUsingActivity(Activity activity);
31 +
32 + /**
33 + *根据红包seed来获取一个红包
34 + * @param
35 + * @return
36 + */
37 + public List<CommonCoupenEntity> dispacthCoupenEntityUsingSeed(CommonCoupenSeed seed);
38 +
39 +
40 + /**
41 + *根据红包coupen来获取一个红包
42 + * @param
43 + * @return
44 + */
45 + public List<CommonCoupenEntity> dispacthCoupenEntityUsingCoupen(CommonCoupenEntity coupenEntity);
46 +}
1 +package com.zhaoonline.coupen.dispatcher;
2 +
3 +import com.zhaoonline.coupen.bean.Activity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
5 +import com.zhaoonline.coupen.bean.OwnerUser;
6 +
7 +import java.util.List;
8 +
9 +/**
10 + * Created by ZhaoOnline<br/>
11 + * User: yangyoupeng<br/>
12 + * Date: 2016/12/15<br/>
13 + * Time: 16:34<br/>
14 + * Description:用户与Coupen的关系映射处理器,
15 + * 同时还包括帮拆的好友信息记录
16 + */
17 +public interface UserCoupenMappingHandler {
18 +
19 +
20 + List<CommonCoupenEntity> getMappingOfUser(Activity activity, OwnerUser user);
21 +
22 + CommonCoupenEntity mappingCoupen2User(CommonCoupenEntity coupenEntity, OwnerUser user);
23 +
24 +
25 + boolean recordHelpOpen(CommonCoupenEntity coupenEntity, OwnerUser helper);
26 +
27 + List<CommonCoupenEntity> getHelpOpenCoupenOfUser(CommonCoupenEntity coupenEntity, OwnerUser drawOwner);
28 +}
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
3 + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
4 + <output url="file://$MODULE_DIR$/target/classes" />
5 + <output-test url="file://$MODULE_DIR$/target/test-classes" />
6 + <content url="file://$MODULE_DIR$">
7 + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
8 + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
9 + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
10 + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
11 + <excludeFolder url="file://$MODULE_DIR$/target" />
12 + </content>
13 + <orderEntry type="inheritedJdk" />
14 + <orderEntry type="sourceFolder" forTests="false" />
15 + <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
16 + <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
17 + <orderEntry type="module" module-name="coupen-core" />
18 + <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
19 + <orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
20 + <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.4" level="project" />
21 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.1" level="project" />
22 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
23 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.1" level="project" />
24 + <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.21" level="project" />
25 + <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.7" level="project" />
26 + <orderEntry type="library" name="Maven: com.zhaoonline:microservice-redis:1.0.0-SNAPSHOT" level="project" />
27 + <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.0" level="project" />
28 + <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.2" level="project" />
29 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:1.7.2.RELEASE" level="project" />
30 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:1.1.2.RELEASE" level="project" />
31 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.12.2.RELEASE" level="project" />
32 + <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.2.6.RELEASE" level="project" />
33 + <orderEntry type="library" name="Maven: org.springframework:spring-oxm:4.2.6.RELEASE" level="project" />
34 + <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.2.6.RELEASE" level="project" />
35 + <orderEntry type="library" name="Maven: aopalliance:aopalliance:1.0" level="project" />
36 + <orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.21" level="project" />
37 + <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.10.19" level="project" />
38 + <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.2.RELEASE" level="project" />
39 + <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.2.RELEASE" level="project" />
40 + <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.2.RELEASE" level="project" />
41 + <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.2.RELEASE" level="project" />
42 + <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.2.RELEASE" level="project" />
43 + <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
44 + <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.0.1" level="project" />
45 + <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
46 + <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.55" level="project" />
47 + <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.7.0" level="project" />
48 + <orderEntry type="library" name="Maven: org.bitbucket.b_c:jose4j:0.5.2" level="project" />
49 + <orderEntry type="module" module-name="coupen-dispatcher-api" />
50 + </component>
51 +</module>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 + <parent>
6 + <artifactId>parent</artifactId>
7 + <groupId>com.zhaoonline.coupen</groupId>
8 + <version>1.0-SNAPSHOT</version>
9 + </parent>
10 + <modelVersion>4.0.0</modelVersion>
11 +
12 + <artifactId>coupen-dispatcher</artifactId>
13 + <dependencies>
14 + <dependency>
15 + <groupId>junit</groupId>
16 + <artifactId>junit</artifactId>
17 + <version>4.12</version>
18 + <scope>test</scope>
19 + </dependency>
20 + <dependency>
21 + <groupId>junit</groupId>
22 + <artifactId>junit</artifactId>
23 + <version>4.12</version>
24 + <scope>test</scope>
25 + </dependency>
26 + <dependency>
27 + <groupId>com.zhaoonline.coupen</groupId>
28 + <artifactId>coupen-core</artifactId>
29 + <version>1.0-SNAPSHOT</version>
30 + </dependency>
31 + <dependency>
32 + <groupId>com.zhaoonline.coupen</groupId>
33 + <artifactId>coupen-dispatcher-api</artifactId>
34 + <version>1.0-SNAPSHOT</version>
35 + </dependency>
36 + </dependencies>
37 +
38 +
39 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.dispatcher;
2 +
3 +import com.zhaoonline.coupen.bean.Activity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
5 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
6 +
7 +import java.util.List;
8 +
9 +/**
10 + * Created by ZhaoOnline<br/>
11 + * User: yangyoupeng<br/>
12 + * Date: 2016/12/15<br/>
13 + * Time: 16:04<br/>
14 + * Description:please descript you class
15 + */
16 +public class DefaultCoupenDispatchHandler implements CoupenDispatchHandler {
17 +
18 +
19 + @Override
20 + public List<CommonCoupenEntity> dispatchCoupenEntityUsingActivity(Activity activity) {
21 + return null;
22 + }
23 +
24 + @Override
25 + public List<CommonCoupenSeed> dispatchCoupenSeedUsingActivity(Activity activity) {
26 + return null;
27 + }
28 +
29 + @Override
30 + public List<CommonCoupenEntity> dispacthCoupenEntityUsingSeed(CommonCoupenSeed seed) {
31 + return null;
32 + }
33 +
34 + @Override
35 + public List<CommonCoupenEntity> dispacthCoupenEntityUsingCoupen(CommonCoupenEntity coupenEntity) {
36 + return null;
37 + }
38 +}
1 +package com.zhaoonline.coupen.dispatcher;
2 +
3 +import com.zhaoonline.coupen.bean.Activity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
5 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
6 +import org.junit.Test;
7 +
8 +import java.util.List;
9 +
10 +/**
11 + * Created by ZhaoOnline<br/>
12 + * User: yangyoupeng<br/>
13 + * Date: 2016/12/15<br/>
14 + * Time: 15:40<br/>
15 + * Description:please descript you class
16 + */
17 +public class TestCoupenDispatchHandler {
18 +
19 +
20 + /**
21 + * 测试根据活动来领取一个红包
22 + */
23 + @Test
24 + public void testDrawCounpenByActivity(){
25 + Activity activity = new Activity();
26 + activity.setActivityID(1);
27 + activity.setActivityName("投资币新年大酬宾");
28 +
29 + CoupenDispatchHandler dispatcher = new DefaultCoupenDispatchHandler();
30 +
31 + List<CommonCoupenSeed> seed = dispatcher.dispatchCoupenSeedUsingActivity(activity);
32 +
33 + List<CommonCoupenEntity> comonCounpenEntity = dispatcher.dispacthCoupenEntityUsingSeed(seed.get(0));
34 +
35 + }
36 +
37 +}
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
3 + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
4 + <output url="file://$MODULE_DIR$/target/classes" />
5 + <output-test url="file://$MODULE_DIR$/target/test-classes" />
6 + <content url="file://$MODULE_DIR$">
7 + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
8 + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
9 + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
10 + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
11 + <excludeFolder url="file://$MODULE_DIR$/target" />
12 + </content>
13 + <orderEntry type="inheritedJdk" />
14 + <orderEntry type="sourceFolder" forTests="false" />
15 + <orderEntry type="module" module-name="coupen-core" />
16 + <orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
17 + <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.4" level="project" />
18 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.1" level="project" />
19 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
20 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.1" level="project" />
21 + <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.21" level="project" />
22 + <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.7" level="project" />
23 + <orderEntry type="library" name="Maven: com.zhaoonline:microservice-redis:1.0.0-SNAPSHOT" level="project" />
24 + <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.0" level="project" />
25 + <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.2" level="project" />
26 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:1.7.2.RELEASE" level="project" />
27 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:1.1.2.RELEASE" level="project" />
28 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.12.2.RELEASE" level="project" />
29 + <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.2.6.RELEASE" level="project" />
30 + <orderEntry type="library" name="Maven: org.springframework:spring-oxm:4.2.6.RELEASE" level="project" />
31 + <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.2.6.RELEASE" level="project" />
32 + <orderEntry type="library" name="Maven: aopalliance:aopalliance:1.0" level="project" />
33 + <orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.21" level="project" />
34 + <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.10.19" level="project" />
35 + <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.2.RELEASE" level="project" />
36 + <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.2.RELEASE" level="project" />
37 + <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.2.RELEASE" level="project" />
38 + <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.2.RELEASE" level="project" />
39 + <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.2.RELEASE" level="project" />
40 + <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
41 + <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.0.1" level="project" />
42 + <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
43 + <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.55" level="project" />
44 + <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.7.0" level="project" />
45 + <orderEntry type="library" name="Maven: org.bitbucket.b_c:jose4j:0.5.2" level="project" />
46 + <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
47 + <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
48 + <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
49 + </component>
50 +</module>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 + <parent>
6 + <artifactId>parent</artifactId>
7 + <groupId>com.zhaoonline.coupen</groupId>
8 + <version>1.0-SNAPSHOT</version>
9 + </parent>
10 + <modelVersion>4.0.0</modelVersion>
11 + <artifactId>coupen-generator</artifactId>
12 + <dependencies>
13 + <dependency>
14 + <groupId>com.zhaoonline.coupen</groupId>
15 + <artifactId>coupen-core</artifactId>
16 + <version>${project.version}</version>
17 + </dependency>
18 +
19 +
20 + <dependency>
21 + <groupId>javax.validation</groupId>
22 + <artifactId>validation-api</artifactId>
23 + </dependency>
24 + <dependency>
25 + <groupId>junit</groupId>
26 + <artifactId>junit</artifactId>
27 + <version>4.12</version>
28 + <scope>test</scope>
29 + </dependency>
30 + </dependencies>
31 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.generator;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/14<br/>
7 + * Time: 20:29<br/>
8 + * Description:please descript you class
9 + */
10 +public class CoupenGenerator {
11 +
12 +
13 +}
1 +package com.zhaoonline.coupen.generator.distribute;
2 +
3 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
5 +import com.zhaoonline.coupen.bean.CoupenContext;
6 +import com.zhaoonline.coupen.utils.Utils;
7 +import org.springframework.util.ObjectUtils;
8 +
9 +import javax.validation.constraints.NotNull;
10 +import java.math.BigDecimal;
11 +import java.util.ArrayList;
12 +import java.util.List;
13 +
14 +/**
15 + * Created by ZhaoOnline<br/>
16 + * User: yangyoupeng<br/>
17 + * Date: 2016/12/14<br/>
18 + * Time: 19:15<br/>
19 + * Description:总金额平均分配
20 + */
21 +public class AverageStrategy implements DistributeStrategy{
22 + private static final String STRATEGY_NAME="avr";
23 + @Override
24 + public CoupenContext<CommonCoupenEntity,CommonCoupenSeed> distribute(@NotNull CommonCoupenSeed seed) {
25 + if(ObjectUtils.isEmpty(seed)){
26 + return CoupenContext.empty();
27 + }
28 + BigDecimal amountPerCoupen = this.amountPerCoupen(seed);
29 + Integer expectCount=seed.getCoupenCount();
30 + List<CommonCoupenEntity> newCreatedCoupens=new ArrayList<CommonCoupenEntity>(expectCount);
31 + for(int i=0 ;i<expectCount.intValue();i++){
32 + CommonCoupenEntity coupenEntity =new CommonCoupenEntity();
33 + coupenEntity.setCoupenID(generateCoupenID());
34 + coupenEntity.setSeed(seed);
35 + coupenEntity.setAmount(amountPerCoupen);
36 + newCreatedCoupens.add(coupenEntity);
37 + }
38 + CoupenContext<CommonCoupenEntity,CommonCoupenSeed> coupenContext=new CoupenContext<CommonCoupenEntity,CommonCoupenSeed>();
39 + coupenContext.setSeed(seed);
40 + coupenContext.setCoupens(newCreatedCoupens);
41 + return coupenContext;
42 + }
43 +
44 + @Override
45 + public String distributeName() {
46 + return STRATEGY_NAME;
47 + }
48 +
49 + private String generateCoupenID(){
50 + return Utils.getRandomForDate(STRATEGY_NAME);
51 + }
52 +
53 +
54 + /**计算每个红包的金额
55 + * @param seed
56 + * @return
57 + */
58 + public BigDecimal amountPerCoupen(CommonCoupenSeed seed){
59 + Integer expectCoupneCount=seed.getCoupenCount();
60 + BigDecimal totalAmount=seed.getTotalAmount();
61 + return totalAmount.divide(new BigDecimal(expectCoupneCount),3,BigDecimal.ROUND_HALF_UP);
62 + }
63 +}
1 +package com.zhaoonline.coupen.generator.distribute;
2 +
3 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
4 +import com.zhaoonline.coupen.bean.CoupenContext;
5 +
6 +/**
7 + * Created by ZhaoOnline<br/>
8 + * User: yangyoupeng<br/>
9 + * Date: 2016/12/14<br/>
10 + * Time: 19:12<br/>
11 + * Description:please descript you class
12 + */
13 +public interface DistributeStrategy {
14 + public CoupenContext distribute(CommonCoupenSeed seed);
15 +
16 + public String distributeName();
17 +}
1 +package com.zhaoonline.coupen.generator.distribute;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/14<br/>
7 + * Time: 20:31<br/>
8 + * Description:根据每一个红包的distributeStrategy生成相应的分配策略
9 + */
10 +public class DistributeStrategyFactory {
11 +
12 +
13 +}
1 +package com.zhaoonline.coupen.generator.distribute;
2 +
3 +import com.zhaoonline.coupen.bean.*;
4 +import com.zhaoonline.coupen.utils.Utils;
5 +import org.springframework.util.ObjectUtils;
6 +
7 +import java.math.BigDecimal;
8 +import java.util.ArrayList;
9 +import java.util.List;
10 +
11 +/**
12 + * Created by ZhaoOnline<br/>
13 + * User: yangyoupeng<br/>
14 + * Date: 2016/12/15<br/>
15 + * Time: 10:20<br/>
16 + * Description:此测试适用于。将每一个大红包的金额。按照所需帮拆好友的数目,再划分若干等分
17 + */
18 +public class LeafAverageStrategy implements DistributeStrategy {
19 + private static final String STRATEGY_NAME="iavr";
20 + AverageStrategy averageStatragy=new AverageStrategy();
21 + @Override
22 + public CoupenContext<LeafCoupenEntity,HelpOpenCoupenSeed> distribute(CommonCoupenSeed seed) {
23 + if(ObjectUtils.isEmpty(seed)){
24 + return CoupenContext.empty();
25 + }
26 + CoupenContext<CommonCoupenEntity,CommonCoupenSeed> contextOfSeed= averageStatragy.distribute(seed);
27 +
28 + HelpOpenCoupenSeed helpOpenCoupenSeed=null;
29 +
30 + if(contextOfSeed.getSeed() instanceof HelpOpenCoupenSeed){
31 + helpOpenCoupenSeed=(HelpOpenCoupenSeed)contextOfSeed.getSeed();
32 + }
33 + List<CommonCoupenEntity> coupenListFromSeed=contextOfSeed.getCoupens();
34 +
35 + List<LeafCoupenEntity> newCreatedCoupens=new ArrayList<LeafCoupenEntity>();
36 +
37 + //帮拆的朋友个数
38 + Integer helperCount=helpOpenCoupenSeed.getHelperCount();
39 +
40 + HelpOpenType helpOpenType=helpOpenCoupenSeed.getHelpOpenType();
41 +
42 + switch (helpOpenType){
43 + case VALIDE_LAST_TIME:{
44 + for(CommonCoupenEntity coupenEntity:coupenListFromSeed){
45 + LeafCoupenEntity leafCoupenEntity=new LeafCoupenEntity();
46 + leafCoupenEntity.setParentCoupen(coupenEntity);
47 + leafCoupenEntity.setSeed(helpOpenCoupenSeed);
48 + leafCoupenEntity.setAmount(coupenEntity.getAmount());
49 + leafCoupenEntity.setCoupenID(generateCoupenID());
50 + newCreatedCoupens.add(leafCoupenEntity);
51 + }
52 + break;
53 + }
54 + case VALIDE_ON_TIME:{
55 + for(CommonCoupenEntity coupenEntity:coupenListFromSeed){
56 + BigDecimal amountPerChildCoupne= amountPerCoupen(coupenEntity.getAmount(),helpOpenCoupenSeed.getHelperCount());
57 + for(int i=0;i< helperCount.intValue();i++){
58 + LeafCoupenEntity leafCoupenEntity=new LeafCoupenEntity();
59 + leafCoupenEntity.setParentCoupen(coupenEntity);
60 + leafCoupenEntity.setSeed(helpOpenCoupenSeed);
61 + leafCoupenEntity.setAmount(amountPerChildCoupne);
62 + leafCoupenEntity.setCoupenID(generateCoupenID());
63 + newCreatedCoupens.add(leafCoupenEntity);
64 + }
65 + };
66 + break;
67 + }
68 + default:{
69 + break;
70 + }
71 + }
72 + CoupenContext<LeafCoupenEntity,HelpOpenCoupenSeed> newContext= new CoupenContext<LeafCoupenEntity,HelpOpenCoupenSeed>();
73 + newContext.setCoupens(newCreatedCoupens);
74 + newContext.setSeed(helpOpenCoupenSeed);
75 + return newContext;
76 +
77 + }
78 +
79 + /** 计算每个红包的金额
80 + * @param totalAmount
81 + * @param divideCount
82 + * @return
83 + */
84 + private BigDecimal amountPerCoupen(BigDecimal totalAmount,Integer divideCount){
85 + return totalAmount.divide(new BigDecimal(divideCount),3,BigDecimal.ROUND_HALF_UP);
86 + }
87 + @Override
88 + public String distributeName() {
89 + return STRATEGY_NAME;
90 + }
91 +
92 + private String generateCoupenID(){
93 + return Utils.getRandomForDate(STRATEGY_NAME);
94 + }
95 +
96 +}
1 +package com.zhaoonline.coupen.repository;
2 +
3 +import com.zhaoonline.coupen.bean.Activity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
5 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
6 +import com.zhaoonline.redis.repository.DataValueRepository;
7 +import org.springframework.beans.factory.annotation.Autowired;
8 +import org.springframework.dao.DataAccessException;
9 +import org.springframework.data.redis.connection.RedisConnection;
10 +import org.springframework.data.redis.core.RedisCallback;
11 +import org.springframework.data.redis.core.RedisTemplate;
12 +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
13 +
14 +
15 +/**
16 + * Created by ZhaoOnline<br/>
17 + * User: yangyoupeng<br/>
18 + * Date: 2016/12/17<br/>
19 + * Time: 14:46<br/>
20 + * Description:please descript you class
21 + */
22 +public class CounpenRepository {
23 +
24 + private static final String radisKeyCoupenPreffix="coupen";
25 + private static final String radisKeyActivityPreffix="activity";
26 + private static final String radisKeySeedPreffix="seed";
27 +
28 + private DataValueRepository<CommonCoupenEntity> coupenRepository =null;
29 + private RedisTemplate<String,CommonCoupenEntity> redisTemplate;
30 + private static GenericJackson2JsonRedisSerializer valueDeSe= new GenericJackson2JsonRedisSerializer();
31 +
32 + @Autowired
33 + public CounpenRepository(DataValueRepository<CommonCoupenEntity> coupenRepository){
34 + this.coupenRepository=coupenRepository;
35 + redisTemplate = this.coupenRepository.getRedisTemplate();
36 + }
37 +
38 + public boolean saveCoupenEntity(CommonCoupenEntity coupen) {
39 + String coupenKey=concatCoupenRedisKey(coupen.getCoupenID());
40 +
41 + CommonCoupenSeed seed=coupen.getSeed();
42 + byte[] activityKeyBytes =null;
43 + byte[] seedKeyBytes=null;
44 + if(seed !=null){
45 + String seedKey=concatSeedRedisKey(seed.getSeedID());
46 + seedKeyBytes=redisTemplate.getStringSerializer().serialize(seedKey);
47 + Activity activity= seed.getActivity();
48 + if(activity != null){
49 + String activityKey=concatActivityRedisKey(activity.getActivityID());
50 + activityKeyBytes=redisTemplate.getStringSerializer().serialize(activityKey);
51 + }
52 + }
53 + byte[] coupenKeyBytes=redisTemplate.getStringSerializer().serialize(coupenKey);
54 + byte[] valueBytes=valueDeSe.serialize(coupen);
55 + CoupenAddRedisCallBack addRedisCallBack = new CoupenAddRedisCallBack(activityKeyBytes,seedKeyBytes,coupenKeyBytes,valueBytes);
56 + redisTemplate.executePipelined(addRedisCallBack);
57 + return true;
58 + }
59 +
60 + private String concatActivityRedisKey(Integer activityID) {
61 + return radisKeyActivityPreffix+":"+activityID;
62 + }
63 +
64 + private String concatSeedRedisKey(String seedID) {
65 + return radisKeySeedPreffix+":"+seedID;
66 + }
67 +
68 + public void deleteCoupenEntityByKey(CommonCoupenEntity coupen){
69 + String coupenKey=concatCoupenRedisKey(coupen.getCoupenID());
70 + CommonCoupenSeed seed=coupen.getSeed();
71 + String seedKey=concatSeedRedisKey(seed.getSeedID());
72 + byte[] coupenKeyBytes=redisTemplate.getStringSerializer().serialize(coupenKey);
73 + byte[] seedKeyBytes=redisTemplate.getStringSerializer().serialize(seedKey);
74 + redisTemplate.executePipelined(new RedisCallback<CommonCoupenEntity>() {
75 + @Override
76 + public CommonCoupenEntity doInRedis(RedisConnection connection) throws DataAccessException {
77 + connection.del(coupenKeyBytes);
78 + connection.sRem(seedKeyBytes,coupenKeyBytes);
79 + //必须要返回null。否则会抛出异常
80 + // org.springframework.dao.InvalidDataAccessApiUsageException: Callback cannot return a non-null value as it gets overwritten by the pipeline
81 + return null;
82 + }
83 + });
84 + //coupenRepository.delete(activitySaveedKey);
85 + }
86 +
87 +
88 + public CommonCoupenEntity getCoupenEntityByKey(String coupenID){
89 + String activitySaveedKey=concatCoupenRedisKey(coupenID);
90 + CommonCoupenEntity result= coupenRepository.get(activitySaveedKey);
91 + return result;
92 + }
93 +
94 +
95 +
96 + private String concatCoupenRedisKey(String key){
97 + return radisKeyCoupenPreffix+":"+key;
98 + }
99 +
100 +
101 + public class CoupenAddRedisCallBack implements RedisCallback<CommonCoupenEntity>{
102 + private byte[] activityKeyBytes =null;
103 + private byte[] seedKeyBytes =null;
104 + private byte[] coupenKeyBytes =null;
105 + private byte[] valueBytes =null;
106 +
107 + public CoupenAddRedisCallBack(byte[] activityKeyBytes , byte[] seedKeyBytes,byte[] coupenKeyBytes, byte[] valueBytes){
108 + this.activityKeyBytes=activityKeyBytes;
109 + this.seedKeyBytes = seedKeyBytes;
110 + this.coupenKeyBytes = coupenKeyBytes;
111 + this.valueBytes = valueBytes;
112 + }
113 + @Override
114 + public CommonCoupenEntity doInRedis(RedisConnection connection) throws DataAccessException {
115 +
116 +// connection.watch(coupenKeyBytes);
117 +// connection.multi();
118 + if(activityKeyBytes != null){
119 + connection.sAdd(activityKeyBytes,seedKeyBytes);
120 + }
121 + if(seedKeyBytes != null){
122 + connection.sAdd(seedKeyBytes,coupenKeyBytes);
123 + }
124 + connection.setNX(coupenKeyBytes,valueBytes);
125 +// connection.exec();
126 +// connection.unwatch();
127 + return null;
128 + }
129 + }
130 +}
1 +package com.zhaoonline.coupen.generator.distribute;
2 +
3 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
5 +import com.zhaoonline.coupen.bean.CoupenContext;
6 +import org.junit.Test;
7 +import org.junit.Assert;
8 +
9 +import java.math.BigDecimal;
10 +
11 +/**
12 + * Created by ZhaoOnline<br/>
13 + * User: yangyoupeng<br/>
14 + * Date: 2016/12/15<br/>
15 + * Time: 11:15<br/>
16 + * Description:please descript you class
17 + */
18 +public class TestAverageStrategy {
19 + AverageStrategy strategy = new AverageStrategy();
20 + @Test
21 + public void testDistributeNullSeed() {
22 + CommonCoupenSeed seed =null;
23 + CoupenContext context = strategy.distribute(seed);
24 + Assert.assertNull(context.getSeed());
25 + }
26 +
27 +
28 + @Test
29 + public void testDistributeSeed() {
30 +
31 + Integer expectCoupenCount=new Integer(10);
32 + BigDecimal totalAmount= new BigDecimal(8880);
33 +
34 + CommonCoupenSeed seed = new CommonCoupenSeed();
35 + seed.setTotalAmount(totalAmount);
36 + seed.setCoupenCount(expectCoupenCount);
37 + CoupenContext<CommonCoupenEntity,CommonCoupenSeed> context = strategy.distribute(seed);
38 + Assert.assertEquals(expectCoupenCount.intValue(), context.getCoupens().size());
39 + Assert.assertEquals(strategy.amountPerCoupen(seed), context.getCoupens().get(0).getAmount());
40 + }
41 +}
1 +package com.zhaoonline.coupen.generator.distribute;
2 +
3 +import com.zhaoonline.coupen.bean.HelpOpenCoupenSeed;
4 +import com.zhaoonline.coupen.bean.LeafCoupenEntity;
5 +import com.zhaoonline.coupen.bean.CoupenContext;
6 +import org.junit.Assert;
7 +import org.junit.Test;
8 +
9 +import java.math.BigDecimal;
10 +
11 +/**
12 + * Created by ZhaoOnline<br/>
13 + * User: yangyoupeng<br/>
14 + * Date: 2016/12/15<br/>
15 + * Time: 13:30<br/>
16 + * Description:please descript you class
17 + */
18 +public class TestItemAverageStrategy {
19 + LeafAverageStrategy strategy = new LeafAverageStrategy();
20 +
21 + @Test
22 + public void testDistribute(){
23 + HelpOpenCoupenSeed helpOpenSeed =new HelpOpenCoupenSeed();
24 + Integer helperCount=new Integer(20);
25 + helpOpenSeed.setHelperCount(helperCount);
26 +
27 + Integer expectCoupenCount=new Integer(10);
28 + BigDecimal totalAmount= new BigDecimal(8880);
29 + helpOpenSeed.setTotalAmount(totalAmount);
30 + helpOpenSeed.setCoupenCount(expectCoupenCount);
31 +
32 + CoupenContext<LeafCoupenEntity,HelpOpenCoupenSeed> context = strategy.distribute(helpOpenSeed);
33 +
34 + Assert.assertEquals(helperCount*expectCoupenCount, context.getCoupens().size());
35 +
36 + }
37 +}
1 +package com.zhaoonline.coupen.repository;
2 +
3 +import com.zhaoonline.coupen.bean.Activity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
5 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
6 +import com.zhaoonline.redis.repository.DataValueRepository;
7 +import com.zhaoonline.redis.template.RedisTemplateFactory;
8 +import org.junit.After;
9 +import org.junit.Assert;
10 +import org.junit.Before;
11 +import org.junit.Test;
12 +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
13 +
14 +/**
15 + * Created by ZhaoOnline<br/>
16 + * User: yangyoupeng<br/>
17 + * Date: 2016/12/17<br/>
18 + * Time: 14:47<br/>
19 + * Description:please descript you class
20 + */
21 +public class TestCounpenRepository {
22 + RedisTemplateFactory factory=null;
23 + JedisConnectionFactory connectionFactory=null;
24 +
25 + @Before
26 + public void prepare(){
27 + connectionFactory=createSimpleFactory();
28 + factory=new RedisTemplateFactory();
29 + factory.setConnectionFactory(connectionFactory);
30 + }
31 + @Test
32 + public void testSaveCounpenRepository(){
33 + DataValueRepository<CommonCoupenEntity> redisRepository=new DataValueRepository<CommonCoupenEntity>(factory);
34 +
35 + CounpenRepository repository = new CounpenRepository(redisRepository);
36 +
37 + CommonCoupenEntity couppen = new CommonCoupenEntity();
38 + Activity activity = new Activity();
39 + activity.setActivityID(1);
40 + activity.setActivityName("testActivity");
41 +
42 + CommonCoupenSeed seed= new CommonCoupenSeed();
43 + seed.setSeedID("testSeed1");
44 + seed.setActivity(activity);
45 + couppen.setCoupenID("testCoupen1");
46 + couppen.setSeed(seed);
47 +
48 + repository.saveCoupenEntity(couppen);
49 +
50 + CommonCoupenEntity saveedCoupen= repository.getCoupenEntityByKey("testCoupen1");
51 +
52 + Assert.assertEquals(couppen.getCoupenID(),saveedCoupen.getCoupenID());
53 +
54 + repository.deleteCoupenEntityByKey(couppen);
55 +
56 + CommonCoupenEntity coupenAfterDelete= repository.getCoupenEntityByKey("testCoupen1");
57 +
58 + Assert.assertNull(coupenAfterDelete);
59 + }
60 +
61 + @After
62 + public void after(){
63 + connectionFactory.destroy();
64 + }
65 +
66 + private JedisConnectionFactory createSimpleFactory(){
67 + JedisConnectionFactory factory = new JedisConnectionFactory();
68 + factory.setHostName("192.168.0.188");
69 + factory.setPort(6377);
70 + factory.setUsePool(true);
71 + factory.setDatabase(1);
72 + factory.afterPropertiesSet();
73 + return factory;
74 + }
75 +
76 +}
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
3 + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
4 + <output url="file://$MODULE_DIR$/target/classes" />
5 + <output-test url="file://$MODULE_DIR$/target/test-classes" />
6 + <content url="file://$MODULE_DIR$">
7 + <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
8 + <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
9 + <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
10 + <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
11 + <excludeFolder url="file://$MODULE_DIR$/target" />
12 + </content>
13 + <orderEntry type="inheritedJdk" />
14 + <orderEntry type="sourceFolder" forTests="false" />
15 + <orderEntry type="module" module-name="coupen-core" />
16 + <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
17 + <orderEntry type="library" name="Maven: com.google.guava:guava:18.0" level="project" />
18 + <orderEntry type="library" name="Maven: joda-time:joda-time:2.9.4" level="project" />
19 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.1" level="project" />
20 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
21 + <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.1" level="project" />
22 + <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.21" level="project" />
23 + <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.7" level="project" />
24 + <orderEntry type="library" name="Maven: com.zhaoonline:microservice-redis:1.0.0-SNAPSHOT" level="project" />
25 + <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.0" level="project" />
26 + <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.2" level="project" />
27 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:1.7.2.RELEASE" level="project" />
28 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:1.1.2.RELEASE" level="project" />
29 + <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.12.2.RELEASE" level="project" />
30 + <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.2.6.RELEASE" level="project" />
31 + <orderEntry type="library" name="Maven: org.springframework:spring-oxm:4.2.6.RELEASE" level="project" />
32 + <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.2.6.RELEASE" level="project" />
33 + <orderEntry type="library" name="Maven: aopalliance:aopalliance:1.0" level="project" />
34 + <orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.21" level="project" />
35 + <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.10.19" level="project" />
36 + <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.2.RELEASE" level="project" />
37 + <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.2.RELEASE" level="project" />
38 + <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.2.RELEASE" level="project" />
39 + <orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.2.RELEASE" level="project" />
40 + <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.2.RELEASE" level="project" />
41 + <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
42 + <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.0.1" level="project" />
43 + <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
44 + <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.55" level="project" />
45 + <orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.7.0" level="project" />
46 + <orderEntry type="library" name="Maven: org.bitbucket.b_c:jose4j:0.5.2" level="project" />
47 + <orderEntry type="module" module-name="coupen-dispatcher-api" />
48 + <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
49 + <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
50 + </component>
51 +</module>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 + <parent>
6 + <artifactId>parent</artifactId>
7 + <groupId>com.zhaoonline.coupen</groupId>
8 + <version>1.0-SNAPSHOT</version>
9 + </parent>
10 + <modelVersion>4.0.0</modelVersion>
11 +
12 + <artifactId>coupen-processor</artifactId>
13 + <dependencies>
14 + <dependency>
15 + <groupId>com.zhaoonline.coupen</groupId>
16 + <artifactId>coupen-core</artifactId>
17 + <version>1.0-SNAPSHOT</version>
18 + </dependency>
19 + <dependency>
20 + <groupId>com.zhaoonline.coupen</groupId>
21 + <artifactId>coupen-dispatcher-api</artifactId>
22 + <version>1.0-SNAPSHOT</version>
23 + </dependency>
24 + <dependency>
25 + <groupId>junit</groupId>
26 + <artifactId>junit</artifactId>
27 + <version>4.12</version>
28 + <scope>test</scope>
29 + </dependency>
30 + <dependency>
31 + <groupId>junit</groupId>
32 + <artifactId>junit</artifactId>
33 + <version>4.12</version>
34 + <scope>test</scope>
35 + </dependency>
36 + <dependency>
37 + <groupId>junit</groupId>
38 + <artifactId>junit</artifactId>
39 + <version>4.12</version>
40 + <scope>test</scope>
41 + </dependency>
42 + </dependencies>
43 +
44 +
45 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +package com.zhaoonline.coupen.handler;
2 +
3 +import com.zhaoonline.coupen.bean.Activity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
5 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
6 +import com.zhaoonline.coupen.bean.OwnerUser;
7 +import com.zhaoonline.coupen.cache.RandomCache;
8 +import com.zhaoonline.coupen.dispatcher.CoupenDispatchHandler;
9 +import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
10 +import com.zhaoonline.coupen.lifecycle.LifeCycle;
11 +import org.slf4j.Logger;
12 +import org.slf4j.LoggerFactory;
13 +import org.springframework.beans.factory.annotation.Autowired;
14 +import org.springframework.util.ObjectUtils;
15 +
16 +import java.util.List;
17 +
18 +/**
19 + * Created by ZhaoOnline<br/>
20 + * User: yangyoupeng<br/>
21 + * Date: 2016/12/15<br/>
22 + * Time: 15:19<br/>
23 + * Description:活动处理器,该处理器的作用,是处理通过活动的入口进来领取红包。
24 + */
25 +public class ActivityHandler {
26 + private Logger logger= LoggerFactory.getLogger(ActivityHandler.class);
27 + private CoupenDispatchHandler coupenDispatcher = null;
28 + private UserCoupenMappingHandler userCoupenMappingHandler= null;
29 + private LifeCycle lifeCycle = new LifeCycle();
30 +
31 + //保存有seed的缓存
32 + private RandomCache<String,CommonCoupenSeed> seedRandomCache=new RandomCache<String,CommonCoupenSeed>();
33 +
34 + private RandomCache<String,RandomCache<String,CommonCoupenEntity>> seedAndCoupenRandomCache=new RandomCache<String,RandomCache<String,CommonCoupenEntity>>();
35 +
36 +
37 + @Autowired
38 + public ActivityHandler(CoupenDispatchHandler coupenDispatcher,UserCoupenMappingHandler userCoupenMappingHandler){
39 + this.coupenDispatcher = coupenDispatcher;
40 + this.userCoupenMappingHandler = userCoupenMappingHandler;
41 + lifeCycle.markStart();
42 + }
43 +
44 + /**
45 + * @param activity
46 + * @param user 点击活动入口的用户信息。领取红包,对于同一个用户。不可以重复获取
47 + * @return
48 + */
49 + public CommonCoupenEntity processRequest(Activity activity,OwnerUser user){
50 + warmCache(activity);
51 + CommonCoupenEntity mappedCoupenEntity = null;
52 + //首先会随机从获取一个seedID,然后获取seedID对应其中一个coupenEntity,如果仍然无法获得未分配的红包。那么就尝试去其他CounpenSeed。
53 + while(ObjectUtils.isEmpty(mappedCoupenEntity)) {
54 + if(seedRandomCache.isEmpty()){
55 + return null;
56 + }
57 + mappedCoupenEntity = tryDrawCoupen(seedRandomCache,seedAndCoupenRandomCache,user);
58 + }
59 + return mappedCoupenEntity;
60 + }
61 +
62 + private void warmCache(Activity activity) {
63 + //如果标记了,不需要进行缓存重置
64 + if(lifeCycle.checkNeedReload()){
65 + seedRandomCache.clear();
66 + seedAndCoupenRandomCache.clear();
67 + }
68 +
69 + if(seedRandomCache.isEmpty()){
70 + boolean coupenSeedWarmResult= warmCommonSeed(activity);
71 + }
72 + if(seedAndCoupenRandomCache.isEmpty()){
73 + boolean coupenEntityWarmResult=warmSeedAndCoupenRandmon(seedRandomCache,seedAndCoupenRandomCache);
74 + }
75 +
76 + }
77 +
78 +
79 + /**尝试获取一个红包
80 + * @param seedCache
81 + * @param seedAndCoupenCache
82 + * @param user
83 + * @return
84 + */
85 + private CommonCoupenEntity tryDrawCoupen(RandomCache<String,CommonCoupenSeed> seedCache, RandomCache<String,RandomCache<String,CommonCoupenEntity>> seedAndCoupenCache,OwnerUser user) {
86 + String randomSeedID=seedCache.randomKey();
87 + CommonCoupenSeed seed=seedCache.getCache(randomSeedID);
88 +
89 + if(ObjectUtils.isEmpty(seed)){
90 + return null;
91 + }
92 +
93 + RandomCache<String,CommonCoupenEntity> coupenCacheOfSeed= seedAndCoupenCache.getCache(seed.getSeedID());
94 +
95 + CommonCoupenEntity unmappedCoupenEntity=null;
96 + CommonCoupenEntity mappedCoupenEntity=null;
97 + while(ObjectUtils.isEmpty(mappedCoupenEntity)){
98 + unmappedCoupenEntity =randomGetCoupenFromCache(coupenCacheOfSeed);
99 + //如果最终cache里面的都coupenEntity都为空,那么则跳出循环。同时删除seedAndCoupenRandomCache中的CacheSeed
100 + if(ObjectUtils.isEmpty(unmappedCoupenEntity)){
101 + seedAndCoupenCache.remove(randomSeedID);
102 + break;
103 + }
104 + //若是该Coupen已经被领取了。直接删除缓存,然后直接返回
105 + if(!ObjectUtils.isEmpty(unmappedCoupenEntity.getOwnerUser())){
106 + coupenCacheOfSeed.remove(unmappedCoupenEntity.getCoupenID());
107 + break;
108 + }
109 + //这一步主要是将coupen和用户进行关系映射
110 + mappedCoupenEntity=userCoupenMappingHandler.mappingCoupen2User(unmappedCoupenEntity,user);
111 + //都需要将已经处理过的entity从缓存中删除
112 + coupenCacheOfSeed.remove(unmappedCoupenEntity.getCoupenID());
113 + }
114 + if(ObjectUtils.isEmpty(unmappedCoupenEntity)){
115 + seedCache.remove(randomSeedID);
116 + }
117 + return mappedCoupenEntity;
118 + }
119 +
120 + private boolean warmSeedAndCoupenRandmon(RandomCache<String, CommonCoupenSeed> seedRandomCache,RandomCache<String,RandomCache<String,CommonCoupenEntity>> cacheResult) {
121 +
122 + List<String> keys=seedRandomCache.allKeys();
123 +
124 + if(ObjectUtils.isEmpty(keys)){
125 + return false;
126 + }
127 +
128 + for(String seedID:keys){
129 + CommonCoupenSeed seed=seedRandomCache.getCache(seedID);
130 +
131 + List<CommonCoupenEntity> allCoupenOfSeed= coupenDispatcher.dispacthCoupenEntityUsingSeed(seed);
132 + if(ObjectUtils.isEmpty(allCoupenOfSeed)){
133 + continue;
134 + }
135 + RandomCache<String,CommonCoupenEntity> coupenCache =new RandomCache<String,CommonCoupenEntity>();
136 +
137 + for(CommonCoupenEntity counpen:allCoupenOfSeed){
138 + coupenCache.put(counpen.getCoupenID(),counpen);
139 + }
140 + cacheResult.put(seed.getSeedID(),coupenCache);
141 + }
142 + return true;
143 + }
144 +
145 +
146 + private CommonCoupenEntity randomGetCoupenFromCache(RandomCache<String,CommonCoupenEntity> coupenCacheOfSeed){
147 + //随机获取一个红包ID
148 + String coupenEntityID=coupenCacheOfSeed.randomKey();
149 + CommonCoupenEntity coupenEntity=coupenCacheOfSeed.getCache(coupenEntityID);
150 + return coupenEntity;
151 + }
152 +
153 + private boolean warmCommonSeed(Activity activity) {
154 + List<CommonCoupenSeed> seedList = coupenDispatcher.dispatchCoupenSeedUsingActivity(activity);
155 + if (!ObjectUtils.isEmpty(seedList)){
156 + for (CommonCoupenSeed seed : seedList) {
157 + seedRandomCache.put(seed.getSeedID(), seed);
158 + }
159 + return true;
160 + }
161 + return false;
162 + }
163 +
164 +
165 + public LifeCycle getLifeCycle() {
166 + return lifeCycle;
167 + }
168 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
5 +import com.zhaoonline.coupen.bean.OwnerUser;
6 +import com.zhaoonline.coupen.dispatcher.CoupenDispatchHandler;
7 +import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
8 +import org.springframework.beans.factory.annotation.Autowired;
9 +import org.springframework.util.ObjectUtils;
10 +
11 +/**
12 + * Created by ZhaoOnline<br/>
13 + * User: yangyoupeng<br/>
14 + * Date: 2016/12/15<br/>
15 + * Time: 14:30<br/>
16 + * Description:红包处理器,该处理器的作用,是处理分享红包
17 + * 帮拆的用户。首先是自己获取一个红包。同时会帮拆好友进行技术
18 + */
19 +public class CoupenHelpOpenHandler {
20 +
21 + private CoupenDispatchHandler coupenDispatcher = null;
22 + private UserCoupenMappingHandler userCoupenMappingHandler= null;
23 +
24 + ActivityHandler activityHandler =null;
25 + @Autowired
26 + public CoupenHelpOpenHandler(CoupenDispatchHandler coupenDispatcher, UserCoupenMappingHandler userCoupenMappingHandler){
27 + this.coupenDispatcher = coupenDispatcher;
28 + this.userCoupenMappingHandler = userCoupenMappingHandler;
29 + activityHandler = new ActivityHandler(coupenDispatcher,userCoupenMappingHandler);
30 + }
31 +
32 + /**
33 + * @param coupenEntity
34 + * @param helper 帮拆好友的信息
35 + * @return
36 + */
37 + public CommonCoupenEntity processRequest(CommonCoupenEntity coupenEntity,OwnerUser helper){
38 +
39 + CommonCoupenSeed seed = coupenEntity.getSeed();
40 + if(ObjectUtils.isEmpty(seed)){
41 + return null;
42 + }
43 + //帮拆的朋友,自己获得一个红包。
44 + CommonCoupenEntity coupenOftheHelper=activityHandler.processRequest(seed.getActivity(),helper);
45 + //记录帮拆信息。。。
46 + boolean helpOpenResult=this.userCoupenMappingHandler.recordHelpOpen(coupenEntity,helper);
47 + return coupenOftheHelper;
48 + }
49 +
50 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/17<br/>
7 + * Time: 10:40<br/>
8 + * Description:配置。每个业务、或者活动的DrawConfig不一样。我们这里只对一些基本进行设置
9 + *
10 + */
11 +public class DrawConfig {
12 +
13 + //重复领取的次数
14 + private int repeatDrawCount=1;
15 +
16 + public int getRepeatDrawCount() {
17 + return repeatDrawCount;
18 + }
19 +
20 + public void setRepeatDrawCount(int repeatDrawCount) {
21 + this.repeatDrawCount = repeatDrawCount;
22 + }
23 +
24 + //每个帮拆好友的帮拆次数
25 + private int helpOpenCountPerUser=1;
26 +
27 + public int getHelpOpenCountPerUser() {
28 + return helpOpenCountPerUser;
29 + }
30 +
31 + public void setHelpOpenCountPerUser(int helpOpenCountPerUser) {
32 + this.helpOpenCountPerUser = helpOpenCountPerUser;
33 + }
34 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +import com.zhaoonline.coupen.bean.OwnerUser;
4 +
5 +/**
6 + * Created by ZhaoOnline<br/>
7 + * User: yangyoupeng<br/>
8 + * Date: 2016/12/17<br/>
9 + * Time: 10:39<br/>
10 + * Description:领取上下文
11 + */
12 +public class DrawContext {
13 + //领取人
14 + private OwnerUser drawOwner;
15 + //领取的相关设定.给予默认配置
16 + private DrawConfig config=new DrawConfig();
17 +
18 + public DrawConfig getConfig() {
19 + return config;
20 + }
21 +
22 + public void setConfig(DrawConfig config) {
23 + this.config = config;
24 + }
25 +
26 + public OwnerUser getDrawOwner() {
27 + return drawOwner;
28 + }
29 +
30 + public void setDrawOwner(OwnerUser drawOwner) {
31 + this.drawOwner = drawOwner;
32 + }
33 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +/**
4 + * Created by ZhaoOnline<br/>
5 + * User: yangyoupeng<br/>
6 + * Date: 2016/12/17<br/>
7 + * Time: 11:12<br/>
8 + * Description:处理器的分配器
9 + */
10 +public class HandlerDispatcher {
11 +
12 +
13 +
14 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenSeed;
5 +import com.zhaoonline.coupen.bean.LeafCoupenEntity;
6 +import com.zhaoonline.coupen.bean.OwnerUser;
7 +import com.zhaoonline.coupen.cache.RandomCache;
8 +import com.zhaoonline.coupen.dispatcher.CoupenDispatchHandler;
9 +import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
10 +import com.zhaoonline.coupen.lifecycle.LifeCycle;
11 +import org.springframework.beans.factory.annotation.Autowired;
12 +import org.springframework.util.ObjectUtils;
13 +
14 +import java.util.List;
15 +
16 +/**
17 + * Created by ZhaoOnline<br/>
18 + * User: yangyoupeng<br/>
19 + * Date: 2016/12/16<br/>
20 + * Time: 13:57<br/>
21 + * Description:该类主要服务于用户投资币。适用于即拆即用的帮拆红包。由于帮拆的好友,一个帮拆好友可以帮三个好友拆。
22 + */
23 +public class LeafCoupenHelpOpenHandler {
24 + private CoupenDispatchHandler coupenDispatcher = null;
25 + private UserCoupenMappingHandler userCoupenMappingHandler= null;
26 +
27 + private ActivityHandler activityHandler =null;
28 + private LifeCycle lifeCycle = new LifeCycle();
29 + private RandomCache<String,RandomCache<String,LeafCoupenEntity>> coupen2LeafCoupenCache=new RandomCache<String,RandomCache<String,LeafCoupenEntity>>();
30 +
31 + @Autowired
32 + public LeafCoupenHelpOpenHandler(CoupenDispatchHandler coupenDispatcher, UserCoupenMappingHandler userCoupenMappingHandler){
33 + this.coupenDispatcher = coupenDispatcher;
34 + this.userCoupenMappingHandler = userCoupenMappingHandler;
35 + activityHandler = new ActivityHandler(coupenDispatcher,userCoupenMappingHandler);
36 + lifeCycle.markStart();
37 + }
38 +
39 + /**
40 + * 要对好友的帮拆次数进行判断
41 + * @param coupenEntity
42 + * @param helper 帮拆好友的信息.
43 + * @return
44 + */
45 + public CommonCoupenEntity processRequest(CommonCoupenEntity coupenEntity, OwnerUser helper){
46 +
47 + CommonCoupenSeed seed = coupenEntity.getSeed();
48 + if(ObjectUtils.isEmpty(seed)){
49 + return null;
50 + }
51 + warmCache(coupenEntity);
52 +
53 + //帮拆的朋友,自己获得一个红包。
54 + CommonCoupenEntity coupenOftheHelper=activityHandler.processRequest(seed.getActivity(),helper);
55 +
56 + //根据coupenEntity实体获取该coupen对应的叶子CoupenEntity
57 + RandomCache<String,LeafCoupenEntity> leafCouppenEntityCache=coupen2LeafCoupenCache.getCache(coupenEntity.getCoupenID());
58 + if(ObjectUtils.isEmpty(leafCouppenEntityCache)){
59 + getOrcacheLeafCounpens(coupenEntity, leafCouppenEntityCache);
60 + }
61 +
62 + //分配一个叶子CoupenEntity
63 + CommonCoupenEntity mappedCoupenEntity = dispacthOneLeafCoupen(coupenEntity, leafCouppenEntityCache);
64 + if(!ObjectUtils.isEmpty(mappedCoupenEntity)){
65 + //记录帮拆信息。。。
66 + boolean helpOpenResult=this.userCoupenMappingHandler.recordHelpOpen(mappedCoupenEntity,helper);
67 + }
68 + return coupenOftheHelper;
69 + }
70 +
71 + private boolean warmCache(CommonCoupenEntity coupenEntity) {
72 + //如果标记了,不需要进行缓存重置
73 + if(lifeCycle.checkNeedReload()){
74 + activityHandler.getLifeCycle().markNeedReload();
75 + coupen2LeafCoupenCache.clear();
76 + }
77 + return true;
78 + }
79 +
80 + private void getOrcacheLeafCounpens(CommonCoupenEntity coupenEntity, RandomCache<String, LeafCoupenEntity> leafCouppenEntityCache) {
81 + List<CommonCoupenEntity> leafCoupens= coupenDispatcher.dispacthCoupenEntityUsingCoupen(coupenEntity);
82 + for(CommonCoupenEntity counpen:leafCoupens){
83 + LeafCoupenEntity leafCoupenEntity = new LeafCoupenEntity();
84 + leafCoupenEntity.setCoupenID(counpen.getCoupenID());
85 + leafCoupenEntity.setParentCoupen(coupenEntity);
86 + leafCoupenEntity.setAmount(counpen.getAmount());
87 + leafCoupenEntity.setOwnerUser(counpen.getOwnerUser());
88 + leafCoupenEntity.setSeed(counpen.getSeed());
89 + leafCoupenEntity.setDistributeDate(counpen.getDistributeDate());
90 + leafCouppenEntityCache.put(leafCoupenEntity.getCoupenID(),leafCoupenEntity);
91 + }
92 + }
93 +
94 + private CommonCoupenEntity dispacthOneLeafCoupen(CommonCoupenEntity coupenEntity, RandomCache<String, LeafCoupenEntity> leafCouppenEntityCache) {
95 + OwnerUser owner = coupenEntity.getOwnerUser();
96 + LeafCoupenEntity unmappedLeafCoupenEntity=null;
97 + CommonCoupenEntity mappedCoupenEntity=null;
98 + while(ObjectUtils.isEmpty(unmappedLeafCoupenEntity)){
99 + unmappedLeafCoupenEntity=randomGetCoupenFromCache(leafCouppenEntityCache);
100 + if(ObjectUtils.isEmpty(unmappedLeafCoupenEntity)){
101 + leafCouppenEntityCache.remove(coupenEntity.getCoupenID());
102 + break;
103 + }
104 + //若是该Coupen已经被领取了。直接删除缓存,然后直接返回
105 + if(!ObjectUtils.isEmpty(unmappedLeafCoupenEntity.getOwnerUser())){
106 + leafCouppenEntityCache.remove(unmappedLeafCoupenEntity.getCoupenID());
107 + break;
108 + }
109 + //这一步主要是将coupen和用户进行关系映射
110 + mappedCoupenEntity=userCoupenMappingHandler.mappingCoupen2User(unmappedLeafCoupenEntity,owner);
111 + //都需要将已经处理过的entity从缓存中删除
112 + leafCouppenEntityCache.remove(unmappedLeafCoupenEntity.getCoupenID());
113 + }
114 + return mappedCoupenEntity;
115 + }
116 +
117 +
118 + private LeafCoupenEntity randomGetCoupenFromCache(RandomCache<String,LeafCoupenEntity> coupenCacheOfSeed){
119 + //随机获取一个红包ID
120 + String coupenEntityID=coupenCacheOfSeed.randomKey();
121 + LeafCoupenEntity coupenEntity=coupenCacheOfSeed.getCache(coupenEntityID);
122 + return coupenEntity;
123 + }
124 +
125 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +import com.zhaoonline.coupen.bean.Activity;
4 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
5 +import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
6 +import org.springframework.beans.factory.annotation.Autowired;
7 +import org.springframework.util.ObjectUtils;
8 +
9 +import java.util.List;
10 +
11 +/**
12 + * Created by ZhaoOnline<br/>
13 + * User: yangyoupeng<br/>
14 + * Date: 2016/12/17<br/>
15 + * Time: 10:22<br/>
16 + * Description:在处理红包之前。
17 + */
18 +public class PreActivityHandler {
19 +
20 + private UserCoupenMappingHandler userCoupenMappingHandler= null;
21 +
22 + @Autowired
23 + public PreActivityHandler(UserCoupenMappingHandler userCoupenMappingHandler){
24 + this.userCoupenMappingHandler = userCoupenMappingHandler;
25 + }
26 +
27 + /**
28 + * 这是是要对根据用户和Activity来判断
29 + * @param activity
30 + * @param context
31 + * @return
32 + */
33 + public boolean preProcessRequest(Activity activity,DrawContext context){
34 + List<CommonCoupenEntity> coupnesOfUserInOneActivity=this.userCoupenMappingHandler.getMappingOfUser(activity,context.getDrawOwner());
35 + if(ObjectUtils.isEmpty(coupnesOfUserInOneActivity) || checkBeyondDrawLimit(context, coupnesOfUserInOneActivity)){
36 + return true;
37 + }
38 + return false;
39 + }
40 +
41 +
42 + /**判断是否用户领取已经超出了限制次数。正常逻辑,每个用户在一个活动中只允许领取一个红包
43 + * @param context
44 + * @param coupnesOfUserInOneActivity
45 + * @return
46 + */
47 + private boolean checkBeyondDrawLimit(DrawContext context, List<CommonCoupenEntity> coupnesOfUserInOneActivity) {
48 + return coupnesOfUserInOneActivity.size() <context.getConfig().getRepeatDrawCount();
49 + }
50 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +import com.zhaoonline.coupen.bean.CommonCoupenEntity;
4 +import com.zhaoonline.coupen.bean.OwnerUser;
5 +import com.zhaoonline.coupen.cache.LRUCache;
6 +import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
7 +import org.springframework.beans.factory.annotation.Autowired;
8 +import org.springframework.util.ObjectUtils;
9 +
10 +import java.util.List;
11 +
12 +/**
13 + * Created by ZhaoOnline<br/>
14 + * User: yangyoupeng<br/>
15 + * Date: 2016/12/17<br/>
16 + * Time: 11:04<br/>
17 + * Description:please descript you class
18 + */
19 +public class PreCoupenHelpOpenHandler {
20 +
21 + private UserCoupenMappingHandler userCoupenMappingHandler= null;
22 +
23 + @Autowired
24 + public PreCoupenHelpOpenHandler(UserCoupenMappingHandler userCoupenMappingHandler){
25 + this.userCoupenMappingHandler = userCoupenMappingHandler;
26 + }
27 +
28 + /**
29 + * 这是是要对根据用户和Activity来判断
30 + * @param coupenEntity
31 + * @param context
32 + * @return
33 + */
34 + public boolean preProcessRequest(CommonCoupenEntity coupenEntity, DrawContext context){
35 + List<CommonCoupenEntity> coupnesOfUserInOneActivity=this.userCoupenMappingHandler.getHelpOpenCoupenOfUser(coupenEntity,context.getDrawOwner());
36 + if(ObjectUtils.isEmpty(coupnesOfUserInOneActivity) || checkBeyondhelpOpenLimit(context, coupnesOfUserInOneActivity)){
37 + return true;
38 + }
39 + return false;
40 + }
41 +
42 + private boolean checkBeyondhelpOpenLimit(DrawContext context, List<CommonCoupenEntity> coupnesOfUserInOneActivity) {
43 + return coupnesOfUserInOneActivity.size() <context.getConfig().getHelpOpenCountPerUser();
44 + }
45 +
46 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +import com.zhaoonline.coupen.bean.*;
4 +import com.zhaoonline.coupen.dispatcher.CoupenDispatchHandler;
5 +import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
6 +import org.junit.Assert;
7 +import org.junit.Test;
8 +import org.junit.runner.RunWith;
9 +import org.mockito.Mockito;
10 +import org.mockito.invocation.InvocationOnMock;
11 +import org.mockito.runners.MockitoJUnitRunner;
12 +import org.mockito.stubbing.Answer;
13 +
14 +import java.math.BigDecimal;
15 +import java.util.ArrayList;
16 +import java.util.HashMap;
17 +import java.util.List;
18 +import java.util.Map;
19 +
20 +/**
21 + * Created by ZhaoOnline<br/>
22 + * User: yangyoupeng<br/>
23 + * Date: 2016/12/16<br/>
24 + * Time: 11:18<br/>
25 + * Description:please descript you class
26 + */
27 +@RunWith(MockitoJUnitRunner.class)
28 +public class TestActivityHandler {
29 + private CoupenDispatchHandler coupenDispatcher = Mockito.mock(CoupenDispatchHandler.class);
30 + private UserCoupenMappingHandler userCoupenMappingHandler= Mockito.mock(UserCoupenMappingHandler.class);
31 +
32 + /**
33 + * 同一个用户在同一个Activity中只允许抢一个红包.
34 + * 一个CoupenSeed、2个CoupenEntity
35 + */
36 + @Test
37 + public void testSameUserOnlyGetOneCoupenIntheSameActivity(){
38 + Activity testActivity= new Activity();
39 + testActivity.setActivityID(1);
40 +
41 + CommonCoupenSeed seed =new CommonCoupenSeed();
42 + seed.setSeedID("testSeedID123456");
43 + seed.setActivity(testActivity);
44 +
45 + List<CommonCoupenSeed> mockedSeedList=new ArrayList<CommonCoupenSeed>();
46 + mockedSeedList.add(seed);
47 +
48 + CommonCoupenEntity coupenEntity=new CommonCoupenEntity();
49 + coupenEntity.setSeed(seed);
50 + coupenEntity.setCoupenID("testCoupenID1234556");
51 + coupenEntity.setAmount(new BigDecimal(880));
52 +
53 + CommonCoupenEntity coupenEntity2=new CommonCoupenEntity();
54 + coupenEntity2.setSeed(seed);
55 + coupenEntity2.setCoupenID("testCoupenID1234552");
56 + coupenEntity2.setAmount(new BigDecimal(880));
57 +
58 + List<CommonCoupenEntity> mockCoupenEntityList=new ArrayList<CommonCoupenEntity>();
59 + mockCoupenEntityList.add(coupenEntity);
60 + mockCoupenEntityList.add(coupenEntity2);
61 +
62 +
63 +
64 + Mockito.when(coupenDispatcher.dispacthCoupenEntityUsingSeed(Mockito.any(CommonCoupenSeed.class))).thenReturn(mockCoupenEntityList);
65 +
66 + Mockito.when(coupenDispatcher.dispatchCoupenSeedUsingActivity(Mockito.any(Activity.class))).thenReturn(mockedSeedList);
67 +
68 + Mockito.when(userCoupenMappingHandler.mappingCoupen2User(Mockito.any(CommonCoupenEntity.class),Mockito.any(OwnerUser.class)))
69 +
70 + .then(new Answer<CommonCoupenEntity>() {
71 + int invokeCount=0;
72 + @Override
73 + public CommonCoupenEntity answer(InvocationOnMock invocation) throws Throwable {
74 + //如果invoke>1 调用多次,表示对于同一个用户在同一个活动中进行了多次领取。
75 + if(invokeCount>=1){
76 + return null;
77 + }
78 + invokeCount=invokeCount+1;
79 + Object[] args=invocation.getArguments();
80 + CommonCoupenEntity coupen= (CommonCoupenEntity) args[0];
81 + OwnerUser owner= (OwnerUser) args[1];
82 + coupen.setOwnerUser(owner);
83 + return coupen;
84 + }
85 + });
86 +
87 + OwnerUser owner=new OwnerUser();
88 + owner.setOwnerUserID("testOwner1");
89 + ActivityHandler activityHandler = new ActivityHandler(coupenDispatcher,userCoupenMappingHandler);
90 + CommonCoupenEntity coupenOfUserFirstDraw=activityHandler.processRequest(testActivity,owner);
91 + Assert.assertNotNull(coupenOfUserFirstDraw);
92 + Assert.assertEquals("testOwner1",coupenOfUserFirstDraw.getOwnerUser().getOwnerUserID());
93 +
94 + CommonCoupenEntity coupenOfUserSecondDraw=activityHandler.processRequest(testActivity,owner);
95 + Assert.assertNull(coupenOfUserSecondDraw);
96 +
97 + CommonCoupenEntity coupenOfUserThirdDraw=activityHandler.processRequest(testActivity,owner);
98 + Assert.assertNull(coupenOfUserThirdDraw);
99 +
100 + }
101 +
102 +
103 + /**
104 + *一个Activity
105 + * 2个CoupenSeed
106 + * 每个CoupenSeed有两个CoupenEntity
107 + */
108 + @Test
109 + public void testNoEnoughCoupen(){
110 + Activity testActivity= new Activity();
111 + testActivity.setActivityID(1);
112 + String seedID1="testSeedID123456";
113 + String seedID2="testSeedID123457";
114 + CommonCoupenSeed seed =new CommonCoupenSeed();
115 + seed.setSeedID(seedID1);
116 + seed.setActivity(testActivity);
117 +
118 + CommonCoupenSeed seed2 =new CommonCoupenSeed();
119 + seed2.setSeedID(seedID2);
120 + seed2.setActivity(testActivity);
121 +
122 +
123 + List<CommonCoupenSeed> mockedSeedList=new ArrayList<CommonCoupenSeed>();
124 + mockedSeedList.add(seed);
125 + mockedSeedList.add(seed2);
126 +
127 + CommonCoupenEntity coupenEntity1=new CommonCoupenEntity();
128 + coupenEntity1.setSeed(seed);
129 + coupenEntity1.setCoupenID("testCoupenID1234551");
130 + coupenEntity1.setAmount(new BigDecimal(880));
131 +
132 + CommonCoupenEntity coupenEntity2=new CommonCoupenEntity();
133 + coupenEntity2.setSeed(seed);
134 + coupenEntity2.setCoupenID("testCoupenID1234552");
135 + coupenEntity2.setAmount(new BigDecimal(880));
136 +
137 +
138 + CommonCoupenEntity coupenEntity3=new CommonCoupenEntity();
139 + coupenEntity3.setSeed(seed2);
140 + coupenEntity3.setCoupenID("testCoupenID1234553");
141 + coupenEntity3.setAmount(new BigDecimal(580));
142 +
143 + CommonCoupenEntity coupenEntity4=new CommonCoupenEntity();
144 + coupenEntity4.setSeed(seed2);
145 + coupenEntity4.setCoupenID("testCoupenID1234554");
146 + coupenEntity4.setAmount(new BigDecimal(580));
147 +
148 +
149 + List<CommonCoupenEntity> mockCoupenEntityList=new ArrayList<CommonCoupenEntity>();
150 + mockCoupenEntityList.add(coupenEntity1);
151 + mockCoupenEntityList.add(coupenEntity2);
152 + List<CommonCoupenEntity> mockCoupenEntityList2=new ArrayList<CommonCoupenEntity>();
153 + mockCoupenEntityList2.add(coupenEntity3);
154 + mockCoupenEntityList2.add(coupenEntity4);
155 +
156 + Map<String,List<CommonCoupenEntity>> seedCoupenMap=new HashMap<String,List<CommonCoupenEntity>>();
157 + seedCoupenMap.put(seedID1,mockCoupenEntityList);
158 + seedCoupenMap.put(seedID2,mockCoupenEntityList2);
159 +
160 + //
161 + Mockito.when(coupenDispatcher.dispacthCoupenEntityUsingSeed(Mockito.any(CommonCoupenSeed.class)))
162 + .then(new Answer<List<CommonCoupenEntity>>() {
163 + Map<String,Integer> invokerCountMap=new HashMap<String, Integer>();
164 +
165 + @Override
166 + public List<CommonCoupenEntity> answer(InvocationOnMock invocation) throws Throwable {
167 + Object[] args=invocation.getArguments();
168 + CommonCoupenSeed coupenSeed= (CommonCoupenSeed) args[0];
169 + List<CommonCoupenEntity> mockCoupenEntityList = seedCoupenMap.get(coupenSeed.getSeedID());
170 + Integer invokerCount= invokerCountMap.get(coupenSeed.getSeedID());
171 + if(invokerCount == null){
172 + invokerCountMap.put(coupenSeed.getSeedID(),new Integer(0));
173 + }else{
174 + if(invokerCount >=1){
175 + for(CommonCoupenEntity coupen :mockCoupenEntityList){
176 + coupen.setOwnerUser(new OwnerUser());
177 + }
178 + }
179 + invokerCountMap.put(coupenSeed.getSeedID(),new Integer(invokerCount.intValue()+1));
180 + }
181 +
182 + return mockCoupenEntityList;
183 + }
184 + });
185 +
186 + Mockito.when(coupenDispatcher.dispatchCoupenSeedUsingActivity(Mockito.any(Activity.class))).thenReturn(mockedSeedList);
187 +
188 + Mockito.when(userCoupenMappingHandler.mappingCoupen2User(Mockito.any(CommonCoupenEntity.class),Mockito.any(OwnerUser.class)))
189 + .then(new Answer<CommonCoupenEntity>() {
190 + @Override
191 + public CommonCoupenEntity answer(InvocationOnMock invocation) throws Throwable {
192 + Object[] args=invocation.getArguments();
193 + CommonCoupenEntity coupen= (CommonCoupenEntity) args[0];
194 + OwnerUser owner= (OwnerUser) args[1];
195 + coupen.setOwnerUser(owner);
196 + return coupen;
197 + }
198 + });
199 +
200 + ActivityHandler activityHandler = new ActivityHandler(coupenDispatcher,userCoupenMappingHandler);
201 +
202 + int userCount=4;
203 + for(int i=0;i<userCount;i++){
204 + OwnerUser owner=new OwnerUser();
205 + owner.setOwnerUserID("testOwner"+i);
206 + CommonCoupenEntity coupenOfUserFirstDraw=activityHandler.processRequest(testActivity,owner);
207 + Assert.assertNotNull(coupenOfUserFirstDraw);
208 + Assert.assertEquals(owner.getOwnerUserID(),coupenOfUserFirstDraw.getOwnerUser().getOwnerUserID());
209 + }
210 + //更多的用来来抢有限的红包
211 + for(int i=5;i<10;i++){
212 + OwnerUser owner=new OwnerUser();
213 + owner.setOwnerUserID("testOwner"+i);
214 + CommonCoupenEntity coupenOfUserFirstDraw=activityHandler.processRequest(testActivity,owner);
215 + Assert.assertNull(coupenOfUserFirstDraw);
216 + }
217 + }
218 +}
1 +package com.zhaoonline.coupen.handler;
2 +
3 +
4 +import com.zhaoonline.coupen.bean.*;
5 +import com.zhaoonline.coupen.dispatcher.CoupenDispatchHandler;
6 +import com.zhaoonline.coupen.dispatcher.UserCoupenMappingHandler;
7 +import org.junit.Assert;
8 +import org.junit.Test;
9 +import org.junit.runner.RunWith;
10 +import org.mockito.Mockito;
11 +import org.mockito.invocation.InvocationOnMock;
12 +import org.mockito.runners.MockitoJUnitRunner;
13 +import org.mockito.stubbing.Answer;
14 +
15 +import java.math.BigDecimal;
16 +import java.util.ArrayList;
17 +import java.util.List;
18 +
19 +/**
20 + * Created by ZhaoOnline<br/>
21 + * User: yangyoupeng<br/>
22 + * Date: 2016/12/16<br/>
23 + * Time: 11:19<br/>
24 + * Description:please descript you class
25 + */
26 +@RunWith(MockitoJUnitRunner.class)
27 +public class TestCoupenHelpOpenHandler {
28 + private CoupenDispatchHandler coupenDispatcher = Mockito.mock(CoupenDispatchHandler.class);
29 + private UserCoupenMappingHandler userCoupenMappingHandler= Mockito.mock(UserCoupenMappingHandler.class);
30 +
31 + /**
32 + *
33 + */
34 + @Test
35 + public void testProcessRequest(){
36 + HelpOpenCoupenSeed seed =new HelpOpenCoupenSeed();
37 + seed.setSeedID("testSeedID123456");
38 + List<CommonCoupenSeed> mockedSeedList=new ArrayList<CommonCoupenSeed>();
39 + mockedSeedList.add(seed);
40 +
41 + OwnerUser owner=new OwnerUser();
42 + owner.setOwnerUserID("testOwner1");
43 + CommonCoupenEntity coupenEntity=new CommonCoupenEntity();
44 + coupenEntity.setOwnerUser(owner);
45 + coupenEntity.setCoupenID("testCoupenID1234556");
46 + coupenEntity.setAmount(new BigDecimal(880));
47 + coupenEntity.setSeed(seed);
48 +
49 + OwnerUser owner2=new OwnerUser();
50 + owner2.setOwnerUserID("testOwner2");
51 +
52 + CommonCoupenEntity coupenEntity2=new CommonCoupenEntity();
53 + coupenEntity2.setCoupenID("testCoupenID1234552");
54 + coupenEntity2.setAmount(new BigDecimal(880));
55 + coupenEntity2.setSeed(seed);
56 +
57 + OwnerUser helper=new OwnerUser();
58 + helper.setOwnerUserID("testHelper1");
59 +
60 + List<CommonCoupenEntity> mockCoupenEntityList=new ArrayList<CommonCoupenEntity>();
61 + mockCoupenEntityList.add(coupenEntity);
62 + mockCoupenEntityList.add(coupenEntity2);
63 +
64 +
65 +
66 + Mockito.when(coupenDispatcher.dispacthCoupenEntityUsingSeed(Mockito.any(CommonCoupenSeed.class))).thenReturn(mockCoupenEntityList);
67 +
68 + Mockito.when(coupenDispatcher.dispatchCoupenSeedUsingActivity(Mockito.any(Activity.class))).thenReturn(mockedSeedList);
69 +
70 +
71 + Mockito.when(userCoupenMappingHandler.mappingCoupen2User(Mockito.any(CommonCoupenEntity.class),Mockito.any(OwnerUser.class)))
72 + .then(new Answer<CommonCoupenEntity>() {
73 + @Override
74 + public CommonCoupenEntity answer(InvocationOnMock invocation) throws Throwable {
75 + Object[] args=invocation.getArguments();
76 + CommonCoupenEntity coupen= (CommonCoupenEntity) args[0];
77 + OwnerUser owner= (OwnerUser) args[1];
78 + coupen.setOwnerUser(owner);
79 + return coupen;
80 + }
81 + });
82 +
83 + CoupenHelpOpenHandler helpOpenHandler = new CoupenHelpOpenHandler(coupenDispatcher,userCoupenMappingHandler);
84 +
85 +
86 + CommonCoupenEntity helperGetNewCoupenAfterHelpOpen=helpOpenHandler.processRequest(coupenEntity,helper);
87 +
88 +
89 + OwnerUser ownerAfterHelpOpen = helperGetNewCoupenAfterHelpOpen.getOwnerUser();
90 +
91 + Assert.assertEquals("testHelper1",ownerAfterHelpOpen.getOwnerUserID());
92 +
93 + }
94 +}
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 + <modelVersion>4.0.0</modelVersion>
6 + <groupId>com.zhaoonline.coupen</groupId>
7 + <artifactId>parent</artifactId>
8 + <version>1.0-SNAPSHOT</version>
9 + <packaging>pom</packaging>
10 + <properties>
11 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
12 + <logback.version>1.1.7</logback.version>
13 + </properties>
14 +
15 + <dependencyManagement>
16 + <dependencies>
17 + <dependency>
18 + <groupId>javax.validation</groupId>
19 + <artifactId>validation-api</artifactId>
20 + <version>1.1.0.Final</version>
21 + </dependency>
22 +
23 + <dependency>
24 + <groupId>com.auth0</groupId>
25 + <artifactId>java-jwt</artifactId>
26 + <version>3.0.1</version>
27 + </dependency>
28 +
29 + <dependency>
30 + <groupId>io.jsonwebtoken</groupId>
31 + <artifactId>jjwt</artifactId>
32 + <version>0.7.0</version>
33 + </dependency>
34 +
35 + <dependency>
36 + <groupId>org.bitbucket.b_c</groupId>
37 + <artifactId>jose4j</artifactId>
38 + <version>0.5.2</version>
39 + </dependency>
40 +
41 + <dependency>
42 + <groupId>com.google.guava</groupId>
43 + <artifactId>guava</artifactId>
44 + <version>18.0</version>
45 + </dependency>
46 +
47 + <dependency>
48 + <groupId>joda-time</groupId>
49 + <artifactId>joda-time</artifactId>
50 + <version>2.9.4</version>
51 + </dependency>
52 +
53 + <dependency>
54 + <groupId>com.fasterxml.jackson.core</groupId>
55 + <artifactId>jackson-databind</artifactId>
56 + <version>2.8.1</version>
57 + </dependency>
58 +
59 + <dependency>
60 + <groupId>org.slf4j</groupId>
61 + <artifactId>slf4j-api</artifactId>
62 + <version>1.7.21</version>
63 + </dependency>
64 +
65 + <dependency>
66 + <groupId>org.slf4j</groupId>
67 + <artifactId>slf4j-api</artifactId>
68 + <version>1.7.21</version>
69 + </dependency>
70 +
71 + <dependency>
72 + <groupId>ch.qos.logback</groupId>
73 + <artifactId>logback-core</artifactId>
74 + <version>${logback.version}</version>
75 + </dependency>
76 +
77 + <dependency>
78 + <groupId>com.zhaoonline</groupId>
79 + <artifactId>microservice-redis</artifactId>
80 + <version>1.0.0-SNAPSHOT</version>
81 + <exclusions>
82 + <exclusion>
83 + <groupId>com.zhaoonline</groupId>
84 + <artifactId>alpaca-config-zookeeper</artifactId>
85 + </exclusion>
86 + </exclusions>
87 + </dependency>
88 +
89 +
90 + <dependency>
91 + <groupId>org.mockito</groupId>
92 + <artifactId>mockito-all</artifactId>
93 + <version>1.10.19</version>
94 + <scope>test</scope>
95 + </dependency>
96 + <dependency>
97 + <groupId>junit</groupId>
98 + <artifactId>junit</artifactId>
99 + <version>4.12</version><!--$NO-MVN-MAN-VER$ -->
100 + <scope>test</scope>
101 + </dependency>
102 +
103 +
104 + </dependencies>
105 +
106 + </dependencyManagement>
107 + <build>
108 + <plugins>
109 + <plugin>
110 + <groupId>org.apache.maven.plugins</groupId>
111 + <artifactId>maven-compiler-plugin</artifactId>
112 + <version>3.1</version>
113 + <configuration>
114 + <source>1.8</source>
115 + <target>1.8</target>
116 + </configuration>
117 + </plugin>
118 + </plugins>
119 + </build>
120 + <modules>
121 + <module>coupen-generator</module>
122 + <module>coupen-dispatcher</module>
123 + <module>coupen-processor</module>
124 + <module>coupen-core</module>
125 + <module>coupen-dispatcher-api</module>
126 + </modules>
127 +
128 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
3 + <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
4 + <output url="file://$MODULE_DIR$/target/classes" />
5 + <output-test url="file://$MODULE_DIR$/target/test-classes" />
6 + <content url="file://$MODULE_DIR$">
7 + <excludeFolder url="file://$MODULE_DIR$/target" />
8 + </content>
9 + <orderEntry type="inheritedJdk" />
10 + <orderEntry type="sourceFolder" forTests="false" />
11 + </component>
12 +</module>
...\ No newline at end of file ...\ No newline at end of file