From 49d5696ef9a5f0e2921ad4dc968a9e15e33aa46d Mon Sep 17 00:00:00 2001 From: dzh Date: Thu, 18 Jul 2019 16:04:33 +0800 Subject: [PATCH 01/47] add jframe-google --- .../jframe/aliyun/service/STSService.java | 8 +- jframe-plugin/jframe-google/pom.xml | 15 + .../main/java/jframe/google/GooglePlugin.java | 10 + .../jframe/google/service/GeocodingApi.java | 11 + .../jframe/google/service/GoogleService.java | 14 + .../service/impl/GoogleServiceImpl.java | 10 + .../main/resources/META-INF/plugin.properties | 9 + jframe-plugin/jframe-zk/pom.xml | 2 +- jframe-plugin/pom.xml | 277 +++++++++--------- 9 files changed, 213 insertions(+), 143 deletions(-) create mode 100644 jframe-plugin/jframe-google/pom.xml create mode 100644 jframe-plugin/jframe-google/src/main/java/jframe/google/GooglePlugin.java create mode 100644 jframe-plugin/jframe-google/src/main/java/jframe/google/service/GeocodingApi.java create mode 100644 jframe-plugin/jframe-google/src/main/java/jframe/google/service/GoogleService.java create mode 100644 jframe-plugin/jframe-google/src/main/java/jframe/google/service/impl/GoogleServiceImpl.java create mode 100644 jframe-plugin/jframe-google/src/main/resources/META-INF/plugin.properties diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java index ad06e9f..62dd7c5 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java @@ -1,12 +1,12 @@ /** - * + * */ package jframe.aliyun.service; -import java.util.Map; - import jframe.core.plugin.annotation.Service; +import java.util.Map; + /** * @author dzh * @date Feb 28, 2016 9:13:38 AM @@ -17,7 +17,7 @@ public interface STSService { /** * 获取临时访问权限 - * + * * @param id * @return */ diff --git a/jframe-plugin/jframe-google/pom.xml b/jframe-plugin/jframe-google/pom.xml new file mode 100644 index 0000000..0fa451d --- /dev/null +++ b/jframe-plugin/jframe-google/pom.xml @@ -0,0 +1,15 @@ + + + + jframe-plugin + io.github.dzh + 2.0.0-SNAPSHOT + + 4.0.0 + + jframe-google + + + \ No newline at end of file diff --git a/jframe-plugin/jframe-google/src/main/java/jframe/google/GooglePlugin.java b/jframe-plugin/jframe-google/src/main/java/jframe/google/GooglePlugin.java new file mode 100644 index 0000000..0f55ad5 --- /dev/null +++ b/jframe-plugin/jframe-google/src/main/java/jframe/google/GooglePlugin.java @@ -0,0 +1,10 @@ +package jframe.google; + +import jframe.core.plugin.DefPlugin; + +/** + * @author dzh + * @date 2019-05-08 10:59 + */ +public class GooglePlugin extends DefPlugin { +} diff --git a/jframe-plugin/jframe-google/src/main/java/jframe/google/service/GeocodingApi.java b/jframe-plugin/jframe-google/src/main/java/jframe/google/service/GeocodingApi.java new file mode 100644 index 0000000..1b746e8 --- /dev/null +++ b/jframe-plugin/jframe-google/src/main/java/jframe/google/service/GeocodingApi.java @@ -0,0 +1,11 @@ +package jframe.google.service; + +/** + * https://developers.google.com/maps/documentation/geocoding/start + * + * @author dzh + * @date 2019-05-08 12:34 + */ +public interface GeocodingApi { + +} diff --git a/jframe-plugin/jframe-google/src/main/java/jframe/google/service/GoogleService.java b/jframe-plugin/jframe-google/src/main/java/jframe/google/service/GoogleService.java new file mode 100644 index 0000000..87f1c1e --- /dev/null +++ b/jframe-plugin/jframe-google/src/main/java/jframe/google/service/GoogleService.java @@ -0,0 +1,14 @@ +package jframe.google.service; + +import jframe.core.plugin.annotation.Service; + +/** + * @author dzh + * @date 2019-05-08 11:00 + */ +@Service(clazz = "jframe.google.service.impl.GoogleServiceImpl", id = "jframe.service.google") +public interface GoogleService { + + + +} diff --git a/jframe-plugin/jframe-google/src/main/java/jframe/google/service/impl/GoogleServiceImpl.java b/jframe-plugin/jframe-google/src/main/java/jframe/google/service/impl/GoogleServiceImpl.java new file mode 100644 index 0000000..00f24b9 --- /dev/null +++ b/jframe-plugin/jframe-google/src/main/java/jframe/google/service/impl/GoogleServiceImpl.java @@ -0,0 +1,10 @@ +package jframe.google.service.impl; + +import jframe.google.service.GoogleService; + +/** + * @author dzh + * @date 2019-05-08 11:01 + */ +public class GoogleServiceImpl implements GoogleService { +} diff --git a/jframe-plugin/jframe-google/src/main/resources/META-INF/plugin.properties b/jframe-plugin/jframe-google/src/main/resources/META-INF/plugin.properties new file mode 100644 index 0000000..0940fc7 --- /dev/null +++ b/jframe-plugin/jframe-google/src/main/resources/META-INF/plugin.properties @@ -0,0 +1,9 @@ +Plugin-Name=jframe.google.GooglePlugin +Plugin-Class=jframe.google.GooglePlugin +#Default library path is META-INF/lib/ +#Plugin-Lib = +#Default DLL path is META-INF/dll +#Plugin-Dll = +Plugin-Service=jframe.google.service.GoogleService +#Export-Class= + diff --git a/jframe-plugin/jframe-zk/pom.xml b/jframe-plugin/jframe-zk/pom.xml index 382bfbf..5ab2f39 100644 --- a/jframe-plugin/jframe-zk/pom.xml +++ b/jframe-plugin/jframe-zk/pom.xml @@ -9,7 +9,7 @@ jframe-zk - 4.0.1 + 4.2.0 diff --git a/jframe-plugin/pom.xml b/jframe-plugin/pom.xml index 252a4dc..8940462 100644 --- a/jframe-plugin/pom.xml +++ b/jframe-plugin/pom.xml @@ -1,141 +1,142 @@ - 4.0.0 - jframe-plugin - 2.0.0-SNAPSHOT - pom - - UTF-8 - 2.0.0-SNAPSHOT - 1.7.25 - - - jframe-activemq - jframe-clrfile - jframe-datasource - jframe-watch - jframe-mybatis - jframe-getui - jframe-pushy - jframe-apns - jframe-memcached-client - jframe-jedis - jframe-httpclient - jframe-mongodb-client - jframe-yunpian - jframe-qiniu - jframe-activemq-client - jframe-rabbitmq-client - jframe-rongcloud - jframe-aliyun - jframe-umeng - jframe-zk - jframe-netty-http - jframe-azure - jframe-yunsms - jframe-californium - jframe-mqtt-client - jframe-wx - jframe-freemarker - jframe-elasticsearch - jframe-redisson - jframe-qcloud - - - - - ${project.groupId} - jframe-ext - ${jframe.version} - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.1 - - - plugin - - - - org.apache.maven.plugins - maven-resources-plugin - 3.1.0 - - - compile - - - - ${project.build.sourceEncoding} - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M2 - - true - - - - org.apache.maven.plugins - maven-clean-plugin - 3.1.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M2 - - true - - - - - - - junit - junit - 4.10 - test - - - org.slf4j - slf4j-api - ${slf4j.version} - - - org.slf4j - slf4j-simple - ${slf4j.version} - test - - - ${project.groupId} - jframe-core - ${jframe.version} - - - io.github.dzh + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + jframe-plugin + 2.0.0-SNAPSHOT + pom + io.github.dzh + + UTF-8 + 2.0.0-SNAPSHOT + 1.7.25 + + + jframe-activemq + jframe-clrfile + jframe-datasource + jframe-watch + jframe-mybatis + jframe-getui + jframe-pushy + jframe-apns + jframe-memcached-client + jframe-jedis + jframe-httpclient + jframe-mongodb-client + jframe-yunpian + jframe-qiniu + jframe-activemq-client + jframe-rabbitmq-client + jframe-rongcloud + jframe-aliyun + jframe-umeng + jframe-zk + jframe-netty-http + jframe-azure + jframe-yunsms + jframe-californium + jframe-mqtt-client + jframe-wx + jframe-freemarker + jframe-elasticsearch + jframe-redisson + jframe-qcloud + jframe-google + + + + + ${project.groupId} + jframe-ext + ${jframe.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.1 + + + plugin + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + compile + + + + ${project.build.sourceEncoding} + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M2 + + true + + + + org.apache.maven.plugins + maven-clean-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M2 + + true + + + + + + + junit + junit + 4.10 + test + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + + ${project.groupId} + jframe-core + ${jframe.version} + + \ No newline at end of file From 60baa730ba1f53508713ab2a35d8495083c674ff Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 22 Jul 2019 07:59:30 +0800 Subject: [PATCH 02/47] upg jframe-pay 2.0.0 --- .gitignore | 16 +- jframe-pay/README.md | 10 + jframe-pay/jframe-pay-client/pom.xml | 36 -- .../jframe-pay-lib/jframe-pay-domain/pom.xml | 89 ++--- .../pay/domain/dao/mapper/Environment.java | 10 +- .../java/jframe/pay/domain/util/HttpUtil.java | 21 +- .../java/jframe/pay/domain/util/IDUtil.java | 28 +- .../java/jframe/pay/domain/util/ToString.java | 27 +- jframe-pay/jframe-pay-lib/pom.xml | 28 +- .../jframe-pay-alipay/pom.xml | 80 ++--- .../java/jframe/pay/alipay/AlipayConfig.java | 6 +- .../pay/alipay/service/AlipayServiceImpl.java | 78 ++--- .../jframe-pay-client/README.md | 0 .../jframe-pay-client/pom.xml | 33 ++ .../java/jframe/pay/client/PayClientConf.java | 0 .../jframe/pay/client/PayClientPlugin.java | 0 .../jframe/pay/client/core/PayClient.java | 0 .../client/service/HttpPayClientService.java | 22 +- .../pay/client/service/PayClientService.java | 0 .../main/resources/META-INF/plugin.properties | 0 .../src/test/resources/payclient.properties | 0 .../jframe-pay-plugin/jframe-pay-dao/pom.xml | 42 ++- .../jframe-pay-plugin/jframe-pay-http/pom.xml | 84 +++-- .../jframe/pay/http/handler/PayHandler.java | 13 +- .../jframe-pay-plugin/jframe-pay-task/pom.xml | 17 +- .../jframe-pay-plugin/jframe-pay-upmp/pom.xml | 125 ++++--- .../jframe/pay/upmp/domain/UpmpConfig.java | 9 +- .../pay/upmp/service/UpmppayServiceImpl.java | 56 ++- .../jframe-pay-plugin/jframe-pay-wx/pom.xml | 82 +++-- .../java/jframe/pay/wx/domain/WxConfig.java | 7 +- .../pay/wx/service/WxpayServiceImpl.java | 54 ++- jframe-pay/jframe-pay-plugin/pom.xml | 82 ++--- .../bin/jframe.sh | 0 .../filter.properties.example | 0 .../filter}/acp_sdk_dev.properties | 6 - .../filter}/acp_sdk_run.properties | 6 - .../filter}/activemq.properties | 8 +- .../filter/alipay.properties | 20 ++ .../filter}/config.properties | 76 ++-- .../filter}/d-activemq.properties | 0 .../filter}/datasource.properties | 0 .../filter}/http.properties | 3 - .../filter/httpclient.properties | 16 + .../filter}/jmxremote.access | 0 .../filter}/jmxremote.password | 0 .../filter/logback-daemon.xml | 45 +++ .../jframe-pay-release/filter/logback.xml | 39 +++ .../filter}/management.properties | 32 -- .../filter/memcached.properties | 20 ++ .../filter}/mybatis-config.xml | 0 .../filter/payclient.properties | 14 + .../jframe-pay-release/filter/task.properties | 15 + .../jframe-pay-release/filter/upmp.properties | 18 + .../conf => jframe-pay-release/filter}/vmargs | 0 .../filter}/vmargs-win | 0 .../filter/wxpay.properties | 20 ++ jframe-pay/jframe-pay-release/pom.xml | 116 ++++++ jframe-pay/pom.xml | 330 ++++++++++++------ .../release/jframe-pay/conf/alipay.properties | 24 -- .../jframe-pay/conf/httpclient.properties | 20 -- .../jframe-pay/conf/logback-daemon.xml | 45 --- .../release/jframe-pay/conf/logback.xml | 39 --- .../jframe-pay/conf/memcached.properties | 26 -- .../jframe-pay/conf/payclient.properties | 18 - .../release/jframe-pay/conf/task.properties | 19 - .../release/jframe-pay/conf/upmp.properties | 22 -- .../release/jframe-pay/conf/wxpay.properties | 27 -- jframe-pay/release/pom.xml | 121 ------- jframe-plugin/jframe-httpclient/pom.xml | 50 +-- 69 files changed, 1108 insertions(+), 1142 deletions(-) delete mode 100644 jframe-pay/jframe-pay-client/pom.xml rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/README.md (100%) create mode 100644 jframe-pay/jframe-pay-plugin/jframe-pay-client/pom.xml rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/src/main/java/jframe/pay/client/PayClientConf.java (100%) rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/src/main/java/jframe/pay/client/PayClientPlugin.java (100%) rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/src/main/java/jframe/pay/client/core/PayClient.java (100%) rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/src/main/java/jframe/pay/client/service/HttpPayClientService.java (89%) rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/src/main/java/jframe/pay/client/service/PayClientService.java (100%) rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/src/main/resources/META-INF/plugin.properties (100%) rename jframe-pay/{ => jframe-pay-plugin}/jframe-pay-client/src/test/resources/payclient.properties (100%) rename jframe-pay/{release/jframe-pay => jframe-pay-release}/bin/jframe.sh (100%) create mode 100644 jframe-pay/jframe-pay-release/filter.properties.example rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/acp_sdk_dev.properties (98%) rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/acp_sdk_run.properties (98%) rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/activemq.properties (55%) create mode 100644 jframe-pay/jframe-pay-release/filter/alipay.properties rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/config.properties (61%) rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/d-activemq.properties (100%) rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/datasource.properties (100%) rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/http.properties (94%) create mode 100755 jframe-pay/jframe-pay-release/filter/httpclient.properties rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/jmxremote.access (100%) rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/jmxremote.password (100%) create mode 100644 jframe-pay/jframe-pay-release/filter/logback-daemon.xml create mode 100644 jframe-pay/jframe-pay-release/filter/logback.xml rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/management.properties (99%) create mode 100755 jframe-pay/jframe-pay-release/filter/memcached.properties rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/mybatis-config.xml (100%) create mode 100755 jframe-pay/jframe-pay-release/filter/payclient.properties create mode 100755 jframe-pay/jframe-pay-release/filter/task.properties create mode 100644 jframe-pay/jframe-pay-release/filter/upmp.properties rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/vmargs (100%) rename jframe-pay/{release/jframe-pay/conf => jframe-pay-release/filter}/vmargs-win (100%) create mode 100644 jframe-pay/jframe-pay-release/filter/wxpay.properties create mode 100644 jframe-pay/jframe-pay-release/pom.xml delete mode 100644 jframe-pay/release/jframe-pay/conf/alipay.properties delete mode 100755 jframe-pay/release/jframe-pay/conf/httpclient.properties delete mode 100644 jframe-pay/release/jframe-pay/conf/logback-daemon.xml delete mode 100644 jframe-pay/release/jframe-pay/conf/logback.xml delete mode 100755 jframe-pay/release/jframe-pay/conf/memcached.properties delete mode 100755 jframe-pay/release/jframe-pay/conf/payclient.properties delete mode 100755 jframe-pay/release/jframe-pay/conf/task.properties delete mode 100644 jframe-pay/release/jframe-pay/conf/upmp.properties delete mode 100644 jframe-pay/release/jframe-pay/conf/wxpay.properties delete mode 100644 jframe-pay/release/pom.xml diff --git a/.gitignore b/.gitignore index 5a611c9..a7f7328 100644 --- a/.gitignore +++ b/.gitignore @@ -20,18 +20,10 @@ jframe-plugin/release/lib/ jframe-plugin/release/plugin/ -jframe-pay/release/jframe-pay/lib/ -jframe-pay/release/jframe-pay/plugin/ -jframe-pay/release/jframe-pay/temp/ -jframe-pay/release/jframe-pay/log/ -jframe-pay/release/jframe-pay/conf/cache/ - - -jframe-demo/demo-release/lib/ -jframe-demo/demo-release/plugin/ -jframe-demo/demo-release/temp/ -jframe-demo/demo-release/log/ -jframe-demo/demo-release/conf/cache/ +jframe-pay/jframe-pay-release/tmp/ +jframe-pay/jframe-pay-release/log/ +jframe-pay/jframe-pay-release/conf/ +jframe-pay/jframe-pay-release/filter.properties # idea *.iml diff --git a/jframe-pay/README.md b/jframe-pay/README.md index e69de29..a0d9574 100644 --- a/jframe-pay/README.md +++ b/jframe-pay/README.md @@ -0,0 +1,10 @@ +jframe pay +=================================== +通用的支付网关 + + +## 工程源码 + + +## 使用说明 + diff --git a/jframe-pay/jframe-pay-client/pom.xml b/jframe-pay/jframe-pay-client/pom.xml deleted file mode 100644 index 3356176..0000000 --- a/jframe-pay/jframe-pay-client/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ - - 4.0.0 - - cn - jframe-pay - 1.0.0 - - jframe-pay-client - - - - - maven-jar-plugin - 2.4 - - plugin - - - - - - - - cn - jframe-httpclient - 1.0.0 - plugin - - - cn - jframe-pay-domain - 1.0.0 - - - \ No newline at end of file diff --git a/jframe-pay/jframe-pay-lib/jframe-pay-domain/pom.xml b/jframe-pay/jframe-pay-lib/jframe-pay-domain/pom.xml index 292fda0..d701b96 100644 --- a/jframe-pay/jframe-pay-lib/jframe-pay-domain/pom.xml +++ b/jframe-pay/jframe-pay-lib/jframe-pay-domain/pom.xml @@ -1,45 +1,52 @@ - 4.0.0 - - cn - jframe-pay-lib - 1.0.0 - - jframe-pay-domain + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay-lib + 2.0.0-SNAPSHOT + + jframe-pay-domain - - - com.alibaba - fastjson - 1.2.6 - - - com.jayway.jsonpath - json-path - 2.0.0 - - - net.minidev - asm - - - - - com.google.code.gson - gson - 2.3 - - - org.mybatis - mybatis - 3.3.0 - - - org.mongodb - mongo-java-driver - 3.0.2 - + + + com.alibaba + fastjson + + + com.jayway.jsonpath + json-path + 2.0.0 + + + net.minidev + asm + + + + + com.google.code.gson + gson + + + org.mybatis + mybatis + 3.3.0 + + + org.mongodb + mongo-java-driver + 3.0.2 + - + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpcore + + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/dao/mapper/Environment.java b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/dao/mapper/Environment.java index 0d63acc..9341a5e 100644 --- a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/dao/mapper/Environment.java +++ b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/dao/mapper/Environment.java @@ -1,21 +1,21 @@ /** - * + * */ package jframe.pay.domain.dao.mapper; /** * enviroment id - * + * * @author dzh * @date Jul 20, 2015 11:59:10 AM * @since 1.0 */ public interface Environment { - String RUN = "run"; + String RUN = "run"; - String RUN_RO1 = "run_ro1"; + String RUN_RO1 = "run_ro1"; - String DEV = "dev"; + String DEV = "dev"; } diff --git a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/HttpUtil.java b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/HttpUtil.java index 91b5157..a89315b 100644 --- a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/HttpUtil.java +++ b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/HttpUtil.java @@ -1,22 +1,17 @@ /** - * + * */ package jframe.pay.domain.util; -import static java.util.stream.Collectors.toList; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; +import java.io.UnsupportedEncodingException; +import java.util.*; + +import static java.util.stream.Collectors.toList; + /** * @author dzh * @date Jul 13, 2015 5:44:13 PM @@ -27,7 +22,7 @@ public class HttpUtil { /** * If req not contains all mustParas , then return emptyList contains empty * parameter - * + * * @param req * req parameters * @param mustParas @@ -70,7 +65,7 @@ public final static String format(Map paras, String charset) { /** * 目前只支持单值情况, 不支持多值和编码 - * + * * @param content * @return * @throws UnsupportedEncodingException diff --git a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/IDUtil.java b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/IDUtil.java index 33ed45d..ac8c3ee 100644 --- a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/IDUtil.java +++ b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/IDUtil.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.pay.domain.util; @@ -27,7 +27,7 @@ public class IDUtil { /** * 生成短信验证码 4位数字 - * + * * @return */ public static String genVCode() { @@ -220,7 +220,7 @@ public static String genSysTaskId() { /** * 线路ID - * + * * @return */ public static String genPathId() { @@ -289,7 +289,7 @@ public static String genMsgGroupId() { /** * 消息头的key - * + * * @return */ public static String genSignKey() { @@ -298,15 +298,15 @@ public static String genSignKey() { int category = new Random().nextInt() % 3; char ch = '0'; switch (category) { - case 0: - ch = (char) ((new Random().nextInt(10) % 10 + 48) & 0xffff); - break; - case 1: - ch = (char) ((new Random().nextInt(26) % 26 + 65) & 0xffff); - break; - case 2: - ch = (char) ((new Random().nextInt(26) % 26 + 97) & 0xffff); - break; + case 0: + ch = (char) ((new Random().nextInt(10) % 10 + 48) & 0xffff); + break; + case 1: + ch = (char) ((new Random().nextInt(26) % 26 + 65) & 0xffff); + break; + case 2: + ch = (char) ((new Random().nextInt(26) % 26 + 97) & 0xffff); + break; } buf.append(ch); } @@ -315,7 +315,7 @@ public static String genSignKey() { /** * 生成邀请码 - * + * * @return */ public static String genInviteCode() { diff --git a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/ToString.java b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/ToString.java index 3476944..b75b076 100755 --- a/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/ToString.java +++ b/jframe-pay/jframe-pay-lib/jframe-pay-domain/src/main/java/jframe/pay/domain/util/ToString.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.pay.domain.util; @@ -10,19 +10,20 @@ * @date Aug 15, 2014 5:26:56 PM * @since 1.0 */ +@Deprecated public class ToString { - public static final String toString(Map map) { - if (map == null || map.isEmpty()) - return ""; - StringBuilder buf = new StringBuilder(); - buf.append("\nbegin\n"); - for (Object o : map.keySet()) { - buf.append(String.valueOf(o) + "->" + String.valueOf(map.get(o)) - + ","); - } - buf.append("\nend\n"); - return buf.toString(); - } + public static final String toString(Map map) { + if (map == null || map.isEmpty()) + return ""; + StringBuilder buf = new StringBuilder(); + buf.append("\nbegin\n"); + for (Object o : map.keySet()) { + buf.append(String.valueOf(o) + "->" + String.valueOf(map.get(o)) + + ","); + } + buf.append("\nend\n"); + return buf.toString(); + } } diff --git a/jframe-pay/jframe-pay-lib/pom.xml b/jframe-pay/jframe-pay-lib/pom.xml index 00b745e..55302c8 100644 --- a/jframe-pay/jframe-pay-lib/pom.xml +++ b/jframe-pay/jframe-pay-lib/pom.xml @@ -1,17 +1,17 @@ - 4.0.0 - - cn - jframe-pay - 1.0.0 - - jframe-pay-lib - pom - - jframe-pay-domain - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay + 2.0.0-SNAPSHOT + + jframe-pay-lib + pom - - + + jframe-pay-domain + + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/pom.xml b/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/pom.xml index 5db93eb..34cdc86 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/pom.xml +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/pom.xml @@ -1,50 +1,36 @@ - 4.0.0 - - cn - jframe-pay-plugin - 1.0.0 - - jframe-pay-alipay + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay-plugin + 2.0.0-SNAPSHOT + + jframe-pay-alipay - - - commons-codec - commons-codec - 1.10 - - - org.apache.httpcomponents - httpcore - 4.4.1 - - - org.apache.httpcomponents - httpclient - 4.5 - - - dom4j - dom4j - 1.6.1 - - - jaxen - jaxen - 1.1.6 - - - cn - jframe-pay-dao - 1.0.0 - plugin - - - cn - jframe-httpclient - 1.0.0 - plugin - - + + + commons-codec + commons-codec + + + org.dom4j + dom4j + + + jaxen + jaxen + + + + io.github.dzh + jframe-pay-dao + plugin + + + io.github.dzh + jframe-httpclient + plugin + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/AlipayConfig.java b/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/AlipayConfig.java index 92f92cd..3a3e4f0 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/AlipayConfig.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/AlipayConfig.java @@ -1,11 +1,9 @@ package jframe.pay.alipay; -import jframe.ext.util.PropertiesConfig; - import com.alipay.sdk.pay.demo.SignUtils; +import jframe.core.util.PropsConf; /** - * * @author dzh * @date Nov 27, 2014 4:49:43 PM * @since 1.0 @@ -32,7 +30,7 @@ public class AlipayConfig { public static final String SIGN_TYPE_QUERY = "sign.type.query"; public static final String SERVICE = "service"; - private static PropertiesConfig config = new PropertiesConfig(); + private static PropsConf config = new PropsConf(); public static void init(String file) throws Exception { config.init(file); diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/service/AlipayServiceImpl.java b/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/service/AlipayServiceImpl.java index 1e8979f..2f27360 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/service/AlipayServiceImpl.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-alipay/src/main/java/jframe/pay/alipay/service/AlipayServiceImpl.java @@ -1,24 +1,10 @@ /** - * + * */ package jframe.pay.alipay.service; -import java.net.URL; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alipay.util.OrderUtil; - -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.InjectService; -import jframe.core.plugin.annotation.Injector; -import jframe.core.plugin.annotation.Start; -import jframe.core.plugin.annotation.Stop; +import jframe.core.plugin.annotation.*; import jframe.httpclient.service.HttpClientService; import jframe.pay.alipay.AlipayConfig; import jframe.pay.alipay.AlipayPlugin; @@ -33,6 +19,14 @@ import jframe.pay.domain.util.HttpUtil; import jframe.pay.domain.util.IDUtil; import jframe.pay.domain.util.ObjectUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URL; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; /** * @author dzh @@ -291,7 +285,7 @@ private void doSuccess(Map req, Map rsp) throws /** * TODO - * + * * @param usrid * @param accountid * @return @@ -333,7 +327,7 @@ public boolean accountExist(String usrid, String accountid) { } public void postBack(OrderAlipay order) { - Map map = new HashMap(); + Map map = new HashMap<>(); map.put(F_payNo, order.payNo); map.put(F_payStatus, order.payStatus); @@ -342,39 +336,37 @@ public void postBack(OrderAlipay order) { URL url = new URL(order.backUrl); int port = url.getPort() == -1 ? 80 : url.getPort(); - if (LOG.isDebugEnabled()) - LOG.debug("postBack start time->{},req->{}", new Date(), map); + LOG.info("postBack -> {},{},{}", url, new Date(), map); Long backtime = System.currentTimeMillis(); Map paras = new HashMap<>(HTTP_PARAS); paras.put("ip", url.getHost()); paras.put("port", String.valueOf(port)); - Map rsp = HttpClient.> send("payback", url.getPath(), + String rsp = HttpClient.send("payback", url.getPath(), HttpUtil.format(map, "utf-8"), null, paras); - if (LOG.isDebugEnabled()) - LOG.debug("postback orderNo={}, postBack->{}, use time->{}, rsp->{}", order.orderNo, url.getPath(), - (System.currentTimeMillis() - backtime), rsp); - if (RspCode.SUCCESS.code.equals(rsp.get(F_rspCode))) { - succ = true; - } else { - LOG.error("payNo=" + order.payNo + "rsp=" + rsp); - } + LOG.info("postback orderNo={}, postBack->{}, use time->{}, rsp->{}", order.orderNo, url.getPath(), + (System.currentTimeMillis() - backtime), rsp); + +// if (RspCode.SUCCESS.code.equals(rsp.get(F_rspCode))) { +// succ = true; +// } else { +// LOG.error("payNo=" + order.payNo + "rsp=" + rsp); +// } } catch (Exception e) { - succ = false; - LOG.error(e.getMessage()); + LOG.error(e.getMessage(), e); } - if (!succ) { - // TODO - // map.put(UsrFields.F_backUrl, order.getBackUrl()); - // Task t = createTask(TaskType.PAY_BACK.type, - // TaskType.PAY_BACK.desc, - // JsonUtil.encode(map), new Date().getTime()); - // try { - // AlipayDao.insertTask_Order(conn, t); - // } catch (Exception e1) { - // LOG.error(e1.getMessage()); - // } - } +// if (!succ) { + // TODO + // map.put(UsrFields.F_backUrl, order.getBackUrl()); + // Task t = createTask(TaskType.PAY_BACK.type, + // TaskType.PAY_BACK.desc, + // JsonUtil.encode(map), new Date().getTime()); + // try { + // AlipayDao.insertTask_Order(conn, t); + // } catch (Exception e1) { + // LOG.error(e1.getMessage()); + // } +// } } diff --git a/jframe-pay/jframe-pay-client/README.md b/jframe-pay/jframe-pay-plugin/jframe-pay-client/README.md similarity index 100% rename from jframe-pay/jframe-pay-client/README.md rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/README.md diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-client/pom.xml b/jframe-pay/jframe-pay-plugin/jframe-pay-client/pom.xml new file mode 100644 index 0000000..da34816 --- /dev/null +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-client/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + + io.github.dzh + jframe-pay + 2.0.0-SNAPSHOT + + jframe-pay-client + + + + + maven-jar-plugin + + plugin + + + + + + + + io.github.dzh + jframe-httpclient + plugin + + + io.github.dzh + jframe-pay-domain + + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/PayClientConf.java b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/PayClientConf.java similarity index 100% rename from jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/PayClientConf.java rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/PayClientConf.java diff --git a/jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/PayClientPlugin.java b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/PayClientPlugin.java similarity index 100% rename from jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/PayClientPlugin.java rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/PayClientPlugin.java diff --git a/jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/core/PayClient.java b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/core/PayClient.java similarity index 100% rename from jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/core/PayClient.java rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/core/PayClient.java diff --git a/jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/service/HttpPayClientService.java b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/service/HttpPayClientService.java similarity index 89% rename from jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/service/HttpPayClientService.java rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/service/HttpPayClientService.java index a03b1f3..a30fffe 100644 --- a/jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/service/HttpPayClientService.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/service/HttpPayClientService.java @@ -1,15 +1,8 @@ /** - * + * */ package jframe.pay.client.service; -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import jframe.core.plugin.annotation.InjectPlugin; import jframe.core.plugin.annotation.InjectService; import jframe.core.plugin.annotation.Injector; @@ -21,6 +14,13 @@ import jframe.pay.domain.TransType; import jframe.pay.domain.http.ReqOp; import jframe.pay.domain.util.HttpUtil; +import jframe.pay.domain.util.JsonUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; /** * @author dzh @@ -98,15 +98,17 @@ public Map pay(Map req) throws Exception { // TODO check - return HttpClient.send(HttpClient_ID, Prefix_ord + req.get(F_reqOp), HttpUtil.format(req, "utf-8"), null, + String result = HttpClient.send(HttpClient_ID, Prefix_ord + req.get(F_reqOp), HttpUtil.format(req, "utf-8"), null, HTTP_PARAS); + return JsonUtil.decode(result); } @Override public Map usr(Map req) throws Exception { // TODO check - return HttpClient.send(HttpClient_ID, Prefix_usr + req.get(F_reqOp), HttpUtil.format(req, "utf-8"), null, + String result = HttpClient.send(HttpClient_ID, Prefix_usr + req.get(F_reqOp), HttpUtil.format(req, "utf-8"), null, HTTP_PARAS); + return JsonUtil.decode(result); } } diff --git a/jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/service/PayClientService.java b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/service/PayClientService.java similarity index 100% rename from jframe-pay/jframe-pay-client/src/main/java/jframe/pay/client/service/PayClientService.java rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/java/jframe/pay/client/service/PayClientService.java diff --git a/jframe-pay/jframe-pay-client/src/main/resources/META-INF/plugin.properties b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/resources/META-INF/plugin.properties similarity index 100% rename from jframe-pay/jframe-pay-client/src/main/resources/META-INF/plugin.properties rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/src/main/resources/META-INF/plugin.properties diff --git a/jframe-pay/jframe-pay-client/src/test/resources/payclient.properties b/jframe-pay/jframe-pay-plugin/jframe-pay-client/src/test/resources/payclient.properties similarity index 100% rename from jframe-pay/jframe-pay-client/src/test/resources/payclient.properties rename to jframe-pay/jframe-pay-plugin/jframe-pay-client/src/test/resources/payclient.properties diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-dao/pom.xml b/jframe-pay/jframe-pay-plugin/jframe-pay-dao/pom.xml index a99846d..85247c3 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-dao/pom.xml +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-dao/pom.xml @@ -1,25 +1,23 @@ - 4.0.0 - - cn - jframe-pay-plugin - 1.0.0 - - jframe-pay-dao + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay-plugin + 2.0.0-SNAPSHOT + + jframe-pay-dao - - - cn - jframe-memcached-client - 1.0.0 - plugin - - - cn - jframe-mybatis - 1.0.0 - plugin - - + + + io.github.dzh + jframe-memcached-client + plugin + + + io.github.dzh + jframe-mybatis + plugin + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-http/pom.xml b/jframe-pay/jframe-pay-plugin/jframe-pay-http/pom.xml index a5c5f21..1195825 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-http/pom.xml +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-http/pom.xml @@ -1,48 +1,44 @@ - 4.0.0 - - cn - jframe-pay-plugin - 1.0.0 - - jframe-pay-http + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay-plugin + 2.0.0-SNAPSHOT + + jframe-pay-http - - - io.netty - netty-all - 4.0.26.Final - - - dom4j - dom4j - 1.6.1 - + + + io.netty + netty-all + 4.0.26.Final + + + dom4j + dom4j + 1.6.1 + - - cn - jframe-pay-alipay - 1.0.0 - plugin - - - cn - jframe-pay-dao - 1.0.0 - plugin - - - cn - jframe-pay-wx - 1.0.0 - plugin - - - cn - jframe-pay-upmp - 1.0.0 - plugin - - + + io.github.dzh + jframe-pay-alipay + plugin + + + io.github.dzh + jframe-pay-dao + plugin + + + io.github.dzh + jframe-pay-wx + plugin + + + io.github.dzh + jframe-pay-upmp + plugin + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-http/src/main/java/jframe/pay/http/handler/PayHandler.java b/jframe-pay/jframe-pay-plugin/jframe-pay-http/src/main/java/jframe/pay/http/handler/PayHandler.java index 652e3d6..68660dd 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-http/src/main/java/jframe/pay/http/handler/PayHandler.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-http/src/main/java/jframe/pay/http/handler/PayHandler.java @@ -1,16 +1,15 @@ /** - * + * */ package jframe.pay.http.handler; -import java.util.Map; - import jframe.pay.domain.Fields; import jframe.pay.domain.http.RspCode; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; + /** * @author dzh * @date Jul 29, 2015 2:09:06 PM @@ -42,10 +41,8 @@ public void service(Map req, Map rsp) throws Pay rsp.put(Fields.F_error, e.getMessage()); } } - if (LOG.isDebugEnabled()) { - LOG.debug("remoteIp->{} reqOp->{} invokeTime->{}ms req->{} rsp->{}", getRemoteIp(), getReqOp(), - System.currentTimeMillis() - start, req, rsp); - } + LOG.info("remoteIp->{} reqOp->{} invokeTime->{}ms req->{} rsp->{}", getRemoteIp(), getReqOp(), + System.currentTimeMillis() - start, req, rsp); } protected abstract void doService(Map req, Map rsp) throws Exception; diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-task/pom.xml b/jframe-pay/jframe-pay-plugin/jframe-pay-task/pom.xml index 2832f38..7af129f 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-task/pom.xml +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-task/pom.xml @@ -1,9 +1,10 @@ - - 4.0.0 - - cn - jframe-pay-plugin - 1.0.0 - - jframe-pay-task + + 4.0.0 + + io.github.dzh + jframe-pay-plugin + 2.0.0-SNAPSHOT + + jframe-pay-task \ No newline at end of file diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/pom.xml b/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/pom.xml index d0ebf6f..319b805 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/pom.xml +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/pom.xml @@ -1,68 +1,65 @@ - 4.0.0 - - cn - jframe-pay-plugin - 1.0.0 - - jframe-pay-upmp + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay-plugin + 2.0.0-SNAPSHOT + + jframe-pay-upmp - - - com.alibaba - fastjson - 1.1.41 - - - cn - jframe-pay-dao - 1.0.0 - plugin - - - cn - jframe-httpclient - 1.0.0 - plugin - + + + com.alibaba + fastjson + - - com - upacp_sdk - 1.0.0 - system - ${project.basedir}/compile/upacp_sdk-1.0.0-20150703140550.jar - - - org.bouncycastle - bcprov-jdk16 - 1.46 - - - commons-codec - commons-codec - 1.10 - - - commons-io - commons-io - 2.4 - - - commons-lang - commons-lang - 2.6 - - - log4j - log4j - 1.2.17 - - - org.slf4j - slf4j-log4j12 - 1.7.13 - - + + com + upacp_sdk + 1.0.0 + system + ${project.basedir}/compile/upacp_sdk-1.0.0-20150703140550.jar + + + org.bouncycastle + bcprov-jdk16 + 1.46 + + + commons-codec + commons-codec + + + commons-io + commons-io + 2.4 + + + commons-lang + commons-lang + 2.6 + + + log4j + log4j + 1.2.17 + + + org.slf4j + slf4j-log4j12 + 1.7.13 + + + + io.github.dzh + jframe-pay-dao + plugin + + + io.github.dzh + jframe-httpclient + plugin + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/domain/UpmpConfig.java b/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/domain/UpmpConfig.java index 2323417..512b733 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/domain/UpmpConfig.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/domain/UpmpConfig.java @@ -1,17 +1,16 @@ /** - * + * */ package jframe.pay.upmp.domain; +import jframe.core.util.PropsConf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jframe.ext.util.PropertiesConfig; - /** *

*

- * + * * @author dzh * @date Nov 25, 2015 3:05:10 PM * @since 1.0 @@ -37,7 +36,7 @@ public class UpmpConfig { static final Logger LOG = LoggerFactory.getLogger(UpmpConfig.class); - public static PropertiesConfig config = new PropertiesConfig(); + public static PropsConf config = new PropsConf(); public static void init(String file) throws Exception { config.init(file); diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/service/UpmppayServiceImpl.java b/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/service/UpmppayServiceImpl.java index f2c3ab6..ce09746 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/service/UpmppayServiceImpl.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-upmp/src/main/java/jframe/pay/upmp/service/UpmppayServiceImpl.java @@ -1,27 +1,12 @@ /** - * + * */ package jframe.pay.upmp.service; -import java.net.URL; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.unionpay.acp.sdk.SDKConfig; - import jframe.core.conf.VarHandler; -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.InjectService; -import jframe.core.plugin.annotation.Injector; -import jframe.core.plugin.annotation.Start; -import jframe.core.plugin.annotation.Stop; -import jframe.ext.util.PropertiesConfig; +import jframe.core.plugin.annotation.*; +import jframe.core.util.PropsConf; import jframe.httpclient.service.HttpClientService; import jframe.memcached.client.MemcachedService; import jframe.pay.dao.service.PayDaoService; @@ -37,6 +22,15 @@ import jframe.pay.upmp.domain.UpmpConfig; import jframe.pay.upmp.domain.UpmpFields; import jframe.pay.upmp.req.ConsumeReq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URL; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; /** * @author dzh @@ -74,7 +68,7 @@ void start() { VarHandler vh = new VarHandler(Plugin.getContext().getConfig()); UpmpConfig.config.replace(vh); - PropertiesConfig acpSDK = new PropertiesConfig(); + PropsConf acpSDK = new PropsConf(); acpSDK.init(UpmpConfig.getConf(UpmpConfig.KEY_ACP_SDK)); acpSDK.replace(vh); SDKConfig.getConfig().loadProperties(acpSDK.clone2Properties()); @@ -102,7 +96,7 @@ public void pay(Map req, Map rsp) throws Excepti return; } - rsp.put(F_filter, JsonUtil.createPropertyFilter(new String[] { F_rspCode, F_rspDesc, F_tn })); + rsp.put(F_filter, JsonUtil.createPropertyFilter(new String[]{F_rspCode, F_rspDesc, F_tn})); if (ConsumeReq.consume(req, rsp)) { OrderUpmp od = PayDao.selectOrderUpmp(req.get(F_payNo)); @@ -226,24 +220,22 @@ public void postBack(OrderUpmp od) { URL url = new URL(od.backUrl); int port = url.getPort() == -1 ? 80 : url.getPort(); - if (LOG.isDebugEnabled()) - LOG.debug("postBack -> {}, {},{}", url.toString(), new Date(), map); - Long packtime = System.currentTimeMillis(); + LOG.info("postBack -> {},{},{}", url, new Date(), map); + Long backtime = System.currentTimeMillis(); Map paras = new HashMap<>(HTTP_PARAS); paras.put("ip", url.getHost()); paras.put("port", String.valueOf(port)); - Map rsp = HttpClient.> send("payback", url.getPath(), + String rsp = HttpClient.send("payback", url.getPath(), HttpUtil.format(map, "utf-8"), null, paras); Long packTime = System.currentTimeMillis(); - if (LOG.isDebugEnabled()) - LOG.debug("orderNo=" + od.orderNo + " postBack" + new Date() + " use time=" + (packTime - packtime) - + " rsp=" + rsp); - if (RspCode.SUCCESS.code.equals(rsp.get(F_rspCode))) { - succ = true; - } else { - LOG.error("payNo=" + od.payNo + "rsp=" + rsp); - } + LOG.info("postback orderNo={}, postBack->{}, use time->{}, rsp->{}", od.orderNo, url.getPath(), + (System.currentTimeMillis() - backtime), rsp); +// if (RspCode.SUCCESS.code.equals(rsp.get(F_rspCode))) { +// succ = true; +// } else { +// LOG.error("payNo=" + od.payNo + "rsp=" + rsp); +// } } catch (Exception e) { succ = false; LOG.error(e.getMessage()); diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-wx/pom.xml b/jframe-pay/jframe-pay-plugin/jframe-pay-wx/pom.xml index 0f45575..fb189db 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-wx/pom.xml +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-wx/pom.xml @@ -1,45 +1,43 @@ - 4.0.0 - - cn - jframe-pay-plugin - 1.0.0 - - jframe-pay-wx + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay-plugin + 2.0.0-SNAPSHOT + + jframe-pay-wx - - - commons-dbutils - commons-dbutils - 1.6 - - - org.jdom - jdom - 2.0.2 - - - org.json - json - 20140107 - - - com.alibaba - fastjson - 1.1.41 - - - cn - jframe-pay-dao - 1.0.0 - plugin - - - cn - jframe-httpclient - 1.0.0 - plugin - - + + + commons-dbutils + commons-dbutils + 1.6 + + + org.jdom + jdom + 2.0.2 + + + org.json + json + 20140107 + + + com.alibaba + fastjson + + + + io.github.dzh + jframe-pay-dao + plugin + + + io.github.dzh + jframe-httpclient + plugin + + \ No newline at end of file diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/domain/WxConfig.java b/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/domain/WxConfig.java index 64dd8c6..3ab6677 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/domain/WxConfig.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/domain/WxConfig.java @@ -1,13 +1,12 @@ /** - * + * */ package jframe.pay.wx.domain; +import jframe.core.util.PropsConf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jframe.ext.util.PropertiesConfig; - /** * @author dzh * @date Sep 25, 2014 1:49:56 PM @@ -39,7 +38,7 @@ public class WxConfig { static Logger LOG = LoggerFactory.getLogger(WxConfig.class); - public static PropertiesConfig config = new PropertiesConfig(); + public static PropsConf config = new PropsConf(); public static void init(String file) throws Exception { config.init(file); diff --git a/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/service/WxpayServiceImpl.java b/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/service/WxpayServiceImpl.java index 5074c6c..7c209c8 100644 --- a/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/service/WxpayServiceImpl.java +++ b/jframe-pay/jframe-pay-plugin/jframe-pay-wx/src/main/java/jframe/pay/wx/service/WxpayServiceImpl.java @@ -1,20 +1,6 @@ package jframe.pay.wx.service; -import java.net.URL; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.InjectService; -import jframe.core.plugin.annotation.Injector; -import jframe.core.plugin.annotation.Start; -import jframe.core.plugin.annotation.Stop; +import jframe.core.plugin.annotation.*; import jframe.httpclient.service.HttpClientService; import jframe.memcached.client.MemcachedService; import jframe.pay.dao.service.PayDaoService; @@ -30,6 +16,15 @@ import jframe.pay.wx.domain.WxConfig; import jframe.pay.wx.domain.WxFields; import jframe.pay.wx.http.client.WxServiceNew; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URL; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; @Injector public class WxpayServiceImpl implements WxpayService, WxFields { @@ -178,7 +173,7 @@ public void payBack(Map req, Map rsp) throws Exc /** * TODO BitSet - * + * * @param req * @return */ @@ -324,10 +319,8 @@ public void wxPayBack(Map req, Map rsp) throws E /** * 通知租车后台 - * - * @param conn + * * @param od - * @param orderStatus */ public void postBack(OrderWx od) { Map map = new HashMap(2, 1); @@ -339,26 +332,23 @@ public void postBack(OrderWx od) { URL url = new URL(od.backUrl); int port = url.getPort() == -1 ? 80 : url.getPort(); - if (LOG.isDebugEnabled()) - LOG.debug("postBack -> {}, {},{}", url.toString(), new Date(), map); - Long packtime = System.currentTimeMillis(); + LOG.info("postBack -> {},{},{}", url, new Date(), map); + Long backtime = System.currentTimeMillis(); Map paras = new HashMap<>(HTTP_PARAS); paras.put("ip", url.getHost()); paras.put("port", String.valueOf(port)); - Map rsp = HttpClient.> send("payback", url.getPath(), + String rsp = HttpClient.send("payback", url.getPath(), HttpUtil.format(map, "utf-8"), null, paras); Long packTime = System.currentTimeMillis(); - if (LOG.isDebugEnabled()) - LOG.debug("orderNo=" + od.orderNo + " postBack" + new Date() + " use time=" + (packTime - packtime) - + " rsp=" + rsp); - if (RspCode.SUCCESS.code.equals(rsp.get(F_rspCode))) { - succ = true; - } else { - LOG.error("payNo=" + od.payNo + "rsp=" + rsp); - } + LOG.info("postback orderNo={}, postBack->{}, use time->{}, rsp->{}", od.orderNo, url.getPath(), + (System.currentTimeMillis() - backtime), rsp); +// if (RspCode.SUCCESS.code.equals(rsp.get(F_rspCode))) { +// succ = true; +// } else { +// LOG.error("payNo=" + od.payNo + "rsp=" + rsp); +// } } catch (Exception e) { - succ = false; LOG.error(e.getMessage()); } diff --git a/jframe-pay/jframe-pay-plugin/pom.xml b/jframe-pay/jframe-pay-plugin/pom.xml index 0eabf0d..81bce4c 100644 --- a/jframe-pay/jframe-pay-plugin/pom.xml +++ b/jframe-pay/jframe-pay-plugin/pom.xml @@ -1,45 +1,45 @@ - 4.0.0 - - cn - jframe-pay - 1.0.0 - - jframe-pay-plugin - pom - - jframe-pay-alipay - jframe-pay-wx - jframe-pay-http - jframe-pay-dao - jframe-pay-task - jframe-pay-upmp - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-pay + 2.0.0-SNAPSHOT + + jframe-pay-plugin + pom + + jframe-pay-alipay + jframe-pay-wx + jframe-pay-http + jframe-pay-dao + jframe-pay-task + jframe-pay-upmp + jframe-pay-client + - - - - maven-jar-plugin - 2.4 - - plugin - - - - + + + + org.apache.maven.plugins + maven-jar-plugin + + plugin + + + + - - - jframe-pay-domain - cn - 1.0.0 - - - cn - jframe-memcached-client - 1.0.0 - plugin - - + + + io.github.dzh + jframe-pay-domain + + + + io.github.dzh + jframe-memcached-client + plugin + + \ No newline at end of file diff --git a/jframe-pay/release/jframe-pay/bin/jframe.sh b/jframe-pay/jframe-pay-release/bin/jframe.sh similarity index 100% rename from jframe-pay/release/jframe-pay/bin/jframe.sh rename to jframe-pay/jframe-pay-release/bin/jframe.sh diff --git a/jframe-pay/jframe-pay-release/filter.properties.example b/jframe-pay/jframe-pay-release/filter.properties.example new file mode 100644 index 0000000..e69de29 diff --git a/jframe-pay/release/jframe-pay/conf/acp_sdk_dev.properties b/jframe-pay/jframe-pay-release/filter/acp_sdk_dev.properties similarity index 98% rename from jframe-pay/release/jframe-pay/conf/acp_sdk_dev.properties rename to jframe-pay/jframe-pay-release/filter/acp_sdk_dev.properties index aac64e1..090f453 100644 --- a/jframe-pay/release/jframe-pay/conf/acp_sdk_dev.properties +++ b/jframe-pay/jframe-pay-release/filter/acp_sdk_dev.properties @@ -1,5 +1,4 @@ ###### SDK \u914d\u7f6e\u6587\u4ef6 \u914d\u7f6e\u6587\u4ef6\u4e2d\u65e5\u5fd7\u548c\u8bc1\u4e66\u7684\u5b58\u653e\u8def\u5f84\u6839\u636e\u5b9e\u9645\u60c5\u51b5\u914d\u7f6e\uff0c\u4ea4\u6613\u5730\u5740\u548c\u8bc1\u4e66\u6839\u636ePM\u73af\u5883\u3001\u751f\u4ea7\u73af\u5883\u914d\u5957\u914d\u7f6e##### - ##########################\u4ea4\u6613\u53d1\u9001\u5730\u5740\u914d\u7f6e############################# ######(\u4ee5\u4e0b\u914d\u7f6e\u4e3aPM\u73af\u5883\uff1a\u5165\u7f51\u6d4b\u8bd5\u73af\u5883\u7528\uff0c\u751f\u4ea7\u73af\u5883\u914d\u7f6e\u89c1\u6587\u6863\u8bf4\u660e)####### ##\u524d\u53f0\u4ea4\u6613\u8bf7\u6c42\u5730\u5740 @@ -16,9 +15,6 @@ acpsdk.batchTransUrl=https://101.231.204.80:5000/gateway/api/batchTransReq.do acpsdk.fileTransUrl=https://101.231.204.80:9080/ ## app \u4EA4\u6613\u8BF7\u6C42\u5730\u5740 acpsdk.appTransUrl=https://101.231.204.80:5000/gateway/api/appTransReq.do - - - #########################\u7b7e\u540d\u8bc1\u4e66\u914d\u7f6e ################################ ######(\u4ee5\u4e0b\u914d\u7f6e\u4e3aPM\u73af\u5883\uff1a\u5165\u7f51\u6d4b\u8bd5\u73af\u5883\u7528\uff0c\u751f\u4ea7\u73af\u5883\u914d\u7f6e\u89c1\u6587\u6863\u8bf4\u660e)####### ##\u7b7e\u540d\u8bc1\u4e66\u8def\u5f84 @@ -27,8 +23,6 @@ acpsdk.signCert.path=D:\\certs\\PM_700000000000001_acp.pfx acpsdk.signCert.pwd=000000 ##\u7b7e\u540d\u8bc1\u4e66\u7c7b\u578b acpsdk.signCert.type=PKCS12 - - ##########################\u9a8c\u7b7e\u8bc1\u4e66\u914d\u7f6e################################ ##\u9a8c\u8bc1\u7b7e\u540d\u8bc1\u4e66\u76ee\u5f55 acpsdk.validateCert.dir=D:\\certs\\ diff --git a/jframe-pay/release/jframe-pay/conf/acp_sdk_run.properties b/jframe-pay/jframe-pay-release/filter/acp_sdk_run.properties similarity index 98% rename from jframe-pay/release/jframe-pay/conf/acp_sdk_run.properties rename to jframe-pay/jframe-pay-release/filter/acp_sdk_run.properties index aac64e1..090f453 100644 --- a/jframe-pay/release/jframe-pay/conf/acp_sdk_run.properties +++ b/jframe-pay/jframe-pay-release/filter/acp_sdk_run.properties @@ -1,5 +1,4 @@ ###### SDK \u914d\u7f6e\u6587\u4ef6 \u914d\u7f6e\u6587\u4ef6\u4e2d\u65e5\u5fd7\u548c\u8bc1\u4e66\u7684\u5b58\u653e\u8def\u5f84\u6839\u636e\u5b9e\u9645\u60c5\u51b5\u914d\u7f6e\uff0c\u4ea4\u6613\u5730\u5740\u548c\u8bc1\u4e66\u6839\u636ePM\u73af\u5883\u3001\u751f\u4ea7\u73af\u5883\u914d\u5957\u914d\u7f6e##### - ##########################\u4ea4\u6613\u53d1\u9001\u5730\u5740\u914d\u7f6e############################# ######(\u4ee5\u4e0b\u914d\u7f6e\u4e3aPM\u73af\u5883\uff1a\u5165\u7f51\u6d4b\u8bd5\u73af\u5883\u7528\uff0c\u751f\u4ea7\u73af\u5883\u914d\u7f6e\u89c1\u6587\u6863\u8bf4\u660e)####### ##\u524d\u53f0\u4ea4\u6613\u8bf7\u6c42\u5730\u5740 @@ -16,9 +15,6 @@ acpsdk.batchTransUrl=https://101.231.204.80:5000/gateway/api/batchTransReq.do acpsdk.fileTransUrl=https://101.231.204.80:9080/ ## app \u4EA4\u6613\u8BF7\u6C42\u5730\u5740 acpsdk.appTransUrl=https://101.231.204.80:5000/gateway/api/appTransReq.do - - - #########################\u7b7e\u540d\u8bc1\u4e66\u914d\u7f6e ################################ ######(\u4ee5\u4e0b\u914d\u7f6e\u4e3aPM\u73af\u5883\uff1a\u5165\u7f51\u6d4b\u8bd5\u73af\u5883\u7528\uff0c\u751f\u4ea7\u73af\u5883\u914d\u7f6e\u89c1\u6587\u6863\u8bf4\u660e)####### ##\u7b7e\u540d\u8bc1\u4e66\u8def\u5f84 @@ -27,8 +23,6 @@ acpsdk.signCert.path=D:\\certs\\PM_700000000000001_acp.pfx acpsdk.signCert.pwd=000000 ##\u7b7e\u540d\u8bc1\u4e66\u7c7b\u578b acpsdk.signCert.type=PKCS12 - - ##########################\u9a8c\u7b7e\u8bc1\u4e66\u914d\u7f6e################################ ##\u9a8c\u8bc1\u7b7e\u540d\u8bc1\u4e66\u76ee\u5f55 acpsdk.validateCert.dir=D:\\certs\\ diff --git a/jframe-pay/release/jframe-pay/conf/activemq.properties b/jframe-pay/jframe-pay-release/filter/activemq.properties similarity index 55% rename from jframe-pay/release/jframe-pay/conf/activemq.properties rename to jframe-pay/jframe-pay-release/filter/activemq.properties index 79c467a..91832d9 100644 --- a/jframe-pay/release/jframe-pay/conf/activemq.properties +++ b/jframe-pay/jframe-pay-release/filter/activemq.properties @@ -1,10 +1,8 @@ # def conf -mq.url = tcp://192.168.1.123:61616 -mq.queue.pay = pay-queue - -# producer mq +mq.url=tcp://192.168.1.123:61616 +mq.queue.pay=pay-queue +# producer mq #p.url = tcp://192.168.1.123:61616 - # consumer mq #c.url = tcp://192.168.1.123:61616 diff --git a/jframe-pay/jframe-pay-release/filter/alipay.properties b/jframe-pay/jframe-pay-release/filter/alipay.properties new file mode 100644 index 0000000..d30fdac --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/alipay.properties @@ -0,0 +1,20 @@ +group.id=test +notify_url=http://ip:port/pay/ord/aliback +# +@test.partner=208********202 +@test.seller.id=*****@***.com +@test.subject=**\u79df\u8f66 +@test.app.id=**** +@test.private.key= +@test.public.key = +@test.ali_public_key= +service = mobile.securitypay.pay +payment_type=1 +input_charset=UTF-8 +it_b_pay=1h +# return_url +# paymethod +# algo +sign.type=RSA +default_charset=UTF-8 +sign.algorithms=SHA1WithRSA diff --git a/jframe-pay/release/jframe-pay/conf/config.properties b/jframe-pay/jframe-pay-release/filter/config.properties similarity index 61% rename from jframe-pay/release/jframe-pay/conf/config.properties rename to jframe-pay/jframe-pay-release/filter/config.properties index c1269c6..5e842ed 100755 --- a/jframe-pay/release/jframe-pay/conf/config.properties +++ b/jframe-pay/jframe-pay-release/filter/config.properties @@ -1,90 +1,78 @@ #application directory -app.conf = ${app.home}/conf -app.lib = ${app.home}/lib -app.plugin = ${app.home}/plugin +app.conf=${app.home}/conf +app.lib=${app.home}/lib +app.plugin=${app.home}/plugin # upgrade file store directory -app.update = ${app.home}/update +app.update=${app.home}/update # plug-in cache directory -app.cache = ${app.home}/conf/cache +app.cache=${app.home}/conf/cache # plug-in temporary directory -app.temp = ${app.home}/temp - +app.temp=${app.home}/temp #configuration files #file.units = ${app.home}/conf/units.xml #file.signals = ${app.home}/conf/signals.def -clean = true +clean=true #application's name,every app should has it's own name -app.name = jframe.pay +app.name=jframe.pay #frame -app.frame = jframe.core.DefFrame -app.launcher = jframe.core.FrameLauncher - +app.frame=jframe.core.DefFrame +app.launcher=jframe.core.FrameLauncher #jvm's configuration file -vmargs = ${app.home}/conf/vmargs +vmargs=${app.home}/conf/vmargs #if system is windows,use vmargs-win #vmargs=${app.home}/conf/vmargs-win - #application's pid file -app.pid = ${app.home}/temp/app.pid +app.pid=${app.home}/temp/app.pid #daemon process's pid file -daemon.pid = ${app.home}/temp/daemon.pid +daemon.pid=${app.home}/temp/daemon.pid #launcher = jframe.launcher.FrameMain #mode=daemon or normal,launch with daemon mode, otherwise launching normally -launch.mode = daemon +launch.mode=daemon #context #default dispatcher is jframe.core.dispatch.DefDispatcher #context.dispatcher = jframe.ext.msg.pool.MsgPoolDispatcher #context.dispatcher = jframe.ext.dispatch.ActivemqDispatcher #file.dispatcher.mq = ${app.home}/conf/d-activemq.properties - -# plugins won't be started when starting +# plugins won't be started when starting #plugin.forbid = jframe.example.plugin.ExamplePlugin - # datasource #multi.datasource=masterdb slavedb #file.masterdb = ${app.home}/conf/mysql.properties #file.slavedb = ${app.home}/conf/mysql_ro1.properties #file.datasource = ${app.home}/conf/datasource.properties - # mybatis -file.mybatis = ${app.home}/conf/mybatis-config.xml -mybatis.id = run run_ro1 -file.mybatis.charset = utf-8 - - -file.upmp = ${app.home}/conf/upmp.properties +file.mybatis=${app.home}/conf/mybatis-config.xml +mybatis.id=run run_ro1 +file.mybatis.charset=utf-8 +file.upmp=${app.home}/conf/upmp.properties #file.upmp = ${app.home}/conf/upmp_p.properties -file.alipay = ${app.home}/conf/alipay.properties -file.wx = ${app.home}/conf/wxpay.properties +file.alipay=${app.home}/conf/alipay.properties +file.wx=${app.home}/conf/wxpay.properties #file.wx.pfx = ${app.home}/conf/1219114301_20140516113900.pfx #alipay.properties -groupid.alipay = test +groupid.alipay=test #wx.properties -groupid.wxpay = test +groupid.wxpay=test #upmp.properties -groupid.upmppay = test - -# http -http.port = 8028 -https.enabled = false - +groupid.upmppay=test +# http +http.port=8028 +https.enabled=false #redis conf file #redis.conf = ${app.home}/conf/redis.properties #file.getui = ${app.home}/conf/getui.properties #file.pushy = ${app.home}/conf/pushy.properties # task -file.task = ${app.home}/conf/task.properties +file.task=${app.home}/conf/task.properties # activemq #file.activemq = ${app.home}/conf/activemq.properties -file.memcached = ${app.home}/conf/memcached.properties +file.memcached=${app.home}/conf/memcached.properties #file.emayclient = ${app.home}/conf/emayclient.properties #file.yunpian = ${app.home}/conf/yunpian.properties -file.httpclient = ${app.home}/conf/httpclient.properties - +file.httpclient=${app.home}/conf/httpclient.properties #file.payclient = ${app.home}/conf/payclient.properties #upmp.back.url = http://localhost:8018/pay/back/upmp #file.qiniu = ${app.home}/conf/qiniu.properties #file.mongoclient = ${app.home}/conf/mongoclient.properties - -token.disable = true -jframe.debug = true +token.disable=true +jframe.debug=true diff --git a/jframe-pay/release/jframe-pay/conf/d-activemq.properties b/jframe-pay/jframe-pay-release/filter/d-activemq.properties similarity index 100% rename from jframe-pay/release/jframe-pay/conf/d-activemq.properties rename to jframe-pay/jframe-pay-release/filter/d-activemq.properties diff --git a/jframe-pay/release/jframe-pay/conf/datasource.properties b/jframe-pay/jframe-pay-release/filter/datasource.properties similarity index 100% rename from jframe-pay/release/jframe-pay/conf/datasource.properties rename to jframe-pay/jframe-pay-release/filter/datasource.properties diff --git a/jframe-pay/release/jframe-pay/conf/http.properties b/jframe-pay/jframe-pay-release/filter/http.properties similarity index 94% rename from jframe-pay/release/jframe-pay/conf/http.properties rename to jframe-pay/jframe-pay-release/filter/http.properties index 04427c6..ac4bd45 100644 --- a/jframe-pay/release/jframe-pay/conf/http.properties +++ b/jframe-pay/jframe-pay-release/filter/http.properties @@ -1,14 +1,11 @@ # 连接超时 http.connection.timeout=15000 - # 应答超时 http.so.timeout=30000 - # 网络参数 http.stale.check.enabled=true http.tcp.no.delay=true http.default.max.connections.per.host=100 http.max.total.connections=1000 - # 字符集 http.content.encoding=utf-8 \ No newline at end of file diff --git a/jframe-pay/jframe-pay-release/filter/httpclient.properties b/jframe-pay/jframe-pay-release/filter/httpclient.properties new file mode 100755 index 0000000..66e674f --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/httpclient.properties @@ -0,0 +1,16 @@ +group.id=payback +#@indexHost.http.method = post +#@indexHost.http.max.conn.route = 200 +#@indexHost.http.keep-alive = 5 +#@payback.ip = 127.0.0.1 +#@payback.port = 80 +@payback.group=jframe.pay +http.method=post +http.max.conn=100 +http.max.conn.route=200 +http.keep-alive=5 +#second +http.idle.conn.close=30 +http.charset=utf-8 +http.so.timeout=2000 +http.conn.timeout=2000 diff --git a/jframe-pay/release/jframe-pay/conf/jmxremote.access b/jframe-pay/jframe-pay-release/filter/jmxremote.access similarity index 100% rename from jframe-pay/release/jframe-pay/conf/jmxremote.access rename to jframe-pay/jframe-pay-release/filter/jmxremote.access diff --git a/jframe-pay/release/jframe-pay/conf/jmxremote.password b/jframe-pay/jframe-pay-release/filter/jmxremote.password similarity index 100% rename from jframe-pay/release/jframe-pay/conf/jmxremote.password rename to jframe-pay/jframe-pay-release/filter/jmxremote.password diff --git a/jframe-pay/jframe-pay-release/filter/logback-daemon.xml b/jframe-pay/jframe-pay-release/filter/logback-daemon.xml new file mode 100644 index 0000000..c21f188 --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/logback-daemon.xml @@ -0,0 +1,45 @@ + + + Application Daemon + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + ${LOG_HOME}/jfd-%d{yyyy-MM-dd}.log + + 10 + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + + + diff --git a/jframe-pay/jframe-pay-release/filter/logback.xml b/jframe-pay/jframe-pay-release/filter/logback.xml new file mode 100644 index 0000000..ddf31d4 --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/logback.xml @@ -0,0 +1,39 @@ + + + Application + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + ${LOG_HOME}/jf-%d{yyyy-MM-dd}.log + + 10 + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + + + diff --git a/jframe-pay/release/jframe-pay/conf/management.properties b/jframe-pay/jframe-pay-release/filter/management.properties similarity index 99% rename from jframe-pay/release/jframe-pay/conf/management.properties rename to jframe-pay/jframe-pay-release/filter/management.properties index db08b78..48aad26 100644 --- a/jframe-pay/release/jframe-pay/conf/management.properties +++ b/jframe-pay/jframe-pay-release/filter/management.properties @@ -28,7 +28,6 @@ # # For setting the SNMP agent port use the following line # com.sun.management.snmp.port= - ##################################################################### # Optional Instrumentation ##################################################################### @@ -45,10 +44,8 @@ # Refer to the specification for the java.lang.management.ThreadMBean # interface - see isThreadContentionMonitoringSupported() method. # - # To enable thread contention monitoring, uncomment the following line # com.sun.management.enableThreadContentionMonitoring - ##################################################################### # SNMP Management Properties ##################################################################### @@ -63,7 +60,6 @@ # Later changes to the above system property (e.g. via setProperty method), this # config file, or the ACL file has no effect to the running SNMP agent. # - # # ##################### SNMP Trap Port ######################### # @@ -73,10 +69,8 @@ # the SNMP agent will send traps at : # Default for this property is 162. # - # To set port for sending traps to a different port use the following line # com.sun.management.snmp.trap= - # # ################ SNMP listen interface ######################### # @@ -90,10 +84,8 @@ # The format of the value for that property is any string accepted # by java.net.InetAddress.getByName(String). # - # For restricting the port on which SNMP agent listens use the following line # com.sun.management.snmp.interface= - # # #################### SNMP ACL file ######################### # @@ -102,10 +94,8 @@ # If this property is specified as false then the ACL file # is not checked: all manager hosts are allowed all access. # - # For SNMP without checking ACL file uncomment the following line # com.sun.management.snmp.acl=false - # # com.sun.management.snmp.acl.file=filepath # Specifies location for ACL file @@ -121,10 +111,8 @@ # Modification to the ACL file has no effect to any running SNMP # agents which read that ACL file at startup. # - # For a non-default acl file location use the following line # com.sun.management.snmp.acl.file=filepath - ##################################################################### # RMI Management Properties ##################################################################### @@ -142,7 +130,6 @@ # this config file, the password file, or the access file have no effect to the # running MBean server, the connector, or the registry. # - # # ########## RMI connector settings for local management ########## # @@ -158,11 +145,9 @@ # For remote management the remote JMX RMI connector server should # be used instead with authentication and SSL/TLS encryption enabled. # - # For allowing the local management agent accept local # and remote connection requests use the following line # com.sun.management.jmxremote.local.only=false - # # ###################### RMI SSL ############################# # @@ -170,10 +155,8 @@ # Default for this property is true. (Case for true/false ignored) # If this property is specified as false then SSL is not used. # - # For RMI monitoring without SSL use the following line # com.sun.management.jmxremote.ssl=false - # com.sun.management.jmxremote.ssl.config.file=filepath # Specifies the location of the SSL configuration file. A properties # file can be used to supply the keystore and truststore location and @@ -194,10 +177,8 @@ # If the property "com.sun.management.jmxremote.ssl" is set to false, # then this property is ignored. # - # For supplying the keystore settings in a file use the following line # com.sun.management.jmxremote.ssl.config.file=filepath - # com.sun.management.jmxremote.ssl.enabled.cipher.suites= # The value of this property is a string that is a comma-separated list # of SSL/TLS cipher suites to enable. This property can be specified in @@ -207,7 +188,6 @@ # the SSL/TLS RMI Server Socket Factory uses the SSL/TLS cipher suites that # are enabled by default. # - # com.sun.management.jmxremote.ssl.enabled.protocols= # The value of this property is a string that is a comma-separated list # of SSL/TLS protocol versions to enable. This property can be specified in @@ -217,17 +197,14 @@ # specified then the SSL/TLS RMI Server Socket Factory uses the SSL/TLS # protocol versions that are enabled by default. # - # com.sun.management.jmxremote.ssl.need.client.auth=true|false # Default for this property is false. (Case for true/false ignored) # If this property is specified as true in conjunction with the previous # property "com.sun.management.jmxremote.ssl" then the SSL/TLS RMI Server # Socket Factory will require client authentication. # - # For RMI monitoring with SSL client authentication use the following line # com.sun.management.jmxremote.ssl.need.client.auth=true - # com.sun.management.jmxremote.registry.ssl=true|false # Default for this property is false. (Case for true/false ignored) # If this property is specified as true then the RMI registry used @@ -243,10 +220,8 @@ # then the RMIServer remote object and the RMI registry are # both exported with the same SSL/TLS RMI Socket Factories. # - # For using an SSL/TLS protected RMI registry use the following line # com.sun.management.jmxremote.registry.ssl=true - # # ################ RMI User authentication ################ # @@ -255,10 +230,8 @@ # If this property is specified as false then no authentication is # performed and all users are allowed all access. # - # For RMI monitoring without any checking use the following line # com.sun.management.jmxremote.authenticate=false - # # ################ RMI Login configuration ################### # @@ -279,10 +252,8 @@ # If the property "com.sun.management.jmxremote.authenticate" is set to # false, then this property and the password & access files are ignored. # - # For a non-default login configuration use the following line # com.sun.management.jmxremote.login.config= - # # ################ RMI Password file location ################## # @@ -296,10 +267,8 @@ # Otherwise the password file must exist and be in the valid format. # If the password file is empty or non-existent then no access is allowed. # - # For a non-default password file location use the following line # com.sun.management.jmxremote.password.file=filepath - # # ################ RMI Access file location ##################### # @@ -313,6 +282,5 @@ # Otherwise, the access file must exist and be in the valid format. # If the access file is empty or non-existent then no access is allowed. # - # For a non-default password file location use the following line # com.sun.management.jmxremote.access.file=filepath diff --git a/jframe-pay/jframe-pay-release/filter/memcached.properties b/jframe-pay/jframe-pay-release/filter/memcached.properties new file mode 100755 index 0000000..f940159 --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/memcached.properties @@ -0,0 +1,20 @@ +mem.name=mem +mem.servers=s1 s2 +#mem.servers = local +mem.server.local.host=127.0.0.1 +mem.server.local.port=11211 +mem.server.local.weight=1 +mem.server.s1.host=10.4.8.151 +mem.server.s1.port=11211 +mem.server.s1.weight=1 +mem.server.s2.host=10.4.8.213 +mem.server.s2.port=11211 +mem.server.s2.weight=1 +# memcached parameters +mem.initconn=10 +mem.minconn=5 +mem.maxconn=250 +# seconds +mem.maxidle=3600000 +mem.timeout.read=3000 +mem.timeout.conn=3000 \ No newline at end of file diff --git a/jframe-pay/release/jframe-pay/conf/mybatis-config.xml b/jframe-pay/jframe-pay-release/filter/mybatis-config.xml similarity index 100% rename from jframe-pay/release/jframe-pay/conf/mybatis-config.xml rename to jframe-pay/jframe-pay-release/filter/mybatis-config.xml diff --git a/jframe-pay/jframe-pay-release/filter/payclient.properties b/jframe-pay/jframe-pay-release/filter/payclient.properties new file mode 100755 index 0000000..0820d55 --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/payclient.properties @@ -0,0 +1,14 @@ +# http,https,ws,dono +pay.connection=http +pay.version=1.0.0 +pay.charset=utf-8 +# http +http.ip=192.168.1.123 +http.port=8028 +http.pay.path=/pay +http.usr.path=/usr +# ws +# ws.ip = +# +ch.timeout=5000 +ch.thread.count=1 diff --git a/jframe-pay/jframe-pay-release/filter/task.properties b/jframe-pay/jframe-pay-release/filter/task.properties new file mode 100755 index 0000000..8146121 --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/task.properties @@ -0,0 +1,15 @@ +#true or false ,default is true +task.start=true +# p,c,pc +task.mode=p +# default +task.timeout=120 +task.count=30 +# TaskType +task.types=1,100 +# task 1 back url +task.1.timeout=120 +task.1.count=30 +# task 100 upmp query order +task.100.timeout=180 +task.100.count=20 diff --git a/jframe-pay/jframe-pay-release/filter/upmp.properties b/jframe-pay/jframe-pay-release/filter/upmp.properties new file mode 100644 index 0000000..716c9e2 --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/upmp.properties @@ -0,0 +1,18 @@ +#group +group.id=test run +# test +@test.mer.id=*********** +@test.back.url=http://ip:port/pay/back/upmpback +#@test.front.url= http://183.129.161.72:8018/pay/back/upmp +@test.acp.sdk=${app.home}/conf/acp_sdk_dev.properties +# run +@run.mer.id=************ +@run.back.url=http://ip:port/pay/back/upmpback +#@test.front.url= http://183.129.161.72:8018/pay/back/upmp +@run.acp.sdk=${app.home}/conf/acp_sdk_run.properties +# 01-Debit Card 02-Credit Card +# mer.reserved={cardType=02} +# message info +version=5.0.0 +charset=UTF-8 + diff --git a/jframe-pay/release/jframe-pay/conf/vmargs b/jframe-pay/jframe-pay-release/filter/vmargs similarity index 100% rename from jframe-pay/release/jframe-pay/conf/vmargs rename to jframe-pay/jframe-pay-release/filter/vmargs diff --git a/jframe-pay/release/jframe-pay/conf/vmargs-win b/jframe-pay/jframe-pay-release/filter/vmargs-win similarity index 100% rename from jframe-pay/release/jframe-pay/conf/vmargs-win rename to jframe-pay/jframe-pay-release/filter/vmargs-win diff --git a/jframe-pay/jframe-pay-release/filter/wxpay.properties b/jframe-pay/jframe-pay-release/filter/wxpay.properties new file mode 100644 index 0000000..8eff0e2 --- /dev/null +++ b/jframe-pay/jframe-pay-release/filter/wxpay.properties @@ -0,0 +1,20 @@ +group.id=test +# partner +@test.partner=******1212 +#@test.partner.key = *********22276e34a +# app +@test.app.id= +@test.app.secret= +@test.app.key = +# message info +version=1.0.0 +charset=UTF-8 +sign.method=sha1 +grant.type=client_credential +# url +token.url=https://api.weixin.qq.com/cgi-bin/token +#gate.url = https://api.weixin.qq.com/pay/genprepay?access_token= +gate.url=https://api.weixin.qq.com/pay/genprepay +notify.url=http://ip:port/pay/ord/wxback +# default is http +use.https=false \ No newline at end of file diff --git a/jframe-pay/jframe-pay-release/pom.xml b/jframe-pay/jframe-pay-release/pom.xml new file mode 100644 index 0000000..8eb39d5 --- /dev/null +++ b/jframe-pay/jframe-pay-release/pom.xml @@ -0,0 +1,116 @@ + + 4.0.0 + + io.github.dzh + jframe-pay + 2.0.0-SNAPSHOT + + jframe-pay-release + pom + + + + ${project.basedir}/filter.properties + + + + org.apache.maven.plugins + maven-resources-plugin + + + compile + + + copy-resources + validate + + copy-resources + + + ${project.basedir}/conf + + + ${project.basedir}/filter + true + + + + + + + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-plugin + package + + copy-dependencies + + + ${project.basedir}/plugin/ + true + true + false + compile + plugin + + + + copy-lib + package + + copy-dependencies + + + ${project.basedir}/lib/ + true + true + false + compile + plugin + + + + + + + + + + io.github.dzh + jframe-launcher + + + + io.github.dzh + jframe-pay-http + plugin + + + io.github.dzh + jframe-pay-dao + plugin + + + io.github.dzh + jframe-pay-alipay + plugin + + + io.github.dzh + jframe-pay-upmp + plugin + + + io.github.dzh + jframe-pay-wx + plugin + + + \ No newline at end of file diff --git a/jframe-pay/pom.xml b/jframe-pay/pom.xml index 3323af8..f1131bb 100644 --- a/jframe-pay/pom.xml +++ b/jframe-pay/pom.xml @@ -1,111 +1,229 @@ - 4.0.0 - cn - jframe-pay - 1.0.0 - pom + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + io.github.dzh + jframe-pay + 2.0.0-SNAPSHOT + pom - - UTF-8 - 1.2.1 - + + UTF-8 + 2.0.0-SNAPSHOT + 1.7.26 + - - - - src/main/java - - **/*.properties - **/*.xml - - - - src/main/resources - - **/*.properties - **/*.xml - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-resources-plugin - 3.1.0 - - - compile - - - - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M2 - - true - - - - + + + + src/main/java + + **/*.properties + **/*.xml + + + + src/main/resources + + **/*.properties + **/*.xml + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + compile + + + + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M2 + + true + + + + - - jframe-pay-lib - jframe-pay-plugin - jframe-pay-client - release - - - - junit - junit - 4.12 - test - - - org.slf4j - slf4j-api - 1.7.12 - - - org.slf4j - slf4j-simple - 1.7.12 - test - - - cn - jframe-core - ${jframe.version} - - - cn - jframe-ext - ${jframe.version} - - - org.apache.httpcomponents - httpcore - 4.4 - - - org.apache.httpcomponents - httpclient - 4.4 - - + + jframe-pay-lib + jframe-pay-plugin + jframe-pay-release + + + + + + + io.github.dzh + jframe-launcher + ${jframe.version} + + + io.github.dzh + jframe-core + ${jframe.version} + + + io.github.dzh + jframe-ext + ${jframe.version} + + + + + io.github.dzh + jframe-memcached-client + ${jframe.version} + plugin + + + io.github.dzh + jframe-httpclient + ${jframe.version} + plugin + + + io.github.dzh + jframe-mybatis + ${jframe.version} + plugin + + + + + io.github.dzh + jframe-pay-domain + ${project.version} + + + org.dom4j + dom4j + 2.1.1 + + + jaxen + jaxen + 1.2.0 + + + com.alibaba + fastjson + 1.2.58 + + + com.google.code.gson + gson + 2.8.5 + + + commons-codec + commons-codec + 1.12 + + + org.apache.httpcomponents + httpcore + 4.4.11 + + + org.apache.httpcomponents + httpclient + 4.5.9 + + + + + io.github.dzh + jframe-pay-alipay + ${project.version} + plugin + + + io.github.dzh + jframe-pay-dao + ${project.version} + plugin + + + io.github.dzh + jframe-pay-http + ${project.version} + plugin + + + io.github.dzh + jframe-pay-task + ${project.version} + plugin + + + io.github.dzh + jframe-pay-upmp + ${project.version} + plugin + + + io.github.dzh + jframe-pay-wx + ${project.version} + plugin + + + io.github.dzh + jframe-pay-client + ${project.version} + plugin + + + + + + + + junit + junit + 4.12 + test + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + slf4j-simple + ${slf4j.version} + test + + \ No newline at end of file diff --git a/jframe-pay/release/jframe-pay/conf/alipay.properties b/jframe-pay/release/jframe-pay/conf/alipay.properties deleted file mode 100644 index 73a296a..0000000 --- a/jframe-pay/release/jframe-pay/conf/alipay.properties +++ /dev/null @@ -1,24 +0,0 @@ -group.id = test - -notify_url = http://ip:port/pay/ord/aliback - -# -@test.partner = 208********202 -@test.seller.id = *****@***.com -@test.subject = **\u79df\u8f66 -@test.app.id = **** -@test.private.key = -@test.public.key = -@test.ali_public_key = - -service = mobile.securitypay.pay -payment_type = 1 -input_charset = UTF-8 -it_b_pay = 1h -# return_url -# paymethod - -# algo -sign.type = RSA -default_charset = UTF-8 -sign.algorithms = SHA1WithRSA diff --git a/jframe-pay/release/jframe-pay/conf/httpclient.properties b/jframe-pay/release/jframe-pay/conf/httpclient.properties deleted file mode 100755 index da4a097..0000000 --- a/jframe-pay/release/jframe-pay/conf/httpclient.properties +++ /dev/null @@ -1,20 +0,0 @@ -group.id = payback - -#@indexHost.http.method = post -#@indexHost.http.max.conn.route = 200 -#@indexHost.http.keep-alive = 5 - -#@payback.ip = 127.0.0.1 -#@payback.port = 80 -@payback.group = jframe.pay - -http.method = post -http.max.conn = 100 -http.max.conn.route = 200 -http.keep-alive = 5 -#second -http.idle.conn.close = 30 -http.charset = utf-8 - -http.so.timeout = 2000 -http.conn.timeout = 2000 diff --git a/jframe-pay/release/jframe-pay/conf/logback-daemon.xml b/jframe-pay/release/jframe-pay/conf/logback-daemon.xml deleted file mode 100644 index c5cf1ae..0000000 --- a/jframe-pay/release/jframe-pay/conf/logback-daemon.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - Application Daemon - - - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - ${LOG_HOME}/jfd-%d{yyyy-MM-dd}.log - - 10 - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n - - - - - - - - - - - - diff --git a/jframe-pay/release/jframe-pay/conf/logback.xml b/jframe-pay/release/jframe-pay/conf/logback.xml deleted file mode 100644 index 1d02fee..0000000 --- a/jframe-pay/release/jframe-pay/conf/logback.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - Application - - - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - ${LOG_HOME}/jf-%d{yyyy-MM-dd}.log - - 10 - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n - - - - - - - - - - - - diff --git a/jframe-pay/release/jframe-pay/conf/memcached.properties b/jframe-pay/release/jframe-pay/conf/memcached.properties deleted file mode 100755 index 075815b..0000000 --- a/jframe-pay/release/jframe-pay/conf/memcached.properties +++ /dev/null @@ -1,26 +0,0 @@ -mem.name = mem - -mem.servers = s1 s2 -#mem.servers = local - -mem.server.local.host = 127.0.0.1 -mem.server.local.port = 11211 -mem.server.local.weight = 1 - -mem.server.s1.host = 10.4.8.151 -mem.server.s1.port = 11211 -mem.server.s1.weight = 1 - -mem.server.s2.host = 10.4.8.213 -mem.server.s2.port = 11211 -mem.server.s2.weight = 1 - - -# memcached parameters -mem.initconn = 10 -mem.minconn = 5 -mem.maxconn = 250 -# seconds -mem.maxidle = 3600000 -mem.timeout.read = 3000 -mem.timeout.conn = 3000 \ No newline at end of file diff --git a/jframe-pay/release/jframe-pay/conf/payclient.properties b/jframe-pay/release/jframe-pay/conf/payclient.properties deleted file mode 100755 index 284fd87..0000000 --- a/jframe-pay/release/jframe-pay/conf/payclient.properties +++ /dev/null @@ -1,18 +0,0 @@ -# http,https,ws,dono -pay.connection = http -pay.version = 1.0.0 -pay.charset = utf-8 - -# http -http.ip = 192.168.1.123 -http.port = 8028 - -http.pay.path = /pay -http.usr.path = /usr - -# ws -# ws.ip = - -# -ch.timeout = 5000 -ch.thread.count = 1 diff --git a/jframe-pay/release/jframe-pay/conf/task.properties b/jframe-pay/release/jframe-pay/conf/task.properties deleted file mode 100755 index 9eb5acf..0000000 --- a/jframe-pay/release/jframe-pay/conf/task.properties +++ /dev/null @@ -1,19 +0,0 @@ -#true or false ,default is true -task.start = true -# p,c,pc -task.mode = p - -# default -task.timeout = 120 -task.count = 30 - -# TaskType -task.types = 1,100 - -# task 1 back url -task.1.timeout = 120 -task.1.count = 30 - -# task 100 upmp query order -task.100.timeout = 180 -task.100.count = 20 diff --git a/jframe-pay/release/jframe-pay/conf/upmp.properties b/jframe-pay/release/jframe-pay/conf/upmp.properties deleted file mode 100644 index cf633b1..0000000 --- a/jframe-pay/release/jframe-pay/conf/upmp.properties +++ /dev/null @@ -1,22 +0,0 @@ -#group -group.id = test run - - -# test -@test.mer.id = *********** -@test.back.url = http://ip:port/pay/back/upmpback -#@test.front.url= http://183.129.161.72:8018/pay/back/upmp -@test.acp.sdk = ${app.home}/conf/acp_sdk_dev.properties - -# run -@run.mer.id = ************ -@run.back.url = http://ip:port/pay/back/upmpback -#@test.front.url= http://183.129.161.72:8018/pay/back/upmp -@run.acp.sdk = ${app.home}/conf/acp_sdk_run.properties -# 01-Debit Card 02-Credit Card -# mer.reserved={cardType=02} - -# message info -version=5.0.0 -charset=UTF-8 - diff --git a/jframe-pay/release/jframe-pay/conf/wxpay.properties b/jframe-pay/release/jframe-pay/conf/wxpay.properties deleted file mode 100644 index 12b46c1..0000000 --- a/jframe-pay/release/jframe-pay/conf/wxpay.properties +++ /dev/null @@ -1,27 +0,0 @@ -group.id = test - -# partner -@test.partner = ******1212 -#@test.partner.key = *********22276e34a -# app -@test.app.id = -@test.app.secret = -@test.app.key = -# message info -version=1.0.0 -charset=UTF-8 -sign.method=sha1 - -grant.type = client_credential - -# url -token.url = https://api.weixin.qq.com/cgi-bin/token - - -#gate.url = https://api.weixin.qq.com/pay/genprepay?access_token= -gate.url = https://api.weixin.qq.com/pay/genprepay - -notify.url = http://ip:port/pay/ord/wxback - -# default is http -use.https=false \ No newline at end of file diff --git a/jframe-pay/release/pom.xml b/jframe-pay/release/pom.xml deleted file mode 100644 index 6acbd2d..0000000 --- a/jframe-pay/release/pom.xml +++ /dev/null @@ -1,121 +0,0 @@ - - 4.0.0 - - cn - jframe-pay - 1.0.0 - - release - pom - - - - - org.apache.maven.plugins - maven-dependency-plugin - 2.10 - - - copy-lib - package - - copy-dependencies - - - ${project.basedir}/jframe-pay/lib/ - true - true - false - compile - plugin - - - - copy-plugin - package - - copy-dependencies - - - ${project.basedir}/jframe-pay/plugin/ - true - true - false - compile - plugin - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - [2.8,) - - copy-dependencies - - - - - - - - - - - - - - - - - - cn - jframe-launcher - ${jframe.version} - - - cn - jframe-pay-http - 1.0.0 - plugin - - - cn - jframe-pay-dao - 1.0.0 - plugin - - - cn - jframe-pay-alipay - 1.0.0 - plugin - - - cn - jframe-pay-upmp - 1.0.0 - plugin - - - cn - jframe-pay-wx - 1.0.0 - plugin - - - \ No newline at end of file diff --git a/jframe-plugin/jframe-httpclient/pom.xml b/jframe-plugin/jframe-httpclient/pom.xml index 917f582..45511bf 100644 --- a/jframe-plugin/jframe-httpclient/pom.xml +++ b/jframe-plugin/jframe-httpclient/pom.xml @@ -1,28 +1,28 @@ - 4.0.0 - - jframe-plugin - 2.0.0-SNAPSHOT - io.github.dzh - - jframe-httpclient + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + jframe-plugin + 2.0.0-SNAPSHOT + io.github.dzh + + jframe-httpclient - - - org.apache.httpcomponents - httpcore - 4.4.10 - - - org.apache.httpcomponents - httpclient - 4.5.6 - - - com.google.code.gson - gson - 2.8.5 - - + + + org.apache.httpcomponents + httpcore + 4.4.11 + + + org.apache.httpcomponents + httpclient + 4.5.9 + + + com.google.code.gson + gson + 2.8.5 + + \ No newline at end of file From e14acfc70894619da74ad079a327e32125de3d6e Mon Sep 17 00:00:00 2001 From: dzh Date: Sat, 3 Aug 2019 17:18:53 +0800 Subject: [PATCH 03/47] add jframe-alipay --- jframe-plugin/jframe-alipay/pom.xml | 23 ++++ .../main/java/jframe/alipay/AlipayPlugin.java | 10 ++ .../jframe/alipay/service/AlipayService.java | 47 +++++++ .../alipay/service/AlipayServiceImpl.java | 124 ++++++++++++++++++ .../main/resources/META-INF/plugin.properties | 7 + .../alipay/service/TestAlipayService.java | 10 ++ .../jframe/alipay/service/alipay.properties | 11 ++ .../aliyun/service/dm/DMServiceImpl.java | 33 ++--- .../aliyun/service/oss/OSSServiceImpl.java | 37 +++--- .../aliyun/service/sms/SMSServiceImpl.java | 37 +++--- .../aliyun/service/sts/STSServiceImpl.java | 34 ++--- jframe-plugin/pom.xml | 1 + 12 files changed, 304 insertions(+), 70 deletions(-) create mode 100644 jframe-plugin/jframe-alipay/pom.xml create mode 100644 jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/AlipayPlugin.java create mode 100644 jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java create mode 100644 jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java create mode 100644 jframe-plugin/jframe-alipay/src/main/resources/META-INF/plugin.properties create mode 100644 jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/TestAlipayService.java create mode 100644 jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/alipay.properties diff --git a/jframe-plugin/jframe-alipay/pom.xml b/jframe-plugin/jframe-alipay/pom.xml new file mode 100644 index 0000000..380949c --- /dev/null +++ b/jframe-plugin/jframe-alipay/pom.xml @@ -0,0 +1,23 @@ + + + + jframe-plugin + io.github.dzh + 2.0.0-SNAPSHOT + + 4.0.0 + + jframe-alipay + + + + com.alipay.sdk + alipay-sdk-java + 3.7.110.ALL + + + + + \ No newline at end of file diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/AlipayPlugin.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/AlipayPlugin.java new file mode 100644 index 0000000..e58270e --- /dev/null +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/AlipayPlugin.java @@ -0,0 +1,10 @@ +package jframe.alipay; + +import jframe.core.plugin.DefPlugin; + +/** + * @author dzh + * @date 2019-07-22 14:55 + */ +public class AlipayPlugin extends DefPlugin { +} diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java new file mode 100644 index 0000000..c314054 --- /dev/null +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java @@ -0,0 +1,47 @@ +package jframe.alipay.service; + +import com.alipay.api.AlipayClient; +import jframe.core.plugin.annotation.Service; + +import java.util.Map; + +/** + * https://docs.open.alipay.com/270/105899/ + * https://docs.open.alipay.com/api_1/alipay.trade.page.pay/ + *

+ * https://openhome.alipay.com/platform/demoManage.htm#/alipay.trade.page.pay + * https://openhome.alipay.com/platform/appDaily.htm?tab=info + * + * @author dzh + * @date 2019-07-22 14:56 + */ +@Service(clazz = "jframe.alipay.service.AlipayServiceImpl", id = "jframe.service.alipay") +public interface AlipayService { + + String F_URL = "url"; + String F_APP_ID = "app.id"; + String F_PRIVATE_KEY = "private.key"; + String F_PUBLIC_KEY = "public.key"; + String F_FORMAT = "format"; + String F_CHARSET = "charset"; + String F_SIGN_TYPE = "sign.type"; + String F_RETURN_URL = "return.url"; + String F_NOTIFY_URL = "notify.url"; + + String TRADE_STATUS_WAIT = "WAIT_BUYER_PAY"; //交易创建,等待买家付款 + String TRADE_STATUS_CLOSED = "TRADE_CLOSED"; //未付款交易超时关闭,或支付完成后全额退款 + String TRADE_STATUS_SUCC = "TRADE_SUCCESS"; //交易支付成功 + String TRADE_STATUS_FINISHED = "TRADE_FINISHED"; //交易结束,不可退款 + + + AlipayClient getClient(String id); + + /** + * @param id + * @param param 异步返回参数 + * @return + */ + boolean checkAsyncReturn(String id, Map param); + + String getConf(String id, String key); +} diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java new file mode 100644 index 0000000..3517fef --- /dev/null +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java @@ -0,0 +1,124 @@ +package jframe.alipay.service; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayClient; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.internal.util.AlipaySignature; +import jframe.alipay.AlipayPlugin; +import jframe.core.conf.Config; +import jframe.core.plugin.annotation.InjectPlugin; +import jframe.core.plugin.annotation.Injector; +import jframe.core.plugin.annotation.Start; +import jframe.core.plugin.annotation.Stop; +import jframe.core.util.PropsConf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; + +/** + * @author dzh + * @date 2019-07-22 14:58 + */ +@Injector +class AlipayServiceImpl implements AlipayService { + static Logger LOG = LoggerFactory.getLogger(AlipayServiceImpl.class); + + @InjectPlugin + static AlipayPlugin plugin; + + static String FILE_ALIPAY = "file.alipay"; + + //group id -> AlipayClient + private Map clients = new HashMap<>(); + + private PropsConf alipayConf; + + @Start + void start() { + LOG.info("Start AlipayService"); + try { + String file = plugin.getConfig(FILE_ALIPAY, plugin.getConfig(Config.APP_CONF) + "/alipay.properties"); + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } + alipayConf = new PropsConf(); + alipayConf.init(file); + for (String id : alipayConf.getGroupIds()) { + AlipayClient client = createAlipayClient(alipayConf, id); + clients.put(id, client); + } + LOG.info("Start AlipayService Successfully!"); + } catch (Exception e) { + LOG.error("Start AlipayService Failed!" + e.getMessage(), e); + } + } + + /** + * https://docs.open.alipay.com/270/105899/ + *

+ * AlipayClient alipayClient = new DefaultAlipayClient(URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE); + *

+ * 配置参数 示例值解释 获取方式/示例值 + * URL 支付宝网关(固定) https://openapi.alipay.com/gateway.do + * APPID APPID 即创建应用后生成 获取见上方创建应用 + * APP_PRIVATE_KEY 开发者私钥,由开发者自己生成 获取见配置密钥 + * FORMAT 参数返回格式,只支持 json json(固定) + * CHARSET 编码集,支持 GBK/UTF-8 开发者根据实际工程编码配置 + * ALIPAY_PUBLIC_KEY 支付宝公钥,由支付宝生成 获取详见配置密钥 + * SIGN_TYPE 商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA,推荐使用 RSA2 RSA2 + * + * @param conf + * @param id + * @return + */ + private AlipayClient createAlipayClient(PropsConf conf, String id) { + String url = conf.getConf(id, F_URL); + String appId = conf.getConf(id, F_APP_ID); + String privateKey = conf.getConf(id, F_PRIVATE_KEY); + String format = conf.getConf(id, F_FORMAT); + String charset = conf.getConf(id, F_CHARSET); + String publicKey = conf.getConf(id, F_PUBLIC_KEY); + String signType = conf.getConf(id, F_SIGN_TYPE); + AlipayClient alipayClient = new DefaultAlipayClient(url, appId, privateKey, format, charset, publicKey, signType); + LOG.info("createAlipayClient {}", appId); + return alipayClient; + } + + @Stop + void stop() { +// if (clients != null) for (Map.Entry c : clients.entrySet()) { +// try { +// } catch (Exception e) { +// LOG.error(e.getMessage(), e.fillInStackTrace()); +// } +// } + clients.clear(); + LOG.info("Stop AlipayService"); + } + + @Override + public AlipayClient getClient(String id) { + return clients.get(id); + } + + @Override + public boolean checkAsyncReturn(String id, Map param) { + try { + return AlipaySignature.rsaCheckV2(param, getConf(id, F_PUBLIC_KEY), getConf(id, F_CHARSET), getConf(id, F_SIGN_TYPE)); + } catch (AlipayApiException e) { + LOG.error(e.getErrMsg(), e); + } + return false; + } + + @Override + public String getConf(String id, String key) { + return alipayConf.getConf(id, key); + } + + +} diff --git a/jframe-plugin/jframe-alipay/src/main/resources/META-INF/plugin.properties b/jframe-plugin/jframe-alipay/src/main/resources/META-INF/plugin.properties new file mode 100644 index 0000000..c55908b --- /dev/null +++ b/jframe-plugin/jframe-alipay/src/main/resources/META-INF/plugin.properties @@ -0,0 +1,7 @@ +Plugin-Name=jframe.alipay.AlipayPlugin +Plugin-Class=jframe.alipay.AlipayPlugin +#Default library path is META-INF/lib/ +#Plugin-Lib = +#Default DLL path is META-INF/dll +#Plugin-Dll = +Plugin-Service=jframe.alipay.service.AlipayService diff --git a/jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/TestAlipayService.java b/jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/TestAlipayService.java new file mode 100644 index 0000000..07c1979 --- /dev/null +++ b/jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/TestAlipayService.java @@ -0,0 +1,10 @@ +package jframe.alipay.service; + +/** + * @author dzh + * @date 2019-07-22 14:59 + */ +public class TestAlipayService { + + +} diff --git a/jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/alipay.properties b/jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/alipay.properties new file mode 100644 index 0000000..1441e6a --- /dev/null +++ b/jframe-plugin/jframe-alipay/src/test/java/jframe/alipay/service/alipay.properties @@ -0,0 +1,11 @@ +group.id=test +# +@test.url=https://openapi.alipaydev.com/gateway.do +@test.app.id= +@test.private.key= +@test.return.url= +@test.notify.url= +format=json +sign.type=RSA2 +charset=UTF-8 +public.key= \ No newline at end of file diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/dm/DMServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/dm/DMServiceImpl.java index 4bac845..bf84f03 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/dm/DMServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/dm/DMServiceImpl.java @@ -1,21 +1,11 @@ package jframe.aliyun.service.dm; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest; import com.aliyuncs.dm.model.v20151123.SingleSendMailResponse; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; - import jframe.aliyun.AliyunField; import jframe.aliyun.AliyunPlugin; import jframe.aliyun.service.DMService; @@ -25,11 +15,19 @@ import jframe.core.plugin.annotation.Start; import jframe.core.plugin.annotation.Stop; import jframe.core.util.PropsConf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; /** * @author dzh - * @date Dec 10, 2018 2:10:20 PM * @version 0.0.1 + * @date Dec 10, 2018 2:10:20 PM */ @Injector public class DMServiceImpl implements DMService, AliyunField { @@ -51,7 +49,9 @@ void start() { try { String file = plugin.getConfig(FILE_ALIDM, plugin.getConfig(Config.APP_CONF) + "/alidm.properties"); - if (!new File(file).exists()) { throw new FileNotFoundException("not found " + file); } + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } _config.init(file); for (String id : _config.getGroupIds()) { // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求 @@ -66,11 +66,10 @@ void start() { DefaultAcsClient client = new DefaultAcsClient(profile); clients.put(id, client); } + LOG.info("Start DMService Successfully!"); } catch (Exception e) { - LOG.error("Start DMService Failure!" + e.getMessage(), e); - return; + LOG.error("Start DMService Failed!" + e.getMessage(), e); } - LOG.info("Start DMService Successfully!"); } @Stop @@ -88,7 +87,9 @@ void stop() { @Override public SingleSendMailResponse singleSend(String id, SingleSendMailRequest request) throws ClientException { DefaultAcsClient client = clients.get(id); - if (client == null) { throw new NullPointerException("not found dm id:" + id); } + if (client == null) { + throw new NullPointerException("not found dm id:" + id); + } return client.getAcsResponse(request); } diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java index c37e820..a5b1bc8 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java @@ -1,19 +1,10 @@ /** - * + * */ package jframe.aliyun.service.oss; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.aliyun.oss.ClientConfiguration; import com.aliyun.oss.OSSClient; - import jframe.aliyun.AliyunField; import jframe.aliyun.AliyunPlugin; import jframe.aliyun.service.OSSService; @@ -22,24 +13,31 @@ import jframe.core.plugin.annotation.Injector; import jframe.core.plugin.annotation.Start; import jframe.core.plugin.annotation.Stop; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; /** - * + * * https://help.aliyun.com/document_detail/32010.html?spm=a2c4g.11186623.6.745.735dc06dS65fFb - * + * * // Endpoint以杭州为例,其它Region请按实际情况填写。 * String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; * // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 * String accessKeyId = ""; * String accessKeySecret = ""; * String securityToken = ""; - * + * * // 创建OSSClient实例。 * OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, securityToken); - * + * * // 关闭OSSClient。 * ossClient.shutdown(); - * + * * @author dzh * @date Feb 26, 2016 11:59:58 AM * @since 1.0 @@ -64,7 +62,9 @@ void start() { try { String file = plugin.getConfig(FILE_ALIOSS, plugin.getConfig(Config.APP_CONF) + "/alioss.properties"); - if (!new File(file).exists()) { throw new FileNotFoundException("not found " + file); } + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } _config.init(file); for (String id : _config.getGroupIds()) { String endpoint = _config.getConf(id, AliyunField.K_endpoint); @@ -76,11 +76,10 @@ void start() { OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf); clients.put(id, ossClient); } + LOG.info("Start OSSService Successfully!"); } catch (Exception e) { - LOG.error("Start OSSService Failure!" + e.getMessage(), e); - return; + LOG.error("Start OSSService Failed!" + e.getMessage(), e); } - LOG.info("Start OSSService Successfully!"); } @Stop diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sms/SMSServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sms/SMSServiceImpl.java index 431178d..8e50e9b 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sms/SMSServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sms/SMSServiceImpl.java @@ -1,21 +1,11 @@ package jframe.aliyun.service.sms; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; - import jframe.aliyun.AliyunField; import jframe.aliyun.AliyunPlugin; import jframe.aliyun.service.SMSService; @@ -25,15 +15,23 @@ import jframe.core.plugin.annotation.Start; import jframe.core.plugin.annotation.Stop; import jframe.core.util.PropsConf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; /** * https://help.aliyun.com/document_detail/55284.html?spm=a2c4g.11186623.6.566.5d1b4175GzAYkw - * + *

* https://helpcdn.aliyun.com/document_detail/68360.html - * + * * @author dzh - * @date Nov 19, 2018 7:01:24 PM * @version 0.0.1 + * @date Nov 19, 2018 7:01:24 PM */ @Injector public class SMSServiceImpl implements SMSService, AliyunField { @@ -55,7 +53,9 @@ void start() { try { String file = plugin.getConfig(FILE_ALISMS, plugin.getConfig(Config.APP_CONF) + "/alisms.properties"); - if (!new File(file).exists()) { throw new FileNotFoundException("not found " + file); } + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } _config.init(file); for (String id : _config.getGroupIds()) { // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求 @@ -69,11 +69,10 @@ void start() { DefaultAcsClient client = new DefaultAcsClient(profile); clients.put(id, client); } + LOG.info("Start SMSService Successfully!"); } catch (Exception e) { - LOG.error("Start SMSService Failure!" + e.getMessage(), e); - return; + LOG.error("Start SMSService Failed!" + e.getMessage(), e); } - LOG.info("Start SMSService Successfully!"); } @Stop @@ -91,7 +90,9 @@ void stop() { @Override public SendSmsResponse send(String id, SendSmsRequest request) throws ClientException { DefaultAcsClient client = clients.get(id); - if (client == null) { throw new NullPointerException("not found sms id:" + id); } + if (client == null) { + throw new NullPointerException("not found sms id:" + id); + } return client.getAcsResponse(request);// TODO async } diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java index 02ec68d..93657eb 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java @@ -1,18 +1,8 @@ /** - * + * */ package jframe.aliyun.service.sts; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.http.MethodType; @@ -21,7 +11,6 @@ import com.aliyuncs.profile.IClientProfile; import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest; import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; - import jframe.aliyun.AliyunField; import jframe.aliyun.AliyunPlugin; import jframe.aliyun.service.STSService; @@ -30,10 +19,19 @@ import jframe.core.plugin.annotation.Injector; import jframe.core.plugin.annotation.Start; import jframe.core.plugin.annotation.Stop; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; /** * https://help.aliyun.com/document_detail/28788.html?spm=a2c4g.11186623.6.695.uQYP1L - * + * * @author dzh * @date Feb 29, 2016 12:44:39 PM * @since 1.0 @@ -58,7 +56,9 @@ void start() { try { String file = plugin.getConfig(FILE_ALISTS, plugin.getConfig(Config.APP_CONF) + "/alists.properties"); - if (!new File(file).exists()) { throw new FileNotFoundException("not found " + file); } + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } _config.init(file); for (String id : _config.getGroupIds()) { // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求 @@ -67,11 +67,11 @@ void start() { DefaultAcsClient client = new DefaultAcsClient(profile); clients.put(id, client); } + LOG.info("Start STSService Successfully!"); } catch (Exception e) { - LOG.error("Start STSService Failure!" + e.getMessage(), e); - return; + LOG.error("Start STSService Failed!" + e.getMessage(), e); } - LOG.info("Start STSService Successfully!"); + } @Stop diff --git a/jframe-plugin/pom.xml b/jframe-plugin/pom.xml index 8940462..5bdd6c3 100644 --- a/jframe-plugin/pom.xml +++ b/jframe-plugin/pom.xml @@ -43,6 +43,7 @@ jframe-redisson jframe-qcloud jframe-google + jframe-alipay From ec499e071ba2e9d98cfe8a40b11a593b06653784 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 13 Aug 2019 16:46:05 +0800 Subject: [PATCH 04/47] upg lib --- .../jframe/alipay/service/AlipayService.java | 1 + jframe-plugin/jframe-aliyun/pom.xml | 70 +++++++++---------- jframe-plugin/jframe-zk/pom.xml | 62 ++++++++-------- .../jframe/zk/service/CuratorService.java | 5 +- .../zk/service/impl/CuratorServiceImpl.java | 33 ++++----- 5 files changed, 86 insertions(+), 85 deletions(-) diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java index c314054..dee0c21 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java @@ -11,6 +11,7 @@ *

* https://openhome.alipay.com/platform/demoManage.htm#/alipay.trade.page.pay * https://openhome.alipay.com/platform/appDaily.htm?tab=info + * https://sandbox.alipaydev.com/user/accountDetails.htm?currentBar=1 * * @author dzh * @date 2019-07-22 14:56 diff --git a/jframe-plugin/jframe-aliyun/pom.xml b/jframe-plugin/jframe-aliyun/pom.xml index e742611..d79fe4e 100644 --- a/jframe-plugin/jframe-aliyun/pom.xml +++ b/jframe-plugin/jframe-aliyun/pom.xml @@ -1,39 +1,39 @@ - 4.0.0 - - io.github.dzh - jframe-plugin - 2.0.0-SNAPSHOT - - jframe-aliyun + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe-plugin + 2.0.0-SNAPSHOT + + jframe-aliyun - - - com.aliyun - aliyun-java-sdk-core - 4.2.1 - + + + com.aliyun + aliyun-java-sdk-core + 4.2.1 + - - com.aliyun.oss - aliyun-sdk-oss - 3.3.0 - - - com.aliyun - aliyun-java-sdk-sts - 3.0.0 - - - com.aliyun - aliyun-java-sdk-dysmsapi - 1.1.0 - - - com.aliyun - aliyun-java-sdk-dm - 3.3.1 - - + + com.aliyun.oss + aliyun-sdk-oss + 3.6.0 + + + com.aliyun + aliyun-java-sdk-sts + 3.0.1 + + + com.aliyun + aliyun-java-sdk-dysmsapi + 1.1.0 + + + com.aliyun + aliyun-java-sdk-dm + 3.3.1 + + \ No newline at end of file diff --git a/jframe-plugin/jframe-zk/pom.xml b/jframe-plugin/jframe-zk/pom.xml index 5ab2f39..131eb1a 100644 --- a/jframe-plugin/jframe-zk/pom.xml +++ b/jframe-plugin/jframe-zk/pom.xml @@ -1,35 +1,35 @@ - 4.0.0 - - jframe-plugin - 2.0.0-SNAPSHOT - io.github.dzh - - jframe-zk + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + jframe-plugin + 2.0.0-SNAPSHOT + io.github.dzh + + jframe-zk - - 4.2.0 - + + 4.2.0 + - - - org.apache.curator - curator-client - ${curator.version} - - - org.apache.curator - curator-framework - ${curator.version} - - - org.apache.curator - curator-recipes - ${curator.version} - - - + + + org.apache.curator + curator-client + ${curator.version} + + + org.apache.curator + curator-framework + ${curator.version} + + + org.apache.curator + curator-recipes + ${curator.version} + + + \ No newline at end of file diff --git a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java index fff9b9c..fc771f4 100644 --- a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java +++ b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java @@ -1,13 +1,12 @@ package jframe.zk.service; -import org.apache.curator.framework.CuratorFramework; - import jframe.core.plugin.annotation.Service; +import org.apache.curator.framework.CuratorFramework; /** * @author dzh - * @date Dec 12, 2018 7:12:56 PM * @version 0.0.1 + * @date Dec 12, 2018 7:12:56 PM */ @Service(clazz = "jframe.zk.service.impl.CuratorServiceImpl", id = "jframe.service.zk.curator") public interface CuratorService { diff --git a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java index b2e8399..0fbc37a 100644 --- a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java +++ b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java @@ -1,22 +1,8 @@ /** - * + * */ package jframe.zk.service.impl; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.apache.curator.RetryPolicy; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.framework.imps.CuratorFrameworkState; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import jframe.core.conf.Config; import jframe.core.plugin.annotation.InjectPlugin; import jframe.core.plugin.annotation.Injector; @@ -26,6 +12,19 @@ import jframe.zk.ZkField; import jframe.zk.ZkPlugin; import jframe.zk.service.CuratorService; +import org.apache.curator.RetryPolicy; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.framework.imps.CuratorFrameworkState; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** * @author dzh @@ -52,7 +51,9 @@ void start() { try { String file = Plugin.getConfig(FILE_CURATOR, Plugin.getConfig(Config.APP_CONF) + "/curator.properties"); - if (!new File(file).exists()) { throw new FileNotFoundException("not found " + file); } + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } _config.init(file); for (String id : _config.getGroupIds()) { String connectString = _config.getConf(id, ZkField.ConnectString); From 966e9eb7e5c3668c976257c69e5b7412160c4702 Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 30 Dec 2019 16:50:24 +0800 Subject: [PATCH 05/47] add RmqDispatcher --- jframe/jframe-ext/pom.xml | 7 + .../ext/dispatch/kafka/KafkaDispatcher.java | 46 ++-- .../ext/dispatch/rocketmq/MsgCodec.java | 19 ++ .../rocketmq/RmqConsumerDispatcher.java | 19 ++ .../ext/dispatch/rocketmq/RmqDispatcher.java | 257 ++++++++++++++++++ .../rocketmq/RmqProducerDispatcher.java | 19 ++ .../ext/dispatch/rocketmq/TextMsgCodec.java | 29 ++ .../java/jframe/ext/plugin/KafkaPlugin.java | 2 +- .../jframe/ext/plugin/RocketmqPlugin.java | 28 ++ 9 files changed, 403 insertions(+), 23 deletions(-) create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/MsgCodec.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConsumerDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqProducerDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/TextMsgCodec.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java diff --git a/jframe/jframe-ext/pom.xml b/jframe/jframe-ext/pom.xml index 8507d0d..5825aae 100644 --- a/jframe/jframe-ext/pom.xml +++ b/jframe/jframe-ext/pom.xml @@ -39,5 +39,12 @@ 2.1.0 + + + org.apache.rocketmq + rocketmq-client + 4.6.0 + + \ No newline at end of file diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java index 91f2f58..7d4a7f3 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java @@ -1,14 +1,8 @@ package jframe.ext.dispatch.kafka; -import java.io.FileInputStream; -import java.time.Duration; -import java.util.Arrays; -import java.util.Collections; -import java.util.Objects; -import java.util.Properties; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; - +import jframe.core.conf.Config; +import jframe.core.dispatch.AbstractDispatcher; +import jframe.core.msg.Msg; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; @@ -18,9 +12,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jframe.core.conf.Config; -import jframe.core.dispatch.AbstractDispatcher; -import jframe.core.msg.Msg; +import java.io.FileInputStream; +import java.time.Duration; +import java.util.Arrays; +import java.util.Collections; +import java.util.Objects; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; /** *

@@ -30,7 +29,7 @@ *

  • file.d.kafka.consumer=${app.home}/conf/d-kafka-consumer.properties
  • *
  • d.kafka.subscribe=topicA topicB topicC *

    - * + * *

    * msg meta: *

  • d.kafka.r.topic 对应{@link ProducerRecord}的topic
  • @@ -38,10 +37,10 @@ *
  • d.kafka.r.partition
  • *
  • d.kafka.r.timestamp
  • *

    - * + * * @author dzh - * @date Dec 26, 2018 5:16:26 PM * @version 0.0.1 + * @date Dec 26, 2018 5:16:26 PM */ public class KafkaDispatcher extends AbstractDispatcher { @@ -118,10 +117,10 @@ private void startProducer() { /** * http://kafka.apache.org/21/javadoc/index.html?org/apache/kafka/clients/producer/KafkaProducer.html - * + * * @param props */ - private void loadDefaultProducer(Properties props) { + protected void loadDefaultProducer(Properties props) { props.put("bootstrap.servers", "localhost:9092"); props.put("acks", "all"); props.put("delivery.timeout.ms", 30000); @@ -154,6 +153,7 @@ private void startConsumer() { } catch (Exception e) { LOG.error(e.getMessage(), e); close(); + return; } final boolean autoCommit = "true".equals(props.get("enable.auto.commit")) ? true : false; this.dispatchT = new Thread(() -> { @@ -185,10 +185,10 @@ protected Consumer> createConsumer(Properties props) { Consumer> consumer = new KafkaConsumer<>(props); String topics = DEFAULT_TOPIC; if (getConfig().contain(D_KAFKA_SUBSCRIBE)) { - topics = getConfig().getConfig(D_KAFKA_SUBSCRIBE); + topics = getConfig().getConfig(D_KAFKA_SUBSCRIBE); //todo put into props consumer.subscribe(Arrays.asList(topics.split("\\s+"))); } else if (getConfig().contain(D_KAFKA_SUBSCRIBE_REGEX)) { - topics = getConfig().getConfig(D_KAFKA_SUBSCRIBE_REGEX); + topics = getConfig().getConfig(D_KAFKA_SUBSCRIBE_REGEX); //todo put into props consumer.subscribe(Pattern.compile(topics)); } else { consumer.subscribe(Arrays.asList(topics)); @@ -199,10 +199,10 @@ protected Consumer> createConsumer(Properties props) { /** * http://kafka.apache.org/21/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html - * + * * @param props */ - private void loadDefaultConsumer(Properties props) { + protected void loadDefaultConsumer(Properties props) { props.put("bootstrap.servers", "localhost:9092"); props.put("group.id", "jframe"); props.put("enable.auto.commit", "true"); @@ -254,6 +254,7 @@ public Consumer> getConsumer() { @Override public void close() { + if (closed) return; // close producer if (enableProducer()) producer.close(WAIT_CLOSED_SECOND, TimeUnit.SECONDS); @@ -263,7 +264,8 @@ public void close() { if (dispatchT != null) { try { dispatchT.join(WAIT_CLOSED_SECOND * 1000L); - } catch (InterruptedException e) {} + } catch (InterruptedException e) { + } } } super.close(); diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/MsgCodec.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/MsgCodec.java new file mode 100644 index 0000000..dc586da --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/MsgCodec.java @@ -0,0 +1,19 @@ +package jframe.ext.dispatch.rocketmq; + +import jframe.core.msg.Msg; + +import java.io.IOException; + +/** + * ThreadSafe + * + * @author dzh + * @date 2019/12/25 21:11 + */ +public interface MsgCodec { + + byte[] encode(Msg msg) throws IOException; + + Msg decode(byte[] msg) throws IOException; + +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConsumerDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConsumerDispatcher.java new file mode 100644 index 0000000..3883840 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConsumerDispatcher.java @@ -0,0 +1,19 @@ +package jframe.ext.dispatch.rocketmq; + +import jframe.core.conf.Config; + +/** + * @author dzh + * @date 2019/12/25 18:15 + */ +public class RmqConsumerDispatcher extends RmqDispatcher { + + public RmqConsumerDispatcher(String id, Config config) { + super(id, config); + } + + @Override + protected boolean enableProducer() { + return false; + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java new file mode 100644 index 0000000..abf3659 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java @@ -0,0 +1,257 @@ +package jframe.ext.dispatch.rocketmq; + +import jframe.core.conf.Config; +import jframe.core.dispatch.AbstractDispatcher; +import jframe.core.msg.Msg; +import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; +import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; +import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; +import org.apache.rocketmq.client.exception.MQClientException; +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.apache.rocketmq.client.producer.SendResult; +import org.apache.rocketmq.common.message.Message; +import org.apache.rocketmq.common.message.MessageExt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileInputStream; +import java.util.Objects; +import java.util.Properties; + +/** + * @author dzh + * @date 2019/12/25 13:02 + */ +public class RmqDispatcher extends AbstractDispatcher { + + static Logger LOG = LoggerFactory.getLogger(RmqDispatcher.class); + +// private volatile boolean closed; + + private DefaultMQProducer producer; + private DefaultMQPushConsumer consumer; + + public static final String FILE_RMQ_PRODUCER = "file.rmq.producer"; + public static final String FILE_RMQ_CONSUMER = "file.rmq.consumer"; + + public static final String D_RMQ_CODEC = "d.rmq.codec"; // MsgCodec + + public static final String DEFAULT_TOPIC = "jframe"; + public static final String D_RMQ_R_TOPIC = "d.rmq.r.topic"; + public static final String D_RMQ_R_TAG = "d.rmq.r.tag"; + public static final String D_RMQ_R_Key = "d.rmq.r.key"; + +// private Thread dispatchT; // consume dispatch thread + + private MsgCodec msgCodec; + + public RmqDispatcher(String id, Config config) { + super(id, config); + } + + protected boolean enableProducer() { + return true; + } + + protected boolean enableConsumer() { + return true; + } + + @Override + public void start() { + try { + initMsgCodec(); + if (enableConsumer()) startConsumer(); + if (enableProducer()) startProducer(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + close(); + } + } + + private void initMsgCodec() { + String clazz = getConfig().getConfig(D_RMQ_CODEC, TextMsgCodec.class.getName()); + try { + msgCodec = (MsgCodec) Class.forName(clazz).newInstance(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } + + private void startProducer() throws MQClientException { + String file = getConfig().getConfig(FILE_RMQ_PRODUCER); + if (Objects.isNull(file)) { + file = getConfig().getConfig(Config.APP_CONF) + "/rmq-producer.properties"; + } + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(file)) { + props.load(fis); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + loadDefaultProducer(props); + } + + LOG.info("start producer with {}", props); + producer = new DefaultMQProducer(); + if (props.containsKey("producer.group")) { + producer.setProducerGroup(props.getProperty("producer.group")); + } + if (props.containsKey("namespace")) { + producer.setNamespace(props.getProperty("namespace")); + } + producer.setNamesrvAddr(props.getProperty("namesrv.addr", "localhost:9876")); + producer.setRetryTimesWhenSendFailed(Integer.parseInt(props.getProperty("retry.times", "3"))); + producer.setVipChannelEnabled(Boolean.parseBoolean(props.getProperty("vipChannelEnabled", "false"))); +// LOG.info("start producer {} {}", producer.getProducerGroup(), producer.getNamesrvAddr()); + producer.start(); +// List mqList = producer.fetchPublishMessageQueues(topic()); +// if (mqList == null || mqList.isEmpty()) { +// producer.createTopic(topicKey(), topic(), topicQueueNum()); +// } + } + + private void loadDefaultProducer(Properties props) { + props.put("producer.group", getConfig().getConfig(Config.APP_NAME)); + props.put("namesrv.addr", "localhost:9876"); + props.put("retry.times", "3"); + props.put("vipChannelEnabled", "false"); + } + + private void startConsumer() { + String file = getConfig().getConfig(FILE_RMQ_CONSUMER); + if (Objects.isNull(file)) { + file = getConfig().getConfig(Config.APP_CONF) + "/rmq-consumer.properties"; + } + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(file)) { + props.load(fis); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + loadDefaultConsumer(props); + } + LOG.info("start consumer with {}", props); + try { + consumer = createConsumer(props); + consumer.start(); +// consumer.seekToEnd(Collections.emptyList()); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + close(); + } + + // pull mode +// this.dispatchT = new Thread(() -> { +// LOG.info("{} start", Thread.currentThread().getName()); +// while (true) { +// if (closed) break; +// try { +// } catch (Exception e) { +// LOG.warn(e.getMessage(), e); +// continue; +// } +// dispatch(record.value()); +// } +// LOG.info("{} closed", Thread.currentThread().getName()); +// }, "rocketmqConsumeThread"); +// dispatchT.start(); + } + + private void loadDefaultConsumer(Properties props) { + props.setProperty("consumer.group", getConfig().getConfig(Config.APP_NAME)); + props.setProperty("namesrv.addr", "localhost:9876"); + + } + + // todo multi topics + private DefaultMQPushConsumer createConsumer(Properties props) throws MQClientException { + DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(props.getProperty("consumer.group")); + consumer.setNamesrvAddr(props.getProperty("namesrv.addr", "localhost:9876")); + String val = props.getProperty("consume.message.batch.maxsize", "1"); //[1,1024] +// consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP); +// consumer.setConsumeTimestamp(consumeTimestamp()); + consumer.setConsumeMessageBatchMaxSize(Integer.parseInt(val)); + val = props.getProperty("consume.timeout", "5"); //minutes + consumer.setConsumeTimeout(Long.parseLong(val)); + consumer.subscribe(props.getProperty("consume.topic", "jframe"), + props.getProperty("consume.subExpression", "*")); + consumer.setVipChannelEnabled(false); + val = props.getProperty("consume.thread.max"); + if (val != null) + consumer.setConsumeThreadMax(Integer.parseInt(val)); + val = props.getProperty("consume.thread.min"); + if (val != null) + consumer.setConsumeThreadMin(Integer.parseInt(val)); + val = props.getProperty("consume.instance.name"); + if (val != null) + consumer.setInstanceName(val); + val = props.getProperty("consume.pull.threshold"); + if (val != null) + consumer.setPullThresholdForQueue(Integer.parseInt(val)); + val = props.getProperty("consume.concurrently.max.span"); + if (val != null) + consumer.setConsumeConcurrentlyMaxSpan(Integer.parseInt(val));// 2000 + val = props.getProperty("consume.max.reconsume.times", "16"); + consumer.setMaxReconsumeTimes(Integer.parseInt(val)); // 16 + val = props.getProperty("consume.persist.consumer.offset.interval", "3000"); + consumer.setPersistConsumerOffsetInterval(Integer.parseInt(val)); // ms + + boolean ingoreTimeoutMsg = Boolean.parseBoolean(props.getProperty("consume.ignore.timeout.msg", "false")); + int ingoreTimeoutMsgMs = Integer.parseInt(props.getProperty("consume.ignore.timeout.msg.ms", "10000")); + consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> { + for (MessageExt msg : msgs) { + try { + if (ingoreTimeoutMsg && (System.currentTimeMillis() - msg.getBornTimestamp()) >= ingoreTimeoutMsgMs) { + LOG.warn("discard rmq timeout msg-{}", msg); + continue; + } + + LOG.info("recv rmq msg-{}", msg); + dispatch(msgCodec.decode(msg.getBody())); + } catch (Exception e) { + LOG.info(e.getMessage(), e); + if (msg.getReconsumeTimes() == consumer.getMaxReconsumeTimes()) { + LOG.warn("over MaxReconsumeTimes, discard msg-{}", msg); + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + } + return ConsumeConcurrentlyStatus.RECONSUME_LATER; + } + } + return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; + }); + return consumer; + } + + @Override + public void receive(Msg msg) { + if (producer != null) { + String topic = (String) msg.getMeta(D_RMQ_R_TOPIC); + if (Objects.isNull(topic)) { + topic = DEFAULT_TOPIC; + } + + try { + Message rmqMsg = new Message(topic, + (String) msg.getMeta(D_RMQ_R_TAG), (String) msg.getMeta(D_RMQ_R_Key), + msgCodec.encode(msg)); + SendResult r = producer.send(rmqMsg); + LOG.debug("receive {}, sendResult {}", msg, r); + } catch (Exception e) { + LOG.error(e.getMessage(), e);//todo + } + } + } + +// private int WAIT_CLOSED_SECOND = 60; + + @Override + public void close() { + // close producer + if (enableProducer()) producer.shutdown(); + + // close dispatcher and consumer + if (enableConsumer()) { + consumer.shutdown(); + } + super.close(); + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqProducerDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqProducerDispatcher.java new file mode 100644 index 0000000..0c83a22 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqProducerDispatcher.java @@ -0,0 +1,19 @@ +package jframe.ext.dispatch.rocketmq; + +import jframe.core.conf.Config; + +/** + * @author dzh + * @date 2019/12/25 18:16 + */ +public class RmqProducerDispatcher extends RmqDispatcher { + + public RmqProducerDispatcher(String id, Config config) { + super(id, config); + } + + @Override + protected boolean enableConsumer() { + return false; + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/TextMsgCodec.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/TextMsgCodec.java new file mode 100644 index 0000000..edeca6a --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/TextMsgCodec.java @@ -0,0 +1,29 @@ +package jframe.ext.dispatch.rocketmq; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import jframe.core.msg.Msg; +import jframe.core.msg.TextMsg; + +import java.io.IOException; + +/** + * @author dzh + * @date 2019/12/25 21:13 + */ +public class TextMsgCodec implements MsgCodec { + + protected String encoding = "UTF8"; + + static final Gson GSON = new GsonBuilder().serializeNulls().create(); + + @Override + public byte[] encode(Msg msg) throws IOException { + return GSON.toJson(msg).getBytes(encoding); //todo msg's data must be String + } + + @Override + public Msg decode(byte[] msg) throws IOException { + return GSON.fromJson(new String(msg, encoding), TextMsg.class); + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java index 2311677..86dd0d0 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java @@ -6,8 +6,8 @@ /** * @author dzh - * @date Dec 27, 2018 3:05:36 PM * @version 0.0.1 + * @date Dec 27, 2018 3:05:36 PM */ public abstract class KafkaPlugin extends PluginSender { diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java new file mode 100644 index 0000000..610a76e --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java @@ -0,0 +1,28 @@ +package jframe.ext.plugin; + +import jframe.core.msg.Msg; +import jframe.core.plugin.PluginSender; +import jframe.ext.dispatch.rocketmq.RmqDispatcher; + +/** + * Rocketmq Plugin + * + * @author dzh + * @date 2019/12/25 15:22 + */ +public abstract class RocketmqPlugin extends PluginSender { + + public void send(Msg msg, String topic, String tag, String key) { + if (msg == null) return; + + msg.setMeta(RmqDispatcher.D_RMQ_R_TOPIC, topic); + msg.setMeta(RmqDispatcher.D_RMQ_R_TAG, tag); + msg.setMeta(RmqDispatcher.D_RMQ_R_Key, key); + + send(msg); + } + + public void send(Msg msg, String topic) { + send(msg, topic, null, null); + } +} From 6fae126c1917de6030eb8c30761065643c329857 Mon Sep 17 00:00:00 2001 From: dzh Date: Sun, 12 Jan 2020 18:14:38 +0800 Subject: [PATCH 06/47] add OnsDispatcher --- jframe/jframe-ext/pom.xml | 91 ++++---- .../ext/dispatch/kafka/KafkaDispatcher.java | 6 +- .../dispatch/ons/OnsConsumerDispatcher.java | 20 ++ .../ext/dispatch/ons/OnsDispatcher.java | 194 ++++++++++++++++++ .../dispatch/ons/OnsProducerDispatcher.java | 19 ++ .../ext/dispatch/rocketmq/RmqConst.java | 18 ++ .../ext/dispatch/rocketmq/RmqDispatcher.java | 20 +- 7 files changed, 308 insertions(+), 60 deletions(-) create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsConsumerDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsProducerDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java diff --git a/jframe/jframe-ext/pom.xml b/jframe/jframe-ext/pom.xml index 5825aae..c8c5d9f 100644 --- a/jframe/jframe-ext/pom.xml +++ b/jframe/jframe-ext/pom.xml @@ -1,50 +1,57 @@ - 4.0.0 - - io.github.dzh - jframe - 2.0.0-SNAPSHOT - - jframe-ext + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + io.github.dzh + jframe + 2.0.0-SNAPSHOT + + jframe-ext - - - ${project.groupId} - jframe-core - + + + ${project.groupId} + jframe-core + - - com.google.code.gson - gson - 2.8.5 - + + com.google.code.gson + gson + 2.8.5 + - - - org.apache.activemq - activemq-client - 5.10.0 - - - org.apache.activemq - activemq-jms-pool - 5.15.7 - + + + org.apache.activemq + activemq-client + 5.10.0 + + + org.apache.activemq + activemq-jms-pool + 5.15.7 + - - - org.apache.kafka - kafka-clients - 2.1.0 - + + + org.apache.kafka + kafka-clients + 2.1.0 + - - - org.apache.rocketmq - rocketmq-client - 4.6.0 - + + + org.apache.rocketmq + rocketmq-client + 4.6.0 + - + + + com.aliyun.openservices + ons-client + 1.8.4.Final + + + \ No newline at end of file diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java index 7d4a7f3..4ee3550 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java @@ -152,8 +152,8 @@ private void startConsumer() { consumer.seekToEnd(Collections.emptyList()); } catch (Exception e) { LOG.error(e.getMessage(), e); - close(); - return; +// close(); +// return; } final boolean autoCommit = "true".equals(props.get("enable.auto.commit")) ? true : false; this.dispatchT = new Thread(() -> { @@ -162,7 +162,7 @@ private void startConsumer() { while (true) { if (closed) break; try { - records = consumer.poll(Duration.ofMillis(1000L)); + records = consumer.poll(Duration.ofMillis(1000L));// } catch (Exception e) { LOG.warn(e.getMessage(), e); continue; diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsConsumerDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsConsumerDispatcher.java new file mode 100644 index 0000000..e4627f7 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsConsumerDispatcher.java @@ -0,0 +1,20 @@ +package jframe.ext.dispatch.ons; + +import jframe.core.conf.Config; + +/** + * @author dzh + * @date 2020/1/11 19:26 + */ +public class OnsConsumerDispatcher extends OnsDispatcher { + + public OnsConsumerDispatcher(String id, Config config) { + super(id, config); + } + + @Override + protected boolean enableProducer() { + return false; + } + +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java new file mode 100644 index 0000000..41e91c0 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java @@ -0,0 +1,194 @@ +package jframe.ext.dispatch.ons; + +import com.aliyun.openservices.ons.api.*; +import jframe.core.conf.Config; +import jframe.core.dispatch.AbstractDispatcher; +import jframe.core.msg.Msg; +import jframe.ext.dispatch.rocketmq.MsgCodec; +import jframe.ext.dispatch.rocketmq.RmqConst; +import jframe.ext.dispatch.rocketmq.TextMsgCodec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileInputStream; +import java.util.Objects; +import java.util.Properties; + +/** + * aliyun rocketmq + * https://help.aliyun.com/document_detail/29547.html + * + * @author dzh + * @date 2020/1/11 19:17 + */ +public class OnsDispatcher extends AbstractDispatcher implements RmqConst { + + static Logger LOG = LoggerFactory.getLogger(OnsDispatcher.class); + + private Producer producer; + private Consumer consumer; + + private MsgCodec msgCodec; + + public OnsDispatcher(String id, Config config) { + super(id, config); + } + + protected boolean enableProducer() { + return true; + } + + protected boolean enableConsumer() { + return true; + } + + @Override + public void start() { + try { + initMsgCodec(); + if (enableConsumer()) startConsumer(); + if (enableProducer()) startProducer(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + close(); + } + } + + //https://help.aliyun.com/document_detail/29547.html?spm=a2c4g.11186623.6.575.73a8d54cqwV0z7 + private void startProducer() { + String file = getConfig().getConfig(FILE_RMQ_PRODUCER); + if (Objects.isNull(file)) { + file = getConfig().getConfig(Config.APP_CONF) + "/rmq-producer.properties"; + } + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(file)) { + props.load(fis); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + return; + } + + LOG.info("start producer with {}", props); + +// Properties properties = new Properties(); +// // AccessKey 阿里云身份验证,在阿里云用户信息管理控制台获取 +// properties.put(PropertyKeyConst.AccessKey, "XXX"); +// // SecretKey 阿里云身份验证,在阿里云用户信息管理控制台获取 +// properties.put(PropertyKeyConst.SecretKey, "XXX"); +// //设置发送超时时间,单位毫秒 +// properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000"); +// // 设置 TCP 接入域名,进入控制台的实例详情页面的获取接入点信息区域查看 +// properties.put(PropertyKeyConst.NAMESRV_ADDR, +// "XXX"); + Producer producer = ONSFactory.createProducer(props); + // 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可 + producer.start(); + } + + private void startConsumer() { + String file = getConfig().getConfig(FILE_RMQ_CONSUMER); + if (Objects.isNull(file)) { + file = getConfig().getConfig(Config.APP_CONF) + "/rmq-consumer.properties"; + } + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(file)) { + props.load(fis); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + return; + } + LOG.info("start consumer with {}", props); + try { + consumer = createConsumer(props); + consumer.start(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); +// close(); + } + } + + //https://help.aliyun.com/document_detail/29551.html?spm=a2c4g.11186623.6.581.7c13d54cmyIEny + private Consumer createConsumer(Properties props) { +// Properties properties = new Properties(); +// // 您在控制台创建的 Group ID +// properties.put(PropertyKeyConst.GROUP_ID, "XXX"); +// // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 +// properties.put(PropertyKeyConst.AccessKey, "XXX"); +// // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 +// properties.put(PropertyKeyConst.SecretKey, "XXX"); +// // 设置 TCP 接入域名,进入控制台的实例管理页面的“获取接入点信息”区域查看 +// properties.put(PropertyKeyConst.NAMESRV_ADDR, +// "XXX"); + // 集群订阅方式 (默认) +// properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING); + // 广播订阅方式 + // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING); + + Consumer consumer = ONSFactory.createConsumer(props); + + boolean ingoreTimeoutMsg = Boolean.parseBoolean(props.getProperty("consume.ignore.timeout.msg", "false")); + int ingoreTimeoutMsgMs = Integer.parseInt(props.getProperty("consume.ignore.timeout.msg.ms", "10000")); + + //订阅多个 Tag + consumer.subscribe(props.getProperty("consume.topic", "jframe"), + props.getProperty("consume.subExpression", "*"), new MessageListener() { + public Action consume(Message msg, ConsumeContext context) { + LOG.debug("consume ons msg-{}", msg); + try { + if (ingoreTimeoutMsg && (System.currentTimeMillis() - msg.getBornTimestamp()) >= ingoreTimeoutMsgMs) { + LOG.warn("discard ons timeout msg-{}", msg); + return Action.CommitMessage; + } + LOG.info("dispatch ons msg-{}", msg.getKey()); + dispatch(msgCodec.decode(msg.getBody())); + } catch (Exception e) { + LOG.info(e.getMessage(), e); + return Action.ReconsumeLater; + } + return Action.CommitMessage; + } + }); + return consumer; + } + + private void initMsgCodec() { + String clazz = getConfig().getConfig(D_RMQ_CODEC, TextMsgCodec.class.getName()); + try { + msgCodec = (MsgCodec) Class.forName(clazz).newInstance(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } + + @Override + public void receive(Msg msg) { + if (producer != null) { + String topic = (String) msg.getMeta(D_RMQ_R_TOPIC); + if (Objects.isNull(topic)) { + topic = DEFAULT_TOPIC; + } + + try { + Message rmqMsg = new Message(topic, + (String) msg.getMeta(D_RMQ_R_TAG), (String) msg.getMeta(D_RMQ_R_Key), + msgCodec.encode(msg)); + SendResult r = producer.send(rmqMsg); + LOG.debug("send msg {}, sendResult {}", msg, r); + } catch (Exception e) { + LOG.error(e.getMessage(), e);//todo + } + } + } + + @Override + public void close() { + // close producer + if (enableProducer()) producer.shutdown(); + + // close dispatcher and consumer + if (enableConsumer()) { + consumer.shutdown(); + } + super.close(); + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsProducerDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsProducerDispatcher.java new file mode 100644 index 0000000..476a6f2 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsProducerDispatcher.java @@ -0,0 +1,19 @@ +package jframe.ext.dispatch.ons; + +import jframe.core.conf.Config; + +/** + * @author dzh + * @date 2020/1/11 19:29 + */ +public class OnsProducerDispatcher extends OnsDispatcher { + + public OnsProducerDispatcher(String id, Config config) { + super(id, config); + } + + @Override + protected boolean enableConsumer() { + return false; + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java new file mode 100644 index 0000000..ef59b7a --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java @@ -0,0 +1,18 @@ +package jframe.ext.dispatch.rocketmq; + +/** + * @author dzh + * @date 2020/1/11 19:35 + */ +public interface RmqConst { + + public static final String FILE_RMQ_PRODUCER = "file.rmq.producer"; + public static final String FILE_RMQ_CONSUMER = "file.rmq.consumer"; + + public static final String D_RMQ_CODEC = "d.rmq.codec"; // MsgCodec + + public static final String DEFAULT_TOPIC = "jframe"; + public static final String D_RMQ_R_TOPIC = "d.rmq.r.topic"; + public static final String D_RMQ_R_TAG = "d.rmq.r.tag"; + public static final String D_RMQ_R_Key = "d.rmq.r.key"; +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java index abf3659..4941e44 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java @@ -22,7 +22,7 @@ * @author dzh * @date 2019/12/25 13:02 */ -public class RmqDispatcher extends AbstractDispatcher { +public class RmqDispatcher extends AbstractDispatcher implements RmqConst { static Logger LOG = LoggerFactory.getLogger(RmqDispatcher.class); @@ -31,16 +31,6 @@ public class RmqDispatcher extends AbstractDispatcher { private DefaultMQProducer producer; private DefaultMQPushConsumer consumer; - public static final String FILE_RMQ_PRODUCER = "file.rmq.producer"; - public static final String FILE_RMQ_CONSUMER = "file.rmq.consumer"; - - public static final String D_RMQ_CODEC = "d.rmq.codec"; // MsgCodec - - public static final String DEFAULT_TOPIC = "jframe"; - public static final String D_RMQ_R_TOPIC = "d.rmq.r.topic"; - public static final String D_RMQ_R_TAG = "d.rmq.r.tag"; - public static final String D_RMQ_R_Key = "d.rmq.r.key"; - // private Thread dispatchT; // consume dispatch thread private MsgCodec msgCodec; @@ -136,7 +126,7 @@ private void startConsumer() { // consumer.seekToEnd(Collections.emptyList()); } catch (Exception e) { LOG.error(e.getMessage(), e); - close(); +// close(); } // pull mode @@ -199,13 +189,13 @@ private DefaultMQPushConsumer createConsumer(Properties props) throws MQClientEx int ingoreTimeoutMsgMs = Integer.parseInt(props.getProperty("consume.ignore.timeout.msg.ms", "10000")); consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> { for (MessageExt msg : msgs) { + LOG.debug("consume rmq msg-{}", msg); try { if (ingoreTimeoutMsg && (System.currentTimeMillis() - msg.getBornTimestamp()) >= ingoreTimeoutMsgMs) { LOG.warn("discard rmq timeout msg-{}", msg); continue; } - - LOG.info("recv rmq msg-{}", msg); + LOG.info("dispatch rmq msg-{}", msg.getKeys()); dispatch(msgCodec.decode(msg.getBody())); } catch (Exception e) { LOG.info(e.getMessage(), e); @@ -234,7 +224,7 @@ public void receive(Msg msg) { (String) msg.getMeta(D_RMQ_R_TAG), (String) msg.getMeta(D_RMQ_R_Key), msgCodec.encode(msg)); SendResult r = producer.send(rmqMsg); - LOG.debug("receive {}, sendResult {}", msg, r); + LOG.debug("send msg {}, sendResult {}", msg, r); } catch (Exception e) { LOG.error(e.getMessage(), e);//todo } From 4f32c4abde23056b7a48931a9961f2ca88a5e631 Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 20 Jan 2020 17:03:28 +0800 Subject: [PATCH 07/47] add OnsDispatcher --- .../src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java index 41e91c0..3ae239d 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java @@ -80,7 +80,7 @@ private void startProducer() { // // 设置 TCP 接入域名,进入控制台的实例详情页面的获取接入点信息区域查看 // properties.put(PropertyKeyConst.NAMESRV_ADDR, // "XXX"); - Producer producer = ONSFactory.createProducer(props); + producer = ONSFactory.createProducer(props); // 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可 producer.start(); } From 122c4ce0b11385adb564f92003823cc593434d33 Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 20 Jan 2020 21:22:36 +0800 Subject: [PATCH 08/47] add endpoint for sts --- .../src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java index 93657eb..baf0a9f 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java @@ -111,6 +111,8 @@ AssumeRoleResponse assumeRole(String id, String roleArn, String roleSessionName, // 创建一个 AssumeRoleRequest 并设置请求参数 final AssumeRoleRequest request = new AssumeRoleRequest(); + // https://help.aliyun.com/document_detail/66053.html?spm=a2c4g.11186623.6.799.7c6d7074SK0BQS + request.setEncoding(_config.getConf(id, K_endpoint, "sts.aliyuncs.com")); request.setVersion(_config.getConf(id, K_api_version)); request.setMethod(MethodType.POST); request.setProtocol(protocolType); From 202beb66b05159f3b6211e0b75d14d88ba63b96e Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 20 Jan 2020 21:42:41 +0800 Subject: [PATCH 09/47] add endpoint for sts --- .../src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java index baf0a9f..21dc982 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/sts/STSServiceImpl.java @@ -112,7 +112,7 @@ AssumeRoleResponse assumeRole(String id, String roleArn, String roleSessionName, // 创建一个 AssumeRoleRequest 并设置请求参数 final AssumeRoleRequest request = new AssumeRoleRequest(); // https://help.aliyun.com/document_detail/66053.html?spm=a2c4g.11186623.6.799.7c6d7074SK0BQS - request.setEncoding(_config.getConf(id, K_endpoint, "sts.aliyuncs.com")); + request.setEndpoint(_config.getConf(id, K_endpoint, "sts.aliyuncs.com")); request.setVersion(_config.getConf(id, K_api_version)); request.setMethod(MethodType.POST); request.setProtocol(protocolType); From 3c7acb7bb08a7908a97fdb7a15afbd7bc86a54ba Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 2 Mar 2020 22:40:24 +0800 Subject: [PATCH 10/47] opt service id --- jframe-plugin/jframe-alipay/pom.xml | 2 +- .../jframe/alipay/service/AlipayService.java | 7 +++- .../alipay/service/AlipayServiceImpl.java | 7 ++-- .../jframe/aliyun/service/OSSService.java | 7 ++-- .../jframe/aliyun/service/SMSService.java | 9 ++--- .../jframe/aliyun/service/STSService.java | 4 ++- jframe-plugin/jframe-httpclient/pom.xml | 4 +-- .../jframe/httpclient/HttpClientConfig.java | 12 +++---- .../httpclient/service/HttpClientService.java | 12 ++++--- .../java/test/client/httpclient.properties | 33 +++++++++---------- .../jframe/jedis/service/JedisService.java | 13 ++++---- 11 files changed, 60 insertions(+), 50 deletions(-) diff --git a/jframe-plugin/jframe-alipay/pom.xml b/jframe-plugin/jframe-alipay/pom.xml index 380949c..9b51915 100644 --- a/jframe-plugin/jframe-alipay/pom.xml +++ b/jframe-plugin/jframe-alipay/pom.xml @@ -15,7 +15,7 @@ com.alipay.sdk alipay-sdk-java - 3.7.110.ALL + 4.9.28.ALL
    diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java index dee0c21..8b4648f 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java @@ -6,6 +6,9 @@ import java.util.Map; /** + * https://docs.open.alipay.com/204 App支付 + * https://docs.open.alipay.com/291/105971 密钥配置 + *

    * https://docs.open.alipay.com/270/105899/ * https://docs.open.alipay.com/api_1/alipay.trade.page.pay/ *

    @@ -16,9 +19,11 @@ * @author dzh * @date 2019-07-22 14:56 */ -@Service(clazz = "jframe.alipay.service.AlipayServiceImpl", id = "jframe.service.alipay") +@Service(clazz = "jframe.alipay.service.AlipayServiceImpl", id = AlipayService.ID) public interface AlipayService { + String ID = "jframe.service.alipay"; + String F_URL = "url"; String F_APP_ID = "app.id"; String F_PRIVATE_KEY = "private.key"; diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java index 3517fef..5b58e53 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java @@ -2,6 +2,7 @@ import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; +import com.alipay.api.AlipayConstants; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.internal.util.AlipaySignature; import jframe.alipay.AlipayPlugin; @@ -79,10 +80,10 @@ private AlipayClient createAlipayClient(PropsConf conf, String id) { String url = conf.getConf(id, F_URL); String appId = conf.getConf(id, F_APP_ID); String privateKey = conf.getConf(id, F_PRIVATE_KEY); - String format = conf.getConf(id, F_FORMAT); - String charset = conf.getConf(id, F_CHARSET); + String format = conf.getConf(id, F_FORMAT, AlipayConstants.FORMAT_JSON); + String charset = conf.getConf(id, F_CHARSET, AlipayConstants.CHARSET_UTF8); String publicKey = conf.getConf(id, F_PUBLIC_KEY); - String signType = conf.getConf(id, F_SIGN_TYPE); + String signType = conf.getConf(id, F_SIGN_TYPE, AlipayConstants.SIGN_TYPE_RSA2); AlipayClient alipayClient = new DefaultAlipayClient(url, appId, privateKey, format, charset, publicKey, signType); LOG.info("createAlipayClient {}", appId); return alipayClient; diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/OSSService.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/OSSService.java index 7c67095..4385f51 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/OSSService.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/OSSService.java @@ -1,10 +1,9 @@ /** - * + * */ package jframe.aliyun.service; import com.aliyun.oss.OSSClient; - import jframe.core.plugin.annotation.Service; /** @@ -12,9 +11,11 @@ * @date Feb 22, 2016 11:07:15 AM * @since 1.0 */ -@Service(clazz = "jframe.aliyun.service.oss.OSSServiceImpl", id = "jframe.service.aliyun.oss") +@Service(clazz = "jframe.aliyun.service.oss.OSSServiceImpl", id = OSSService.ID) public interface OSSService { + String ID = "jframe.service.aliyun.oss"; + OSSClient getOSSClient(String id); } diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/SMSService.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/SMSService.java index 32d8f8b..ed956ef 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/SMSService.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/SMSService.java @@ -3,19 +3,20 @@ import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; - import jframe.core.plugin.annotation.Service; /** * 阿里云短信 - * + * * @author dzh - * @date Nov 19, 2018 7:00:39 PM * @version 0.0.1 + * @date Nov 19, 2018 7:00:39 PM */ -@Service(clazz = "jframe.aliyun.service.sms.SMSServiceImpl", id = "jframe.service.aliyun.sms") +@Service(clazz = "jframe.aliyun.service.sms.SMSServiceImpl", id = SMSService.ID) public interface SMSService { + String ID = "jframe.service.aliyun.sms"; + SendSmsResponse send(String id, SendSmsRequest request) throws ClientException; } diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java index 62dd7c5..b4dfb33 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/STSService.java @@ -12,9 +12,11 @@ * @date Feb 28, 2016 9:13:38 AM * @since 1.0 */ -@Service(clazz = "jframe.aliyun.service.sts.STSServiceImpl", id = "jframe.service.aliyun.sts") +@Service(clazz = "jframe.aliyun.service.sts.STSServiceImpl", id = STSService.ID) public interface STSService { + String ID = "jframe.service.aliyun.sts"; + /** * 获取临时访问权限 * diff --git a/jframe-plugin/jframe-httpclient/pom.xml b/jframe-plugin/jframe-httpclient/pom.xml index 45511bf..6580ad2 100644 --- a/jframe-plugin/jframe-httpclient/pom.xml +++ b/jframe-plugin/jframe-httpclient/pom.xml @@ -12,12 +12,12 @@ org.apache.httpcomponents httpcore - 4.4.11 + 4.4.13 org.apache.httpcomponents httpclient - 4.5.9 + 4.5.11 com.google.code.gson diff --git a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/HttpClientConfig.java b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/HttpClientConfig.java index 918d561..a0afba2 100644 --- a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/HttpClientConfig.java +++ b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/HttpClientConfig.java @@ -1,18 +1,18 @@ /** - * + * */ package jframe.httpclient; +import jframe.core.util.PropsConf; + import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Random; -import jframe.core.util.PropsConf; - /** * TODO 配置文件验证 - * + * * @author dzh * @date Dec 3, 2014 11:07:29 AM * @since 1.0 @@ -59,12 +59,12 @@ public static String getConf(String group, String key) { } /** - * + * * @param gid * @return */ public static List getHostByGroup(String gid) { - List hosts = new LinkedList(); + List hosts = new LinkedList<>(); for (String host : getHosts()) { if (gid.equals(CONFIG.getConf(host, GROUP))) { hosts.add(host); diff --git a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/HttpClientService.java b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/HttpClientService.java index 610bdd7..be2a8f4 100644 --- a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/HttpClientService.java +++ b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/HttpClientService.java @@ -1,12 +1,12 @@ /** - * + * */ package jframe.httpclient.service; -import java.util.Map; - import jframe.core.plugin.annotation.Service; +import java.util.Map; + /** *

    * 特性: @@ -15,14 +15,16 @@ *

  • TODO 支持https
  • *
  • TODO 发送失败异常处理
  • *

    - * + * * @author dzh * @date Dec 2, 2014 12:10:16 PM * @since 1.0 */ -@Service(clazz = "jframe.httpclient.service.impl.HttpClientServiceImpl", id = "jframe.service.httpclient") +@Service(clazz = "jframe.httpclient.service.impl.HttpClientServiceImpl", id = HttpClientService.ID) public interface HttpClientService { + String ID = "jframe.service.httpclient"; + String P_MIMETYPE = "mimeType"; String P_METHOD = "method"; diff --git a/jframe-plugin/jframe-httpclient/src/test/java/test/client/httpclient.properties b/jframe-plugin/jframe-httpclient/src/test/java/test/client/httpclient.properties index a9f5fe1..d6d9b16 100644 --- a/jframe-plugin/jframe-httpclient/src/test/java/test/client/httpclient.properties +++ b/jframe-plugin/jframe-httpclient/src/test/java/test/client/httpclient.properties @@ -1,22 +1,19 @@ -group.id = host1 host2 - -@host1.ip = localhost -@host1.port = -@host1.scheme = http -@host1.group = +group.id=host1 host2 +@host1.ip=localhost +@host1.port= +@host1.scheme=http +@host1.group= #@host1.http.method = post #@host1.http.max.conn.route = 60 #@host1.http.keep-alive = 5 - -@host2.ip = 192.168.1.123 -@host2.port = 8038 -@host1.scheme = http -@host2.group = - -http.method = post -http.max.conn = 200 -http.max.conn.route = 50 -http.keep-alive = 5 +@host2.ip=192.168.1.123 +@host2.port=8038 +@host2.scheme=http +@host2.group= +http.method=post +http.max.conn=200 +http.max.conn.route=50 +http.keep-alive=5 #second -http.idle.conn.close = 30 -http.charset = utf-8 +http.idle.conn.close=30 +http.charset=utf-8 diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java index d146c31..2a0fa07 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.jedis.service; @@ -12,11 +12,12 @@ * @date Dec 2, 2014 10:37:37 AM * @since 1.0 */ -@Service(clazz = "jframe.jedis.service.JedisServiceImpl", id = "jframe.service.jedis") +@Service(clazz = "jframe.jedis.service.JedisServiceImpl", id = JedisService.ID) public interface JedisService { + String ID = "jframe.service.jedis"; /** - * + * * @return jedis.host.default's jedis */ Jedis getJedis(); @@ -25,7 +26,7 @@ public interface JedisService { /** * use {@link redis.clients.jedis.Jedis#close()} - * + * * @param jedis */ @Deprecated @@ -33,7 +34,7 @@ public interface JedisService { /** * use {@link redis.clients.jedis.Jedis#close()} - * + * * @param jedis */ @Deprecated @@ -41,7 +42,7 @@ public interface JedisService { /** * unsupported - * + * * @param name * @return */ From ebf9f0f53cd96fc5dcaa9a9fafd85cdb2b1394df Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 13 Mar 2020 15:59:36 +0800 Subject: [PATCH 11/47] opt log --- .../alipay/service/AlipayServiceImpl.java | 2 +- .../jframe/umeng/service/UmengService.java | 12 +++--- .../umeng/service/impl/UmengServiceImpl.java | 39 +++++++++---------- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java index 5b58e53..86065ea 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java @@ -82,7 +82,7 @@ private AlipayClient createAlipayClient(PropsConf conf, String id) { String privateKey = conf.getConf(id, F_PRIVATE_KEY); String format = conf.getConf(id, F_FORMAT, AlipayConstants.FORMAT_JSON); String charset = conf.getConf(id, F_CHARSET, AlipayConstants.CHARSET_UTF8); - String publicKey = conf.getConf(id, F_PUBLIC_KEY); + String publicKey = conf.getConf(id, F_PUBLIC_KEY); //alipay public key String signType = conf.getConf(id, F_SIGN_TYPE, AlipayConstants.SIGN_TYPE_RSA2); AlipayClient alipayClient = new DefaultAlipayClient(url, appId, privateKey, format, charset, publicKey, signType); LOG.info("createAlipayClient {}", appId); diff --git a/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/UmengService.java b/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/UmengService.java index ed8b6c1..0682127 100644 --- a/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/UmengService.java +++ b/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/UmengService.java @@ -1,22 +1,24 @@ /** - * + * */ package jframe.umeng.service; -import java.util.Map; - import jframe.core.plugin.annotation.Service; +import java.util.Map; + /** * https://developer.umeng.com/docs/66632/detail/68343 - * + * * @author dzh * @date Mar 4, 2016 10:12:32 PM * @since 1.0 */ -@Service(clazz = "jframe.umeng.service.impl.UmengServiceImpl", id = "jframe.service.umeng") +@Service(clazz = "jframe.umeng.service.impl.UmengServiceImpl", id = UmengService.ID) public interface UmengService { + String ID = "jframe.service.umeng"; + void sendAndBroadcast(String groupId, String token, String ticker, String title, String text, Map custom) throws Exception; diff --git a/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/impl/UmengServiceImpl.java b/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/impl/UmengServiceImpl.java index cb5e883..50c9ed0 100644 --- a/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/impl/UmengServiceImpl.java +++ b/jframe-plugin/jframe-umeng/src/main/java/jframe/umeng/service/impl/UmengServiceImpl.java @@ -1,26 +1,16 @@ /** - * + * */ package jframe.umeng.service.impl; -import java.io.File; -import java.io.FileInputStream; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.codec.digest.DigestUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.InjectService; -import jframe.core.plugin.annotation.Injector; -import jframe.core.plugin.annotation.Start; -import jframe.core.plugin.annotation.Stop; +import jframe.core.plugin.annotation.*; import jframe.httpclient.service.HttpClientService; import jframe.umeng.UmengConfig; import jframe.umeng.UmengPlugin; import jframe.umeng.service.UmengService; +import org.apache.commons.codec.digest.DigestUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import push.AndroidNotification; import push.AndroidNotification.DisplayType; import push.UmengNotification; @@ -29,8 +19,13 @@ import push.ios.IOSBroadcast; import push.ios.IOSUnicast; +import java.io.File; +import java.io.FileInputStream; +import java.util.HashMap; +import java.util.Map; + /** - * + * * @author dzh * @date Mar 4, 2016 10:13:18 PM * @since 1.0 @@ -79,7 +74,8 @@ public void start(String path) { } @Stop - void stop() {} + void stop() { + } /** * "alert":""/{ // 当content-available=1时(静默推送),可选; 否则必填。 @@ -147,13 +143,14 @@ void sendUmengNotification(UmengNotification n, String groupId) throws Exception String httpid = _config.getConf(null, UmengConfig.HttpId, "umeng"); String path = "/api/send?sign=" + sign; - Map headers = new HashMap(1, 1); + Map headers = new HashMap<>(1, 1); headers.put("User-Agent", "Mozilla/5.0"); Object rsp = _http.send(httpid, path, postBody, headers, null); + LOG.info("m->sendUmengNotification data->{} rsp->{}", postBody, rsp); - if (LOG.isDebugEnabled()) { - LOG.debug("m->sendUmengNotification data->{} rsp->{}", n.getPostBody(), rsp); - } +// if (LOG.isDebugEnabled()) { +// LOG.debug("m->sendUmengNotification data->{} rsp->{}", postBody, rsp); +// } } @Override From 14fb8cc1dfd98699154cb491ce1ba7045d52e596 Mon Sep 17 00:00:00 2001 From: dzh Date: Wed, 19 Aug 2020 15:55:37 +0800 Subject: [PATCH 12/47] add jframe-wxpay --- .../freemarker/service/FreemarkerService.java | 6 +- .../main/java/jframe/getui/GetuiService.java | 74 +- .../java/jframe/getui/MultiGetuiService.java | 85 +-- .../jframe/mybatis/MultiMybatisService.java | 21 +- .../jframe/qiniu/service/QiniuService.java | 7 +- .../rongcloud/service/RongcloudService.java | 14 +- jframe-plugin/jframe-wxpay/pom.xml | 36 + .../com/github/wxpay/sdk/IWXPayDomain.java | 45 ++ .../github/wxpay/sdk/JframeWxpayConfig.java | 55 ++ .../main/java/com/github/wxpay/sdk/WXPay.java | 689 ++++++++++++++++++ .../com/github/wxpay/sdk/WXPayConfig.java | 103 +++ .../com/github/wxpay/sdk/WXPayConstants.java | 59 ++ .../com/github/wxpay/sdk/WXPayReport.java | 265 +++++++ .../com/github/wxpay/sdk/WXPayRequest.java | 258 +++++++ .../java/com/github/wxpay/sdk/WXPayUtil.java | 295 ++++++++ .../com/github/wxpay/sdk/WXPayXmlUtil.java | 30 + .../src/main/java/jframe/wxpay/WxpayConf.java | 55 ++ .../main/java/jframe/wxpay/WxpayPlugin.java | 11 + .../jframe/wxpay/service/WxpayService.java | 39 + .../jframe/wxpay/service/WxpayServiceV2.java | 115 +++ .../jframe/wxpay/service/WxpayServiceV3.java | 86 +++ .../main/resources/META-INF/plugin.properties | 7 + .../src/test/resources/wxpay.properties | 12 + jframe-plugin/pom.xml | 1 + 24 files changed, 2268 insertions(+), 100 deletions(-) create mode 100644 jframe-plugin/jframe-wxpay/pom.xml create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/IWXPayDomain.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConfig.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayReport.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayRequest.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayUtil.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayXmlUtil.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayPlugin.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java create mode 100644 jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties create mode 100644 jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties diff --git a/jframe-plugin/jframe-freemarker/src/main/java/jframe/freemarker/service/FreemarkerService.java b/jframe-plugin/jframe-freemarker/src/main/java/jframe/freemarker/service/FreemarkerService.java index eb6d7ef..97ad5a7 100644 --- a/jframe-plugin/jframe-freemarker/src/main/java/jframe/freemarker/service/FreemarkerService.java +++ b/jframe-plugin/jframe-freemarker/src/main/java/jframe/freemarker/service/FreemarkerService.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.freemarker.service; @@ -11,9 +11,11 @@ * @date Aug 25, 2016 1:50:52 PM * @since 1.0 */ -@Service(clazz = "jframe.freemarker.service.impl.FreemarkerServiceImpl", id = "jframe.service.freemarker") +@Service(clazz = "jframe.freemarker.service.impl.FreemarkerServiceImpl", id = FreemarkerService.ID) public interface FreemarkerService { + String ID = "jframe.service.freemarker"; + Template getTemplate(String id, String ftl) throws Exception; } diff --git a/jframe-plugin/jframe-getui/src/main/java/jframe/getui/GetuiService.java b/jframe-plugin/jframe-getui/src/main/java/jframe/getui/GetuiService.java index f3c9069..16d54c6 100644 --- a/jframe-plugin/jframe-getui/src/main/java/jframe/getui/GetuiService.java +++ b/jframe-plugin/jframe-getui/src/main/java/jframe/getui/GetuiService.java @@ -1,56 +1,56 @@ /** - * + * */ package jframe.getui; -import java.util.List; - -import jframe.core.plugin.annotation.Service; - import com.gexin.rp.sdk.base.IPushResult; import com.gexin.rp.sdk.base.ITemplate; import com.gexin.rp.sdk.base.impl.SingleMessage; +import jframe.core.plugin.annotation.Service; + +import java.util.List; /** * @author dzh * @date Sep 29, 2014 12:00:46 PM * @since 1.0 */ -@Service(clazz = "jframe.getui.andriod.GetuiServiceImpl", id = "jframe.service.getui") +@Service(clazz = "jframe.getui.andriod.GetuiServiceImpl", id = GetuiService.ID) public interface GetuiService { + String ID = "jframe.service.getui"; // IPushResult push2App(ITemplate data, boolean isOffline, // long offlineExpireTime) throws Exception; - IPushResult push2Single(ITemplate data, boolean isOffline, - long offlineExpireTime, String token) throws Exception; - - public static class Utils { - - public SingleMessage createSingleMessage(boolean isOffline, - long offlineExpireTime, ITemplate data) { - SingleMessage message = new SingleMessage(); - message.setOffline(isOffline); - message.setOfflineExpireTime(offlineExpireTime); - message.setData(data); - return message; - } - - // public ITemplate createTemplate() { - // PopupTransmissionTemplate template = new PopupTransmissionTemplate(); - // template.setAppId(GetuiConfig.APPID); - // template.setAppkey(GetuiConfig.APPKEY); - // template.setText(""); - // template.setTitle(""); - // template.setImg(""); - // template.setConfirmButtonText(""); - // template.setCancelButtonText(""); - // template.setTransmissionContent("111"); - // template.setTransmissionType(1); - // } - - } - - IPushResult push2List(ITemplate data, boolean isOffline, - long offlineExpireTime, List token); + IPushResult push2Single(ITemplate data, boolean isOffline, + long offlineExpireTime, String token) throws Exception; + + public static class Utils { + + public SingleMessage createSingleMessage(boolean isOffline, + long offlineExpireTime, ITemplate data) { + SingleMessage message = new SingleMessage(); + message.setOffline(isOffline); + message.setOfflineExpireTime(offlineExpireTime); + message.setData(data); + return message; + } + + // public ITemplate createTemplate() { + // PopupTransmissionTemplate template = new PopupTransmissionTemplate(); + // template.setAppId(GetuiConfig.APPID); + // template.setAppkey(GetuiConfig.APPKEY); + // template.setText(""); + // template.setTitle(""); + // template.setImg(""); + // template.setConfirmButtonText(""); + // template.setCancelButtonText(""); + // template.setTransmissionContent("111"); + // template.setTransmissionType(1); + // } + + } + + IPushResult push2List(ITemplate data, boolean isOffline, + long offlineExpireTime, List token); } diff --git a/jframe-plugin/jframe-getui/src/main/java/jframe/getui/MultiGetuiService.java b/jframe-plugin/jframe-getui/src/main/java/jframe/getui/MultiGetuiService.java index 2c99742..b9d91ff 100644 --- a/jframe-plugin/jframe-getui/src/main/java/jframe/getui/MultiGetuiService.java +++ b/jframe-plugin/jframe-getui/src/main/java/jframe/getui/MultiGetuiService.java @@ -1,59 +1,60 @@ /** - * + * */ package jframe.getui; -import java.util.List; - -import jframe.core.plugin.annotation.Service; - import com.gexin.rp.sdk.base.IPushResult; import com.gexin.rp.sdk.base.ITemplate; import com.gexin.rp.sdk.base.impl.SingleMessage; +import jframe.core.plugin.annotation.Service; + +import java.util.List; /** * @author dzh * @date Aug 20, 2015 3:52:51 PM * @since 1.0 */ -@Service(clazz = "jframe.getui.andriod.MultiGetuiServiceImpl", id = "jframe.service.multigetui") +@Service(clazz = "jframe.getui.andriod.MultiGetuiServiceImpl", id = MultiGetuiService.ID) public interface MultiGetuiService { - // IPushResult push2App(ITemplate data, boolean isOffline, - // long offlineExpireTime) throws Exception; - - IPushResult push2Single(String id, ITemplate data, boolean isOffline, - long offlineExpireTime, String token) throws Exception; - - public static class Utils { - - public SingleMessage createSingleMessage(boolean isOffline, - long offlineExpireTime, ITemplate data) { - SingleMessage message = new SingleMessage(); - message.setOffline(isOffline); - message.setOfflineExpireTime(offlineExpireTime); - message.setData(data); - return message; - } - - // public ITemplate createTemplate() { - // PopupTransmissionTemplate template = new PopupTransmissionTemplate(); - // template.setAppId(GetuiConfig.APPID); - // template.setAppkey(GetuiConfig.APPKEY); - // template.setText(""); - // template.setTitle(""); - // template.setImg(""); - // template.setConfirmButtonText(""); - // template.setCancelButtonText(""); - // template.setTransmissionContent("111"); - // template.setTransmissionType(1); - // } - - } - - IPushResult push2List(String id, ITemplate data, boolean isOffline, - long offlineExpireTime, List token); - - String getConf(String id, String key); + String ID = "jframe.service.multigetui"; + + // IPushResult push2App(ITemplate data, boolean isOffline, + // long offlineExpireTime) throws Exception; + + IPushResult push2Single(String id, ITemplate data, boolean isOffline, + long offlineExpireTime, String token) throws Exception; + + public static class Utils { + + public SingleMessage createSingleMessage(boolean isOffline, + long offlineExpireTime, ITemplate data) { + SingleMessage message = new SingleMessage(); + message.setOffline(isOffline); + message.setOfflineExpireTime(offlineExpireTime); + message.setData(data); + return message; + } + + // public ITemplate createTemplate() { + // PopupTransmissionTemplate template = new PopupTransmissionTemplate(); + // template.setAppId(GetuiConfig.APPID); + // template.setAppkey(GetuiConfig.APPKEY); + // template.setText(""); + // template.setTitle(""); + // template.setImg(""); + // template.setConfirmButtonText(""); + // template.setCancelButtonText(""); + // template.setTransmissionContent("111"); + // template.setTransmissionType(1); + // } + + } + + IPushResult push2List(String id, ITemplate data, boolean isOffline, + long offlineExpireTime, List token); + + String getConf(String id, String key); } diff --git a/jframe-plugin/jframe-mybatis/src/main/java/jframe/mybatis/MultiMybatisService.java b/jframe-plugin/jframe-mybatis/src/main/java/jframe/mybatis/MultiMybatisService.java index 1dc97f8..6993731 100644 --- a/jframe-plugin/jframe-mybatis/src/main/java/jframe/mybatis/MultiMybatisService.java +++ b/jframe-plugin/jframe-mybatis/src/main/java/jframe/mybatis/MultiMybatisService.java @@ -1,10 +1,9 @@ /** - * + * */ package jframe.mybatis; import jframe.core.plugin.annotation.Service; - import org.apache.ibatis.session.SqlSessionFactory; /** @@ -12,15 +11,17 @@ * @date Jul 17, 2015 11:36:43 AM * @since 1.0 */ -@Service(clazz = "jframe.mybatis.MultiMybatisServiceImpl", id = "jframe.service.multimybatis") +@Service(clazz = "jframe.mybatis.MultiMybatisServiceImpl", id = MultiMybatisService.ID) public interface MultiMybatisService { - /** - * - * @param id - * environment[@id] in mybatis-config.xml - * @return - */ - SqlSessionFactory getSqlSessionFactory(String id); + String ID = "jframe.service.multimybatis"; + + /** + * + * @param id + * environment[@id] in mybatis-config.xml + * @return + */ + SqlSessionFactory getSqlSessionFactory(String id); } diff --git a/jframe-plugin/jframe-qiniu/src/main/java/jframe/qiniu/service/QiniuService.java b/jframe-plugin/jframe-qiniu/src/main/java/jframe/qiniu/service/QiniuService.java index 1dd76e7..4326f12 100644 --- a/jframe-plugin/jframe-qiniu/src/main/java/jframe/qiniu/service/QiniuService.java +++ b/jframe-plugin/jframe-qiniu/src/main/java/jframe/qiniu/service/QiniuService.java @@ -1,12 +1,11 @@ /** - * + * */ package jframe.qiniu.service; import com.qiniu.storage.BucketManager; import com.qiniu.util.Auth; import com.qiniu.util.StringMap; - import jframe.core.plugin.annotation.Service; /** @@ -14,9 +13,11 @@ * @date Jul 28, 2015 10:09:03 AM * @since 1.0 */ -@Service(clazz = "jframe.qiniu.service.QiniuServiceImpl", id = "jframe.service.qiniu") +@Service(clazz = "jframe.qiniu.service.QiniuServiceImpl", id = QiniuService.ID) public interface QiniuService { + String ID = "jframe.service.qiniu"; + String uploadToken(String id, String key); String uploadToken(String id, String key, long expires); diff --git a/jframe-plugin/jframe-rongcloud/src/main/java/jframe/rongcloud/service/RongcloudService.java b/jframe-plugin/jframe-rongcloud/src/main/java/jframe/rongcloud/service/RongcloudService.java index 5767f72..2893290 100644 --- a/jframe-plugin/jframe-rongcloud/src/main/java/jframe/rongcloud/service/RongcloudService.java +++ b/jframe-plugin/jframe-rongcloud/src/main/java/jframe/rongcloud/service/RongcloudService.java @@ -1,24 +1,26 @@ /** - * + * */ package jframe.rongcloud.service; -import java.util.List; -import java.util.Map; - import jframe.core.plugin.annotation.Service; import jframe.rongcloud.Fields; +import java.util.List; +import java.util.Map; + /** * http://www.rongcloud.cn/docs/server.html - * + * * @author dzh * @date Feb 14, 2016 9:39:42 PM * @since 1.0 */ -@Service(clazz = "jframe.rongcloud.service.impl.RongcloudServiceImpl", id = "jframe.service.rongcloud") +@Service(clazz = "jframe.rongcloud.service.impl.RongcloudServiceImpl", id = RongcloudService.ID) public interface RongcloudService extends Fields { + String ID = "jframe.service.rongcloud"; + String getToken(String id, Map req); boolean refreshUsr(String id, Map req); diff --git a/jframe-plugin/jframe-wxpay/pom.xml b/jframe-plugin/jframe-wxpay/pom.xml new file mode 100644 index 0000000..a782915 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/pom.xml @@ -0,0 +1,36 @@ + + + + jframe-plugin + io.github.dzh + 2.0.0-SNAPSHOT + + 4.0.0 + + jframe-wxpay + + + + org.apache.httpcomponents + httpclient + 4.5.11 + + + + + + com.github.wechatpay-apiv3 + wechatpay-apache-httpclient + 0.2.1 + + + + \ No newline at end of file diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/IWXPayDomain.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/IWXPayDomain.java new file mode 100644 index 0000000..aa9e6e6 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/IWXPayDomain.java @@ -0,0 +1,45 @@ +package com.github.wxpay.sdk; + +/** + * 域名管理,实现主备域名自动切换 + */ +public abstract interface IWXPayDomain { + /** + * 上报域名网络状况 + * + * @param domain 域名。 比如:api.mch.weixin.qq.com + * @param elapsedTimeMillis 耗时 + * @param ex 网络请求中出现的异常。 + * null表示没有异常 + * ConnectTimeoutException,表示建立网络连接异常 + * UnknownHostException, 表示dns解析异常 + */ + abstract void report(final String domain, long elapsedTimeMillis, final Exception ex); + + /** + * 获取域名 + * + * @param config 配置 + * @return 域名 + */ + abstract DomainInfo getDomain(final WXPayConfig config); + + static class DomainInfo { + public String domain; //域名 + public boolean primaryDomain; //该域名是否为主域名。例如:api.mch.weixin.qq.com为主域名 + + public DomainInfo(String domain, boolean primaryDomain) { + this.domain = domain; + this.primaryDomain = primaryDomain; + } + + @Override + public String toString() { + return "DomainInfo{" + + "domain='" + domain + '\'' + + ", primaryDomain=" + primaryDomain + + '}'; + } + } + +} \ No newline at end of file diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java new file mode 100644 index 0000000..d992c58 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java @@ -0,0 +1,55 @@ +package com.github.wxpay.sdk; + +import java.io.InputStream; + +/** + * @author dzh + * @date 2020/8/18 19:21 + */ +public class JframeWxpayConfig extends WXPayConfig { + + private String appId; + + private String mchId; + private String apikey; + + private InputStream certStream; + + public static JframeWxpayConfig create(String appId, String mchId, String apikey, InputStream certStream) { + JframeWxpayConfig conf = new JframeWxpayConfig(); + conf.appId = appId; + conf.mchId = mchId; + conf.apikey = apikey; + conf.certStream = certStream; + return conf; + } + + @Override + String getAppID() { + return appId; + } + + @Override + String getMchID() { + return mchId; + } + + @Override + String getKey() { + return apikey; + } + + @Override + InputStream getCertStream() { + return certStream; + } + + @Override + IWXPayDomain getWXPayDomain() { + return null; + } + +// public boolean shouldAutoReport() { +// return false; +// } +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java new file mode 100644 index 0000000..7f0fbcd --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java @@ -0,0 +1,689 @@ +package com.github.wxpay.sdk; + +import com.github.wxpay.sdk.WXPayConstants.SignType; + +import java.util.HashMap; +import java.util.Map; + +public class WXPay { + + private WXPayConfig config; + private SignType signType; + private boolean autoReport; + private boolean useSandbox; + private String notifyUrl; + private WXPayRequest wxPayRequest; + + public WXPay(final WXPayConfig config) throws Exception { + this(config, null, true, false); + } + + public WXPay(final WXPayConfig config, final boolean autoReport) throws Exception { + this(config, null, autoReport, false); + } + + + public WXPay(final WXPayConfig config, final boolean autoReport, final boolean useSandbox) throws Exception{ + this(config, null, autoReport, useSandbox); + } + + public WXPay(final WXPayConfig config, final String notifyUrl) throws Exception { + this(config, notifyUrl, true, false); + } + + public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport) throws Exception { + this(config, notifyUrl, autoReport, false); + } + + public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception { + this.config = config; + this.notifyUrl = notifyUrl; + this.autoReport = autoReport; + this.useSandbox = useSandbox; + if (useSandbox) { + this.signType = SignType.MD5; // 沙箱环境 + } + else { + this.signType = SignType.HMACSHA256; + } + this.wxPayRequest = new WXPayRequest(config); + } + + private void checkWXPayConfig() throws Exception { + if (this.config == null) { + throw new Exception("config is null"); + } + if (this.config.getAppID() == null || this.config.getAppID().trim().length() == 0) { + throw new Exception("appid in config is empty"); + } + if (this.config.getMchID() == null || this.config.getMchID().trim().length() == 0) { + throw new Exception("appid in config is empty"); + } + if (this.config.getCertStream() == null) { + throw new Exception("cert stream in config is empty"); + } + if (this.config.getWXPayDomain() == null){ + throw new Exception("config.getWXPayDomain() is null"); + } + + if (this.config.getHttpConnectTimeoutMs() < 10) { + throw new Exception("http connect timeout is too small"); + } + if (this.config.getHttpReadTimeoutMs() < 10) { + throw new Exception("http read timeout is too small"); + } + + } + + /** + * 向 Map 中添加 appid、mch_id、nonce_str、sign_type、sign
    + * 该函数适用于商户适用于统一下单等接口,不适用于红包、代金券接口 + * + * @param reqData + * @return + * @throws Exception + */ + public Map fillRequestData(Map reqData) throws Exception { + reqData.put("appid", config.getAppID()); + reqData.put("mch_id", config.getMchID()); + reqData.put("nonce_str", WXPayUtil.generateNonceStr()); + if (SignType.MD5.equals(this.signType)) { + reqData.put("sign_type", WXPayConstants.MD5); + } + else if (SignType.HMACSHA256.equals(this.signType)) { + reqData.put("sign_type", WXPayConstants.HMACSHA256); + } + reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType)); + return reqData; + } + + /** + * 判断xml数据的sign是否有效,必须包含sign字段,否则返回false。 + * + * @param reqData 向wxpay post的请求数据 + * @return 签名是否有效 + * @throws Exception + */ + public boolean isResponseSignatureValid(Map reqData) throws Exception { + // 返回数据的签名方式和请求中给定的签名方式是一致的 + return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), this.signType); + } + + /** + * 判断支付结果通知中的sign是否有效 + * + * @param reqData 向wxpay post的请求数据 + * @return 签名是否有效 + * @throws Exception + */ + public boolean isPayResultNotifySignatureValid(Map reqData) throws Exception { + String signTypeInData = reqData.get(WXPayConstants.FIELD_SIGN_TYPE); + SignType signType; + if (signTypeInData == null) { + signType = SignType.MD5; + } + else { + signTypeInData = signTypeInData.trim(); + if (signTypeInData.length() == 0) { + signType = SignType.MD5; + } + else if (WXPayConstants.MD5.equals(signTypeInData)) { + signType = SignType.MD5; + } + else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) { + signType = SignType.HMACSHA256; + } + else { + throw new Exception(String.format("Unsupported sign_type: %s", signTypeInData)); + } + } + return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), signType); + } + + + /** + * 不需要证书的请求 + * @param urlSuffix String + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 超时时间,单位是毫秒 + * @param readTimeoutMs 超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public String requestWithoutCert(String urlSuffix, Map reqData, + int connectTimeoutMs, int readTimeoutMs) throws Exception { + String msgUUID = reqData.get("nonce_str"); + String reqBody = WXPayUtil.mapToXml(reqData); + + String resp = this.wxPayRequest.requestWithoutCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, autoReport); + return resp; + } + + + /** + * 需要证书的请求 + * @param urlSuffix String + * @param reqData 向wxpay post的请求数据 Map + * @param connectTimeoutMs 超时时间,单位是毫秒 + * @param readTimeoutMs 超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public String requestWithCert(String urlSuffix, Map reqData, + int connectTimeoutMs, int readTimeoutMs) throws Exception { + String msgUUID= reqData.get("nonce_str"); + String reqBody = WXPayUtil.mapToXml(reqData); + + String resp = this.wxPayRequest.requestWithCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, this.autoReport); + return resp; + } + + /** + * 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。 + * @param xmlStr API返回的XML格式数据 + * @return Map类型数据 + * @throws Exception + */ + public Map processResponseXml(String xmlStr) throws Exception { + String RETURN_CODE = "return_code"; + String return_code; + Map respData = WXPayUtil.xmlToMap(xmlStr); + if (respData.containsKey(RETURN_CODE)) { + return_code = respData.get(RETURN_CODE); + } + else { + throw new Exception(String.format("No `return_code` in XML: %s", xmlStr)); + } + + if (return_code.equals(WXPayConstants.FAIL)) { + return respData; + } + else if (return_code.equals(WXPayConstants.SUCCESS)) { + if (this.isResponseSignatureValid(respData)) { + return respData; + } + else { + throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr)); + } + } + else { + throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr)); + } + } + + /** + * 作用:提交刷卡支付
    + * 场景:刷卡支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map microPay(Map reqData) throws Exception { + return this.microPay(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:提交刷卡支付
    + * 场景:刷卡支付 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map microPay(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_MICROPAY_URL_SUFFIX; + } + else { + url = WXPayConstants.MICROPAY_URL_SUFFIX; + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + /** + * 提交刷卡支付,针对软POS,尽可能做成功 + * 内置重试机制,最多60s + * @param reqData + * @return + * @throws Exception + */ + public Map microPayWithPos(Map reqData) throws Exception { + return this.microPayWithPos(reqData, this.config.getHttpConnectTimeoutMs()); + } + + /** + * 提交刷卡支付,针对软POS,尽可能做成功 + * 内置重试机制,最多60s + * @param reqData + * @param connectTimeoutMs + * @return + * @throws Exception + */ + public Map microPayWithPos(Map reqData, int connectTimeoutMs) throws Exception { + int remainingTimeMs = 60*1000; + long startTimestampMs = 0; + Map lastResult = null; + Exception lastException = null; + + while (true) { + startTimestampMs = WXPayUtil.getCurrentTimestampMs(); + int readTimeoutMs = remainingTimeMs - connectTimeoutMs; + if (readTimeoutMs > 1000) { + try { + lastResult = this.microPay(reqData, connectTimeoutMs, readTimeoutMs); + String returnCode = lastResult.get("return_code"); + if (returnCode.equals("SUCCESS")) { + String resultCode = lastResult.get("result_code"); + String errCode = lastResult.get("err_code"); + if (resultCode.equals("SUCCESS")) { + break; + } + else { + // 看错误码,若支付结果未知,则重试提交刷卡支付 + if (errCode.equals("SYSTEMERROR") || errCode.equals("BANKERROR") || errCode.equals("USERPAYING")) { + remainingTimeMs = remainingTimeMs - (int)(WXPayUtil.getCurrentTimestampMs() - startTimestampMs); + if (remainingTimeMs <= 100) { + break; + } + else { + WXPayUtil.getLogger().info("microPayWithPos: try micropay again"); + if (remainingTimeMs > 5*1000) { + Thread.sleep(5*1000); + } + else { + Thread.sleep(1*1000); + } + continue; + } + } + else { + break; + } + } + } + else { + break; + } + } + catch (Exception ex) { + lastResult = null; + lastException = ex; + } + } + else { + break; + } + } + + if (lastResult == null) { + throw lastException; + } + else { + return lastResult; + } + } + + + + /** + * 作用:统一下单
    + * 场景:公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map unifiedOrder(Map reqData) throws Exception { + return this.unifiedOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:统一下单
    + * 场景:公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map unifiedOrder(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_UNIFIEDORDER_URL_SUFFIX; + } + else { + url = WXPayConstants.UNIFIEDORDER_URL_SUFFIX; + } + if(this.notifyUrl != null) { + reqData.put("notify_url", this.notifyUrl); + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + + /** + * 作用:查询订单
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map orderQuery(Map reqData) throws Exception { + return this.orderQuery(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:查询订单
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 int + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map orderQuery(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_ORDERQUERY_URL_SUFFIX; + } + else { + url = WXPayConstants.ORDERQUERY_URL_SUFFIX; + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + + /** + * 作用:撤销订单
    + * 场景:刷卡支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map reverse(Map reqData) throws Exception { + return this.reverse(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:撤销订单
    + * 场景:刷卡支付
    + * 其他:需要证书 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map reverse(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_REVERSE_URL_SUFFIX; + } + else { + url = WXPayConstants.REVERSE_URL_SUFFIX; + } + String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + + /** + * 作用:关闭订单
    + * 场景:公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map closeOrder(Map reqData) throws Exception { + return this.closeOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:关闭订单
    + * 场景:公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map closeOrder(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_CLOSEORDER_URL_SUFFIX; + } + else { + url = WXPayConstants.CLOSEORDER_URL_SUFFIX; + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + + /** + * 作用:申请退款
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map refund(Map reqData) throws Exception { + return this.refund(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:申请退款
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付
    + * 其他:需要证书 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map refund(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_REFUND_URL_SUFFIX; + } + else { + url = WXPayConstants.REFUND_URL_SUFFIX; + } + String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + + /** + * 作用:退款查询
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map refundQuery(Map reqData) throws Exception { + return this.refundQuery(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:退款查询
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map refundQuery(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_REFUNDQUERY_URL_SUFFIX; + } + else { + url = WXPayConstants.REFUNDQUERY_URL_SUFFIX; + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + + /** + * 作用:对账单下载(成功时返回对账单数据,失败时返回XML格式数据)
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map downloadBill(Map reqData) throws Exception { + return this.downloadBill(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:对账单下载
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付
    + * 其他:无论是否成功都返回Map。若成功,返回的Map中含有return_code、return_msg、data, + * 其中return_code为`SUCCESS`,data为对账单数据。 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return 经过封装的API返回数据 + * @throws Exception + */ + public Map downloadBill(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_DOWNLOADBILL_URL_SUFFIX; + } + else { + url = WXPayConstants.DOWNLOADBILL_URL_SUFFIX; + } + String respStr = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs).trim(); + Map ret; + // 出现错误,返回XML数据 + if (respStr.indexOf("<") == 0) { + ret = WXPayUtil.xmlToMap(respStr); + } + else { + // 正常返回csv数据 + ret = new HashMap(); + ret.put("return_code", WXPayConstants.SUCCESS); + ret.put("return_msg", "ok"); + ret.put("data", respStr); + } + return ret; + } + + + /** + * 作用:交易保障
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map report(Map reqData) throws Exception { + return this.report(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:交易保障
    + * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map report(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_REPORT_URL_SUFFIX; + } + else { + url = WXPayConstants.REPORT_URL_SUFFIX; + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return WXPayUtil.xmlToMap(respXml); + } + + + /** + * 作用:转换短链接
    + * 场景:刷卡支付、扫码支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map shortUrl(Map reqData) throws Exception { + return this.shortUrl(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:转换短链接
    + * 场景:刷卡支付、扫码支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map shortUrl(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_SHORTURL_URL_SUFFIX; + } + else { + url = WXPayConstants.SHORTURL_URL_SUFFIX; + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + + /** + * 作用:授权码查询OPENID接口
    + * 场景:刷卡支付 + * @param reqData 向wxpay post的请求数据 + * @return API返回数据 + * @throws Exception + */ + public Map authCodeToOpenid(Map reqData) throws Exception { + return this.authCodeToOpenid(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + } + + + /** + * 作用:授权码查询OPENID接口
    + * 场景:刷卡支付 + * @param reqData 向wxpay post的请求数据 + * @param connectTimeoutMs 连接超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 + * @return API返回数据 + * @throws Exception + */ + public Map authCodeToOpenid(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + String url; + if (this.useSandbox) { + url = WXPayConstants.SANDBOX_AUTHCODETOOPENID_URL_SUFFIX; + } + else { + url = WXPayConstants.AUTHCODETOOPENID_URL_SUFFIX; + } + String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); + return this.processResponseXml(respXml); + } + + +} // end class diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConfig.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConfig.java new file mode 100644 index 0000000..9af5dca --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConfig.java @@ -0,0 +1,103 @@ +package com.github.wxpay.sdk; + +import java.io.InputStream; + +public abstract class WXPayConfig { + + + + /** + * 获取 App ID + * + * @return App ID + */ + abstract String getAppID(); + + + /** + * 获取 Mch ID + * + * @return Mch ID + */ + abstract String getMchID(); + + + /** + * 获取 API 密钥 + * + * @return API密钥 + */ + abstract String getKey(); + + + /** + * 获取商户证书内容 + * + * @return 商户证书内容 + */ + abstract InputStream getCertStream(); + + /** + * HTTP(S) 连接超时时间,单位毫秒 + * + * @return + */ + public int getHttpConnectTimeoutMs() { + return 6*1000; + } + + /** + * HTTP(S) 读数据超时时间,单位毫秒 + * + * @return + */ + public int getHttpReadTimeoutMs() { + return 8*1000; + } + + /** + * 获取WXPayDomain, 用于多域名容灾自动切换 + * @return + */ + abstract IWXPayDomain getWXPayDomain(); + + /** + * 是否自动上报。 + * 若要关闭自动上报,子类中实现该函数返回 false 即可。 + * + * @return + */ + public boolean shouldAutoReport() { + return true; + } + + /** + * 进行健康上报的线程的数量 + * + * @return + */ + public int getReportWorkerNum() { + return 6; + } + + + /** + * 健康上报缓存消息的最大数量。会有线程去独立上报 + * 粗略计算:加入一条消息200B,10000消息占用空间 2000 KB,约为2MB,可以接受 + * + * @return + */ + public int getReportQueueMaxSize() { + return 10000; + } + + /** + * 批量上报,一次最多上报多个数据 + * + * @return + */ + public int getReportBatchSize() { + return 10; + } + +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java new file mode 100644 index 0000000..d4e6c87 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java @@ -0,0 +1,59 @@ +package com.github.wxpay.sdk; + +import org.apache.http.client.HttpClient; + +/** + * 常量 + */ +public class WXPayConstants { + + public enum SignType { + MD5, HMACSHA256 + } + + public static final String DOMAIN_API = "api.mch.weixin.qq.com"; + public static final String DOMAIN_API2 = "api2.mch.weixin.qq.com"; + public static final String DOMAIN_APIHK = "apihk.mch.weixin.qq.com"; + public static final String DOMAIN_APIUS = "apius.mch.weixin.qq.com"; + + + public static final String FAIL = "FAIL"; + public static final String SUCCESS = "SUCCESS"; + public static final String HMACSHA256 = "HMAC-SHA256"; + public static final String MD5 = "MD5"; + + public static final String FIELD_SIGN = "sign"; + public static final String FIELD_SIGN_TYPE = "sign_type"; + + public static final String WXPAYSDK_VERSION = "WXPaySDK/3.0.9"; + public static final String USER_AGENT = WXPAYSDK_VERSION + + " (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") + + ") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion(); + + public static final String MICROPAY_URL_SUFFIX = "/pay/micropay"; + public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder"; + public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery"; + public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse"; + public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder"; + public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund"; + public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery"; + public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill"; + public static final String REPORT_URL_SUFFIX = "/payitil/report"; + public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl"; + public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid"; + + // sandbox + public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay"; + public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder"; + public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery"; + public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse"; + public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder"; + public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund"; + public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery"; + public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill"; + public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report"; + public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl"; + public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid"; + +} + diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayReport.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayReport.java new file mode 100644 index 0000000..88c411a --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayReport.java @@ -0,0 +1,265 @@ +package com.github.wxpay.sdk; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; +import org.apache.http.util.EntityUtils; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; + +/** + * 交易保障 + */ +public class WXPayReport { + + public static class ReportInfo { + + /** + * 布尔变量使用int。0为false, 1为true。 + */ + + // 基本信息 + private String version = "v1"; + private String sdk = WXPayConstants.WXPAYSDK_VERSION; + private String uuid; // 交易的标识 + private long timestamp; // 上报时的时间戳,单位秒 + private long elapsedTimeMillis; // 耗时,单位 毫秒 + + // 针对主域名 + private String firstDomain; // 第1次请求的域名 + private boolean primaryDomain; //是否主域名 + private int firstConnectTimeoutMillis; // 第1次请求设置的连接超时时间,单位 毫秒 + private int firstReadTimeoutMillis; // 第1次请求设置的读写超时时间,单位 毫秒 + private int firstHasDnsError; // 第1次请求是否出现dns问题 + private int firstHasConnectTimeout; // 第1次请求是否出现连接超时 + private int firstHasReadTimeout; // 第1次请求是否出现连接超时 + + public ReportInfo(String uuid, long timestamp, long elapsedTimeMillis, String firstDomain, boolean primaryDomain, int firstConnectTimeoutMillis, int firstReadTimeoutMillis, boolean firstHasDnsError, boolean firstHasConnectTimeout, boolean firstHasReadTimeout) { + this.uuid = uuid; + this.timestamp = timestamp; + this.elapsedTimeMillis = elapsedTimeMillis; + this.firstDomain = firstDomain; + this.primaryDomain = primaryDomain; + this.firstConnectTimeoutMillis = firstConnectTimeoutMillis; + this.firstReadTimeoutMillis = firstReadTimeoutMillis; + this.firstHasDnsError = firstHasDnsError?1:0; + this.firstHasConnectTimeout = firstHasConnectTimeout?1:0; + this.firstHasReadTimeout = firstHasReadTimeout?1:0; + } + + @Override + public String toString() { + return "ReportInfo{" + + "version='" + version + '\'' + + ", sdk='" + sdk + '\'' + + ", uuid='" + uuid + '\'' + + ", timestamp=" + timestamp + + ", elapsedTimeMillis=" + elapsedTimeMillis + + ", firstDomain='" + firstDomain + '\'' + + ", primaryDomain=" + primaryDomain + + ", firstConnectTimeoutMillis=" + firstConnectTimeoutMillis + + ", firstReadTimeoutMillis=" + firstReadTimeoutMillis + + ", firstHasDnsError=" + firstHasDnsError + + ", firstHasConnectTimeout=" + firstHasConnectTimeout + + ", firstHasReadTimeout=" + firstHasReadTimeout + + '}'; + } + + /** + * 转换成 csv 格式 + * + * @return + */ + public String toLineString(String key) { + String separator = ","; + Object[] objects = new Object[] { + version, sdk, uuid, timestamp, elapsedTimeMillis, + firstDomain, primaryDomain, firstConnectTimeoutMillis, firstReadTimeoutMillis, + firstHasDnsError, firstHasConnectTimeout, firstHasReadTimeout + }; + StringBuffer sb = new StringBuffer(); + for(Object obj: objects) { + sb.append(obj).append(separator); + } + try { + String sign = WXPayUtil.HMACSHA256(sb.toString(), key); + sb.append(sign); + return sb.toString(); + } + catch (Exception ex) { + return null; + } + + } + + } + + private static final String REPORT_URL = "http://report.mch.weixin.qq.com/wxpay/report/default"; + // private static final String REPORT_URL = "http://127.0.0.1:5000/test"; + + + private static final int DEFAULT_CONNECT_TIMEOUT_MS = 6*1000; + private static final int DEFAULT_READ_TIMEOUT_MS = 8*1000; + + private LinkedBlockingQueue reportMsgQueue = null; + private WXPayConfig config; + private ExecutorService executorService; + + private volatile static WXPayReport INSTANCE; + + private WXPayReport(final WXPayConfig config) { + this.config = config; + reportMsgQueue = new LinkedBlockingQueue(config.getReportQueueMaxSize()); + + // 添加处理线程 + executorService = Executors.newFixedThreadPool(config.getReportWorkerNum(), new ThreadFactory() { + public Thread newThread(Runnable r) { + Thread t = Executors.defaultThreadFactory().newThread(r); + t.setDaemon(true); + return t; + } + }); + + if (config.shouldAutoReport()) { + WXPayUtil.getLogger().info("report worker num: {}", config.getReportWorkerNum()); + for (int i = 0; i < config.getReportWorkerNum(); ++i) { + executorService.execute(new Runnable() { + public void run() { + while (true) { + // 先用 take 获取数据 + try { + StringBuffer sb = new StringBuffer(); + String firstMsg = reportMsgQueue.take(); + WXPayUtil.getLogger().info("get first report msg: {}", firstMsg); + String msg = null; + sb.append(firstMsg); //会阻塞至有消息 + int remainNum = config.getReportBatchSize() - 1; + for (int j=0; jcreate() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", SSLConnectionSocketFactory.getSocketFactory()) + .build(), + null, + null, + null + ); + HttpClient httpClient = HttpClientBuilder.create() + .setConnectionManager(connManager) + .build(); + + HttpPost httpPost = new HttpPost(REPORT_URL); + + RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build(); + httpPost.setConfig(requestConfig); + + StringEntity postEntity = new StringEntity(data, "UTF-8"); + httpPost.addHeader("Content-Type", "text/xml"); + httpPost.addHeader("User-Agent", WXPayConstants.USER_AGENT); + httpPost.setEntity(postEntity); + + HttpResponse httpResponse = httpClient.execute(httpPost); + HttpEntity httpEntity = httpResponse.getEntity(); + return EntityUtils.toString(httpEntity, "UTF-8"); + } + +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayRequest.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayRequest.java new file mode 100644 index 0000000..7209777 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayRequest.java @@ -0,0 +1,258 @@ +package com.github.wxpay.sdk; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; +import org.apache.http.util.EntityUtils; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import java.io.InputStream; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.security.KeyStore; +import java.security.SecureRandom; + +import static com.github.wxpay.sdk.WXPayConstants.USER_AGENT; + +public class WXPayRequest { + private WXPayConfig config; + public WXPayRequest(WXPayConfig config) throws Exception{ + + this.config = config; + } + + /** + * 请求,只请求一次,不做重试 + * @param domain + * @param urlSuffix + * @param uuid + * @param data + * @param connectTimeoutMs + * @param readTimeoutMs + * @param useCert 是否使用证书,针对退款、撤销等操作 + * @return + * @throws Exception + */ + private String requestOnce(final String domain, String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean useCert) throws Exception { + BasicHttpClientConnectionManager connManager; + if (useCert) { + // 证书 + char[] password = config.getMchID().toCharArray(); + InputStream certStream = config.getCertStream(); + KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(certStream, password); + + // 实例化密钥库 & 初始化密钥工厂 + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(ks, password); + + // 创建 SSLContext + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(kmf.getKeyManagers(), null, new SecureRandom()); + + SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory( + sslContext, + new String[]{"TLSv1"}, + null, + new DefaultHostnameVerifier()); + + connManager = new BasicHttpClientConnectionManager( + RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", sslConnectionSocketFactory) + .build(), + null, + null, + null + ); + } + else { + connManager = new BasicHttpClientConnectionManager( + RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + .register("https", SSLConnectionSocketFactory.getSocketFactory()) + .build(), + null, + null, + null + ); + } + + HttpClient httpClient = HttpClientBuilder.create() + .setConnectionManager(connManager) + .build(); + + String url = "https://" + domain + urlSuffix; + HttpPost httpPost = new HttpPost(url); + + RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build(); + httpPost.setConfig(requestConfig); + + StringEntity postEntity = new StringEntity(data, "UTF-8"); + httpPost.addHeader("Content-Type", "text/xml"); + httpPost.addHeader("User-Agent", USER_AGENT + " " + config.getMchID()); + httpPost.setEntity(postEntity); + + HttpResponse httpResponse = httpClient.execute(httpPost); + HttpEntity httpEntity = httpResponse.getEntity(); + return EntityUtils.toString(httpEntity, "UTF-8"); + + } + + + private String request(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean useCert, boolean autoReport) throws Exception { + Exception exception = null; + long elapsedTimeMillis = 0; + long startTimestampMs = WXPayUtil.getCurrentTimestampMs(); + boolean firstHasDnsErr = false; + boolean firstHasConnectTimeout = false; + boolean firstHasReadTimeout = false; + IWXPayDomain.DomainInfo domainInfo = config.getWXPayDomain().getDomain(config); + if(domainInfo == null){ + throw new Exception("WXPayConfig.getWXPayDomain().getDomain() is empty or null"); + } + try { + String result = requestOnce(domainInfo.domain, urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, useCert); + elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs; + config.getWXPayDomain().report(domainInfo.domain, elapsedTimeMillis, null); + WXPayReport.getInstance(config).report( + uuid, + elapsedTimeMillis, + domainInfo.domain, + domainInfo.primaryDomain, + connectTimeoutMs, + readTimeoutMs, + firstHasDnsErr, + firstHasConnectTimeout, + firstHasReadTimeout); + return result; + } + catch (UnknownHostException ex) { // dns 解析错误,或域名不存在 + exception = ex; + firstHasDnsErr = true; + elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs; + WXPayUtil.getLogger().warn("UnknownHostException for domainInfo {}", domainInfo); + WXPayReport.getInstance(config).report( + uuid, + elapsedTimeMillis, + domainInfo.domain, + domainInfo.primaryDomain, + connectTimeoutMs, + readTimeoutMs, + firstHasDnsErr, + firstHasConnectTimeout, + firstHasReadTimeout + ); + } + catch (ConnectTimeoutException ex) { + exception = ex; + firstHasConnectTimeout = true; + elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs; + WXPayUtil.getLogger().warn("connect timeout happened for domainInfo {}", domainInfo); + WXPayReport.getInstance(config).report( + uuid, + elapsedTimeMillis, + domainInfo.domain, + domainInfo.primaryDomain, + connectTimeoutMs, + readTimeoutMs, + firstHasDnsErr, + firstHasConnectTimeout, + firstHasReadTimeout + ); + } + catch (SocketTimeoutException ex) { + exception = ex; + firstHasReadTimeout = true; + elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs; + WXPayUtil.getLogger().warn("timeout happened for domainInfo {}", domainInfo); + WXPayReport.getInstance(config).report( + uuid, + elapsedTimeMillis, + domainInfo.domain, + domainInfo.primaryDomain, + connectTimeoutMs, + readTimeoutMs, + firstHasDnsErr, + firstHasConnectTimeout, + firstHasReadTimeout); + } + catch (Exception ex) { + exception = ex; + elapsedTimeMillis = WXPayUtil.getCurrentTimestampMs()-startTimestampMs; + WXPayReport.getInstance(config).report( + uuid, + elapsedTimeMillis, + domainInfo.domain, + domainInfo.primaryDomain, + connectTimeoutMs, + readTimeoutMs, + firstHasDnsErr, + firstHasConnectTimeout, + firstHasReadTimeout); + } + config.getWXPayDomain().report(domainInfo.domain, elapsedTimeMillis, exception); + throw exception; + } + + + /** + * 可重试的,非双向认证的请求 + * @param urlSuffix + * @param uuid + * @param data + * @return + */ + public String requestWithoutCert(String urlSuffix, String uuid, String data, boolean autoReport) throws Exception { + return this.request(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), false, autoReport); + } + + /** + * 可重试的,非双向认证的请求 + * @param urlSuffix + * @param uuid + * @param data + * @param connectTimeoutMs + * @param readTimeoutMs + * @return + */ + public String requestWithoutCert(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean autoReport) throws Exception { + return this.request(urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, false, autoReport); + } + + /** + * 可重试的,双向认证的请求 + * @param urlSuffix + * @param uuid + * @param data + * @return + */ + public String requestWithCert(String urlSuffix, String uuid, String data, boolean autoReport) throws Exception { + return this.request(urlSuffix, uuid, data, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs(), true, autoReport); + } + + /** + * 可重试的,双向认证的请求 + * @param urlSuffix + * @param uuid + * @param data + * @param connectTimeoutMs + * @param readTimeoutMs + * @return + */ + public String requestWithCert(String urlSuffix, String uuid, String data, int connectTimeoutMs, int readTimeoutMs, boolean autoReport) throws Exception { + return this.request(urlSuffix, uuid, data, connectTimeoutMs, readTimeoutMs, true, autoReport); + } +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayUtil.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayUtil.java new file mode 100644 index 0000000..e893353 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayUtil.java @@ -0,0 +1,295 @@ +package com.github.wxpay.sdk; + +import com.github.wxpay.sdk.WXPayConstants.SignType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.StringWriter; +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.*; + + +public class WXPayUtil { + + private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + private static final Random RANDOM = new SecureRandom(); + + /** + * XML格式字符串转换为Map + * + * @param strXML XML字符串 + * @return XML数据转换后的Map + * @throws Exception + */ + public static Map xmlToMap(String strXML) throws Exception { + try { + Map data = new HashMap(); + DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder(); + InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8")); + org.w3c.dom.Document doc = documentBuilder.parse(stream); + doc.getDocumentElement().normalize(); + NodeList nodeList = doc.getDocumentElement().getChildNodes(); + for (int idx = 0; idx < nodeList.getLength(); ++idx) { + Node node = nodeList.item(idx); + if (node.getNodeType() == Node.ELEMENT_NODE) { + org.w3c.dom.Element element = (org.w3c.dom.Element) node; + data.put(element.getNodeName(), element.getTextContent()); + } + } + try { + stream.close(); + } catch (Exception ex) { + // do nothing + } + return data; + } catch (Exception ex) { + WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML); + throw ex; + } + + } + + /** + * 将Map转换为XML格式的字符串 + * + * @param data Map类型数据 + * @return XML格式的字符串 + * @throws Exception + */ + public static String mapToXml(Map data) throws Exception { + org.w3c.dom.Document document = WXPayXmlUtil.newDocument(); + org.w3c.dom.Element root = document.createElement("xml"); + document.appendChild(root); + for (String key: data.keySet()) { + String value = data.get(key); + if (value == null) { + value = ""; + } + value = value.trim(); + org.w3c.dom.Element filed = document.createElement(key); + filed.appendChild(document.createTextNode(value)); + root.appendChild(filed); + } + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + DOMSource source = new DOMSource(document); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", ""); + try { + writer.close(); + } + catch (Exception ex) { + } + return output; + } + + + /** + * 生成带有 sign 的 XML 格式字符串 + * + * @param data Map类型数据 + * @param key API密钥 + * @return 含有sign字段的XML + */ + public static String generateSignedXml(final Map data, String key) throws Exception { + return generateSignedXml(data, key, SignType.MD5); + } + + /** + * 生成带有 sign 的 XML 格式字符串 + * + * @param data Map类型数据 + * @param key API密钥 + * @param signType 签名类型 + * @return 含有sign字段的XML + */ + public static String generateSignedXml(final Map data, String key, SignType signType) throws Exception { + String sign = generateSignature(data, key, signType); + data.put(WXPayConstants.FIELD_SIGN, sign); + return mapToXml(data); + } + + + /** + * 判断签名是否正确 + * + * @param xmlStr XML格式数据 + * @param key API密钥 + * @return 签名是否正确 + * @throws Exception + */ + public static boolean isSignatureValid(String xmlStr, String key) throws Exception { + Map data = xmlToMap(xmlStr); + if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) { + return false; + } + String sign = data.get(WXPayConstants.FIELD_SIGN); + return generateSignature(data, key).equals(sign); + } + + /** + * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。 + * + * @param data Map类型数据 + * @param key API密钥 + * @return 签名是否正确 + * @throws Exception + */ + public static boolean isSignatureValid(Map data, String key) throws Exception { + return isSignatureValid(data, key, SignType.MD5); + } + + /** + * 判断签名是否正确,必须包含sign字段,否则返回false。 + * + * @param data Map类型数据 + * @param key API密钥 + * @param signType 签名方式 + * @return 签名是否正确 + * @throws Exception + */ + public static boolean isSignatureValid(Map data, String key, SignType signType) throws Exception { + if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) { + return false; + } + String sign = data.get(WXPayConstants.FIELD_SIGN); + return generateSignature(data, key, signType).equals(sign); + } + + /** + * 生成签名 + * + * @param data 待签名数据 + * @param key API密钥 + * @return 签名 + */ + public static String generateSignature(final Map data, String key) throws Exception { + return generateSignature(data, key, SignType.MD5); + } + + /** + * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。 + * + * @param data 待签名数据 + * @param key API密钥 + * @param signType 签名方式 + * @return 签名 + */ + public static String generateSignature(final Map data, String key, SignType signType) throws Exception { + Set keySet = data.keySet(); + String[] keyArray = keySet.toArray(new String[keySet.size()]); + Arrays.sort(keyArray); + StringBuilder sb = new StringBuilder(); + for (String k : keyArray) { + if (k.equals(WXPayConstants.FIELD_SIGN)) { + continue; + } + if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名 + sb.append(k).append("=").append(data.get(k).trim()).append("&"); + } + sb.append("key=").append(key); + if (SignType.MD5.equals(signType)) { + return MD5(sb.toString()).toUpperCase(); + } + else if (SignType.HMACSHA256.equals(signType)) { + return HMACSHA256(sb.toString(), key); + } + else { + throw new Exception(String.format("Invalid sign_type: %s", signType)); + } + } + + + /** + * 获取随机字符串 Nonce Str + * + * @return String 随机字符串 + */ + public static String generateNonceStr() { + char[] nonceChars = new char[32]; + for (int index = 0; index < nonceChars.length; ++index) { + nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); + } + return new String(nonceChars); + } + + + /** + * 生成 MD5 + * + * @param data 待处理数据 + * @return MD5结果 + */ + public static String MD5(String data) throws Exception { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] array = md.digest(data.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (byte item : array) { + sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString().toUpperCase(); + } + + /** + * 生成 HMACSHA256 + * @param data 待处理数据 + * @param key 密钥 + * @return 加密结果 + * @throws Exception + */ + public static String HMACSHA256(String data, String key) throws Exception { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (byte item : array) { + sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString().toUpperCase(); + } + + /** + * 日志 + * @return + */ + public static Logger getLogger() { + Logger logger = LoggerFactory.getLogger("wxpay java sdk"); + return logger; + } + + /** + * 获取当前时间戳,单位秒 + * @return + */ + public static long getCurrentTimestamp() { + return System.currentTimeMillis()/1000; + } + + /** + * 获取当前时间戳,单位毫秒 + * @return + */ + public static long getCurrentTimestampMs() { + return System.currentTimeMillis(); + } + +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayXmlUtil.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayXmlUtil.java new file mode 100644 index 0000000..500d9a4 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayXmlUtil.java @@ -0,0 +1,30 @@ +package com.github.wxpay.sdk; + +import org.w3c.dom.Document; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +/** + * 2018/7/3 + */ +public final class WXPayXmlUtil { + public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); + documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + documentBuilderFactory.setXIncludeAware(false); + documentBuilderFactory.setExpandEntityReferences(false); + + return documentBuilderFactory.newDocumentBuilder(); + } + + public static Document newDocument() throws ParserConfigurationException { + return newDocumentBuilder().newDocument(); + } +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java new file mode 100644 index 0000000..8e0ced6 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java @@ -0,0 +1,55 @@ +package jframe.wxpay; + +import jframe.core.conf.Config; +import jframe.core.plugin.annotation.InjectPlugin; +import jframe.core.plugin.annotation.Injector; +import jframe.core.util.PropsConf; + +import java.io.*; +import java.nio.file.Paths; + +/** + * @author dzh + * @date 2020/8/18 19:39 + */ +@Injector +public class WxpayConf extends PropsConf { + + @InjectPlugin + static WxpayPlugin plugin; + + public static final String CERTNAME = "apiclient_cert.p12"; + + public static final String P_appId = "appId"; + public static final String P_mchId = "mchId"; + public static final String P_apiKey = "apiKey"; + public static final String P_certPath = "certPath"; + public static final String P_notifyUrl = "notifyUrl"; + public static final String P_autoReport = "autoReport"; + public static final String P_useSandbox = "useSandbox"; + + public synchronized void init(InputStream is) throws Exception { + super.init(is); + } + + /** + * @param id groupid + * @return cert bytes + * @throws IOException + */ + public byte[] loadCert(String id) throws IOException { + String certPath = this.getConf(id, P_certPath); + File file = new File(certPath); + if (!file.exists()) { + file = Paths.get(plugin.getConfig(Config.APP_CONF), CERTNAME).toFile(); + } + if (!file.exists()) { + throw new FileNotFoundException(CERTNAME); + } + try (InputStream certStream = new FileInputStream(file)) { + byte[] certData = new byte[(int) file.length()]; + certStream.read(certData); + return certData; + } + } +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayPlugin.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayPlugin.java new file mode 100644 index 0000000..83fe5bb --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayPlugin.java @@ -0,0 +1,11 @@ +package jframe.wxpay; + +import jframe.core.plugin.DefPlugin; + +/** + * @author dzh + * @date 2020/8/18 16:44 + */ +public class WxpayPlugin extends DefPlugin { + +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java new file mode 100644 index 0000000..8f27495 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java @@ -0,0 +1,39 @@ +package jframe.wxpay.service; + +import jframe.core.plugin.annotation.Service; + +import java.util.Map; + +/** + * @author dzh + * @date 2020/8/18 16:45 + */ +@Service(clazz = "jframe.wxpay.service.WxpayServiceV2", id = WxpayService.ID) +public interface WxpayService { + + String ID = "jframe.service.wxpay"; + + String NOTIFY_SUCC = ""; + String NOTIFY_FAIL = ""; + + /** + * @param id groupid + * @param key properties key + * @return properties value + */ + String conf(String id, String key); + + Map orderPrepay(String id, Map req) throws Exception; + + Map orderClose(String id, Map req) throws Exception; + + Map orderQuery(String id, Map req) throws Exception; + + Map processResponseXml(String id, String xmlStr) throws Exception; + + Map refund(String id, Map req) throws Exception; + + Map refundQuery(String id, Map req) throws Exception; + + +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java new file mode 100644 index 0000000..e455e18 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -0,0 +1,115 @@ +package jframe.wxpay.service; + +import com.github.wxpay.sdk.JframeWxpayConfig; +import com.github.wxpay.sdk.WXPay; +import jframe.core.conf.Config; +import jframe.core.plugin.annotation.InjectPlugin; +import jframe.core.plugin.annotation.Injector; +import jframe.core.plugin.annotation.Start; +import jframe.core.plugin.annotation.Stop; +import jframe.wxpay.WxpayConf; +import jframe.wxpay.WxpayPlugin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; + +/** + * https://pay.weixin.qq.com/wiki/doc/api/index.html + * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 + * + * @author dzh + * @date 2020/8/18 17:40 + */ +@Injector +public class WxpayServiceV2 implements WxpayService { + + static Logger LOG = LoggerFactory.getLogger(WxpayServiceV2.class); + + @InjectPlugin + static WxpayPlugin plugin; + + static String FILE_WXPAY = "file.wxpay"; + + //group id -> AlipayClient + private Map clients = new HashMap<>(); + + private WxpayConf wxpayConf; + + @Start + void start() { + LOG.info("Start WxpayServiceV2"); + try { + String file = plugin.getConfig(FILE_WXPAY, plugin.getConfig(Config.APP_CONF) + "/wxpay.properties"); + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } + wxpayConf = new WxpayConf(); + wxpayConf.init(file); + for (String id : wxpayConf.getGroupIds()) { + WXPay wxpay = createWxpay(wxpayConf, id); + clients.put(id, wxpay); + } + LOG.info("Start WxpayServiceV2 Successfully!"); + } catch (Exception e) { + LOG.error("Start WxpayServiceV2 Failed!" + e.getMessage(), e); + } + } + + @Stop + void stop() { + clients.clear(); + LOG.info("Stop WxpayServiceV2"); + } + + private WXPay createWxpay(WxpayConf props, String id) throws Exception { + byte[] bytes = props.loadCert(id); + JframeWxpayConfig conf = JframeWxpayConfig.create(props.getConf(id, WxpayConf.P_appId), + props.getConf(id, WxpayConf.P_mchId), props.getConf(id, WxpayConf.P_appId), new ByteArrayInputStream(bytes)); + return new WXPay(conf, props.getConf(id, WxpayConf.P_notifyUrl), + Boolean.parseBoolean(props.getConf(id, WxpayConf.P_autoReport, "true")), + Boolean.parseBoolean(props.getConf(id, WxpayConf.P_useSandbox, "false"))); + } + + + @Override + public String conf(String id, String key) { + return wxpayConf.getConf(id, key); + } + + @Override + public Map orderPrepay(String id, Map req) throws Exception { +// req.putIfAbsent("appid", conf(id, WxpayConf.P_appId)); +// req.putIfAbsent("mch_id", conf(id, WxpayConf.P_mchId)); + return clients.get(id).unifiedOrder(req); + } + + @Override + public Map orderClose(String id, Map req) throws Exception { + return clients.get(id).closeOrder(req); + } + + @Override + public Map orderQuery(String id, Map req) throws Exception { + return clients.get(id).orderQuery(req); + } + + @Override + public Map processResponseXml(String id, String xmlStr) throws Exception { + return clients.get(id).processResponseXml(xmlStr); + } + + @Override + public Map refund(String id, Map req) throws Exception { + return clients.get(id).refund(req); + } + + @Override + public Map refundQuery(String id, Map req) throws Exception { + return clients.get(id).refundQuery(req); + } +} diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java new file mode 100644 index 0000000..33e90ff --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java @@ -0,0 +1,86 @@ +package jframe.wxpay.service; + +import jframe.core.conf.Config; +import jframe.core.plugin.annotation.InjectPlugin; +import jframe.core.plugin.annotation.Injector; +import jframe.core.plugin.annotation.Start; +import jframe.core.plugin.annotation.Stop; +import jframe.wxpay.WxpayConf; +import jframe.wxpay.WxpayPlugin; +import org.apache.http.client.HttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; + +/** + * https://wechatpay-api.gitbook.io/wechatpay-api-v3/ + * https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/transactions.shtml 接口文档 + * https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient + *

    + * 请求的唯一标示包含在应答的HTTP头Request-ID中 + *

    + * User-Agent + * 使用HTTP客户端默认的User-Agent。 + * 遵循HTTP协议,使用自身系统和应用的名称和版本等信息,组成自己独有的User-Agent。 + *

    + * Accept-Language + * en + * zh-CN + * zh-HK + * zh-TW + * + * @author dzh + * @date 2020/8/18 17:38 + */ +@Injector +public class WxpayServiceV3 { + + static Logger LOG = LoggerFactory.getLogger(WxpayServiceV3.class); + + @InjectPlugin + static WxpayPlugin plugin; + + static String FILE_WXPAY = "file.wxpay"; + + private WxpayConf wxpayConf; + + private Map clients = new HashMap<>(); + + @Start + void start() { + LOG.info("Start {}", WxpayServiceV3.class.getSimpleName()); + try { + String file = plugin.getConfig(FILE_WXPAY, plugin.getConfig(Config.APP_CONF) + "/wxpay.properties"); + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } + wxpayConf = new WxpayConf(); + wxpayConf.init(file); + for (String id : wxpayConf.getGroupIds()) { + HttpClient wxpay = createWxpay(wxpayConf, id); + clients.put(id, wxpay); + } + LOG.info("Start WxpayServiceV3 Successfully!"); + } catch (Exception e) { + LOG.error("Start WxpayServiceV3 Failed!" + e.getMessage(), e); + } + } + + private HttpClient createWxpay(WxpayConf wxpayConf, String id) { +// WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() +// .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey) +// .withWechatpay(wechatpayCertificates); + return null; + } + + @Stop + void stop() { + clients.clear(); + LOG.info("Stop WxpayServiceV3"); + } + +} diff --git a/jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties b/jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties new file mode 100644 index 0000000..9df13fe --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties @@ -0,0 +1,7 @@ +Plugin-Name=jframe.wxpay.WxpayPlugin +Plugin-Class=jframe.wxpay.WxpayPlugin +#Default library path is META-INF/lib/ +#Plugin-Lib = +#Default DLL path is META-INF/dll +#Plugin-Dll = +Plugin-Service=jframe.wxpay.service.WxpayService diff --git a/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties b/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties new file mode 100644 index 0000000..32ee586 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties @@ -0,0 +1,12 @@ +group.id=xxx +# +@xxx.appId= +@xxx.mchId= +@xxx.apiKey= +@xxx.certPath= +@xxx.notifyUrl= +@xxx.autoReport=true +@xxx.useSandbox=false +# common + + diff --git a/jframe-plugin/pom.xml b/jframe-plugin/pom.xml index 5bdd6c3..c2a1212 100644 --- a/jframe-plugin/pom.xml +++ b/jframe-plugin/pom.xml @@ -44,6 +44,7 @@ jframe-qcloud jframe-google jframe-alipay + jframe-wxpay From 268e8d2d0b1ca8c387b704f6b6feab31f348d3ee Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 4 Sep 2020 14:23:53 +0800 Subject: [PATCH 13/47] add log --- .../src/main/java/jframe/wxpay/service/WxpayServiceV2.java | 2 +- .../src/main/java/jframe/zk/service/CuratorService.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index e455e18..ec209db 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -54,7 +54,7 @@ void start() { WXPay wxpay = createWxpay(wxpayConf, id); clients.put(id, wxpay); } - LOG.info("Start WxpayServiceV2 Successfully!"); + LOG.info("Start WxpayServiceV2 Successfully! ids:{}", wxpayConf.getGroupIds()); } catch (Exception e) { LOG.error("Start WxpayServiceV2 Failed!" + e.getMessage(), e); } diff --git a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java index fc771f4..bc0d5cb 100644 --- a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java +++ b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/CuratorService.java @@ -8,9 +8,11 @@ * @version 0.0.1 * @date Dec 12, 2018 7:12:56 PM */ -@Service(clazz = "jframe.zk.service.impl.CuratorServiceImpl", id = "jframe.service.zk.curator") +@Service(clazz = "jframe.zk.service.impl.CuratorServiceImpl", id = CuratorService.ID) public interface CuratorService { + String ID = "jframe.service.zk.curator"; + CuratorFramework client(String id); } From 81714b2293eb6ee64e13965c20d0165e524d921d Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 4 Sep 2020 14:47:51 +0800 Subject: [PATCH 14/47] fix wxpay domain --- .../github/wxpay/sdk/JframeWxpayConfig.java | 19 ++++++++++++++++++- .../jframe/wxpay/service/WxpayServiceV2.java | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java index d992c58..78b85be 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/JframeWxpayConfig.java @@ -1,5 +1,8 @@ package com.github.wxpay.sdk; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.InputStream; /** @@ -8,6 +11,8 @@ */ public class JframeWxpayConfig extends WXPayConfig { + static Logger LOG = LoggerFactory.getLogger(JframeWxpayConfig.class); + private String appId; private String mchId; @@ -46,7 +51,19 @@ InputStream getCertStream() { @Override IWXPayDomain getWXPayDomain() { - return null; + return new IWXPayDomain() { + + public void report(String domain, long elapsedTimeMillis, Exception ex) { + if (ex != null) { + LOG.info("{} {} {}", domain, elapsedTimeMillis, ex); + } + } + + public DomainInfo getDomain(WXPayConfig config) { + return new DomainInfo(WXPayConstants.DOMAIN_API, true); + } + }; + } // public boolean shouldAutoReport() { diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index ec209db..820000d 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -69,7 +69,7 @@ void stop() { private WXPay createWxpay(WxpayConf props, String id) throws Exception { byte[] bytes = props.loadCert(id); JframeWxpayConfig conf = JframeWxpayConfig.create(props.getConf(id, WxpayConf.P_appId), - props.getConf(id, WxpayConf.P_mchId), props.getConf(id, WxpayConf.P_appId), new ByteArrayInputStream(bytes)); + props.getConf(id, WxpayConf.P_mchId), props.getConf(id, WxpayConf.P_apiKey), new ByteArrayInputStream(bytes)); return new WXPay(conf, props.getConf(id, WxpayConf.P_notifyUrl), Boolean.parseBoolean(props.getConf(id, WxpayConf.P_autoReport, "true")), Boolean.parseBoolean(props.getConf(id, WxpayConf.P_useSandbox, "false"))); From e81c60253cb357fb065c87f4c145a371d194b1d0 Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 4 Sep 2020 17:28:07 +0800 Subject: [PATCH 15/47] add wx signPrepay --- .../main/java/com/github/wxpay/sdk/WXPay.java | 207 +++++++++--------- .../com/github/wxpay/sdk/WXPayConstants.java | 46 ++-- .../jframe/wxpay/service/WxpayService.java | 13 ++ .../jframe/wxpay/service/WxpayServiceV2.java | 19 ++ 4 files changed, 164 insertions(+), 121 deletions(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java index 7f0fbcd..e9bc580 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java @@ -23,7 +23,7 @@ public WXPay(final WXPayConfig config, final boolean autoReport) throws Exceptio } - public WXPay(final WXPayConfig config, final boolean autoReport, final boolean useSandbox) throws Exception{ + public WXPay(final WXPayConfig config, final boolean autoReport, final boolean useSandbox) throws Exception { this(config, null, autoReport, useSandbox); } @@ -42,13 +42,17 @@ public WXPay(final WXPayConfig config, final String notifyUrl, final boolean aut this.useSandbox = useSandbox; if (useSandbox) { this.signType = SignType.MD5; // 沙箱环境 - } - else { + } else { this.signType = SignType.HMACSHA256; } this.wxPayRequest = new WXPayRequest(config); } + public SignType signType() { + return signType; + } + + private void checkWXPayConfig() throws Exception { if (this.config == null) { throw new Exception("config is null"); @@ -62,7 +66,7 @@ private void checkWXPayConfig() throws Exception { if (this.config.getCertStream() == null) { throw new Exception("cert stream in config is empty"); } - if (this.config.getWXPayDomain() == null){ + if (this.config.getWXPayDomain() == null) { throw new Exception("config.getWXPayDomain() is null"); } @@ -89,8 +93,7 @@ public Map fillRequestData(Map reqData) throws E reqData.put("nonce_str", WXPayUtil.generateNonceStr()); if (SignType.MD5.equals(this.signType)) { reqData.put("sign_type", WXPayConstants.MD5); - } - else if (SignType.HMACSHA256.equals(this.signType)) { + } else if (SignType.HMACSHA256.equals(this.signType)) { reqData.put("sign_type", WXPayConstants.HMACSHA256); } reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType)); @@ -121,19 +124,15 @@ public boolean isPayResultNotifySignatureValid(Map reqData) thro SignType signType; if (signTypeInData == null) { signType = SignType.MD5; - } - else { + } else { signTypeInData = signTypeInData.trim(); if (signTypeInData.length() == 0) { signType = SignType.MD5; - } - else if (WXPayConstants.MD5.equals(signTypeInData)) { + } else if (WXPayConstants.MD5.equals(signTypeInData)) { signType = SignType.MD5; - } - else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) { + } else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) { signType = SignType.HMACSHA256; - } - else { + } else { throw new Exception(String.format("Unsupported sign_type: %s", signTypeInData)); } } @@ -143,10 +142,11 @@ else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) { /** * 不需要证书的请求 - * @param urlSuffix String - * @param reqData 向wxpay post的请求数据 + * + * @param urlSuffix String + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 超时时间,单位是毫秒 - * @param readTimeoutMs 超时时间,单位是毫秒 + * @param readTimeoutMs 超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -162,16 +162,17 @@ public String requestWithoutCert(String urlSuffix, Map reqData, /** * 需要证书的请求 - * @param urlSuffix String - * @param reqData 向wxpay post的请求数据 Map + * + * @param urlSuffix String + * @param reqData 向wxpay post的请求数据 Map * @param connectTimeoutMs 超时时间,单位是毫秒 - * @param readTimeoutMs 超时时间,单位是毫秒 + * @param readTimeoutMs 超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ public String requestWithCert(String urlSuffix, Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { - String msgUUID= reqData.get("nonce_str"); + String msgUUID = reqData.get("nonce_str"); String reqBody = WXPayUtil.mapToXml(reqData); String resp = this.wxPayRequest.requestWithCert(urlSuffix, msgUUID, reqBody, connectTimeoutMs, readTimeoutMs, this.autoReport); @@ -180,6 +181,7 @@ public String requestWithCert(String urlSuffix, Map reqData, /** * 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。 + * * @param xmlStr API返回的XML格式数据 * @return Map类型数据 * @throws Exception @@ -190,23 +192,19 @@ public Map processResponseXml(String xmlStr) throws Exception { Map respData = WXPayUtil.xmlToMap(xmlStr); if (respData.containsKey(RETURN_CODE)) { return_code = respData.get(RETURN_CODE); - } - else { + } else { throw new Exception(String.format("No `return_code` in XML: %s", xmlStr)); } if (return_code.equals(WXPayConstants.FAIL)) { return respData; - } - else if (return_code.equals(WXPayConstants.SUCCESS)) { - if (this.isResponseSignatureValid(respData)) { - return respData; - } - else { - throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr)); - } - } - else { + } else if (return_code.equals(WXPayConstants.SUCCESS)) { + if (this.isResponseSignatureValid(respData)) { + return respData; + } else { + throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr)); + } + } else { throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr)); } } @@ -214,6 +212,7 @@ else if (return_code.equals(WXPayConstants.SUCCESS)) { /** * 作用:提交刷卡支付
    * 场景:刷卡支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -226,9 +225,10 @@ public Map microPay(Map reqData) throws Exceptio /** * 作用:提交刷卡支付
    * 场景:刷卡支付 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -236,8 +236,7 @@ public Map microPay(Map reqData, int connectTime String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_MICROPAY_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.MICROPAY_URL_SUFFIX; } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -247,6 +246,7 @@ public Map microPay(Map reqData, int connectTime /** * 提交刷卡支付,针对软POS,尽可能做成功 * 内置重试机制,最多60s + * * @param reqData * @return * @throws Exception @@ -258,13 +258,14 @@ public Map microPayWithPos(Map reqData) throws E /** * 提交刷卡支付,针对软POS,尽可能做成功 * 内置重试机制,最多60s + * * @param reqData * @param connectTimeoutMs * @return * @throws Exception */ public Map microPayWithPos(Map reqData, int connectTimeoutMs) throws Exception { - int remainingTimeMs = 60*1000; + int remainingTimeMs = 60 * 1000; long startTimestampMs = 0; Map lastResult = null; Exception lastException = null; @@ -281,57 +282,49 @@ public Map microPayWithPos(Map reqData, int conn String errCode = lastResult.get("err_code"); if (resultCode.equals("SUCCESS")) { break; - } - else { + } else { // 看错误码,若支付结果未知,则重试提交刷卡支付 if (errCode.equals("SYSTEMERROR") || errCode.equals("BANKERROR") || errCode.equals("USERPAYING")) { - remainingTimeMs = remainingTimeMs - (int)(WXPayUtil.getCurrentTimestampMs() - startTimestampMs); + remainingTimeMs = remainingTimeMs - (int) (WXPayUtil.getCurrentTimestampMs() - startTimestampMs); if (remainingTimeMs <= 100) { break; - } - else { + } else { WXPayUtil.getLogger().info("microPayWithPos: try micropay again"); - if (remainingTimeMs > 5*1000) { - Thread.sleep(5*1000); - } - else { - Thread.sleep(1*1000); + if (remainingTimeMs > 5 * 1000) { + Thread.sleep(5 * 1000); + } else { + Thread.sleep(1 * 1000); } continue; } - } - else { + } else { break; } } - } - else { + } else { break; } - } - catch (Exception ex) { + } catch (Exception ex) { lastResult = null; lastException = ex; } - } - else { + } else { break; } } if (lastResult == null) { throw lastException; - } - else { + } else { return lastResult; } } - /** * 作用:统一下单
    * 场景:公共号支付、扫码支付、APP支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -344,21 +337,21 @@ public Map unifiedOrder(Map reqData) throws Exce /** * 作用:统一下单
    * 场景:公共号支付、扫码支付、APP支付 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ - public Map unifiedOrder(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + public Map unifiedOrder(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_UNIFIEDORDER_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.UNIFIEDORDER_URL_SUFFIX; } - if(this.notifyUrl != null) { + if (this.notifyUrl != null) { reqData.put("notify_url", this.notifyUrl); } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -369,6 +362,7 @@ public Map unifiedOrder(Map reqData, int connec /** * 作用:查询订单
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -381,9 +375,10 @@ public Map orderQuery(Map reqData) throws Except /** * 作用:查询订单
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 - * @param reqData 向wxpay post的请求数据 int + * + * @param reqData 向wxpay post的请求数据 int * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -391,8 +386,7 @@ public Map orderQuery(Map reqData, int connectTi String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_ORDERQUERY_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.ORDERQUERY_URL_SUFFIX; } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -403,6 +397,7 @@ public Map orderQuery(Map reqData, int connectTi /** * 作用:撤销订单
    * 场景:刷卡支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -416,9 +411,10 @@ public Map reverse(Map reqData) throws Exception * 作用:撤销订单
    * 场景:刷卡支付
    * 其他:需要证书 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -426,8 +422,7 @@ public Map reverse(Map reqData, int connectTimeo String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_REVERSE_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.REVERSE_URL_SUFFIX; } String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -438,6 +433,7 @@ public Map reverse(Map reqData, int connectTimeo /** * 作用:关闭订单
    * 场景:公共号支付、扫码支付、APP支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -450,18 +446,18 @@ public Map closeOrder(Map reqData) throws Except /** * 作用:关闭订单
    * 场景:公共号支付、扫码支付、APP支付 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ - public Map closeOrder(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { + public Map closeOrder(Map reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception { String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_CLOSEORDER_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.CLOSEORDER_URL_SUFFIX; } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -472,6 +468,7 @@ public Map closeOrder(Map reqData, int connectT /** * 作用:申请退款
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -485,9 +482,10 @@ public Map refund(Map reqData) throws Exception * 作用:申请退款
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付
    * 其他:需要证书 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -495,8 +493,7 @@ public Map refund(Map reqData, int connectTimeou String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_REFUND_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.REFUND_URL_SUFFIX; } String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -507,6 +504,7 @@ public Map refund(Map reqData, int connectTimeou /** * 作用:退款查询
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -519,9 +517,10 @@ public Map refundQuery(Map reqData) throws Excep /** * 作用:退款查询
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -529,8 +528,7 @@ public Map refundQuery(Map reqData, int connectT String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_REFUNDQUERY_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.REFUNDQUERY_URL_SUFFIX; } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -541,6 +539,7 @@ public Map refundQuery(Map reqData, int connectT /** * 作用:对账单下载(成功时返回对账单数据,失败时返回XML格式数据)
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -554,10 +553,11 @@ public Map downloadBill(Map reqData) throws Exce * 作用:对账单下载
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付
    * 其他:无论是否成功都返回Map。若成功,返回的Map中含有return_code、return_msg、data, - * 其中return_code为`SUCCESS`,data为对账单数据。 - * @param reqData 向wxpay post的请求数据 + * 其中return_code为`SUCCESS`,data为对账单数据。 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return 经过封装的API返回数据 * @throws Exception */ @@ -565,8 +565,7 @@ public Map downloadBill(Map reqData, int connect String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_DOWNLOADBILL_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.DOWNLOADBILL_URL_SUFFIX; } String respStr = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs).trim(); @@ -574,8 +573,7 @@ public Map downloadBill(Map reqData, int connect // 出现错误,返回XML数据 if (respStr.indexOf("<") == 0) { ret = WXPayUtil.xmlToMap(respStr); - } - else { + } else { // 正常返回csv数据 ret = new HashMap(); ret.put("return_code", WXPayConstants.SUCCESS); @@ -589,6 +587,7 @@ public Map downloadBill(Map reqData, int connect /** * 作用:交易保障
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -601,9 +600,10 @@ public Map report(Map reqData) throws Exception /** * 作用:交易保障
    * 场景:刷卡支付、公共号支付、扫码支付、APP支付 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -611,8 +611,7 @@ public Map report(Map reqData, int connectTimeou String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_REPORT_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.REPORT_URL_SUFFIX; } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -623,6 +622,7 @@ public Map report(Map reqData, int connectTimeou /** * 作用:转换短链接
    * 场景:刷卡支付、扫码支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -635,6 +635,7 @@ public Map shortUrl(Map reqData) throws Exceptio /** * 作用:转换短链接
    * 场景:刷卡支付、扫码支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -643,8 +644,7 @@ public Map shortUrl(Map reqData, int connectTime String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_SHORTURL_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.SHORTURL_URL_SUFFIX; } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); @@ -655,6 +655,7 @@ public Map shortUrl(Map reqData, int connectTime /** * 作用:授权码查询OPENID接口
    * 场景:刷卡支付 + * * @param reqData 向wxpay post的请求数据 * @return API返回数据 * @throws Exception @@ -667,9 +668,10 @@ public Map authCodeToOpenid(Map reqData) throws /** * 作用:授权码查询OPENID接口
    * 场景:刷卡支付 - * @param reqData 向wxpay post的请求数据 + * + * @param reqData 向wxpay post的请求数据 * @param connectTimeoutMs 连接超时时间,单位是毫秒 - * @param readTimeoutMs 读超时时间,单位是毫秒 + * @param readTimeoutMs 读超时时间,单位是毫秒 * @return API返回数据 * @throws Exception */ @@ -677,8 +679,7 @@ public Map authCodeToOpenid(Map reqData, int con String url; if (this.useSandbox) { url = WXPayConstants.SANDBOX_AUTHCODETOOPENID_URL_SUFFIX; - } - else { + } else { url = WXPayConstants.AUTHCODETOOPENID_URL_SUFFIX; } String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs); diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java index d4e6c87..bb45a08 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java @@ -11,14 +11,24 @@ public enum SignType { MD5, HMACSHA256 } + public static String signTypeName(SignType type) { + switch (type) { + case MD5: + return WXPayConstants.MD5; + case HMACSHA256: + return WXPayConstants.HMACSHA256; + } + return WXPayConstants.MD5; + } + public static final String DOMAIN_API = "api.mch.weixin.qq.com"; public static final String DOMAIN_API2 = "api2.mch.weixin.qq.com"; public static final String DOMAIN_APIHK = "apihk.mch.weixin.qq.com"; public static final String DOMAIN_APIUS = "apius.mch.weixin.qq.com"; - public static final String FAIL = "FAIL"; - public static final String SUCCESS = "SUCCESS"; + public static final String FAIL = "FAIL"; + public static final String SUCCESS = "SUCCESS"; public static final String HMACSHA256 = "HMAC-SHA256"; public static final String MD5 = "MD5"; @@ -30,29 +40,29 @@ public enum SignType { " (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") + ") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion(); - public static final String MICROPAY_URL_SUFFIX = "/pay/micropay"; + public static final String MICROPAY_URL_SUFFIX = "/pay/micropay"; public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder"; - public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery"; - public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse"; - public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder"; - public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund"; - public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery"; + public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery"; + public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse"; + public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder"; + public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund"; + public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery"; public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill"; - public static final String REPORT_URL_SUFFIX = "/payitil/report"; - public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl"; + public static final String REPORT_URL_SUFFIX = "/payitil/report"; + public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl"; public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid"; // sandbox - public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay"; + public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay"; public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder"; - public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery"; - public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse"; - public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder"; - public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund"; - public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery"; + public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery"; + public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse"; + public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder"; + public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund"; + public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery"; public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill"; - public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report"; - public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl"; + public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report"; + public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl"; public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid"; } diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java index 8f27495..f4d503a 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java @@ -25,6 +25,19 @@ public interface WxpayService { Map orderPrepay(String id, Map req) throws Exception; + /** + * 签名预支付信息,返回给前端 + * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5 + *

    + * Map{appId,timeStamp,nonceStr,package,signType} + * + * @param id group id + * @param prepareId orderPrepay response + * @return Map{timeStamp,nonceStr,package,package,signType,paySign} + * @throws Exception + */ + Map signPrepay(String id, String prepareId) throws Exception; + Map orderClose(String id, Map req) throws Exception; Map orderQuery(String id, Map req) throws Exception; diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index 820000d..457216e 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -2,6 +2,8 @@ import com.github.wxpay.sdk.JframeWxpayConfig; import com.github.wxpay.sdk.WXPay; +import com.github.wxpay.sdk.WXPayConstants; +import com.github.wxpay.sdk.WXPayUtil; import jframe.core.conf.Config; import jframe.core.plugin.annotation.InjectPlugin; import jframe.core.plugin.annotation.Injector; @@ -88,6 +90,23 @@ public Map orderPrepay(String id, Map req) throw return clients.get(id).unifiedOrder(req); } + @Override + public Map signPrepay(String id, String prepareId) throws Exception { + //appId,timeStamp,nonceStr,package,signType + Map data = new HashMap<>(); + data.put("appId", conf(id, WxpayConf.P_appId)); + data.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp())); + data.put("nonceStr", WXPayUtil.generateNonceStr()); + data.put("package", prepareId); + WXPayConstants.SignType signType = clients.get(id).signType(); + String paySign = WXPayUtil.generateSignature(data, conf(id, WxpayConf.P_apiKey), signType); + //timeStamp,nonceStr,package,signType,paySign + data.put("signType", WXPayConstants.signTypeName(signType)); + data.put("paySign", paySign); + data.remove("appId"); + return data; + } + @Override public Map orderClose(String id, Map req) throws Exception { return clients.get(id).closeOrder(req); From 2c2e3ad781a65aad1a396e945869b641fd54ffe9 Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 4 Sep 2020 17:55:43 +0800 Subject: [PATCH 16/47] add wx signPrepay --- .../src/main/java/jframe/wxpay/service/WxpayServiceV2.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index 457216e..b993bc6 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -103,7 +103,6 @@ public Map signPrepay(String id, String prepareId) throws Except //timeStamp,nonceStr,package,signType,paySign data.put("signType", WXPayConstants.signTypeName(signType)); data.put("paySign", paySign); - data.remove("appId"); return data; } From 57de3e805e8de002b7e222f50354e64d75779356 Mon Sep 17 00:00:00 2001 From: dzh Date: Sat, 5 Sep 2020 21:45:21 +0800 Subject: [PATCH 17/47] fix wxpay prepay_id --- .../src/main/java/jframe/wxpay/service/WxpayService.java | 8 ++++++++ .../main/java/jframe/wxpay/service/WxpayServiceV2.java | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java index f4d503a..4eb06ac 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java @@ -40,6 +40,14 @@ public interface WxpayService { Map orderClose(String id, Map req) throws Exception; + /** + * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2 + * + * @param id group id + * @param req map{transaction_id,out_trade_no} + * @return + * @throws Exception + */ Map orderQuery(String id, Map req) throws Exception; Map processResponseXml(String id, String xmlStr) throws Exception; diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index b993bc6..94840df 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -17,6 +17,7 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -92,12 +93,15 @@ public Map orderPrepay(String id, Map req) throw @Override public Map signPrepay(String id, String prepareId) throws Exception { + if (prepareId == null) { + return Collections.emptyMap(); + } //appId,timeStamp,nonceStr,package,signType Map data = new HashMap<>(); data.put("appId", conf(id, WxpayConf.P_appId)); data.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp())); data.put("nonceStr", WXPayUtil.generateNonceStr()); - data.put("package", prepareId); + data.put("package", prepareId.startsWith("prepay_id") ? prepareId : "prepay_id=" + prepareId); WXPayConstants.SignType signType = clients.get(id).signType(); String paySign = WXPayUtil.generateSignature(data, conf(id, WxpayConf.P_apiKey), signType); //timeStamp,nonceStr,package,signType,paySign From f9198eb3281ec6b3ab0cebaa572630d9105a82f3 Mon Sep 17 00:00:00 2001 From: dzh Date: Sun, 6 Sep 2020 00:47:05 +0800 Subject: [PATCH 18/47] fix signPrepay --- .../src/main/java/jframe/wxpay/service/WxpayService.java | 4 ++-- .../main/java/jframe/wxpay/service/WxpayServiceV2.java | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java index 4eb06ac..00adcf2 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java @@ -32,11 +32,11 @@ public interface WxpayService { * Map{appId,timeStamp,nonceStr,package,signType} * * @param id group id - * @param prepareId orderPrepay response + * @param req Map{prepareId,nonceStr} * @return Map{timeStamp,nonceStr,package,package,signType,paySign} * @throws Exception */ - Map signPrepay(String id, String prepareId) throws Exception; + Map signPrepay(String id, Map req) throws Exception; Map orderClose(String id, Map req) throws Exception; diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index 94840df..def2067 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -92,16 +92,17 @@ public Map orderPrepay(String id, Map req) throw } @Override - public Map signPrepay(String id, String prepareId) throws Exception { - if (prepareId == null) { + public Map signPrepay(String id, Map req) throws Exception { + String prepayId = req.get("prepayId"); + if (prepayId == null) { return Collections.emptyMap(); } //appId,timeStamp,nonceStr,package,signType Map data = new HashMap<>(); data.put("appId", conf(id, WxpayConf.P_appId)); data.put("timeStamp", String.valueOf(WXPayUtil.getCurrentTimestamp())); - data.put("nonceStr", WXPayUtil.generateNonceStr()); - data.put("package", prepareId.startsWith("prepay_id") ? prepareId : "prepay_id=" + prepareId); + data.put("nonceStr", req.getOrDefault("nonceStr", WXPayUtil.generateNonceStr())); + data.put("package", prepayId.startsWith("prepay_id") ? prepayId : "prepay_id=" + prepayId); WXPayConstants.SignType signType = clients.get(id).signType(); String paySign = WXPayUtil.generateSignature(data, conf(id, WxpayConf.P_apiKey), signType); //timeStamp,nonceStr,package,signType,paySign From 34a26f291565f663d333af8e5d7ec508ec8158e6 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 8 Sep 2020 11:21:32 +0800 Subject: [PATCH 19/47] opt wxpay signType --- .../main/java/com/github/wxpay/sdk/WXPay.java | 19 ++++++++--- .../com/github/wxpay/sdk/WXPayConstants.java | 32 +++++++++++++------ .../src/main/java/jframe/wxpay/WxpayConf.java | 1 + .../jframe/wxpay/service/WxpayServiceV2.java | 5 +-- .../src/test/resources/wxpay.properties | 2 ++ 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java index e9bc580..ce14eca 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java @@ -36,15 +36,25 @@ public WXPay(final WXPayConfig config, final String notifyUrl, final boolean aut } public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception { + this(config, notifyUrl, autoReport, useSandbox, null); + } + + public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox, SignType signType) throws Exception { this.config = config; this.notifyUrl = notifyUrl; this.autoReport = autoReport; this.useSandbox = useSandbox; - if (useSandbox) { - this.signType = SignType.MD5; // 沙箱环境 - } else { - this.signType = SignType.HMACSHA256; + if (signType != null) { + this.signType = signType; + } + if (signType == null) { + if (useSandbox) { + this.signType = SignType.MD5; // 沙箱环境 + } else { + this.signType = SignType.HMACSHA256; + } } + this.wxPayRequest = new WXPayRequest(config); } @@ -52,7 +62,6 @@ public SignType signType() { return signType; } - private void checkWXPayConfig() throws Exception { if (this.config == null) { throw new Exception("config is null"); diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java index bb45a08..5d37939 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPayConstants.java @@ -8,17 +8,31 @@ public class WXPayConstants { public enum SignType { - MD5, HMACSHA256 - } + MD5, HMACSHA256; - public static String signTypeName(SignType type) { - switch (type) { - case MD5: - return WXPayConstants.MD5; - case HMACSHA256: - return WXPayConstants.HMACSHA256; + public String typeName() { + switch (this) { + case MD5: + return WXPayConstants.MD5; + case HMACSHA256: + return WXPayConstants.HMACSHA256; + } + return WXPayConstants.MD5; } - return WXPayConstants.MD5; + + public static SignType of(String name) { + if (name == null) return MD5; + + switch (name) { + case WXPayConstants.MD5: + return MD5; + case WXPayConstants.HMACSHA256: + return HMACSHA256; + default: + return MD5; + } + } + } public static final String DOMAIN_API = "api.mch.weixin.qq.com"; diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java index 8e0ced6..cbfc566 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java @@ -27,6 +27,7 @@ public class WxpayConf extends PropsConf { public static final String P_notifyUrl = "notifyUrl"; public static final String P_autoReport = "autoReport"; public static final String P_useSandbox = "useSandbox"; + public static final String P_signType = "signType"; public synchronized void init(InputStream is) throws Exception { super.init(is); diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index def2067..be8a797 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -75,7 +75,8 @@ private WXPay createWxpay(WxpayConf props, String id) throws Exception { props.getConf(id, WxpayConf.P_mchId), props.getConf(id, WxpayConf.P_apiKey), new ByteArrayInputStream(bytes)); return new WXPay(conf, props.getConf(id, WxpayConf.P_notifyUrl), Boolean.parseBoolean(props.getConf(id, WxpayConf.P_autoReport, "true")), - Boolean.parseBoolean(props.getConf(id, WxpayConf.P_useSandbox, "false"))); + Boolean.parseBoolean(props.getConf(id, WxpayConf.P_useSandbox, "false")), + WXPayConstants.SignType.of(props.getConf(id, WxpayConf.P_signType))); } @@ -106,7 +107,7 @@ public Map signPrepay(String id, Map req) throws WXPayConstants.SignType signType = clients.get(id).signType(); String paySign = WXPayUtil.generateSignature(data, conf(id, WxpayConf.P_apiKey), signType); //timeStamp,nonceStr,package,signType,paySign - data.put("signType", WXPayConstants.signTypeName(signType)); + data.put("signType", signType.typeName()); data.put("paySign", paySign); return data; } diff --git a/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties b/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties index 32ee586..e207d44 100644 --- a/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties +++ b/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties @@ -9,4 +9,6 @@ group.id=xxx @xxx.useSandbox=false # common +signType= + From 774f62b118fad5556893ffd4a496912b92a1f7b5 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 8 Sep 2020 16:06:00 +0800 Subject: [PATCH 20/47] opt wxpay --- .../src/main/java/jframe/wxpay/service/WxpayServiceV2.java | 2 +- jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index be8a797..f61dbd6 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -105,9 +105,9 @@ public Map signPrepay(String id, Map req) throws data.put("nonceStr", req.getOrDefault("nonceStr", WXPayUtil.generateNonceStr())); data.put("package", prepayId.startsWith("prepay_id") ? prepayId : "prepay_id=" + prepayId); WXPayConstants.SignType signType = clients.get(id).signType(); + data.put("signType", signType.typeName()); String paySign = WXPayUtil.generateSignature(data, conf(id, WxpayConf.P_apiKey), signType); //timeStamp,nonceStr,package,signType,paySign - data.put("signType", signType.typeName()); data.put("paySign", paySign); return data; } diff --git a/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties b/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties index e207d44..828d40c 100644 --- a/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties +++ b/jframe-plugin/jframe-wxpay/src/test/resources/wxpay.properties @@ -8,7 +8,6 @@ group.id=xxx @xxx.autoReport=true @xxx.useSandbox=false # common - -signType= +signType=MD5 From 414c9ad83fbb565a5edd6cfba11eb055abb50227 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 20 Oct 2020 23:11:10 +0800 Subject: [PATCH 21/47] opt oss https --- .../jframe-aliyun/src/main/java/jframe/aliyun/AliyunField.java | 3 ++- .../main/java/jframe/aliyun/service/oss/OSSServiceImpl.java | 3 +++ .../test/java/jframe/aliyun/service/oss/oss-config.properties | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/AliyunField.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/AliyunField.java index 8514e1d..1a0f645 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/AliyunField.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/AliyunField.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.aliyun; @@ -16,6 +16,7 @@ public interface AliyunField { String K_client_conn_timetout = "client.conn.timetout"; String K_client_max_retry = "client.max.retry"; String K_client_socket_timetout = "client.socket.timetout"; + String K_client_protocol = "client.protocol"; String K_roleArn = "roleArn"; String K_policy = "policy"; diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java index a5b1bc8..fbab1e2 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java @@ -5,6 +5,7 @@ import com.aliyun.oss.ClientConfiguration; import com.aliyun.oss.OSSClient; +import com.aliyun.oss.common.comm.Protocol; import jframe.aliyun.AliyunField; import jframe.aliyun.AliyunPlugin; import jframe.aliyun.service.OSSService; @@ -70,8 +71,10 @@ void start() { String endpoint = _config.getConf(id, AliyunField.K_endpoint); String accessKeyId = _config.getConf(id, AliyunField.K_accessKeyId); String accessKeySecret = _config.getConf(id, AliyunField.K_accessKeySecret); + String protocol = _config.getConf(id, AliyunField.K_client_protocol, "https"); ClientConfiguration conf = new ClientConfiguration(); + conf.setProtocol(Protocol.HTTPS.toString().equals(protocol) ? Protocol.HTTPS : Protocol.HTTP); // TODO config client OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf); clients.put(id, ossClient); diff --git a/jframe-plugin/jframe-aliyun/src/test/java/jframe/aliyun/service/oss/oss-config.properties b/jframe-plugin/jframe-aliyun/src/test/java/jframe/aliyun/service/oss/oss-config.properties index a1c7eb1..02489fe 100644 --- a/jframe-plugin/jframe-aliyun/src/test/java/jframe/aliyun/service/oss/oss-config.properties +++ b/jframe-plugin/jframe-aliyun/src/test/java/jframe/aliyun/service/oss/oss-config.properties @@ -8,4 +8,5 @@ group.id = test client.max.conn = 100 client.conn.timeout = 5000 client.max.retry = 3 -client.socket.timeout = 2000 \ No newline at end of file +client.socket.timeout = 2000 +client.protocol = http \ No newline at end of file From 6b0a3c55781b45017b3ee8a021e2908797d6c250 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 20 Oct 2020 23:33:56 +0800 Subject: [PATCH 22/47] opt oss https --- .../java/jframe/aliyun/service/oss/OSSServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java index fbab1e2..03523f1 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/oss/OSSServiceImpl.java @@ -5,6 +5,7 @@ import com.aliyun.oss.ClientConfiguration; import com.aliyun.oss.OSSClient; +import com.aliyun.oss.common.auth.DefaultCredentialProvider; import com.aliyun.oss.common.comm.Protocol; import jframe.aliyun.AliyunField; import jframe.aliyun.AliyunPlugin; @@ -71,12 +72,14 @@ void start() { String endpoint = _config.getConf(id, AliyunField.K_endpoint); String accessKeyId = _config.getConf(id, AliyunField.K_accessKeyId); String accessKeySecret = _config.getConf(id, AliyunField.K_accessKeySecret); - String protocol = _config.getConf(id, AliyunField.K_client_protocol, "https"); + String protocol = _config.getConf(id, AliyunField.K_client_protocol, Protocol.HTTPS.toString()); ClientConfiguration conf = new ClientConfiguration(); conf.setProtocol(Protocol.HTTPS.toString().equals(protocol) ? Protocol.HTTPS : Protocol.HTTP); // TODO config client - OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf); + OSSClient ossClient = new OSSClient(endpoint, + new DefaultCredentialProvider(accessKeyId, accessKeySecret), conf); + LOG.info("OSSClient {} {} {}", id, endpoint, conf.getProtocol()); clients.put(id, ossClient); } LOG.info("Start OSSService Successfully!"); From 3bfe244cc4099e8d7454824101c0df939b00cb00 Mon Sep 17 00:00:00 2001 From: dzh Date: Thu, 19 Nov 2020 10:32:05 +0800 Subject: [PATCH 23/47] upd curator 5.1.0 --- jframe-plugin/jframe-zk/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jframe-plugin/jframe-zk/pom.xml b/jframe-plugin/jframe-zk/pom.xml index 131eb1a..b1cb173 100644 --- a/jframe-plugin/jframe-zk/pom.xml +++ b/jframe-plugin/jframe-zk/pom.xml @@ -9,7 +9,7 @@ jframe-zk - 4.2.0 + 5.1.0 From dedd9ca05deaf47e9a3718baf3d3f278a82297a8 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 1 Dec 2020 14:07:46 +0800 Subject: [PATCH 24/47] opt httpclient --- .../service/impl/HttpClientServiceImpl.java | 65 ++++++++----------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java index 176567d..5ca4ca7 100644 --- a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java +++ b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java @@ -1,18 +1,18 @@ /** - * + * */ package jframe.httpclient.service.impl; -import java.nio.charset.Charset; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.apache.http.HeaderElement; -import org.apache.http.HeaderElementIterator; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.HttpResponse; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import jframe.core.plugin.annotation.InjectPlugin; +import jframe.core.plugin.annotation.Injector; +import jframe.core.plugin.annotation.Start; +import jframe.core.plugin.annotation.Stop; +import jframe.httpclient.HttpClientConfig; +import jframe.httpclient.HttpClientPlugin; +import jframe.httpclient.service.HttpClientService; +import org.apache.http.*; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -34,19 +34,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.Injector; -import jframe.core.plugin.annotation.Start; -import jframe.core.plugin.annotation.Stop; -import jframe.httpclient.HttpClientConfig; -import jframe.httpclient.HttpClientPlugin; -import jframe.httpclient.service.HttpClientService; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** - * + * * @author dzh * @date Dec 2, 2014 12:11:23 PM * @since 1.0 @@ -106,7 +100,8 @@ public long getKeepAliveDuration(HttpResponse response, HttpContext context) { if (value != null && param.equalsIgnoreCase("timeout")) { try { return Long.parseLong(value) * 1000; - } catch (NumberFormatException ignore) {} + } catch (NumberFormatException ignore) { + } } } @@ -200,12 +195,13 @@ public String send(String id, String path, String data, Map head // String ip = paras.containsKey("ip") ? paras.get("ip") : HttpClientConfig.getConf(id, HttpClientConfig.IP); String port = paras.containsKey("port") ? paras.get("port") : HttpClientConfig.getConf(id, HttpClientConfig.PORT, "80"); - String scheme = HttpClientConfig.getConf(id, HttpClientConfig.SCHEME, HttpHost.DEFAULT_SCHEME_NAME); - + String scheme = paras.containsKey(HttpClientConfig.SCHEME) ? paras.get(HttpClientConfig.SCHEME) + : HttpClientConfig.getConf(id, HttpClientConfig.SCHEME, HttpHost.DEFAULT_SCHEME_NAME); HttpHost target = new HttpHost(ip, Integer.parseInt(port), scheme); + String mehtod = paras.containsKey(HttpClientConfig.HTTP_METHOD) ? paras.get(HttpClientConfig.HTTP_METHOD) + : HttpClientConfig.getConf(id, HttpClientConfig.HTTP_METHOD, HttpClientConfig.M_POST); HttpRequestBase request; - String mehtod = HttpClientConfig.getConf(id, HttpClientConfig.HTTP_METHOD, HttpClientConfig.M_POST); if (HttpClientConfig.M_GET.equals(mehtod)) { request = new HttpGet(target.toURI() + path + "?" + data); } else { @@ -216,15 +212,11 @@ public String send(String id, String path, String data, Map head } request.setConfig(requestConfig); - if (headers != null) { - for (String key : headers.keySet()) { - request.addHeader(key, headers.get(key)); - } + for (String key : headers.keySet()) { + request.addHeader(key, headers.get(key)); } - CloseableHttpResponse rsp = null; - try { - rsp = httpClient.execute(request); + try (CloseableHttpResponse rsp = httpClient.execute(request)) { // ResponseHandler responseHandler = new // ResponseHandler() { // @@ -260,10 +252,6 @@ public String send(String id, String path, String data, Map head // return (T) EntityUtils.toString(entity, charset); // } return EntityUtils.toString(entity, charset); - } finally { - if (rsp != null) { - rsp.close(); - } } } @@ -349,7 +337,8 @@ public long getKeepAliveDuration(HttpResponse response, HttpContext context) { if (value != null && param.equalsIgnoreCase("timeout")) { try { return Long.parseLong(value) * 1000; - } catch (NumberFormatException ignore) {} + } catch (NumberFormatException ignore) { + } } } From 8b304755af8444e14d5ffb8b8988d2105b39195a Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 1 Dec 2020 17:55:49 +0800 Subject: [PATCH 25/47] opt httpclient --- .../jframe/httpclient/service/impl/HttpClientServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java index 5ca4ca7..b94107f 100644 --- a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java +++ b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java @@ -206,7 +206,7 @@ public String send(String id, String path, String data, Map head request = new HttpGet(target.toURI() + path + "?" + data); } else { request = new HttpPost(target.toURI() + path); - String mimeType = paras.isEmpty() ? "text/plain" : paras.get(P_MIMETYPE); + String mimeType = paras.getOrDefault(P_MIMETYPE, "text/plain"); ((HttpPost) request).setEntity( new StringEntity(data, ContentType.create(mimeType, HttpClientConfig.getConf(id, HttpClientConfig.HTTP_CHARSET)))); } From 745517336f7e350b3d6a9e068999be4761febdca Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 1 Mar 2021 00:17:06 +0800 Subject: [PATCH 26/47] opt wxpay response --- .../httpclient/service/impl/HttpClientServiceImpl.java | 4 ++-- .../main/java/jframe/wxpay/service/WxpayService.java | 6 +++++- .../main/java/jframe/wxpay/service/WxpayServiceV2.java | 10 ++++++++++ .../main/java/jframe/wxpay/service/WxpayServiceV3.java | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java index b94107f..a97093e 100644 --- a/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java +++ b/jframe-plugin/jframe-httpclient/src/main/java/jframe/httpclient/service/impl/HttpClientServiceImpl.java @@ -198,11 +198,11 @@ public String send(String id, String path, String data, Map head String scheme = paras.containsKey(HttpClientConfig.SCHEME) ? paras.get(HttpClientConfig.SCHEME) : HttpClientConfig.getConf(id, HttpClientConfig.SCHEME, HttpHost.DEFAULT_SCHEME_NAME); HttpHost target = new HttpHost(ip, Integer.parseInt(port), scheme); - String mehtod = paras.containsKey(HttpClientConfig.HTTP_METHOD) ? paras.get(HttpClientConfig.HTTP_METHOD) + String method = paras.containsKey(HttpClientConfig.HTTP_METHOD) ? paras.get(HttpClientConfig.HTTP_METHOD) : HttpClientConfig.getConf(id, HttpClientConfig.HTTP_METHOD, HttpClientConfig.M_POST); HttpRequestBase request; - if (HttpClientConfig.M_GET.equals(mehtod)) { + if (HttpClientConfig.M_GET.equals(method)) { request = new HttpGet(target.toURI() + path + "?" + data); } else { request = new HttpPost(target.toURI() + path); diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java index 00adcf2..9f6257f 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java @@ -31,7 +31,7 @@ public interface WxpayService { *

    * Map{appId,timeStamp,nonceStr,package,signType} * - * @param id group id + * @param id group id * @param req Map{prepareId,nonceStr} * @return Map{timeStamp,nonceStr,package,package,signType,paySign} * @throws Exception @@ -52,6 +52,10 @@ public interface WxpayService { Map processResponseXml(String id, String xmlStr) throws Exception; + Map processResponseXmlUnsafe(String xmlStr) throws Exception; + + boolean isResponseSignatureValid(String id, Map res) throws Exception; + Map refund(String id, Map req) throws Exception; Map refundQuery(String id, Map req) throws Exception; diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index f61dbd6..4fab0c4 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -127,6 +127,16 @@ public Map processResponseXml(String id, String xmlStr) throws E return clients.get(id).processResponseXml(xmlStr); } + @Override + public Map processResponseXmlUnsafe(String xmlStr) throws Exception { + return WXPayUtil.xmlToMap(xmlStr); + } + + @Override + public boolean isResponseSignatureValid(String id, Map res) throws Exception { + return clients.get(id).isResponseSignatureValid(res); + } + @Override public Map refund(String id, Map req) throws Exception { return clients.get(id).refund(req); diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java index 33e90ff..56e5d68 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java @@ -36,6 +36,7 @@ * @author dzh * @date 2020/8/18 17:38 */ +@Deprecated @Injector public class WxpayServiceV3 { From ed45d7b2554f35b1b255906cac40ef1cddfcaab5 Mon Sep 17 00:00:00 2001 From: dzh Date: Thu, 11 Mar 2021 10:55:51 +0800 Subject: [PATCH 27/47] catch KafkaConsumer dispatch exp --- .../jedis/service/JedisServiceImpl.java | 1 - .../ext/dispatch/kafka/KafkaDispatcher.java | 20 +++++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java index 8bc8aaf..f4c540d 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java @@ -100,7 +100,6 @@ public void start(PropsConf conf) { _jedis.put(h, new JedisPool(config, ip, port, timeout, "".equals(passwd) ? null : passwd, database)); } catch (Exception e) { LOG.error(e.getMessage(), e); - continue; } } LOG.info("JedisServiceImpl start successfully"); diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java index 4ee3550..3d370e5 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java @@ -155,25 +155,23 @@ private void startConsumer() { // close(); // return; } - final boolean autoCommit = "true".equals(props.get("enable.auto.commit")) ? true : false; + final boolean autoCommit = "true".equals(props.get("enable.auto.commit")); this.dispatchT = new Thread(() -> { LOG.info("{} start", Thread.currentThread().getName()); ConsumerRecords> records = null; - while (true) { - if (closed) break; + while (!closed) { try { records = consumer.poll(Duration.ofMillis(1000L));// + if (records == null) continue; + + records.forEach(record -> { + dispatch(record.value()); + }); + // commit if autoCommit is false + if (!autoCommit) consumer.commitAsync(); } catch (Exception e) { LOG.warn(e.getMessage(), e); - continue; } - if (records == null) continue; - - records.forEach(record -> { - dispatch(record.value()); - }); - // commit if autoCommit is false - if (!autoCommit) consumer.commitAsync(); } consumer.close(Duration.ofSeconds(WAIT_CLOSED_SECOND)); // consumer close LOG.info("{} closed", Thread.currentThread().getName()); From b20901a05292ad31bf87de111510349bc11e3d7f Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 15 Nov 2021 16:23:58 +0800 Subject: [PATCH 28/47] opt JedisService --- .../jframe/jedis/service/JedisService.java | 8 +++ .../jedis/service/JedisServiceImpl.java | 71 ++++++++++++++----- .../jframe/core/plugin/DefPluginContext.java | 71 ++++++++----------- .../ext/dispatch/rocketmq/RmqDispatcher.java | 2 +- 4 files changed, 94 insertions(+), 58 deletions(-) diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java index 2a0fa07..3718e4b 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java @@ -55,4 +55,12 @@ public interface JedisService { void del(String id, String key); + long incr(String id, String key); + + long incrBy(String id, String key, long val); + + long decr(String id, String key); + + long decrBy(String id, String key, long val); + } diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java index f4c540d..f61c9ed 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java @@ -1,8 +1,18 @@ /** - * + * */ package jframe.jedis.service; +import jframe.core.plugin.annotation.InjectPlugin; +import jframe.core.plugin.annotation.Injector; +import jframe.core.plugin.annotation.Start; +import jframe.core.plugin.annotation.Stop; +import jframe.core.util.PropsConf; +import jframe.jedis.JedisPlugin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import redis.clients.jedis.*; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -11,21 +21,6 @@ import java.util.Iterator; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.Injector; -import jframe.core.plugin.annotation.Start; -import jframe.core.plugin.annotation.Stop; -import jframe.core.util.PropsConf; -import jframe.jedis.JedisPlugin; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisCluster; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; -import redis.clients.jedis.Protocol; - /** * @author dzh * @date Aug 6, 2014 1:31:26 PM @@ -208,7 +203,9 @@ public void recycleJedis(String name, Jedis jedis) { @Override public String get(String id, String key) { try (Jedis jedis = getJedis(id)) { - if (jedis != null) { return jedis.get(key); } + if (jedis != null) { + return jedis.get(key); + } } return null; } @@ -234,4 +231,44 @@ public void del(String id, String key) { } } + @Override + public long incr(String id, String key) { + try (Jedis jedis = getJedis(id)) { + if (jedis != null) { + return jedis.incr(key); + } + } + return -1; + } + + @Override + public long incrBy(String id, String key, long val) { + try (Jedis jedis = getJedis(id)) { + if (jedis != null) { + return jedis.incrBy(key, val); + } + } + return -1; + } + + @Override + public long decr(String id, String key) { + try (Jedis jedis = getJedis(id)) { + if (jedis != null) { + return jedis.decr(key); + } + } + return -1; + } + + @Override + public long decrBy(String id, String key, long val) { + try (Jedis jedis = getJedis(id)) { + if (jedis != null) { + return jedis.decrBy(key, val); + } + } + return -1; + } + } diff --git a/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java b/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java index 908eaee..1a40190 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java +++ b/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java @@ -1,21 +1,8 @@ /** - * + * */ package jframe.core.plugin; -import java.lang.reflect.Proxy; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; -import java.util.TreeSet; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import jframe.core.conf.Config; import jframe.core.conf.ConfigConstants; import jframe.core.dispatch.DefDispatcher; @@ -27,6 +14,11 @@ import jframe.core.plugin.dispatch.DispatchSourceHandler; import jframe.core.plugin.dispatch.DispatchTargetHandler; import jframe.core.signal.Signal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Proxy; +import java.util.*; /** * @author dzh @@ -121,7 +113,7 @@ public PluginRef regPlugin(Plugin plugin) { } /** - * @param plugin + * @param ref */ private void regDispatch(PluginRef ref) { Plugin plugin = ref.getPlugin(); @@ -147,7 +139,7 @@ private void regDispatch(PluginRef ref) { private void createDispatchTarget(PluginRef ref) { Object pdt = ref.getPolicy(PluginRef.DispatchTarget); if (pdt == null) { - pdt = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { DispatchTarget.class }, new DispatchTargetHandler(ref)); + pdt = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{DispatchTarget.class}, new DispatchTargetHandler(ref)); ref.regPolicy(PluginRef.DispatchTarget, pdt); if (getDispatcher() != null) getDispatcher().addDispatchTarget((DispatchTarget) pdt); @@ -163,7 +155,7 @@ private void createDispatchTarget(PluginRef ref) { private void createDispatchSource(PluginRef ref) { Object pds = ref.getPolicy(PluginRef.DispatchSource); // null is normal if (pds == null) { - pds = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { DispatchSource.class }, new DispatchSourceHandler(ref)); + pds = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{DispatchSource.class}, new DispatchSourceHandler(ref)); ref.regPolicy(PluginRef.DispatchSource, pds); if (getDispatcher() != null) getDispatcher().addDispatchSource((DispatchSource) pds); @@ -230,7 +222,7 @@ public void signal(Signal sig) { *

  • 关闭dispatch
  • *

    * (non-Javadoc) - * + * * @see jframe.core.plugin.PluginContext#dispose() */ public void dispose() { @@ -253,7 +245,7 @@ private int newPluginID() { /* * (non-Javadoc) - * + * * @see jframe.core.plugin.PluginContext#getConfig() */ public Config getConfig() { @@ -262,7 +254,7 @@ public Config getConfig() { /* * (non-Javadoc) - * + * * @see * jframe.core.plugin.PluginContext#regPluginListener(jframe.core.plugin * .PluginListener) @@ -277,7 +269,7 @@ public void regPluginListener(PluginListener l) { /* * (non-Javadoc) - * + * * @see * jframe.core.plugin.PluginContext#unregPluginListener(jframe.core.plugin * .PluginListener) @@ -290,7 +282,7 @@ public void unregPluginListener(PluginListener l) { /* * (non-Javadoc) - * + * * @see * jframe.core.plugin.PluginContext#notifyPluginEvent(jframe.core.plugin * .PluginEvent) @@ -305,10 +297,9 @@ public void notifyPluginEvent(PluginEvent event) { } /** - * + * * (non-Javadoc) - * - * @see jframe.core.plugin.PluginContext#containRef(jframe.core.plugin.Plugin) + * * @return if find PluginRef return it, or return null */ private PluginRef containRef(Plugin plugin) { @@ -326,7 +317,7 @@ private PluginRef containRef(Plugin plugin) { /* * (non-Javadoc) - * + * * @see jframe.core.plugin.IDispatchable#getDispatcher() */ public Dispatcher getDispatcher() { @@ -335,7 +326,7 @@ public Dispatcher getDispatcher() { /* * (non-Javadoc) - * + * * @see jframe.core.plugin.PluginContext#getPlugin(java.lang.String) */ public PluginRef getPlugin(String name) { @@ -350,7 +341,7 @@ public PluginRef getPlugin(String name) { /* * (non-Javadoc) - * + * * @see jframe.core.plugin.PluginContext#regPlugins(java.util.Collection, * java.util.Comparator) */ @@ -383,7 +374,7 @@ public void regPlugins(Collection plugins, Comparator co /* * (non-Javadoc) - * + * * @see jframe.core.plugin.PluginContext#unregPlugins(java.util.Collection, * java.util.Comparator) */ @@ -419,7 +410,7 @@ public PluginComparator(TYPE type) { /* * (non-Javadoc) - * + * * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(Plugin o1, Plugin o2) { @@ -427,14 +418,14 @@ public int compare(Plugin o1, Plugin o2) { jframe.core.plugin.annotation.Plugin ap1 = o1.getClass().getAnnotation(jframe.core.plugin.annotation.Plugin.class); jframe.core.plugin.annotation.Plugin ap2 = o2.getClass().getAnnotation(jframe.core.plugin.annotation.Plugin.class); switch (type) { - case START: { - v = minus(ap1.startOrder(), ap2.startOrder()); - break; - } - case STOP: { - v = minus(ap1.stopOrder(), ap2.stopOrder()); - break; - } + case START: { + v = minus(ap1.startOrder(), ap2.startOrder()); + break; + } + case STOP: { + v = minus(ap1.stopOrder(), ap2.stopOrder()); + break; + } } if (v == 0) { @@ -445,7 +436,7 @@ public int compare(Plugin o1, Plugin o2) { /** * 负数作为最大整数 - * + * * @param minuend * @param subtrahend * @return @@ -463,7 +454,7 @@ int minus(int minuend, int subtrahend) { /* * (non-Javadoc) - * + * * @see * jframe.core.plugin.PluginContext#unregPlugin(jframe.core.plugin.PluginRef * ) diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java index 4941e44..4cee232 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java @@ -89,7 +89,7 @@ private void startProducer() throws MQClientException { if (props.containsKey("namespace")) { producer.setNamespace(props.getProperty("namespace")); } - producer.setNamesrvAddr(props.getProperty("namesrv.addr", "localhost:9876")); + producer.setNamesrvAddr(DefPluginContext.getProperty("namesrv.addr", "localhost:9876")); producer.setRetryTimesWhenSendFailed(Integer.parseInt(props.getProperty("retry.times", "3"))); producer.setVipChannelEnabled(Boolean.parseBoolean(props.getProperty("vipChannelEnabled", "false"))); // LOG.info("start producer {} {}", producer.getProducerGroup(), producer.getNamesrvAddr()); From 8b100042fb48fed30fdc7c0782507bebdb5608a8 Mon Sep 17 00:00:00 2001 From: dzh Date: Sat, 20 Nov 2021 17:16:29 +0800 Subject: [PATCH 29/47] opt redis expire --- .../jframe/jedis/service/JedisService.java | 4 ++++ .../jframe/jedis/service/JedisServiceImpl.java | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java index 3718e4b..040e048 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java @@ -63,4 +63,8 @@ public interface JedisService { long decrBy(String id, String key, long val); + void expire(String id, String key, int seconds); + + void expireAt(String id, String key, int ts); + } diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java index f61c9ed..c68558b 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java @@ -271,4 +271,22 @@ public long decrBy(String id, String key, long val) { return -1; } + @Override + public void expire(String id, String key, int seconds) { + try (Jedis jedis = getJedis(id)) { + if (jedis != null) { + jedis.expire(key, seconds); + } + } + } + + @Override + public void expireAt(String id, String key, int ts) { + try (Jedis jedis = getJedis(id)) { + if (jedis != null) { + jedis.expireAt(key, ts); + } + } + } + } From d7c888f4b913b04bab47ae0e94b551efa9d5d646 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 22 Feb 2022 11:06:23 +0800 Subject: [PATCH 30/47] fix rmq props --- .../main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java index 4cee232..4941e44 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java @@ -89,7 +89,7 @@ private void startProducer() throws MQClientException { if (props.containsKey("namespace")) { producer.setNamespace(props.getProperty("namespace")); } - producer.setNamesrvAddr(DefPluginContext.getProperty("namesrv.addr", "localhost:9876")); + producer.setNamesrvAddr(props.getProperty("namesrv.addr", "localhost:9876")); producer.setRetryTimesWhenSendFailed(Integer.parseInt(props.getProperty("retry.times", "3"))); producer.setVipChannelEnabled(Boolean.parseBoolean(props.getProperty("vipChannelEnabled", "false"))); // LOG.info("start producer {} {}", producer.getProducerGroup(), producer.getNamesrvAddr()); From 481451d2c587e6f2190fa192db785720a5b97a64 Mon Sep 17 00:00:00 2001 From: dzh Date: Tue, 24 May 2022 12:55:02 +0800 Subject: [PATCH 31/47] add wxpay transfer paybank --- .../jframe/jedis/service/JedisService.java | 2 + .../jedis/service/JedisServiceImpl.java | 10 ++ .../main/java/com/github/wxpay/sdk/WXPay.java | 91 +++++++++++++++++++ .../jframe/wxpay/service/WxpayService.java | 9 ++ .../jframe/wxpay/service/WxpayServiceV2.java | 20 ++++ 5 files changed, 132 insertions(+) diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java index 040e048..1109206 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisService.java @@ -51,6 +51,8 @@ public interface JedisService { /************************** simple method ***************************/ String get(String id, String key); +// String getdel(String id, String key); + void setex(String id, String key, String value, Integer expiredSeconds); void del(String id, String key); diff --git a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java index c68558b..d16277a 100644 --- a/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java +++ b/jframe-plugin/jframe-jedis/src/main/java/jframe/jedis/service/JedisServiceImpl.java @@ -210,6 +210,16 @@ public String get(String id, String key) { return null; } +// @Override +// public String getdel(String id, String key) { +// try (Jedis jedis = getJedis(id)) { +// if (jedis != null) { +// return jedis.get +// } +// } +// return null; +// } + @Override public void setex(String id, String key, String value, Integer expiredSeconds) { if (value == null) return; // do nothing diff --git a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java index ce14eca..4029dac 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/com/github/wxpay/sdk/WXPay.java @@ -5,6 +5,10 @@ import java.util.HashMap; import java.util.Map; +/** + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_4 微信银行编号 + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=4_2 银行字符码 + */ public class WXPay { private WXPayConfig config; @@ -695,5 +699,92 @@ public Map authCodeToOpenid(Map reqData, int con return this.processResponseXml(respXml); } + /** + * 用于向微信用户个人付款 + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 + * + * @param reqData + * @return API返回数据 + * @throws Exception + */ + public Map promotionTransfers(Map reqData) throws Exception { + String url = "/mmpaymkttransfers/promotion/transfers"; + reqData.put("mch_appid", config.getAppID()); + reqData.put("mchid", config.getMchID()); + reqData.put("nonce_str", WXPayUtil.generateNonceStr()); + reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), SignType.MD5)); + String respXml = this.requestWithoutCert(url, reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + return this.processResponseXml(respXml); + } + + /** + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3 + * + * @param reqData + * @return API返回数据 + * @throws Exception + */ + public Map gettransferinfo(Map reqData) throws Exception { + String url = "/mmpaymkttransfers/gettransferinfo"; + reqData.put("appid", config.getAppID()); + reqData.put("mch_id", config.getMchID()); + reqData.put("nonce_str", WXPayUtil.generateNonceStr()); + reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), SignType.MD5)); + String respXml = this.requestWithoutCert(url, reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + return this.processResponseXml(respXml); + } + + + /** + * 付款到银行卡 + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_2 + * + * @param reqData + * @return API返回数据 + * @throws Exception + */ + public Map payBank(Map reqData) throws Exception { + String url = "/mmpaysptrans/pay_bank"; + reqData.put("mch_id", config.getMchID()); + reqData.put("nonce_str", WXPayUtil.generateNonceStr()); + reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), SignType.MD5)); + String respXml = this.requestWithoutCert(url, reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + return this.processResponseXml(respXml); + } + + /** + * 对商户付款到银行卡操作进行结果查询 + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_3 + * + * @param reqData + * @return API返回数据 + * @throws Exception + */ + public Map queryBank(Map reqData) throws Exception { + String url = "/mmpaysptrans/query_bank"; + reqData.put("mch_id", config.getMchID()); + reqData.put("nonce_str", WXPayUtil.generateNonceStr()); + reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), SignType.MD5)); + String respXml = this.requestWithoutCert(url, reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); + return this.processResponseXml(respXml); + } + + /** + * 获取RSA加密公钥API + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=24_7&index=4 + * + * @param reqData + * @return + * @throws Exception + */ +// public Map getPublicKey(Map reqData) throws Exception { +// String url = "/mmpaysptrans/query_bank"; +// reqData.put("mch_id", config.getMchID()); +// reqData.put("nonce_str", WXPayUtil.generateNonceStr()); +// reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), SignType.MD5)); +// String respXml = this.requestWithoutCert(url, reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs()); +// return this.processResponseXml(respXml); +// } + } // end class diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java index 9f6257f..331013e 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java @@ -5,6 +5,8 @@ import java.util.Map; /** + * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1 付款到零钱 + * * @author dzh * @date 2020/8/18 16:45 */ @@ -60,5 +62,12 @@ public interface WxpayService { Map refundQuery(String id, Map req) throws Exception; + Map promotionTransfers(String id, Map reqData) throws Exception; + + Map gettransferinfo(String id, Map reqData) throws Exception; + + Map payBank(String id, Map reqData) throws Exception; + + Map queryBank(String id, Map reqData) throws Exception; } diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index 4fab0c4..d67fe63 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -146,4 +146,24 @@ public Map refund(String id, Map req) throws Exc public Map refundQuery(String id, Map req) throws Exception { return clients.get(id).refundQuery(req); } + + @Override + public Map promotionTransfers(String id, Map reqData) throws Exception { + return clients.get(id).promotionTransfers(reqData); + } + + @Override + public Map gettransferinfo(String id, Map reqData) throws Exception { + return clients.get(id).gettransferinfo(reqData); + } + + @Override + public Map payBank(String id, Map reqData) throws Exception { + return clients.get(id).payBank(reqData); + } + + @Override + public Map queryBank(String id, Map reqData) throws Exception { + return clients.get(id).queryBank(reqData); + } } From 39304edad7956662b57a11a9f7ccdca579b9dafb Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 27 May 2022 17:23:31 +0800 Subject: [PATCH 32/47] opt props load utf8 --- .../src/main/java/jframe/launcher/Main.java | 2 - .../java/jframe/launcher/MainLauncher.java | 4 +- .../java/jframe/launcher/api/DefConfig.java | 2 +- .../java/jframe/launcher/api/Launcher.java | 2 +- .../jframe/launcher/util/VarProperties.java | 41 ++++++++----------- .../java/jframe/launcher/util/VmargsFile.java | 2 +- 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java index 6c129a8..ab9edf4 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java @@ -26,8 +26,6 @@ public class Main { * * @param lclazz * launcher class - * @param deflclazz - * default launcher class * @return */ public static Launcher createLauncher(String lclazz) throws LauncherException { diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/MainLauncher.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/MainLauncher.java index d04e16d..97619e9 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/MainLauncher.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/MainLauncher.java @@ -60,7 +60,7 @@ public void launch(Config config) { } /** - * @param conf + * @param config */ private void launchNormal(Config config) { LOG.info("Launching normal mode!"); @@ -101,7 +101,7 @@ private Process launchInternal(Config config) { } /** - * @param conf + * @param config */ private void launchDaemon(final Config config) { LOG.info("Launch daemon mode! write pid: {}", config.getConfig(DefConfig.PID_DAEMON)); diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/api/DefConfig.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/api/DefConfig.java index 8b11397..29e213f 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/api/DefConfig.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/api/DefConfig.java @@ -79,7 +79,7 @@ public String replace(String input) { /** * replace all variables in input * - * @param system + * @param config * jvm系统变量,一般是System.getProperty * @param input * @return diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/api/Launcher.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/api/Launcher.java index 13933f2..dd1004e 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/api/Launcher.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/api/Launcher.java @@ -21,7 +21,7 @@ public interface Launcher { /** * - * @param conf + * @param config * @throws Exception */ void launch(Config config) throws LauncherException; diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java index b1c1114..81a20e5 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java @@ -1,13 +1,13 @@ /** - * + * */ package jframe.launcher.util; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.Map; import java.util.Properties; @@ -15,12 +15,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * support variable feature - * + * * @author dzh * @date Feb 16, 2016 10:14:22 AM * @since 1.2.1 @@ -30,7 +27,7 @@ public class VarProperties extends Properties { static Logger LOG = LoggerFactory.getLogger(VarProperties.class); /** - * + * */ private static final long serialVersionUID = -6146614559017054452L; @@ -59,21 +56,19 @@ public synchronized void load(String file) throws IOException { } public synchronized void load(File file) throws IOException { - FileInputStream fis = null; - try { - fis = new FileInputStream(file); + if (file == null) return; + try (InputStreamReader fis = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) { load(fis); } catch (Exception e) { LOG.warn(e.getMessage()); - } finally { - if (file != null) { - try { - fis.close(); - } catch (IOException e) { - LOG.error(e.getMessage()); - } - } } +// finally { +// try { +// fis.close(); +// } catch (IOException e) { +// LOG.error(e.getMessage()); +// } +// } } @Override @@ -89,7 +84,7 @@ private void replaceAllVar() { /** * TODO handle circle key - * + * * @param key * @param value * @keys avoid circle key diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VmargsFile.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VmargsFile.java index 17e2360..d89eae4 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VmargsFile.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VmargsFile.java @@ -25,7 +25,7 @@ public class VmargsFile { Logger LOG = LoggerFactory.getLogger(VmargsFile.class); /** - * @param string + * @param file */ public List loadVmargs(String file) { File f = new File(file); // vmargs file From 737d979a27a8d2312ea3b724fef61d45243c0681 Mon Sep 17 00:00:00 2001 From: dzh Date: Wed, 3 Aug 2022 17:49:16 +0800 Subject: [PATCH 33/47] opt jframe-alipay --- jframe-plugin/jframe-alipay/pom.xml | 2 +- .../jframe/alipay/service/AlipayService.java | 2 + .../alipay/service/AlipayServiceImpl.java | 39 ++++++++++++------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/jframe-plugin/jframe-alipay/pom.xml b/jframe-plugin/jframe-alipay/pom.xml index 9b51915..1167b47 100644 --- a/jframe-plugin/jframe-alipay/pom.xml +++ b/jframe-plugin/jframe-alipay/pom.xml @@ -15,7 +15,7 @@ com.alipay.sdk alipay-sdk-java - 4.9.28.ALL + 4.31.72.ALL diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java index 8b4648f..f6ee674 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java @@ -31,6 +31,8 @@ public interface AlipayService { String F_FORMAT = "format"; String F_CHARSET = "charset"; String F_SIGN_TYPE = "sign.type"; + String F_ENCRYPT_KEY = "encrypt.key"; + String F_ENCRYPT_TYPE = "encrypt.type"; String F_RETURN_URL = "return.url"; String F_NOTIFY_URL = "notify.url"; diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java index 86065ea..cc91341 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java @@ -1,9 +1,6 @@ package jframe.alipay.service; -import com.alipay.api.AlipayApiException; -import com.alipay.api.AlipayClient; -import com.alipay.api.AlipayConstants; -import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.*; import com.alipay.api.internal.util.AlipaySignature; import jframe.alipay.AlipayPlugin; import jframe.core.conf.Config; @@ -50,7 +47,8 @@ void start() { alipayConf.init(file); for (String id : alipayConf.getGroupIds()) { AlipayClient client = createAlipayClient(alipayConf, id); - clients.put(id, client); + if (client != null) + clients.put(id, client); } LOG.info("Start AlipayService Successfully!"); } catch (Exception e) { @@ -77,16 +75,26 @@ void start() { * @return */ private AlipayClient createAlipayClient(PropsConf conf, String id) { - String url = conf.getConf(id, F_URL); - String appId = conf.getConf(id, F_APP_ID); - String privateKey = conf.getConf(id, F_PRIVATE_KEY); - String format = conf.getConf(id, F_FORMAT, AlipayConstants.FORMAT_JSON); - String charset = conf.getConf(id, F_CHARSET, AlipayConstants.CHARSET_UTF8); - String publicKey = conf.getConf(id, F_PUBLIC_KEY); //alipay public key - String signType = conf.getConf(id, F_SIGN_TYPE, AlipayConstants.SIGN_TYPE_RSA2); - AlipayClient alipayClient = new DefaultAlipayClient(url, appId, privateKey, format, charset, publicKey, signType); - LOG.info("createAlipayClient {}", appId); - return alipayClient; + AlipayConfig config = new AlipayConfig(); + config.setServerUrl(conf.getConf(id, F_URL, "https://openapi.alipay.com/gateway.do")); + config.setAppId(conf.getConf(id, F_APP_ID)); + config.setPrivateKey(conf.getConf(id, F_PRIVATE_KEY)); + config.setFormat(conf.getConf(id, F_FORMAT, AlipayConstants.FORMAT_JSON)); + config.setCharset(conf.getConf(id, F_CHARSET, AlipayConstants.CHARSET_UTF8)); + config.setAlipayPublicKey(conf.getConf(id, F_PUBLIC_KEY));//alipay public key + config.setSignType(conf.getConf(id, F_SIGN_TYPE, AlipayConstants.SIGN_TYPE_RSA2)); + String encryptKey = conf.getConf(id, F_ENCRYPT_KEY); + if (encryptKey != null && !"".equals(encryptKey)) { + config.setEncryptKey(encryptKey); + config.setEncryptType(conf.getConf(id, F_ENCRYPT_TYPE, AlipayConstants.ENCRYPT_TYPE_AES)); + } + try { + LOG.info("createAlipayClient {}", config.getAppId()); + return new DefaultAlipayClient(config); + } catch (AlipayApiException e) { + LOG.error("failed to createAlipayClient " + e.getMessage(), e); + return null; + } } @Stop @@ -103,6 +111,7 @@ void stop() { @Override public AlipayClient getClient(String id) { + if (id == null) return null; return clients.get(id); } From 793525785d73532182d9eaac0e61eb0efcdc9717 Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 12 Aug 2022 15:17:43 +0800 Subject: [PATCH 34/47] opt alipay --- .../src/main/java/jframe/alipay/service/AlipayService.java | 4 ++++ .../main/java/jframe/alipay/service/AlipayServiceImpl.java | 2 +- .../src/main/java/jframe/wxpay/service/WxpayServiceV2.java | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java index f6ee674..dc96b79 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayService.java @@ -8,6 +8,7 @@ /** * https://docs.open.alipay.com/204 App支付 * https://docs.open.alipay.com/291/105971 密钥配置 + * https://opendocs.alipay.com/open/203/105286 支付Notify说明 *

    * https://docs.open.alipay.com/270/105899/ * https://docs.open.alipay.com/api_1/alipay.trade.page.pay/ @@ -41,6 +42,9 @@ public interface AlipayService { String TRADE_STATUS_SUCC = "TRADE_SUCCESS"; //交易支付成功 String TRADE_STATUS_FINISHED = "TRADE_FINISHED"; //交易结束,不可退款 + //https://opendocs.alipay.com/support/01raw4 + String TRADE_NOTIFY_RES_SUCC = "success";//接收成功 + String TRADE_NOTIFY_RES_FAIL = "fail"; //接收失败,重新发送通知 AlipayClient getClient(String id); diff --git a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java index cc91341..723b01d 100644 --- a/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java +++ b/jframe-plugin/jframe-alipay/src/main/java/jframe/alipay/service/AlipayServiceImpl.java @@ -89,7 +89,7 @@ private AlipayClient createAlipayClient(PropsConf conf, String id) { config.setEncryptType(conf.getConf(id, F_ENCRYPT_TYPE, AlipayConstants.ENCRYPT_TYPE_AES)); } try { - LOG.info("createAlipayClient {}", config.getAppId()); + LOG.info("createAlipayClient {} {}", id, config.getAppId()); return new DefaultAlipayClient(config); } catch (AlipayApiException e) { LOG.error("failed to createAlipayClient " + e.getMessage(), e); diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java index d67fe63..4ffedfa 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java @@ -56,8 +56,8 @@ void start() { for (String id : wxpayConf.getGroupIds()) { WXPay wxpay = createWxpay(wxpayConf, id); clients.put(id, wxpay); + LOG.info("createWxpay id {}", id); } - LOG.info("Start WxpayServiceV2 Successfully! ids:{}", wxpayConf.getGroupIds()); } catch (Exception e) { LOG.error("Start WxpayServiceV2 Failed!" + e.getMessage(), e); } From 7f0d98a8a102bc9a8c55841524b67ecbaa0c8499 Mon Sep 17 00:00:00 2001 From: dzh Date: Fri, 19 Aug 2022 15:08:08 +0800 Subject: [PATCH 35/47] add DMService id --- .../src/main/java/jframe/aliyun/service/DMService.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/DMService.java b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/DMService.java index 2033aee..558c642 100644 --- a/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/DMService.java +++ b/jframe-plugin/jframe-aliyun/src/main/java/jframe/aliyun/service/DMService.java @@ -3,19 +3,20 @@ import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest; import com.aliyuncs.dm.model.v20151123.SingleSendMailResponse; import com.aliyuncs.exceptions.ClientException; - import jframe.core.plugin.annotation.Service; /** * 邮件推送服务 - * + * * @author dzh - * @date Dec 10, 2018 1:46:37 PM * @version 0.0.1 + * @date Dec 10, 2018 1:46:37 PM */ -@Service(clazz = "jframe.aliyun.service.dm.DMServiceImpl", id = "jframe.service.aliyun.dm") +@Service(clazz = "jframe.aliyun.service.dm.DMServiceImpl", id = DMService.ID) public interface DMService { + String ID = "jframe.service.aliyun.dm"; + SingleSendMailResponse singleSend(String id, SingleSendMailRequest request) throws ClientException; } \ No newline at end of file From cdd77b4f462d3d10fa18312744991ef573568067 Mon Sep 17 00:00:00 2001 From: dzh Date: Sat, 19 Nov 2022 17:32:43 +0800 Subject: [PATCH 36/47] add MnsDispatcher --- .../src/main/java/jframe/core/FrameEvent.java | 4 +- .../core/dispatch/DefDispatchFactory.java | 104 +++++------ .../jframe/core/plugin/DefPluginContext.java | 1 - .../loader/ext/PluginServiceClassLoader.java | 5 +- .../java/jframe/core/unit/PluginUnit.java | 28 ++- jframe/jframe-ext/pom.xml | 18 +- .../jframe/ext/dispatch/kafka/KafkaConst.java | 24 +++ .../ext/dispatch/kafka/KafkaDispatcher.java | 32 +--- .../jframe/ext/dispatch/mns/MnsConst.java | 23 +++ .../dispatch/mns/MnsConsumerDispatcher.java | 19 ++ .../ext/dispatch/mns/MnsDispatcher.java | 175 ++++++++++++++++++ .../dispatch/mns/MnsProducerDispatcher.java | 19 ++ .../ext/dispatch/ons/OnsDispatcher.java | 10 +- .../ext/dispatch/rocketmq/RmqConst.java | 15 +- .../ext/dispatch/rocketmq/RmqDispatcher.java | 10 +- .../{dispatch/rocketmq => msg}/MsgCodec.java | 2 +- .../rocketmq => msg}/TextMsgCodec.java | 3 +- .../java/jframe/ext/plugin/KafkaPlugin.java | 13 +- .../java/jframe/ext/plugin/MnsPlugin.java | 20 ++ .../main/java/jframe/ext/plugin/MqPlugin.java | 13 ++ .../jframe/ext/plugin/RocketmqPlugin.java | 11 +- 21 files changed, 416 insertions(+), 133 deletions(-) create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaConst.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConst.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConsumerDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsDispatcher.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsProducerDispatcher.java rename jframe/jframe-ext/src/main/java/jframe/ext/{dispatch/rocketmq => msg}/MsgCodec.java (87%) rename jframe/jframe-ext/src/main/java/jframe/ext/{dispatch/rocketmq => msg}/TextMsgCodec.java (92%) create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/plugin/MnsPlugin.java create mode 100644 jframe/jframe-ext/src/main/java/jframe/ext/plugin/MqPlugin.java diff --git a/jframe/jframe-core/src/main/java/jframe/core/FrameEvent.java b/jframe/jframe-core/src/main/java/jframe/core/FrameEvent.java index ef5f92a..9649c12 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/FrameEvent.java +++ b/jframe/jframe-core/src/main/java/jframe/core/FrameEvent.java @@ -17,9 +17,9 @@ public class FrameEvent extends EventObject { */ private static final long serialVersionUID = 1L; - private int type; + private final int type; - public static final int Init = 1 << 0; + public static final int Init = 1; public static final int Start = 1 << 1; public static final int Stop = 1 << 2; diff --git a/jframe/jframe-core/src/main/java/jframe/core/dispatch/DefDispatchFactory.java b/jframe/jframe-core/src/main/java/jframe/core/dispatch/DefDispatchFactory.java index 303be81..33d4be1 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/dispatch/DefDispatchFactory.java +++ b/jframe/jframe-core/src/main/java/jframe/core/dispatch/DefDispatchFactory.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.core.dispatch; @@ -10,68 +10,68 @@ /** * dispatch管理管理工厂 - * + * * @author dzh * @date Jun 20, 2013 9:47:12 AM */ public class DefDispatchFactory implements DispatchFactory { - private final Object _lock = new Object(); + private final Object _lock = new Object(); - private List _dList = new ArrayList(2); + private List _dList = new ArrayList(2); - private DefDispatchFactory() { + private DefDispatchFactory() { - } + } - public static final DispatchFactory newInstance() { - return new DefDispatchFactory(); - } + public static DispatchFactory newInstance() { + return new DefDispatchFactory(); + } - public Dispatcher findDispatcher(String dispatcherID) { - List list = _dList; - Dispatcher dl = null; - synchronized (_lock) { - for (Dispatcher d : list) { - if (d.getID().equals(dispatcherID)) { - dl = d; - break; - } - } - } - return dl; - } + public Dispatcher findDispatcher(String dispatcherID) { + List list = _dList; + Dispatcher dl = null; + synchronized (_lock) { + for (Dispatcher d : list) { + if (d.getID().equals(dispatcherID)) { + dl = d; + break; + } + } + } + return dl; + } - public Dispatcher createDispatcher(String dispatcherID, Config config) { - Dispatcher d = DefDispatcher.newDispatcher(dispatcherID, config); - d.start(); - synchronized (_lock) { - _dList.add(d); - } - return d; - } + public Dispatcher createDispatcher(String dispatcherID, Config config) { + Dispatcher d = DefDispatcher.newDispatcher(dispatcherID, config); + d.start(); + synchronized (_lock) { + _dList.add(d); + } + return d; + } - /** - * if dispatcherID==Null, close all delegates - */ - public void removeDispatcher(String dispatcherID) { - List list = _dList; - if (dispatcherID == null) { - synchronized (_lock) { - for (Dispatcher d : list) { - d.close(); - } - } - list.clear(); - } else { - synchronized (_lock) { - Dispatcher d = findDispatcher(dispatcherID); - if (d != null) { - d.close(); - list.remove(d); - } - } - } - } + /** + * if dispatcherID==Null, close all delegates + */ + public void removeDispatcher(String dispatcherID) { + List list = _dList; + if (dispatcherID == null) { + synchronized (_lock) { + for (Dispatcher d : list) { + d.close(); + } + } + list.clear(); + } else { + synchronized (_lock) { + Dispatcher d = findDispatcher(dispatcherID); + if (d != null) { + d.close(); + list.remove(d); + } + } + } + } } diff --git a/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java b/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java index 1a40190..d6dda6e 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java +++ b/jframe/jframe-core/src/main/java/jframe/core/plugin/DefPluginContext.java @@ -297,7 +297,6 @@ public void notifyPluginEvent(PluginEvent event) { } /** - * * (non-Javadoc) * * @return if find PluginRef return it, or return null diff --git a/jframe/jframe-core/src/main/java/jframe/core/plugin/loader/ext/PluginServiceClassLoader.java b/jframe/jframe-core/src/main/java/jframe/core/plugin/loader/ext/PluginServiceClassLoader.java index 09cbcbf..2453207 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/plugin/loader/ext/PluginServiceClassLoader.java +++ b/jframe/jframe-core/src/main/java/jframe/core/plugin/loader/ext/PluginServiceClassLoader.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.core.plugin.loader.ext; @@ -52,9 +52,8 @@ protected void injectImportService(Field f) { /** * register export-service - * + * * @param pc - * @param p */ public void loadService(PluginCase pc) { ServiceContext sc = plc.getServiceContext(); diff --git a/jframe/jframe-core/src/main/java/jframe/core/unit/PluginUnit.java b/jframe/jframe-core/src/main/java/jframe/core/unit/PluginUnit.java index 70d96b0..603814b 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/unit/PluginUnit.java +++ b/jframe/jframe-core/src/main/java/jframe/core/unit/PluginUnit.java @@ -1,18 +1,8 @@ /** - * + * */ package jframe.core.unit; -import java.io.File; -import java.io.FilenameFilter; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import jframe.core.Frame; import jframe.core.conf.Config; import jframe.core.plugin.DefPluginContext; @@ -27,13 +17,22 @@ import jframe.core.plugin.loader.ext.PluginServiceCreator; import jframe.core.signal.Signal; import jframe.core.util.FileUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; /** *

    * Feature: *

  • load plug-in
  • *

    - * + * * @author dzh * @date Sep 23, 2013 2:47:41 PM * @since 1.0 @@ -75,7 +74,7 @@ public void start() throws UnitException { } /** - * + * */ private void cleanCache() { Config config = getFrame().getConfig(); @@ -89,8 +88,7 @@ private void cleanCache() { } /** - * - * @param path_plugin + * */ private List loadPlugin() { // create plugin diff --git a/jframe/jframe-ext/pom.xml b/jframe/jframe-ext/pom.xml index c8c5d9f..bd8b64e 100644 --- a/jframe/jframe-ext/pom.xml +++ b/jframe/jframe-ext/pom.xml @@ -17,40 +17,46 @@ com.google.code.gson gson - 2.8.5 + 2.10 org.apache.activemq activemq-client - 5.10.0 + 5.17.2 org.apache.activemq activemq-jms-pool - 5.15.7 + 5.17.2 org.apache.kafka kafka-clients - 2.1.0 + 3.3.1 org.apache.rocketmq rocketmq-client - 4.6.0 + 5.0.0 com.aliyun.openservices ons-client - 1.8.4.Final + 2.0.4.Final + + + + com.aliyun.mns + aliyun-sdk-mns + 1.1.9.1 diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaConst.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaConst.java new file mode 100644 index 0000000..0fee659 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaConst.java @@ -0,0 +1,24 @@ +package jframe.ext.dispatch.kafka; + +/** + * @author dzh + * @date 2022/11/18 11:13 + */ +public interface KafkaConst { + + // default + String DEFAULT_TOPIC = "jframe"; + + // config + String FILE_KAFKA_PRODUCER = "file.kafka.producer"; + String FILE_KAFKA_CONSUMER = "file.kafka.consumer"; + String D_KAFKA_SUBSCRIBE = "d.kafka.subscribe"; + String D_KAFKA_SUBSCRIBE_REGEX = "d.kafka.subscribe.regex"; + + // msg meta + String M_KAFKA_TOPIC = "m.kafka.topic"; + String M_KAFKA_KEY = "m.kafka.key"; + String M_KAFKA_PARTITION = "m.kafka.partition"; + String M_KAFKA_TIMESTAMP = "m.kafka.timestamp"; + +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java index 3d370e5..6790b9a 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/kafka/KafkaDispatcher.java @@ -18,7 +18,6 @@ import java.util.Collections; import java.util.Objects; import java.util.Properties; -import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; /** @@ -42,25 +41,10 @@ * @version 0.0.1 * @date Dec 26, 2018 5:16:26 PM */ -public class KafkaDispatcher extends AbstractDispatcher { +public class KafkaDispatcher extends AbstractDispatcher implements KafkaConst { static Logger LOG = LoggerFactory.getLogger(KafkaDispatcher.class); - // default - public static final String DEFAULT_TOPIC = "jframe"; - - // config - public static final String FILE_KAFKA_PRODUCER = "file.kafka.producer"; - public static final String FILE_KAFKA_CONSUMER = "file.kafka.consumer"; - public static final String D_KAFKA_SUBSCRIBE = "d.kafka.subscribe"; - public static final String D_KAFKA_SUBSCRIBE_REGEX = "d.kafka.subscribe.regex"; - - // msg meta - public static final String D_KAFKA_R_TOPIC = "d.kafka.r.topic"; - public static final String D_KAFKA_R_KEY = "d.kafka.r.key"; - public static final String D_KAFKA_R_PARTITION = "d.kafka.r.partition"; - public static final String D_KAFKA_R_TIMESTAMP = "d.kafka.r.timestamp"; - private Producer> producer; private Consumer> consumer; @@ -214,20 +198,20 @@ protected void loadDefaultConsumer(Properties props) { @Override public void receive(Msg msg) { if (producer != null) { - String topic = (String) msg.getMeta(D_KAFKA_R_TOPIC); + String topic = (String) msg.getMeta(M_KAFKA_TOPIC); if (Objects.isNull(topic)) { topic = DEFAULT_TOPIC; } Integer partition = partition(msg); Long timestamp = timestamp(msg); - String key = (String) msg.getMeta(D_KAFKA_R_KEY); + String key = (String) msg.getMeta(M_KAFKA_KEY); ProducerRecord> record = new ProducerRecord<>(topic, partition, timestamp, key, msg, null); producer.send(record); } } private Long timestamp(Msg msg) { - Object ts = msg.getMeta(D_KAFKA_R_TIMESTAMP); + Object ts = msg.getMeta(M_KAFKA_TIMESTAMP); if (ts == null) return null; if (ts instanceof Long) return (Long) ts; if (ts instanceof String) return Long.parseLong((String) ts); @@ -235,7 +219,7 @@ private Long timestamp(Msg msg) { } private Integer partition(Msg msg) { - Object p = msg.getMeta(D_KAFKA_R_PARTITION); + Object p = msg.getMeta(M_KAFKA_PARTITION); if (p == null) return null; if (p instanceof Integer) return (Integer) p; if (p instanceof String) return Integer.parseInt((String) p); @@ -254,11 +238,12 @@ public Consumer> getConsumer() { public void close() { if (closed) return; // close producer - if (enableProducer()) producer.close(WAIT_CLOSED_SECOND, TimeUnit.SECONDS); + if (enableProducer()) +// producer.close(WAIT_CLOSED_SECOND, TimeUnit.SECONDS); + producer.close(Duration.ofSeconds(WAIT_CLOSED_SECOND)); // close dispatcher and consumer if (enableConsumer()) { - closed = true; if (dispatchT != null) { try { dispatchT.join(WAIT_CLOSED_SECOND * 1000L); @@ -266,6 +251,7 @@ public void close() { } } } + closed = true; super.close(); } diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConst.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConst.java new file mode 100644 index 0000000..85497d2 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConst.java @@ -0,0 +1,23 @@ +package jframe.ext.dispatch.mns; + +/** + * @author dzh + * @date 2022/11/18 11:06 + */ +public interface MnsConst { + + String FILE_MNS = "file.mns"; + + // conf field + String MNS_ACCESSKEYID = "mns.accesskeyid"; + String MNS_ACCESSKEYSECRET = "mns.accesskeysecret"; + String MNS_ACCOUNTENDPOINT = "mns.accountendpoint"; + String MNS_QUEUE = "mns.queue"; //queue name, e.g. queueName1 queueName2 + + // msg meta + String M_MNS_CODEC = "m.mns.codec"; + String M_MNS_QUEUE = "m.mns.queue"; + + // default topic + String DEFAULT_QUEUE = "jframe"; +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConsumerDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConsumerDispatcher.java new file mode 100644 index 0000000..e7275c9 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsConsumerDispatcher.java @@ -0,0 +1,19 @@ +package jframe.ext.dispatch.mns; + +import jframe.core.conf.Config; + +/** + * @author dzh + * @date 2022/11/17 19:20 + */ +public class MnsConsumerDispatcher extends MnsDispatcher { + + public MnsConsumerDispatcher(String id, Config config) { + super(id, config); + } + + @Override + protected boolean enableProducer() { + return false; + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsDispatcher.java new file mode 100644 index 0000000..6281b2c --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsDispatcher.java @@ -0,0 +1,175 @@ +package jframe.ext.dispatch.mns; + +import com.aliyun.mns.client.*; +import com.aliyun.mns.model.Message; +import jframe.core.conf.Config; +import jframe.core.dispatch.AbstractDispatcher; +import jframe.core.msg.Msg; +import jframe.ext.msg.MsgCodec; +import jframe.ext.msg.TextMsgCodec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.FileInputStream; +import java.util.Objects; +import java.util.Properties; + +/** + * 限制 https://help.aliyun.com/document_detail/128343.html + * 接入点 https://help.aliyun.com/document_detail/175569.html + * http(s)://AccountId.mns.cn-shanghai.aliyuncs.com + * http://AccountId.mns.cn-shanghai-internal.aliyuncs.com + * + * @author dzh + * @date 2022/11/17 16:04 + */ +public class MnsDispatcher extends AbstractDispatcher implements AsyncCallback, MnsConst { + + static Logger LOG = LoggerFactory.getLogger(MnsDispatcher.class); + + private MNSClient client; + + private MsgCodec msgCodec; + + private String queue; //queue name, 目前支持单个队列消费 + + private volatile boolean closed; + + private Thread dispatchT; // consume dispatch thread + + public MnsDispatcher(String id, Config config) { + super(id, config); + } + + @Override + public void start() { + closed = false; + try { + initMNSClient(); + initMsgCodec(); + if (enableConsumer()) startConsumer(); + if (enableProducer()) startProducer(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + close(); + } + } + + private void initMsgCodec() { + String clazz = getConfig().getConfig(M_MNS_CODEC, TextMsgCodec.class.getName()); + try { + LOG.info("initMsgCodec {}", clazz); + msgCodec = (MsgCodec) Class.forName(clazz).newInstance(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } + + private void initMNSClient() { + String file = getConfig().getConfig(FILE_MNS); + if (Objects.isNull(file)) { + file = getConfig().getConfig(Config.APP_CONF) + "/mns.properties"; + } + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(file)) { + props.load(fis); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + return; + } + LOG.info("initMNSClient {}", props); + + CloudAccount account = new CloudAccount( + props.getProperty(MNS_ACCESSKEYID), + props.getProperty(MNS_ACCESSKEYSECRET), + props.getProperty(MNS_ACCOUNTENDPOINT)); + client = account.getMNSClient(); + this.queue = props.getProperty(MNS_QUEUE, DEFAULT_QUEUE); + } + + private void startProducer() { + + } + + private void startConsumer() { +// List queues = Arrays.asList(getConfig().getConfig(MnsConst.MNS_QUEUES, "").split("\\s+")); +// if (queues.isEmpty()) { +// LOG.error("msg.queue is not defined. failed to create consumer"); +// return; +// } + this.dispatchT = new Thread(() -> { + LOG.info("{} start", Thread.currentThread().getName()); + CloudQueue q = client.getQueueRef(this.queue); + while (!closed) { + try { +// for (String queue : queues) { + Message msg = q.popMessage(60); + if (msg != null) { + dispatch(msgCodec.decode(msg.getMessageBodyAsBytes())); + q.deleteMessage(msg.getReceiptHandle()); + } +// } + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } + LOG.info("{} closed", Thread.currentThread().getName()); + }, "MnsConsumeThread"); + dispatchT.start(); + } + + @Override + public void receive(Msg msg) { + if (enableProducer() && client != null && client.isOpen()) { + String q = (String) msg.getMeta(M_MNS_QUEUE); + if (Objects.isNull(q)) { + q = this.queue; //default queue + } + try { + AsyncResult r = client.getQueueRef(q).asyncPutMessage(new Message(msgCodec.encode(msg)), this); +// client.getQueueRef(q).putMessage(new Message(msgCodec.encode(msg))); + LOG.debug("send msg {}, result {}", msg, r); + } catch (Exception e) { + LOG.error(e.getMessage(), e);//todo + } + } else { + LOG.error("discard msg {}", msg); + } + } + + @Override + public void close() { + if (closed) return; + if (client != null) client.close(); + + // close dispatcher and consumer + if (enableConsumer()) { + if (dispatchT != null) { + try { + dispatchT.join(60 * 1000L); + } catch (InterruptedException e) { + } + } + } + closed = true; + super.close(); + } + + protected boolean enableProducer() { + return true; + } + + protected boolean enableConsumer() { + return true; + } + + @Override + public void onSuccess(Message msg) { + LOG.debug("mns put message {} successfully", msg); + } + + @Override + public void onFail(Exception e) { + LOG.error(e.getMessage(), e); + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsProducerDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsProducerDispatcher.java new file mode 100644 index 0000000..b804b9e --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/mns/MnsProducerDispatcher.java @@ -0,0 +1,19 @@ +package jframe.ext.dispatch.mns; + +import jframe.core.conf.Config; + +/** + * @author dzh + * @date 2022/11/17 19:20 + */ +public class MnsProducerDispatcher extends MnsDispatcher { + + public MnsProducerDispatcher(String id, Config config) { + super(id, config); + } + + @Override + protected boolean enableConsumer() { + return false; + } +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java index 3ae239d..4bba3eb 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/ons/OnsDispatcher.java @@ -4,9 +4,9 @@ import jframe.core.conf.Config; import jframe.core.dispatch.AbstractDispatcher; import jframe.core.msg.Msg; -import jframe.ext.dispatch.rocketmq.MsgCodec; import jframe.ext.dispatch.rocketmq.RmqConst; -import jframe.ext.dispatch.rocketmq.TextMsgCodec; +import jframe.ext.msg.MsgCodec; +import jframe.ext.msg.TextMsgCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -152,7 +152,7 @@ public Action consume(Message msg, ConsumeContext context) { } private void initMsgCodec() { - String clazz = getConfig().getConfig(D_RMQ_CODEC, TextMsgCodec.class.getName()); + String clazz = getConfig().getConfig(M_RMQ_CODEC, TextMsgCodec.class.getName()); try { msgCodec = (MsgCodec) Class.forName(clazz).newInstance(); } catch (Exception e) { @@ -163,14 +163,14 @@ private void initMsgCodec() { @Override public void receive(Msg msg) { if (producer != null) { - String topic = (String) msg.getMeta(D_RMQ_R_TOPIC); + String topic = (String) msg.getMeta(M_RMQ_TOPIC); if (Objects.isNull(topic)) { topic = DEFAULT_TOPIC; } try { Message rmqMsg = new Message(topic, - (String) msg.getMeta(D_RMQ_R_TAG), (String) msg.getMeta(D_RMQ_R_Key), + (String) msg.getMeta(M_RMQ_TAG), (String) msg.getMeta(M_RMQ_Key), msgCodec.encode(msg)); SendResult r = producer.send(rmqMsg); LOG.debug("send msg {}, sendResult {}", msg, r); diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java index ef59b7a..6752897 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqConst.java @@ -6,13 +6,14 @@ */ public interface RmqConst { - public static final String FILE_RMQ_PRODUCER = "file.rmq.producer"; - public static final String FILE_RMQ_CONSUMER = "file.rmq.consumer"; + String FILE_RMQ_PRODUCER = "file.rmq.producer"; + String FILE_RMQ_CONSUMER = "file.rmq.consumer"; - public static final String D_RMQ_CODEC = "d.rmq.codec"; // MsgCodec + // msg meta + String M_RMQ_CODEC = "m.rmq.codec"; // MsgCodec + String M_RMQ_TOPIC = "m.rmq.topic"; + String M_RMQ_TAG = "m.rmq.tag"; + String M_RMQ_Key = "m.rmq.key"; - public static final String DEFAULT_TOPIC = "jframe"; - public static final String D_RMQ_R_TOPIC = "d.rmq.r.topic"; - public static final String D_RMQ_R_TAG = "d.rmq.r.tag"; - public static final String D_RMQ_R_Key = "d.rmq.r.key"; + String DEFAULT_TOPIC = "jframe"; } diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java index 4941e44..005ba57 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/RmqDispatcher.java @@ -3,6 +3,8 @@ import jframe.core.conf.Config; import jframe.core.dispatch.AbstractDispatcher; import jframe.core.msg.Msg; +import jframe.ext.msg.MsgCodec; +import jframe.ext.msg.TextMsgCodec; import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; @@ -60,7 +62,7 @@ public void start() { } private void initMsgCodec() { - String clazz = getConfig().getConfig(D_RMQ_CODEC, TextMsgCodec.class.getName()); + String clazz = getConfig().getConfig(M_RMQ_CODEC, TextMsgCodec.class.getName()); try { msgCodec = (MsgCodec) Class.forName(clazz).newInstance(); } catch (Exception e) { @@ -162,7 +164,7 @@ private DefaultMQPushConsumer createConsumer(Properties props) throws MQClientEx consumer.setConsumeMessageBatchMaxSize(Integer.parseInt(val)); val = props.getProperty("consume.timeout", "5"); //minutes consumer.setConsumeTimeout(Long.parseLong(val)); - consumer.subscribe(props.getProperty("consume.topic", "jframe"), + consumer.subscribe(props.getProperty("consume.topic", RmqConst.DEFAULT_TOPIC), props.getProperty("consume.subExpression", "*")); consumer.setVipChannelEnabled(false); val = props.getProperty("consume.thread.max"); @@ -214,14 +216,14 @@ private DefaultMQPushConsumer createConsumer(Properties props) throws MQClientEx @Override public void receive(Msg msg) { if (producer != null) { - String topic = (String) msg.getMeta(D_RMQ_R_TOPIC); + String topic = (String) msg.getMeta(M_RMQ_TOPIC); if (Objects.isNull(topic)) { topic = DEFAULT_TOPIC; } try { Message rmqMsg = new Message(topic, - (String) msg.getMeta(D_RMQ_R_TAG), (String) msg.getMeta(D_RMQ_R_Key), + (String) msg.getMeta(M_RMQ_TAG), (String) msg.getMeta(M_RMQ_Key), msgCodec.encode(msg)); SendResult r = producer.send(rmqMsg); LOG.debug("send msg {}, sendResult {}", msg, r); diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/MsgCodec.java b/jframe/jframe-ext/src/main/java/jframe/ext/msg/MsgCodec.java similarity index 87% rename from jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/MsgCodec.java rename to jframe/jframe-ext/src/main/java/jframe/ext/msg/MsgCodec.java index dc586da..3343ce7 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/MsgCodec.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/msg/MsgCodec.java @@ -1,4 +1,4 @@ -package jframe.ext.dispatch.rocketmq; +package jframe.ext.msg; import jframe.core.msg.Msg; diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/TextMsgCodec.java b/jframe/jframe-ext/src/main/java/jframe/ext/msg/TextMsgCodec.java similarity index 92% rename from jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/TextMsgCodec.java rename to jframe/jframe-ext/src/main/java/jframe/ext/msg/TextMsgCodec.java index edeca6a..a45e349 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/dispatch/rocketmq/TextMsgCodec.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/msg/TextMsgCodec.java @@ -1,9 +1,10 @@ -package jframe.ext.dispatch.rocketmq; +package jframe.ext.msg; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import jframe.core.msg.Msg; import jframe.core.msg.TextMsg; +import jframe.ext.msg.MsgCodec; import java.io.IOException; diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java index 86dd0d0..b1fdd22 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/KafkaPlugin.java @@ -1,23 +1,22 @@ package jframe.ext.plugin; import jframe.core.msg.Msg; -import jframe.core.plugin.PluginSender; -import jframe.ext.dispatch.kafka.KafkaDispatcher; +import jframe.ext.dispatch.kafka.KafkaConst; /** * @author dzh * @version 0.0.1 * @date Dec 27, 2018 3:05:36 PM */ -public abstract class KafkaPlugin extends PluginSender { +public class KafkaPlugin extends MqPlugin { public void send(Msg msg, String topic, Integer partition, Long timestamp, String key) { if (msg == null) return; - msg.setMeta(KafkaDispatcher.D_KAFKA_R_TOPIC, topic); - msg.setMeta(KafkaDispatcher.D_KAFKA_R_PARTITION, partition); - msg.setMeta(KafkaDispatcher.D_KAFKA_R_TIMESTAMP, timestamp); - msg.setMeta(KafkaDispatcher.D_KAFKA_R_KEY, key); + msg.setMeta(KafkaConst.M_KAFKA_TOPIC, topic); + msg.setMeta(KafkaConst.M_KAFKA_PARTITION, partition); + msg.setMeta(KafkaConst.M_KAFKA_TIMESTAMP, timestamp); + msg.setMeta(KafkaConst.M_KAFKA_KEY, key); send(msg); } diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/MnsPlugin.java b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/MnsPlugin.java new file mode 100644 index 0000000..dd428d1 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/MnsPlugin.java @@ -0,0 +1,20 @@ +package jframe.ext.plugin; + +import jframe.core.msg.Msg; +import jframe.ext.dispatch.mns.MnsConst; + +/** + * @author dzh + * @date 2022/11/17 18:06 + */ +public class MnsPlugin extends MqPlugin { + + public void send(Msg msg, String queue) { + if (msg == null) return; + + msg.setMeta(MnsConst.M_MNS_QUEUE, queue); + + send(msg); + } + +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/MqPlugin.java b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/MqPlugin.java new file mode 100644 index 0000000..3d006b7 --- /dev/null +++ b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/MqPlugin.java @@ -0,0 +1,13 @@ +package jframe.ext.plugin; + +import jframe.core.plugin.PluginSender; + +/** + * @author dzh + * @date 2022/11/18 09:48 + */ +public class MqPlugin extends PluginSender { + + + +} diff --git a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java index 610a76e..6e1e634 100644 --- a/jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java +++ b/jframe/jframe-ext/src/main/java/jframe/ext/plugin/RocketmqPlugin.java @@ -1,8 +1,7 @@ package jframe.ext.plugin; import jframe.core.msg.Msg; -import jframe.core.plugin.PluginSender; -import jframe.ext.dispatch.rocketmq.RmqDispatcher; +import jframe.ext.dispatch.rocketmq.RmqConst; /** * Rocketmq Plugin @@ -10,14 +9,14 @@ * @author dzh * @date 2019/12/25 15:22 */ -public abstract class RocketmqPlugin extends PluginSender { +public class RocketmqPlugin extends MqPlugin { public void send(Msg msg, String topic, String tag, String key) { if (msg == null) return; - msg.setMeta(RmqDispatcher.D_RMQ_R_TOPIC, topic); - msg.setMeta(RmqDispatcher.D_RMQ_R_TAG, tag); - msg.setMeta(RmqDispatcher.D_RMQ_R_Key, key); + msg.setMeta(RmqConst.M_RMQ_TOPIC, topic); + msg.setMeta(RmqConst.M_RMQ_TAG, tag); + msg.setMeta(RmqConst.M_RMQ_Key, key); send(msg); } From 0aafee572e9b6dae8e60c4ced7fc36243017f6b5 Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 22 Apr 2024 11:43:12 +0800 Subject: [PATCH 37/47] upgrade version --- jframe-plugin/jframe-activemq/pom.xml | 2 +- jframe-plugin/jframe-datasource/pom.xml | 4 ++-- jframe-plugin/jframe-mybatis/pom.xml | 8 ++++---- jframe-plugin/pom.xml | 24 ++++++++---------------- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/jframe-plugin/jframe-activemq/pom.xml b/jframe-plugin/jframe-activemq/pom.xml index 623bfa5..1e6a069 100644 --- a/jframe-plugin/jframe-activemq/pom.xml +++ b/jframe-plugin/jframe-activemq/pom.xml @@ -12,7 +12,7 @@ org.apache.activemq activemq-client - 5.11.1 + 6.0.1 \ No newline at end of file diff --git a/jframe-plugin/jframe-datasource/pom.xml b/jframe-plugin/jframe-datasource/pom.xml index b47d36e..fbce88a 100644 --- a/jframe-plugin/jframe-datasource/pom.xml +++ b/jframe-plugin/jframe-datasource/pom.xml @@ -12,12 +12,12 @@ com.alibaba druid - 1.1.12 + 1.2.22 mysql mysql-connector-java - 8.0.13 + 8.0.33 \ No newline at end of file diff --git a/jframe-plugin/jframe-mybatis/pom.xml b/jframe-plugin/jframe-mybatis/pom.xml index 0afc3e9..ff2e44e 100644 --- a/jframe-plugin/jframe-mybatis/pom.xml +++ b/jframe-plugin/jframe-mybatis/pom.xml @@ -19,7 +19,7 @@ org.mybatis mybatis - 3.4.6 + 3.5.16 ${project.groupId} @@ -30,12 +30,12 @@ cglib cglib - 3.2.9 + 3.3.0 ognl ognl - 3.2.8 + 3.3.5 javassist @@ -46,7 +46,7 @@ org.javassist javassist - 3.24.0-GA + 3.30.2-GA \ No newline at end of file diff --git a/jframe-plugin/pom.xml b/jframe-plugin/pom.xml index c2a1212..3e3d936 100644 --- a/jframe-plugin/pom.xml +++ b/jframe-plugin/pom.xml @@ -9,10 +9,11 @@ UTF-8 2.0.0-SNAPSHOT - 1.7.25 + 1.7.36 jframe-activemq + jframe-activemq-client jframe-clrfile jframe-datasource jframe-watch @@ -26,7 +27,6 @@ jframe-mongodb-client jframe-yunpian jframe-qiniu - jframe-activemq-client jframe-rabbitmq-client jframe-rongcloud jframe-aliyun @@ -60,7 +60,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.0 + 3.13.0 1.8 1.8 @@ -70,7 +70,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.1.1 + 3.3.0 plugin @@ -79,7 +79,7 @@ org.apache.maven.plugins maven-resources-plugin - 3.1.0 + 3.3.1 compile @@ -94,23 +94,15 @@ ${session.executionRootDirectory}/release/lib/ true true true provided --> - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M2 - - true - - org.apache.maven.plugins maven-clean-plugin - 3.1.0 + 3.3.2 org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M2 + 3.2.5 true @@ -121,7 +113,7 @@ junit junit - 4.10 + 4.13.2 test From 62583ea760ca4fe4103466a11ddc2c87c26895b0 Mon Sep 17 00:00:00 2001 From: dzh Date: Thu, 11 Jul 2024 15:56:23 +0800 Subject: [PATCH 38/47] wxpayv3 --- jframe-plugin/jframe-wxpay/pom.xml | 25 +- .../src/main/java/jframe/wxpay/WxpayConf.java | 36 +-- .../jframe/wxpay/service/WxpayService.java | 25 +- .../jframe/wxpay/service/WxpayServiceV3.java | 107 ++----- .../WxpayServiceV2Impl.java} | 63 +++- .../service/impl/WxpayServiceV3Impl.java | 300 ++++++++++++++++++ .../main/resources/META-INF/plugin.properties | 2 +- jframe-plugin/pom.xml | 4 +- 8 files changed, 428 insertions(+), 134 deletions(-) rename jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/{WxpayServiceV2.java => impl/WxpayServiceV2Impl.java} (71%) create mode 100644 jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java diff --git a/jframe-plugin/jframe-wxpay/pom.xml b/jframe-plugin/jframe-wxpay/pom.xml index a782915..0d0e0bb 100644 --- a/jframe-plugin/jframe-wxpay/pom.xml +++ b/jframe-plugin/jframe-wxpay/pom.xml @@ -7,6 +7,18 @@ io.github.dzh 2.0.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + 4.0.0 jframe-wxpay @@ -15,7 +27,7 @@ org.apache.httpcomponents httpclient - 4.5.11 + 4.5.13 + + + + + + com.github.wechatpay-apiv3 - wechatpay-apache-httpclient - 0.2.1 + wechatpay-java + 0.2.12 + \ No newline at end of file diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java index cbfc566..f370884 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java @@ -1,23 +1,15 @@ package jframe.wxpay; -import jframe.core.conf.Config; -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.Injector; import jframe.core.util.PropsConf; -import java.io.*; -import java.nio.file.Paths; +import java.io.InputStream; /** * @author dzh * @date 2020/8/18 19:39 */ -@Injector public class WxpayConf extends PropsConf { - @InjectPlugin - static WxpayPlugin plugin; - public static final String CERTNAME = "apiclient_cert.p12"; public static final String P_appId = "appId"; @@ -28,29 +20,15 @@ public class WxpayConf extends PropsConf { public static final String P_autoReport = "autoReport"; public static final String P_useSandbox = "useSandbox"; public static final String P_signType = "signType"; + //v3 + public static final String P_apiKeyV3 = "apiKeyV3"; + public static final String P_privateKeyPath = "privateKeyPath"; + public static final String P_certSN = "certSN"; + public static final String P_notifyOrderV3 = "notifyOrderV3"; + public static final String P_notifyRefundV3 = "notifyRefundV3"; public synchronized void init(InputStream is) throws Exception { super.init(is); } - /** - * @param id groupid - * @return cert bytes - * @throws IOException - */ - public byte[] loadCert(String id) throws IOException { - String certPath = this.getConf(id, P_certPath); - File file = new File(certPath); - if (!file.exists()) { - file = Paths.get(plugin.getConfig(Config.APP_CONF), CERTNAME).toFile(); - } - if (!file.exists()) { - throw new FileNotFoundException(CERTNAME); - } - try (InputStream certStream = new FileInputStream(file)) { - byte[] certData = new byte[(int) file.length()]; - certStream.read(certData); - return certData; - } - } } diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java index 331013e..8c685f6 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayService.java @@ -5,19 +5,26 @@ import java.util.Map; /** - * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1 付款到零钱 + * API列表 + * 付款到零钱 * * @author dzh * @date 2020/8/18 16:45 */ -@Service(clazz = "jframe.wxpay.service.WxpayServiceV2", id = WxpayService.ID) +@Service(clazz = "jframe.wxpay.service.impl.WxpayServiceV2Impl", id = WxpayService.ID) public interface WxpayService { String ID = "jframe.service.wxpay"; + String V2 = "v2"; + String NOTIFY_SUCC = ""; String NOTIFY_FAIL = ""; + default String version() { + return V2; + } + /** * @param id groupid * @param key properties key @@ -29,37 +36,41 @@ public interface WxpayService { /** * 签名预支付信息,返回给前端 - * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5 + * 预支付信息 *

    * Map{appId,timeStamp,nonceStr,package,signType} * * @param id group id * @param req Map{prepareId,nonceStr} * @return Map{timeStamp,nonceStr,package,package,signType,paySign} - * @throws Exception */ Map signPrepay(String id, Map req) throws Exception; + Map orderPrepayAndSign(String id, Map req) throws Exception; + Map orderClose(String id, Map req) throws Exception; /** - * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2 + * 订单查询 * * @param id group id * @param req map{transaction_id,out_trade_no} - * @return - * @throws Exception + * @return order */ Map orderQuery(String id, Map req) throws Exception; Map processResponseXml(String id, String xmlStr) throws Exception; + @Deprecated Map processResponseXmlUnsafe(String xmlStr) throws Exception; boolean isResponseSignatureValid(String id, Map res) throws Exception; Map refund(String id, Map req) throws Exception; + // 退款通知 + Map refundNotify(String id, String reqBody, Map headers) throws Exception; + Map refundQuery(String id, Map req) throws Exception; Map promotionTransfers(String id, Map reqData) throws Exception; diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java index 56e5d68..818de1e 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV3.java @@ -1,87 +1,44 @@ package jframe.wxpay.service; -import jframe.core.conf.Config; -import jframe.core.plugin.annotation.InjectPlugin; -import jframe.core.plugin.annotation.Injector; -import jframe.core.plugin.annotation.Start; -import jframe.core.plugin.annotation.Stop; -import jframe.wxpay.WxpayConf; -import jframe.wxpay.WxpayPlugin; -import org.apache.http.client.HttpClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.HashMap; +import com.wechat.pay.java.service.payments.model.Transaction; +import com.wechat.pay.java.service.refund.model.Refund; +import com.wechat.pay.java.service.refund.model.RefundNotification; +import jframe.core.plugin.annotation.Service; + import java.util.Map; /** - * https://wechatpay-api.gitbook.io/wechatpay-api-v3/ - * https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/transactions.shtml 接口文档 - * https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient - *

    - * 请求的唯一标示包含在应答的HTTP头Request-ID中 - *

    - * User-Agent - * 使用HTTP客户端默认的User-Agent。 - * 遵循HTTP协议,使用自身系统和应用的名称和版本等信息,组成自己独有的User-Agent。 - *

    - * Accept-Language - * en - * zh-CN - * zh-HK - * zh-TW - * * @author dzh - * @date 2020/8/18 17:38 + * @date 2024/7/3 09:49 */ -@Deprecated -@Injector -public class WxpayServiceV3 { - - static Logger LOG = LoggerFactory.getLogger(WxpayServiceV3.class); - - @InjectPlugin - static WxpayPlugin plugin; - - static String FILE_WXPAY = "file.wxpay"; - - private WxpayConf wxpayConf; - - private Map clients = new HashMap<>(); - - @Start - void start() { - LOG.info("Start {}", WxpayServiceV3.class.getSimpleName()); - try { - String file = plugin.getConfig(FILE_WXPAY, plugin.getConfig(Config.APP_CONF) + "/wxpay.properties"); - if (!new File(file).exists()) { - throw new FileNotFoundException("not found " + file); - } - wxpayConf = new WxpayConf(); - wxpayConf.init(file); - for (String id : wxpayConf.getGroupIds()) { - HttpClient wxpay = createWxpay(wxpayConf, id); - clients.put(id, wxpay); - } - LOG.info("Start WxpayServiceV3 Successfully!"); - } catch (Exception e) { - LOG.error("Start WxpayServiceV3 Failed!" + e.getMessage(), e); - } - } +@Service(clazz = "jframe.wxpay.service.impl.WxpayServiceV3Impl", id = WxpayServiceV3.ID) +public interface WxpayServiceV3 { - private HttpClient createWxpay(WxpayConf wxpayConf, String id) { -// WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() -// .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey) -// .withWechatpay(wechatpayCertificates); - return null; - } + String ID = "jframe.service.wxpayv3"; + + String V3 = "v3"; - @Stop - void stop() { - clients.clear(); - LOG.info("Stop WxpayServiceV3"); + default String version() { + return V3; } + String conf(String id, String key); + + Map orderPrepay(String id, Map req) throws Exception; + + Map signPrepay(String id, Map req) throws Exception; + + Map orderPrepayAndSign(String id, Map req) throws Exception; + + void orderClose(String id, Map req) throws Exception; + + Transaction orderQuery(String id, Map req) throws Exception; + + Transaction orderNotify(String id, String reqBody, Map headers) throws Exception; + + Refund refund(String id, Map req) throws Exception; + + Refund refundQuery(String id, Map req) throws Exception; + + RefundNotification refundNotify(String id, String reqBody, Map headers) throws Exception; } diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV2Impl.java similarity index 71% rename from jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java rename to jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV2Impl.java index 4ffedfa..70f724d 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/WxpayServiceV2.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV2Impl.java @@ -1,4 +1,4 @@ -package jframe.wxpay.service; +package jframe.wxpay.service.impl; import com.github.wxpay.sdk.JframeWxpayConfig; import com.github.wxpay.sdk.WXPay; @@ -11,27 +11,27 @@ import jframe.core.plugin.annotation.Stop; import jframe.wxpay.WxpayConf; import jframe.wxpay.WxpayPlugin; +import jframe.wxpay.service.WxpayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileNotFoundException; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** - * https://pay.weixin.qq.com/wiki/doc/api/index.html - * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 + * 开发文档首页 * * @author dzh * @date 2020/8/18 17:40 */ @Injector -public class WxpayServiceV2 implements WxpayService { +public class WxpayServiceV2Impl implements WxpayService { - static Logger LOG = LoggerFactory.getLogger(WxpayServiceV2.class); + static Logger LOG = LoggerFactory.getLogger(WxpayServiceV2Impl.class); @InjectPlugin static WxpayPlugin plugin; @@ -39,7 +39,7 @@ public class WxpayServiceV2 implements WxpayService { static String FILE_WXPAY = "file.wxpay"; //group id -> AlipayClient - private Map clients = new HashMap<>(); + private final Map clients = new HashMap<>(); private WxpayConf wxpayConf; @@ -69,16 +69,35 @@ void stop() { LOG.info("Stop WxpayServiceV2"); } - private WXPay createWxpay(WxpayConf props, String id) throws Exception { - byte[] bytes = props.loadCert(id); - JframeWxpayConfig conf = JframeWxpayConfig.create(props.getConf(id, WxpayConf.P_appId), - props.getConf(id, WxpayConf.P_mchId), props.getConf(id, WxpayConf.P_apiKey), new ByteArrayInputStream(bytes)); - return new WXPay(conf, props.getConf(id, WxpayConf.P_notifyUrl), - Boolean.parseBoolean(props.getConf(id, WxpayConf.P_autoReport, "true")), - Boolean.parseBoolean(props.getConf(id, WxpayConf.P_useSandbox, "false")), - WXPayConstants.SignType.of(props.getConf(id, WxpayConf.P_signType))); + /** + * @param id groupid + * @return cert bytes + */ + byte[] loadCert(WxpayConf props, String id) throws IOException { + String certPath = props.getConf(id, WxpayConf.P_certPath); + File file = new File(certPath); + if (!file.exists()) { + file = Paths.get(plugin.getConfig(Config.APP_CONF), WxpayConf.CERTNAME).toFile(); + } + if (!file.exists()) { + throw new FileNotFoundException(WxpayConf.CERTNAME); + } + try (InputStream certStream = Files.newInputStream(file.toPath())) { + byte[] certData = new byte[(int) file.length()]; + long size = certStream.read(certData); + LOG.info("read {} {}", size, WxpayConf.CERTNAME); + return certData; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + throw new IOException(e.getMessage(), e.getCause()); + } } + private WXPay createWxpay(WxpayConf props, String id) throws Exception { + byte[] bytes = loadCert(props, id); + JframeWxpayConfig conf = JframeWxpayConfig.create(props.getConf(id, WxpayConf.P_appId), props.getConf(id, WxpayConf.P_mchId), props.getConf(id, WxpayConf.P_apiKey), new ByteArrayInputStream(bytes)); + return new WXPay(conf, props.getConf(id, WxpayConf.P_notifyUrl), Boolean.parseBoolean(props.getConf(id, WxpayConf.P_autoReport, "true")), Boolean.parseBoolean(props.getConf(id, WxpayConf.P_useSandbox, "false")), WXPayConstants.SignType.of(props.getConf(id, WxpayConf.P_signType))); + } @Override public String conf(String id, String key) { @@ -112,6 +131,11 @@ public Map signPrepay(String id, Map req) throws return data; } + @Override + public Map orderPrepayAndSign(String id, Map req) throws Exception { + return signPrepay(id, orderPrepay(id, req)); + } + @Override public Map orderClose(String id, Map req) throws Exception { return clients.get(id).closeOrder(req); @@ -142,6 +166,11 @@ public Map refund(String id, Map req) throws Exc return clients.get(id).refund(req); } + @Override + public Map refundNotify(String id, String reqBody, Map headers) throws Exception { + return Map.of();//todo + } + @Override public Map refundQuery(String id, Map req) throws Exception { return clients.get(id).refundQuery(req); diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java new file mode 100644 index 0000000..93a4f24 --- /dev/null +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java @@ -0,0 +1,300 @@ +package jframe.wxpay.service.impl; + +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.core.util.NonceUtil; +import com.wechat.pay.java.service.payments.jsapi.JsapiService; +import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; +import com.wechat.pay.java.service.payments.jsapi.model.Amount; +import com.wechat.pay.java.service.payments.jsapi.model.*; +import com.wechat.pay.java.service.payments.model.Transaction; +import com.wechat.pay.java.service.refund.RefundService; +import com.wechat.pay.java.service.refund.model.*; +import jframe.core.plugin.annotation.InjectPlugin; +import jframe.core.plugin.annotation.Injector; +import jframe.core.plugin.annotation.Start; +import jframe.core.plugin.annotation.Stop; +import jframe.wxpay.WxpayConf; +import jframe.wxpay.WxpayPlugin; +import jframe.wxpay.service.WxpayServiceV3; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; + +/** + * V3开发说明 + * 接口文档 + * wechatpay-apache-httpclient + * v3 java sdk + *

    + * 请求的唯一标示包含在应答的HTTP头Request-ID中 + *

    + * User-Agent + * 使用HTTP客户端默认的User-Agent。 + * 遵循HTTP协议,使用自身系统和应用的名称和版本等信息,组成自己独有的User-Agent。 + *

    + * Accept-Language + * en + * zh-CN + * zh-HK + * zh-TW + * + * @author dzh + * @date 2020/8/18 17:38 + */ +@Injector +public class WxpayServiceV3Impl implements WxpayServiceV3 { + + static Logger LOG = LoggerFactory.getLogger(WxpayServiceV3Impl.class); + + @InjectPlugin + static WxpayPlugin plugin; + + static String FILE_WXPAY = "file.wxpay"; + + private WxpayConf wxpayConf; + + // 使用自动更新平台证书的RSA配置 + // 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错 + private final Map payConf = new HashMap<>();//mchId->conf + + @Start + void start() { + LOG.info("Start {}", WxpayServiceV3Impl.class.getSimpleName()); + try { + String file = plugin.getConfig(FILE_WXPAY, plugin.getConfig(jframe.core.conf.Config.APP_CONF) + "/wxpay.properties"); + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } + wxpayConf = new WxpayConf(); + wxpayConf.init(file); + + initPayConf(wxpayConf); + + LOG.info("WxpayServiceV3 start successfully!"); + } catch (Exception e) { + LOG.error("WxpayServiceV3 start failed! {}", e.getMessage(), e); + } + } + + private void initPayConf(WxpayConf wxpayConf) { + for (String id : wxpayConf.getGroupIds()) { + String mid = wxpayConf.getConf(id, WxpayConf.P_mchId); + if (payConf.containsKey(mid)) continue; + String privateKeyPath = wxpayConf.getConf(id, WxpayConf.P_privateKeyPath); + if (privateKeyPath == null || privateKeyPath.trim().isEmpty()) { + privateKeyPath = plugin.getConfig(jframe.core.conf.Config.APP_CONF) + "/appclient_key.pem"; + } + RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder().merchantId(mid).privateKeyFromPath(privateKeyPath).merchantSerialNumber(wxpayConf.getConf(id, WxpayConf.P_certSN)).apiV3Key(wxpayConf.getConf(id, WxpayConf.P_apiKeyV3)).build(); + payConf.put(mid, config); + } + } + + private RSAAutoCertificateConfig payConfig(String id) { + String mid = wxpayConf.getConf(id, WxpayConf.P_mchId); + return payConf.get(mid); + } + + @Stop + void stop() { + payConf.clear(); + LOG.info("WxpayServiceV3 stopped"); + } + + @Override + public String conf(String id, String key) { + return wxpayConf.getConf(id, key); + } + + private PrepayRequest toPrepayRequest(String id, Map req) { + PrepayRequest request = new PrepayRequest(); + request.setAppid(conf(id, WxpayConf.P_appId)); + request.setMchid(conf(id, WxpayConf.P_mchId)); + request.setDescription(req.getOrDefault("description", req.get("body"))); + request.setOutTradeNo(req.get("out_trade_no")); + if (req.containsKey("time_expire")) request.setTimeExpire(req.get("time_expire")); + if (req.containsKey("attach")) request.setAttach(req.get("attach")); + if (req.containsKey("notify_url")) request.setNotifyUrl(req.get("notify_url")); + else request.setNotifyUrl(conf(id, WxpayConf.P_notifyOrderV3)); + if (req.containsKey("goods_tag")) request.setGoodsTag(req.get("goods_tag")); + if (req.containsKey("support_fapiao")) + request.setSupportFapiao(Boolean.parseBoolean(req.get("support_fapiao"))); + Amount amount = new Amount(); + amount.setTotal(Integer.parseInt(req.get("total_fee"))); + amount.setCurrency(req.getOrDefault("currency", "CNY")); + request.setAmount(amount); + Payer payer = new Payer(); + payer.setOpenid(req.get("openid")); + request.setPayer(payer); + // +// request.setDetail(); +// request.setSceneInfo(); +// request.setSettleInfo(); + return request; + } + + //https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/direct-jsons/jsapi-prepay.html + @Override + public Map orderPrepay(String id, Map req) throws Exception { + JsapiService service = new JsapiService.Builder().config(payConfig(id)).build(); + PrepayResponse response = service.prepay(toPrepayRequest(id, req)); + return Map.of("prepay_id", response.getPrepayId()); + } + + /** + * @param id group id + * @param req Map{prepareId,nonceStr} + * @return replace with orderPrepay + */ + @Override + public Map signPrepay(String id, Map req) throws Exception { + Config config = payConfig(id); +// Signer signer = config.createSigner(); + + String appid = conf(id, WxpayConf.P_appId); + String prepayId = req.get("prepay_id"); + long timestamp = Instant.now().getEpochSecond(); + String nonceStr = NonceUtil.createNonce(32); + String packageVal = "prepay_id=" + prepayId; + String message = appid + "\n" + timestamp + "\n" + nonceStr + "\n" + packageVal + "\n"; + String sign = config.createSigner().sign(message).getSign(); + + Map data = new HashMap<>(); + data.put("appId", appid); + data.put("timeStamp", String.valueOf(timestamp)); + data.put("nonceStr", nonceStr); + data.put("package", packageVal); + data.put("signType", "RSA"); + data.put("paySign", sign); + return data; + } + + @Override + public Map orderPrepayAndSign(String id, Map req) throws Exception { + JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(payConfig(id)).build(); + PrepayRequest request = toPrepayRequest(id, req); + PrepayWithRequestPaymentResponse prepayRes = service.prepayWithRequestPayment(request); + //appId,timeStamp,nonceStr,package,signType + Map data = new HashMap<>(); + data.put("appId", conf(id, WxpayConf.P_appId)); + data.put("timeStamp", prepayRes.getTimeStamp()); + data.put("nonceStr", prepayRes.getNonceStr()); + data.put("package", prepayRes.getPackageVal()); + data.put("signType", prepayRes.getSignType()); + data.put("paySign", prepayRes.getPaySign()); + return data; + } + + //https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/close-order.html + @Override + public void orderClose(String id, Map req) throws Exception { + JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(payConfig(id)).build(); + CloseOrderRequest request = new CloseOrderRequest(); + request.setMchid(conf(id, WxpayConf.P_mchId)); + request.setOutTradeNo(req.get("out_trade_no")); + service.closeOrder(request); + } + + @Override + public Transaction orderQuery(String id, Map req) throws Exception { + JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(payConfig(id)).build(); + + Transaction t = null; + if (req.containsKey("out_trade_no")) { + QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest(); + request.setMchid(conf(id, WxpayConf.P_mchId)); + request.setOutTradeNo(req.get("out_trade_no")); + t = service.queryOrderByOutTradeNo(request); + } else if (req.containsKey("transaction_id")) { + QueryOrderByIdRequest request = new QueryOrderByIdRequest(); + request.setMchid(conf(id, WxpayConf.P_mchId)); + request.setTransactionId(req.get("transaction_id")); + t = service.queryOrderById(request); + } +// if (t != null) { +// return Map.of("appid", t.getAppid(), "out_trade_no", t.getOutTradeNo(), "transaction_id", t.getTransactionId(), "trade_type", t.getTradeType().name(), "trade_state", t.getTradeState().name(), "trade_state_desc", t.getTradeStateDesc(), "attach", t.getAttach()); +// } + return t; + } + + /** + * 通知API + * 具体步骤如下: + *

    + * 使用回调通知请求的数据,构建 RequestParam。 + * HTTP 请求体 body。切记使用原始报文,不要用 JSON 对象序列化后的字符串,避免验签的 body 和原文不一致。 + * HTTP 头 Wechatpay-Signature。应答的微信支付签名。 + * HTTP 头 Wechatpay-Serial。微信支付平台证书的序列号,验签必须使用序列号对应的微信支付平台证书。 + * HTTP 头 Wechatpay-Nonce。签名中的随机数。 + * HTTP 头 Wechatpay-Timestamp。签名中的时间戳。 + * HTTP 头 Wechatpay-Signature-Type。签名类型。 + * 初始化 RSAAutoCertificateConfig。微信支付平台证书由 SDK 的自动更新平台能力提供,也可以使用本地证书。 + * 初始化 NotificationParser。 + * 调用 NotificationParser.parse() 验签、解密并将 JSON 转换成具体的通知回调对象。如果验签失败,SDK 会抛出 ValidationException。 + * 接下来可以执行你的业务逻辑了。如果执行成功,你应返回 200 OK 的状态码。如果执行失败,你应返回 4xx 或者 5xx的状态码,例如数据库操作失败建议返回 500 Internal Server Error。 + * + * @param id group id + * @param reqBody request body + * @param headers request headers contains signature info + * @return Transaction + */ + @Override + public Transaction orderNotify(String id, String reqBody, Map headers) throws Exception { + NotificationConfig config = payConfig(id); + NotificationParser parser = new NotificationParser(config); + + // 构造 RequestParam + RequestParam requestParam = new RequestParam.Builder().serialNumber(headers.get("Wechatpay-Serial")).nonce(headers.get("Wechatpay-Nonce")).signature(headers.get("Wechatpay-Signature")).timestamp(headers.get("Wechatpay-Timestamp")).body(reqBody).build(); + return parser.parse(requestParam, Transaction.class); +// return Map.of("out_trade_no", od.getOutTradeNo(), "success_time", od.getSuccessTime(), "openid", od.getPayer().getOpenid(), "transaction_id", od.getTransactionId(), "result_code", od.getTradeState().name()); + } + + + //https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/create.html + @Override + public Refund refund(String id, Map req) throws Exception { + RefundService service = new RefundService.Builder().config(payConfig(id)).build(); + CreateRequest request = new CreateRequest(); + request.setTransactionId(req.get("transaction_id")); + request.setOutTradeNo(req.get("out_trade_no")); + request.setOutRefundNo(req.get("out_refund_no")); + if (req.containsKey("reason")) request.setReason(req.get("reason")); + if (req.containsKey("notify_url")) request.setNotifyUrl(req.get("notify_url")); + else request.setNotifyUrl(conf(id, WxpayConf.P_notifyRefundV3)); +// if(req.containsKey("funds_account")) +// request.setFundsAccount(); + AmountReq amount = new AmountReq(); + amount.setCurrency(req.getOrDefault("amount_currency", "CNY")); + amount.setRefund(Long.parseLong(req.get("amount_refund"))); + amount.setTotal(Long.parseLong(req.getOrDefault("amount_total", req.get("refund")))); + request.setAmount(amount); + return service.create(request); + } + + //https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/query-by-out-refund-no.html + @Override + public Refund refundQuery(String id, Map req) throws Exception { + RefundService service = new RefundService.Builder().config(payConfig(id)).build(); + QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest(); + request.setOutRefundNo(req.get("out_refund_no")); + return service.queryByOutRefundNo(request); + } + + @Override + public RefundNotification refundNotify(String id, String reqBody, Map headers) throws Exception { + NotificationConfig config = payConfig(id); + NotificationParser parser = new NotificationParser(config); + // 构造 RequestParam + RequestParam requestParam = new RequestParam.Builder().serialNumber(headers.get("Wechatpay-Serial")).nonce(headers.get("Wechatpay-Nonce")).signature(headers.get("Wechatpay-Signature")).timestamp(headers.get("Wechatpay-Timestamp")).body(reqBody).build(); + return parser.parse(requestParam, RefundNotification.class); + } + +} diff --git a/jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties b/jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties index 9df13fe..194c05e 100644 --- a/jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties +++ b/jframe-plugin/jframe-wxpay/src/main/resources/META-INF/plugin.properties @@ -4,4 +4,4 @@ Plugin-Class=jframe.wxpay.WxpayPlugin #Plugin-Lib = #Default DLL path is META-INF/dll #Plugin-Dll = -Plugin-Service=jframe.wxpay.service.WxpayService +Plugin-Service=jframe.wxpay.service.WxpayService jframe.wxpay.service.WxpayServiceV3 diff --git a/jframe-plugin/pom.xml b/jframe-plugin/pom.xml index 3e3d936..e8dddbf 100644 --- a/jframe-plugin/pom.xml +++ b/jframe-plugin/pom.xml @@ -62,8 +62,8 @@ maven-compiler-plugin 3.13.0 - 1.8 - 1.8 + 11 + 11 ${project.build.sourceEncoding} From 2b8d26c17832c4382a7d498a4f34eda9f992ee56 Mon Sep 17 00:00:00 2001 From: dzh Date: Thu, 18 Jul 2024 13:28:58 +0800 Subject: [PATCH 39/47] fix name apiclient_key.pem --- .../jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java | 1 + .../main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java index f370884..a310f8b 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/WxpayConf.java @@ -11,6 +11,7 @@ public class WxpayConf extends PropsConf { public static final String CERTNAME = "apiclient_cert.p12"; + public static final String V3_PRIVATE_KEY = "apiclient_key.pem"; public static final String P_appId = "appId"; public static final String P_mchId = "mchId"; diff --git a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java index 93a4f24..f82edf8 100644 --- a/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java +++ b/jframe-plugin/jframe-wxpay/src/main/java/jframe/wxpay/service/impl/WxpayServiceV3Impl.java @@ -91,7 +91,7 @@ private void initPayConf(WxpayConf wxpayConf) { if (payConf.containsKey(mid)) continue; String privateKeyPath = wxpayConf.getConf(id, WxpayConf.P_privateKeyPath); if (privateKeyPath == null || privateKeyPath.trim().isEmpty()) { - privateKeyPath = plugin.getConfig(jframe.core.conf.Config.APP_CONF) + "/appclient_key.pem"; + privateKeyPath = plugin.getConfig(jframe.core.conf.Config.APP_CONF) + "/" + WxpayConf.V3_PRIVATE_KEY; } RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder().merchantId(mid).privateKeyFromPath(privateKeyPath).merchantSerialNumber(wxpayConf.getConf(id, WxpayConf.P_certSN)).apiV3Key(wxpayConf.getConf(id, WxpayConf.P_apiKeyV3)).build(); payConf.put(mid, config); From 58e2e779c6c97287d0b61a5994af022e4e9b1233 Mon Sep 17 00:00:00 2001 From: dzh Date: Thu, 18 Jul 2024 13:48:24 +0800 Subject: [PATCH 40/47] upg wxpay maven dep --- jframe-plugin/jframe-wxpay/pom.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/jframe-plugin/jframe-wxpay/pom.xml b/jframe-plugin/jframe-wxpay/pom.xml index 0d0e0bb..65de4ff 100644 --- a/jframe-plugin/jframe-wxpay/pom.xml +++ b/jframe-plugin/jframe-wxpay/pom.xml @@ -27,7 +27,12 @@ org.apache.httpcomponents httpclient - 4.5.13 + 4.5.14 + + + commons-codec + commons-codec + 1.16.1 + + + + + com.aliyun.openservices ons-client - 2.0.4.Final + 1.9.5.Final From 9aa96765441ff57aab1da5866190666bb4473424 Mon Sep 17 00:00:00 2001 From: dzh Date: Sun, 22 Jun 2025 16:46:46 +0800 Subject: [PATCH 42/47] add jframe-id,SnowflakeService --- .../jframe/datasource/DataSourcePlugin.java | 1 + jframe-plugin/jframe-id/pom.xml | 25 ++ .../jframe-id/snowflake-eg.properties | 20 ++ .../src/main/java/jframe/id/IdField.java | 31 ++ .../src/main/java/jframe/id/IdPlugin.java | 11 + .../java/jframe/id/service/IdService.java | 15 + .../id/service/SnowflakeIdGenerator.java | 201 +++++++++++++ .../jframe/id/service/SnowflakeService.java | 271 ++++++++++++++++++ .../main/resources/META-INF/plugin.properties | 4 + .../java/jframe/id/service/TestIDUtil.java | 51 ++++ .../zk/service/impl/CuratorServiceImpl.java | 5 +- jframe-plugin/pom.xml | 1 + 12 files changed, 633 insertions(+), 3 deletions(-) create mode 100644 jframe-plugin/jframe-id/pom.xml create mode 100644 jframe-plugin/jframe-id/snowflake-eg.properties create mode 100644 jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java create mode 100644 jframe-plugin/jframe-id/src/main/java/jframe/id/IdPlugin.java create mode 100644 jframe-plugin/jframe-id/src/main/java/jframe/id/service/IdService.java create mode 100644 jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java create mode 100644 jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java create mode 100644 jframe-plugin/jframe-id/src/main/resources/META-INF/plugin.properties create mode 100644 jframe-plugin/jframe-id/src/test/java/jframe/id/service/TestIDUtil.java diff --git a/jframe-plugin/jframe-datasource/src/main/java/jframe/datasource/DataSourcePlugin.java b/jframe-plugin/jframe-datasource/src/main/java/jframe/datasource/DataSourcePlugin.java index d3bd74c..3dfc527 100644 --- a/jframe-plugin/jframe-datasource/src/main/java/jframe/datasource/DataSourcePlugin.java +++ b/jframe-plugin/jframe-datasource/src/main/java/jframe/datasource/DataSourcePlugin.java @@ -13,4 +13,5 @@ */ @Plugin(startOrder = 1, stopOrder = 1000) public class DataSourcePlugin extends DefPlugin { + } diff --git a/jframe-plugin/jframe-id/pom.xml b/jframe-plugin/jframe-id/pom.xml new file mode 100644 index 0000000..b037bd0 --- /dev/null +++ b/jframe-plugin/jframe-id/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + io.github.dzh + jframe-plugin + 2.0.0-SNAPSHOT + + + jframe-id + + + + + + ${project.groupId} + jframe-zk + ${project.version} + plugin + + + + \ No newline at end of file diff --git a/jframe-plugin/jframe-id/snowflake-eg.properties b/jframe-plugin/jframe-id/snowflake-eg.properties new file mode 100644 index 0000000..b389747 --- /dev/null +++ b/jframe-plugin/jframe-id/snowflake-eg.properties @@ -0,0 +1,20 @@ +#snowflake id +#e.g. 2025-06-01T00:00:00Z +snowflake.epoch=${snowflake.epoch} +# +snowflake.datacenter.id=${snowflake.datacenter.id} +snowflake.worker.id=${snowflake.worker.id} +#bit number +snowflake.timestamp.bits=${snowflake.timestamp.bits} +snowflake.datacenter.bits=${snowflake.datacenter.bits} +snowflake.worker.bits=${snowflake.worker.bits} +snowflake.sequence.bits=${snowflake.sequence.bits} +# worker id generation:[zk,ip] +snowflake.worker.generation=zk +#worker's ip env name +snowflake.worker.env.ip=${snowflake.worker.env.ip} +#zk +snowflake.zk.id=${snowflake.zk.id} +snowflake.zk.worker.path=${snowflake.zk.path} + + diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java new file mode 100644 index 0000000..8715da9 --- /dev/null +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java @@ -0,0 +1,31 @@ +package jframe.id; + +/** + * @author dzh + * @date 2025/6/21 16:42 + */ +public interface IdField { + /******snowflake******/ + String SNOWFLAKE_EPOCH = "snowflake.epoch"; + String SNOWFLAKE_WORKER_ID = "snowflake.worker.id"; + String SNOWFLAKE_DATACENTER_ID = "snowflake.datacenter.id"; + // the number of binary digits + String SNOWFLAKE_TIMESTAMP_BITS = "snowflake.timestamp.bits"; + String SNOWFLAKE_DATACENTER_BITS = "snowflake.datacenter.bits"; + String SNOWFLAKE_WORKER_BITS = "snowflake.worker.bits"; + String SNOWFLAKE_SEQUENCE_BITS = "snowflake.sequence.bits"; + // worker id generation method + String SNOWFLAKE_WORKER_GENERATION = "SNOWFLAKE.WORKER.generation"; + String SNOWFLAKE_WORKER_ENV_IP = "snowflake.worker.env.ip";//worker's ip environment variable name + // zk + String SNOWFLAKE_ZK_ID = "snowflake.zk.id"; // jframe-zk curator group id + String SNOWFLAKE_ZK_WORKER_PATH = "snowflake.zk.worker.path"; + // + String GENERATION_IP = "ip"; + String GENERATION_ZK = "zk"; + //default env name + String ENV_HOST_IP = "HOST_IP"; + //default zk id + String ZK_ID = "snowflake"; + String ZK_WORKER_PATH = "/snowflake/worker_ids"; +} diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdPlugin.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdPlugin.java new file mode 100644 index 0000000..6d90c76 --- /dev/null +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdPlugin.java @@ -0,0 +1,11 @@ +package jframe.id; + +import jframe.core.plugin.DefPlugin; + +/** + * @author dzh + * @date 2025/6/21 16:10 + */ +public class IdPlugin extends DefPlugin { + +} diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/IdService.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/IdService.java new file mode 100644 index 0000000..2379dff --- /dev/null +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/IdService.java @@ -0,0 +1,15 @@ +package jframe.id.service; + +import jframe.core.plugin.annotation.Service; + +/** + * @author dzh + * @date 2025/6/21 16:10 + */ +@Service(clazz = "jframe.id.service.SnowflakeService", id = IdService.ID) +public interface IdService { + + String ID = "jframe.service.id"; + + long nextId(); +} diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java new file mode 100644 index 0000000..34fc512 --- /dev/null +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java @@ -0,0 +1,201 @@ +package jframe.id.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; +import java.util.concurrent.atomic.AtomicLong; + +/** + * +------------------+----------------+----------------+----------------+ + * | 1位符号位 | 41位时间戳 | 5位数据中心ID | 5位机器ID | 12位序列号 | + * +------------------+----------------+----------------+----------------+ + * 雪花算法 ID 结构 + * 一个标准的雪花算法 ID 由以下部分组成(总长度 64 位): + * 部分 位数 说明 + * 符号位 1 位 固定为 0,表示正数 + * 时间戳 41 位 记录生成 ID 的时间戳(毫秒级),支持约 69 年的时间范围 + * 工作机器 ID 10 位 用于标识不同的机器节点,最多支持 1024 个节点(5 位数据中心 ID + 5 位机器 ID) + * 序列号 12 位 同一毫秒内生成的不同 ID,每毫秒最多生成 4096 个 ID + *

    + *

    + * 组合 数据中心数 每中心机器数 全局总机器数 适用场景 + * 5+5 32 32 1,024 中小型分布式系统 + * 4+6 16 64 1,024 数据中心少但规模大 + * 3+7 8 128 1,024 容器化环境(Pod 动态创建) + * 2+10 4 1,024 4,096 超大规模单数据中心 + * + * @author dzh + * @date 2025/6/19 23:12 + */ +public class SnowflakeIdGenerator { + + private static final Logger LOG = LoggerFactory.getLogger(SnowflakeIdGenerator.class); + // 开始时间戳 e.g. Instant.parse("2025-06-01T00:00:00Z").toEpochMilli(); + private final long epoch; + // 位移定义 +// private final int timestampBits; // 扩展为42位,支持138年 +// private final int dataCenterIdBits; +// private final int workerIdBits; +// private final int sequenceBits; + + //左移位数 +// private final int workerIdShift; +// private final int dataCenterIdShift; + private final int timestampShift; + + // 计算时间戳上限(毫秒) + private final long maxTimestamp; + //~(-1L << dataCenterIdBits) +// private long maxDataCenterId = (1L << dataCenterIdBits) - 1;//8 + //~(-1L << workerIdBits) +// private long maxWorkerId = (1L << workerIdBits) - 1;//64 + // ~(-1L << sequenceBits); + private final long maxSequence;// 4095 + + // 左移后的值 + private final long dataCenterIdOffset; + private final long workerIdOffset; + + // 使用原子变量替代普通变量 + private final AtomicLong lastTimestamp = new AtomicLong(-1); + private final AtomicLong sequence = new AtomicLong(0); + + // 单例模式:使用静态内部类实现延迟加载和线程安全 +// private static class SingletonHolder { +// private static final SnowflakeIdGenerator INSTANCE; +// +// static { +// try { +// // 从机器IP自动生成dataCenterId和workerId +// INSTANCE = new SnowflakeIdGenerator(); +// } catch (Exception e) { +// throw new RuntimeException("Failed to initialize SnowflakeIdGenerator", e); +// } +// } +// } + + // 获取单例实例的静态方法 +// public static SnowflakeIdGenerator getInstance() { +// return SingletonHolder.INSTANCE; +// } + + // 私有构造函数,防止外部实例化 + public SnowflakeIdGenerator(String epoch, long dataCenterId, long workerId, int timestampBits, int dataCenterIdBits, int workerIdBits, int sequenceBits) throws Exception { + if (epoch == null || epoch.isEmpty()) throw new IllegalArgumentException("epoch is empty"); + this.epoch = Instant.parse(epoch).toEpochMilli(); + + int sunBits = timestampBits + dataCenterIdBits + workerIdBits + sequenceBits; + if (sunBits != 63) { + throw new IllegalArgumentException("timestampBits+dataCenterId+workerIdBits+sequenceBits != 63,sumBits=" + sunBits); + } + //设置左移数量 + int workerIdShift = sequenceBits; + int dataCenterIdShift = sequenceBits + workerIdBits; + this.timestampShift = sequenceBits + workerIdBits + dataCenterIdBits; + // 计算时间戳上限(毫秒) + this.maxTimestamp = (1L << timestampBits) - 1; + // 计算最大序列号 + this.maxSequence = (1L << sequenceBits) - 1;// 4095 + + long maxDataCenterId = (1L << dataCenterIdBits) - 1;//8 + // 校验生成的ID + if (dataCenterId > maxDataCenterId || dataCenterId < 0) { + throw new IllegalArgumentException("Invalid dataCenterId: " + dataCenterId); + } + long maxWorkerId = (1L << workerIdBits) - 1;//64 + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException("Invalid workerId: " + workerId); + } + this.dataCenterIdOffset = dataCenterId << dataCenterIdShift; + this.workerIdOffset = workerId << workerIdShift; + + LOG.info("new SnowflakeIdGenerator(epoch={}, dataCenterId={}, workerId={}, timestampBits={}, dataCenterIdBits={}, workerIdBits={}, sequenceBits={})", epoch, dataCenterId, workerId, timestampBits, dataCenterIdBits, workerIdBits, sequenceBits); +// LOG.info("SnowflakeIdGenerator initialized with DataCenterID: {}, workerId: {}", dataCenterId, workerId); + } + + // 无锁化ID生成方法(保持不变) + public long nextId() { + long currentTimestamp = System.currentTimeMillis(); + + // 检查时间戳是否超出限制 + long elapsedTime = currentTimestamp - epoch; + if (elapsedTime > maxTimestamp) { + throw new RuntimeException("Timestamp limit exceeded: " + elapsedTime + "ms"); + } + + long oldTimestamp; + long oldSequence; + long newSequence; + // 处理时钟回拨(先检查再获取锁) + if (currentTimestamp < lastTimestamp.get()) { + throw new RuntimeException("Clock moved backwards..."); + } + + // 无锁循环CAS更新序列号 + do { + oldTimestamp = lastTimestamp.get(); + + if (currentTimestamp > oldTimestamp) { + // 新的毫秒,重置序列号 + if (sequence.compareAndSet(sequence.get(), 0)) { + break; + } + } else if (currentTimestamp == oldTimestamp) { + // 同一毫秒,尝试递增序列号 + oldSequence = sequence.get(); + newSequence = (oldSequence + 1) & maxSequence; + if (newSequence == 0) { + // 序列号用尽,等待下一毫秒 + currentTimestamp = waitNextMillis(oldTimestamp); + continue; + } + if (sequence.compareAndSet(oldSequence, newSequence)) { + break; + } + } else { + // currentTimestamp < oldTimestamp 已在前面处理 + throw new IllegalStateException("Invalid timestamp state"); + } + } while (true); + + // 更新lastTimestamp(使用CAS保证原子性) + if (!lastTimestamp.compareAndSet(oldTimestamp, currentTimestamp)) { + throw new IllegalStateException("Failed to update timestamp"); + } + + // 生成ID + return ((currentTimestamp - epoch) << timestampShift) | this.dataCenterIdOffset | this.workerIdOffset | sequence.get(); + } + + // 等待下一毫秒(保持不变) + private long waitNextMillis(long lastTimestamp) { + long timestamp = System.currentTimeMillis(); + while (timestamp <= lastTimestamp) { + timestamp = System.currentTimeMillis(); + } + return timestamp; + } + + @Override + public String toString() { +// String date = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT).withZone(ZoneId.of("UTC")).format(Instant.ofEpochMilli(epoch)); + String date = Instant.ofEpochMilli(epoch).toString(); + return String.format("epoch=%s, dataCenterIdOffset=%s, workerIdOffset=%s, timestampShift=%s, maxTimestamp=%s, maxSequence=%s", date, dataCenterIdOffset, workerIdOffset, timestampShift, maxTimestamp, maxSequence); + } + + // 测试示例 +// public static void main(String[] args) { +// // 获取单例实例并生成ID +// try { +// SnowflakeIdGenerator generator = new SnowflakeIdGenerator(); +// // 生成10个ID测试 +// for (int i = 0; i < 10; i++) { +// System.out.println(generator.nextId()); +// } +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// +// } +} diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java new file mode 100644 index 0000000..5283a23 --- /dev/null +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java @@ -0,0 +1,271 @@ +package jframe.id.service; + +import jframe.core.conf.Config; +import jframe.core.plugin.annotation.*; +import jframe.core.util.PropsConf; +import jframe.id.IdField; +import jframe.id.IdPlugin; +import jframe.zk.service.CuratorService; +import org.apache.curator.framework.CuratorFramework; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.KeeperException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author dzh + * @date 2025/6/21 16:12 + */ +@Injector +public class SnowflakeService implements IdService { + + static Logger LOG = LoggerFactory.getLogger(SnowflakeService.class); + + @InjectPlugin + static IdPlugin Plugin; + + @InjectService(id = CuratorService.ID) + static CuratorService ZK; + + static String FILE_SNOWFLAKE = "file.snowflake"; + + static PropsConf _config = new PropsConf(); + + static SnowflakeIdGenerator _generator; + + private long workerId; + + @Start + void start() { + LOG.info("SnowflakeService startup..."); + + try { + String file = Plugin.getConfig(FILE_SNOWFLAKE, Plugin.getConfig(Config.APP_CONF) + "/snowflake.properties"); + if (!new File(file).exists()) { + throw new FileNotFoundException("not found " + file); + } + _config.init(file); + LOG.info("load snowflake config {}", _config); + + this.workerId = workerId(); + _generator = new SnowflakeIdGenerator(epoch(), dataCenterId(), this.workerId, timestampBits(), dataCenterBits(), workerBits(), sequenceBits()); + } catch (Exception e) { + LOG.error("SnowflakeService startup failed!", e); + return; + } + LOG.info("SnowflakeService startup success!"); + } + + + protected String epoch() { + return _config.getConf(null, IdField.SNOWFLAKE_EPOCH, "2025-06-01T00:00:00Z"); + } + + protected long dataCenterId() { + return _config.getConfLong(null, IdField.SNOWFLAKE_DATACENTER_ID, "0"); + } + + protected long workerId() { + String workerGeneration = _config.getConf(null, IdField.SNOWFLAKE_WORKER_GENERATION, ""); + switch (workerGeneration) { + case IdField.GENERATION_IP: + return generateWorkerIdFromIP(); + case IdField.GENERATION_ZK: + return generateWorkerIdFromZK(); + default: + return _config.getConfLong(null, IdField.SNOWFLAKE_WORKER_ID, "0"); + } + } + + private boolean isZK() { + String workerGeneration = _config.getConf(null, IdField.SNOWFLAKE_WORKER_GENERATION, ""); + return IdField.GENERATION_ZK.equals(workerGeneration); + } + + protected String zkId() { + return _config.getConf(null, IdField.SNOWFLAKE_ZK_ID, IdField.ZK_ID); + } + + protected String workerZKPath() { + return _config.getConf(null, IdField.SNOWFLAKE_ZK_WORKER_PATH, IdField.ZK_WORKER_PATH); + } + + protected long generateWorkerIdFromZK() { + try { + CuratorFramework zk = ZK.client(zkId()); + String workerIdPath = workerZKPath(); //parent path + if (zk.checkExists().forPath(workerIdPath) == null) { + zk.create().creatingParentsIfNeeded().forPath(workerIdPath); + } + // 获取当前所有已分配的ID + List existingNodes = zk.getChildren().forPath(workerIdPath); + LOG.info("existing workers {}", existingNodes); + Set usedIds = new HashSet<>(); + // 解析现有节点中的ID + for (String node : existingNodes) { + try { + long id = Long.parseLong(node.substring("worker-".length())); + usedIds.add(id); + } catch (NumberFormatException e) { + LOG.error(e.getMessage(), e); + } + } + long maxWorkerId = maxWorkerId(); + // 查找最小的可用ID + for (long id = 0; id <= maxWorkerId; id++) { + if (!usedIds.contains(id)) { + // 尝试创建该ID对应的节点 + String path = workerIdZKPath(id); + try { + zk.create().withMode(CreateMode.EPHEMERAL).forPath(path); + LOG.info("generate workerId {} from zk {}", id, path); + return id; + } catch (KeeperException.NodeExistsException e) { + // 另一个进程可能已经占用了这个ID,继续尝试下一个 + LOG.warn(e.getMessage(), e); + continue; + } + } + } + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + return -1L; + } + + protected long generateWorkerIdFromIP() { + String ip = ip(); + if (ip == null || ip.isEmpty()) { + LOG.error("No valid non-loopback IP address found"); + return -1L; + } + + // 解析IP地址的最后两段 + String[] parts = ip.split("\\."); + if (parts.length != 4) { + throw new IllegalArgumentException("Invalid IPv4 address: " + ip); + } + + // 提取最后两段作为基础 + int segment3 = Integer.parseInt(parts[2]); + int segment4 = Integer.parseInt(parts[3]); + + // 使用简单的哈希算法生成唯一ID,这里使用异或和移位确保分布更均匀 +// long dataCenterId = (segment3 ^ ((long) segment4 << 4)) % (maxDataCenterId() + 1); + long workerId = (segment4 ^ ((long) segment3 << 4)) % (maxWorkerId() + 1); + // 确保生成的ID为正数 +// dataCenterId = Math.abs(dataCenterId); + workerId = Math.abs(workerId); + +// LOG.info("generateDataCenterAndworkerId {} {} {}", ip, dataCenterId, workerId); +// return new long[]{dataCenterId, workerId}; + return workerId; + } + + + protected int timestampBits() { + return _config.getConfInt(null, IdField.SNOWFLAKE_TIMESTAMP_BITS, "41"); + } + + protected int dataCenterBits() { + return _config.getConfInt(null, IdField.SNOWFLAKE_DATACENTER_BITS, "5"); + } + + protected int workerBits() { + return _config.getConfInt(null, IdField.SNOWFLAKE_WORKER_BITS, "5"); + } + + protected int sequenceBits() { + return _config.getConfInt(null, IdField.SNOWFLAKE_SEQUENCE_BITS, "12"); + } + + @Override + public long nextId() { + return _generator.nextId(); + } + + protected String ip() { + String ip = System.getenv(ipEnv()); + if (ip == null || ip.isEmpty()) { + try { + ip = nonLoopbackIP(); + } catch (SocketException e) { + LOG.error(e.getMessage(), e); + } + } + return ip; + } + + protected String ipEnv() { + return _config.getConf(null, IdField.SNOWFLAKE_WORKER_ENV_IP, IdField.ENV_HOST_IP); + } + + // 获取非回环IP地址(保持不变) + public static String nonLoopbackIP() throws SocketException { + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + + while (interfaces.hasMoreElements()) { + NetworkInterface ni = interfaces.nextElement(); + if (ni.isUp() && !ni.isLoopback() && !ni.isVirtual()) { + Enumeration addresses = ni.getInetAddresses(); + while (addresses.hasMoreElements()) { + InetAddress addr = addresses.nextElement(); + //todo 这个判断是否正确 + if (!addr.isLoopbackAddress() && addr.getHostAddress().indexOf(':') == -1) { + return addr.getHostAddress(); + } + } + } + } + + return null; + } + + public long maxWorkerId() { + int workerIdBits = workerBits(); + return (1L << workerIdBits) - 1; + } + + public long maxDataCenterId() { + int dataCenterIdBits = dataCenterBits(); + return (1L << dataCenterIdBits) - 1; + } + + @Stop + void stop() { + if (isZK()) { + releaseWorkerId(workerId); + } + } + + public String workerIdZKPath(long workerId) { + String workerIdPath = workerZKPath(); + return workerIdPath + "/worker-" + String.format("%010d", workerId); + } + + private void releaseWorkerId(long workerId) { + String path = workerIdZKPath(workerId); + try { + CuratorFramework zk = ZK.client(zkId()); + if (zk.checkExists().forPath(path) != null) { + zk.delete().forPath(path); + LOG.info("Worker ID {} released successfully", workerId); + } else { + LOG.warn("Worker ID {} already deleted", workerId); + } + } catch (Exception e) { + LOG.error("Failed to release worker ID {}", workerId, e); + } + } + +} diff --git a/jframe-plugin/jframe-id/src/main/resources/META-INF/plugin.properties b/jframe-plugin/jframe-id/src/main/resources/META-INF/plugin.properties new file mode 100644 index 0000000..7c6d6e4 --- /dev/null +++ b/jframe-plugin/jframe-id/src/main/resources/META-INF/plugin.properties @@ -0,0 +1,4 @@ +Plugin-Name=jframe.id.IdPlugin +Plugin-Class=jframe.id.IdPlugin +Plugin-Service=jframe.id.service.IdService +Import-Class=jframe.zk.service.CuratorService \ No newline at end of file diff --git a/jframe-plugin/jframe-id/src/test/java/jframe/id/service/TestIDUtil.java b/jframe-plugin/jframe-id/src/test/java/jframe/id/service/TestIDUtil.java new file mode 100644 index 0000000..e13c959 --- /dev/null +++ b/jframe-plugin/jframe-id/src/test/java/jframe/id/service/TestIDUtil.java @@ -0,0 +1,51 @@ +package jframe.id.service; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + +/** + * @author dzh + * @date 2025/6/20 00:28 + */ +public class TestIDUtil { + + static Logger LOG = LoggerFactory.getLogger(TestIDUtil.class); + + @Test + public void testSnowflake() throws Exception { + SnowflakeIdGenerator id = new SnowflakeIdGenerator("2025-06-01T00:00:00Z", 0, 1, 41, 5, 5, 12); + LOG.info("id generator: {}", id); + for (int i = 0; i < 6; i++) { + LOG.info("{} {}", i, id.nextId()); + } + } + + @Test + public void decodeID() { + long id = 7738971916341248L; + long epoch = Instant.parse("2025-06-01T00:00:00Z").toEpochMilli(); + long currentTime = id >> 22 + epoch; + LOG.info("{} {}", currentTime, Instant.ofEpochMilli(currentTime).toString()); + } + + @Test + public void testZkWorkerPath() { + SnowflakeService sfs = new SnowflakeService(); + String workerPath = sfs.workerIdZKPath(1); + LOG.info("workerPath: {}", workerPath); + } + + @Test + public void testEpoch() { + long epoch = System.currentTimeMillis(); + String date = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT).withZone(ZoneId.of("UTC")).format(Instant.ofEpochMilli(epoch)); + LOG.info("{} {} {}", epoch, date, Instant.ofEpochMilli(epoch).toString()); + } + +} diff --git a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java index 0fbc37a..60b3cd5 100644 --- a/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java +++ b/jframe-plugin/jframe-zk/src/main/java/jframe/zk/service/impl/CuratorServiceImpl.java @@ -64,8 +64,7 @@ void start() { int retryInterval = _config.getConfInt(id, ZkField.RetryInterval, "5000"); int retryTimes = _config.getConfInt(id, ZkField.RetryTimes, "3"); RetryPolicy retryPolicy = new ExponentialBackoffRetry(retryInterval, retryTimes); - CuratorFramework zkCli = CuratorFrameworkFactory.builder().connectString(connectString).retryPolicy(retryPolicy) - .connectionTimeoutMs(connectTimeout).sessionTimeoutMs(sessionTimeout).namespace(ns).build(); + CuratorFramework zkCli = CuratorFrameworkFactory.builder().connectString(connectString).retryPolicy(retryPolicy).connectionTimeoutMs(connectTimeout).sessionTimeoutMs(sessionTimeout).namespace(ns).build(); try { zkCli.start(); zkCli.blockUntilConnected(10, TimeUnit.SECONDS); @@ -76,7 +75,7 @@ void start() { if (zkCli.getState() == CuratorFrameworkState.STARTED) clients.put(id, zkCli); } } catch (Exception e) { - LOG.error("Start CuratorService Failure!" + e.getMessage(), e); + LOG.error("Start CuratorService Failure!", e); return; } LOG.info("Start CuratorService Successfully!"); diff --git a/jframe-plugin/pom.xml b/jframe-plugin/pom.xml index e8dddbf..102f6da 100644 --- a/jframe-plugin/pom.xml +++ b/jframe-plugin/pom.xml @@ -45,6 +45,7 @@ jframe-google jframe-alipay jframe-wxpay + jframe-id From d8fac302d5b0904d12e0aca1900bbfbb207fb364 Mon Sep 17 00:00:00 2001 From: dzh Date: Sun, 22 Jun 2025 16:53:48 +0800 Subject: [PATCH 43/47] opt eg file --- jframe-plugin/jframe-id/snowflake-eg.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jframe-plugin/jframe-id/snowflake-eg.properties b/jframe-plugin/jframe-id/snowflake-eg.properties index b389747..535b902 100644 --- a/jframe-plugin/jframe-id/snowflake-eg.properties +++ b/jframe-plugin/jframe-id/snowflake-eg.properties @@ -10,11 +10,11 @@ snowflake.datacenter.bits=${snowflake.datacenter.bits} snowflake.worker.bits=${snowflake.worker.bits} snowflake.sequence.bits=${snowflake.sequence.bits} # worker id generation:[zk,ip] -snowflake.worker.generation=zk +snowflake.worker.generation=${snowflake.worker.generation} #worker's ip env name snowflake.worker.env.ip=${snowflake.worker.env.ip} #zk snowflake.zk.id=${snowflake.zk.id} -snowflake.zk.worker.path=${snowflake.zk.path} +snowflake.zk.worker.path=${snowflake.zk.worker.path} From ff3d25836999204045993bb60c01af2b423a23cc Mon Sep 17 00:00:00 2001 From: dzh Date: Sun, 22 Jun 2025 21:30:50 +0800 Subject: [PATCH 44/47] add disabled option for snowflake --- jframe-plugin/jframe-id/snowflake-eg.properties | 2 ++ .../jframe-id/src/main/java/jframe/id/IdField.java | 1 + .../src/main/java/jframe/id/service/SnowflakeService.java | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/jframe-plugin/jframe-id/snowflake-eg.properties b/jframe-plugin/jframe-id/snowflake-eg.properties index 535b902..274c043 100644 --- a/jframe-plugin/jframe-id/snowflake-eg.properties +++ b/jframe-plugin/jframe-id/snowflake-eg.properties @@ -1,4 +1,6 @@ #snowflake id +#default false,service disabled if true +#snowflake.disabled=${snowflake.disabled} #e.g. 2025-06-01T00:00:00Z snowflake.epoch=${snowflake.epoch} # diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java index 8715da9..d04d90f 100644 --- a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java @@ -6,6 +6,7 @@ */ public interface IdField { /******snowflake******/ + String SNOWFLAKE_DISABLED = "snowflake.disabled";//default false String SNOWFLAKE_EPOCH = "snowflake.epoch"; String SNOWFLAKE_WORKER_ID = "snowflake.worker.id"; String SNOWFLAKE_DATACENTER_ID = "snowflake.datacenter.id"; diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java index 5283a23..d69b4ae 100644 --- a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java @@ -57,6 +57,10 @@ void start() { _config.init(file); LOG.info("load snowflake config {}", _config); + if (disabled()) { + LOG.info("SnowflakeService is disabled"); + return; + } this.workerId = workerId(); _generator = new SnowflakeIdGenerator(epoch(), dataCenterId(), this.workerId, timestampBits(), dataCenterBits(), workerBits(), sequenceBits()); } catch (Exception e) { @@ -66,6 +70,9 @@ void start() { LOG.info("SnowflakeService startup success!"); } + protected boolean disabled() { + return _config.getConfBool(null, IdField.SNOWFLAKE_DISABLED, "false"); + } protected String epoch() { return _config.getConf(null, IdField.SNOWFLAKE_EPOCH, "2025-06-01T00:00:00Z"); @@ -191,6 +198,7 @@ protected int sequenceBits() { @Override public long nextId() { + if (_generator == null || disabled()) return 0L; return _generator.nextId(); } From 52332e2d7e694d07c534c96380c58168a7b4763d Mon Sep 17 00:00:00 2001 From: dzh Date: Sun, 22 Jun 2025 23:33:42 +0800 Subject: [PATCH 45/47] fix PropsConf val is empty --- .../jframe-id/snowflake-eg.properties | 2 +- .../src/main/java/jframe/id/IdField.java | 6 +- .../jframe/id/service/SnowflakeService.java | 13 ++-- .../java/jframe/core/conf/VarHandler.java | 23 +++---- .../main/java/jframe/core/util/PropsConf.java | 69 +++++++------------ 5 files changed, 48 insertions(+), 65 deletions(-) diff --git a/jframe-plugin/jframe-id/snowflake-eg.properties b/jframe-plugin/jframe-id/snowflake-eg.properties index 274c043..be2e3f0 100644 --- a/jframe-plugin/jframe-id/snowflake-eg.properties +++ b/jframe-plugin/jframe-id/snowflake-eg.properties @@ -12,7 +12,7 @@ snowflake.datacenter.bits=${snowflake.datacenter.bits} snowflake.worker.bits=${snowflake.worker.bits} snowflake.sequence.bits=${snowflake.sequence.bits} # worker id generation:[zk,ip] -snowflake.worker.generation=${snowflake.worker.generation} +snowflake.worker.generator=${snowflake.worker.generator} #worker's ip env name snowflake.worker.env.ip=${snowflake.worker.env.ip} #zk diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java index d04d90f..4156811 100644 --- a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java @@ -16,14 +16,14 @@ public interface IdField { String SNOWFLAKE_WORKER_BITS = "snowflake.worker.bits"; String SNOWFLAKE_SEQUENCE_BITS = "snowflake.sequence.bits"; // worker id generation method - String SNOWFLAKE_WORKER_GENERATION = "SNOWFLAKE.WORKER.generation"; + String SNOWFLAKE_WORKER_GENERATOR = "SNOWFLAKE.WORKER.generator"; String SNOWFLAKE_WORKER_ENV_IP = "snowflake.worker.env.ip";//worker's ip environment variable name // zk String SNOWFLAKE_ZK_ID = "snowflake.zk.id"; // jframe-zk curator group id String SNOWFLAKE_ZK_WORKER_PATH = "snowflake.zk.worker.path"; // - String GENERATION_IP = "ip"; - String GENERATION_ZK = "zk"; + String WORK_GENERATOR_IP = "ip"; + String WORK_GENERATOR_ZK = "zk"; //default env name String ENV_HOST_IP = "HOST_IP"; //default zk id diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java index d69b4ae..3c88256 100644 --- a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeService.java @@ -83,11 +83,11 @@ protected long dataCenterId() { } protected long workerId() { - String workerGeneration = _config.getConf(null, IdField.SNOWFLAKE_WORKER_GENERATION, ""); - switch (workerGeneration) { - case IdField.GENERATION_IP: + String workerGenerator = _config.getConf(null, IdField.SNOWFLAKE_WORKER_GENERATOR, ""); + switch (workerGenerator) { + case IdField.WORK_GENERATOR_IP: return generateWorkerIdFromIP(); - case IdField.GENERATION_ZK: + case IdField.WORK_GENERATOR_ZK: return generateWorkerIdFromZK(); default: return _config.getConfLong(null, IdField.SNOWFLAKE_WORKER_ID, "0"); @@ -95,10 +95,11 @@ protected long workerId() { } private boolean isZK() { - String workerGeneration = _config.getConf(null, IdField.SNOWFLAKE_WORKER_GENERATION, ""); - return IdField.GENERATION_ZK.equals(workerGeneration); + String workerGenerator = _config.getConf(null, IdField.SNOWFLAKE_WORKER_GENERATOR, ""); + return IdField.WORK_GENERATOR_ZK.equals(workerGenerator); } + // jframe-zk curator group id protected String zkId() { return _config.getConf(null, IdField.SNOWFLAKE_ZK_ID, IdField.ZK_ID); } diff --git a/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java b/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java index 2717bbc..f707c06 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java +++ b/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.core.conf; @@ -7,7 +7,7 @@ import java.util.regex.Pattern; /** - * + * * @author dzh * @date Oct 11, 2013 1:12:37 PM * @since 1.0 @@ -16,7 +16,7 @@ public class VarHandler { public static final Pattern P_VAR = Pattern.compile(Config.REGEX_VAR, Pattern.CASE_INSENSITIVE); - private Config _config; + private final Config _config; public VarHandler(Config config) { this._config = config; @@ -24,20 +24,19 @@ public VarHandler(Config config) { /** * 利用config中的变量值,替换value里的变量 - * - * @param v - * @return + * + * @param input 待替换的字符串 + * @return 替换后的字符串 */ public String replace(String input) { return replace(_config, input); } /** - * - * @param system - * jvm系统变量,一般是System.getProperty - * @param input - * @return + * + * @param config system jvm系统变量,一般是System.getProperty + * @param input 待替换的字符串 + * @return 替换后的字符串 */ public String replace(Config config, String input) { Matcher m = P_VAR.matcher(input); @@ -51,7 +50,7 @@ public String replace(Config config, String input) { continue; } - input = input.replaceAll("\\$\\{" + var + "\\}", val); + input = input.replaceAll("\\$\\{" + var + "}", val); } return input; } diff --git a/jframe/jframe-core/src/main/java/jframe/core/util/PropsConf.java b/jframe/jframe-core/src/main/java/jframe/core/util/PropsConf.java index 1826d53..01bf08b 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/util/PropsConf.java +++ b/jframe/jframe-core/src/main/java/jframe/core/util/PropsConf.java @@ -1,21 +1,21 @@ /** - * + * */ package jframe.core.util; -import java.io.FileInputStream; +import jframe.core.conf.VarHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jframe.core.conf.VarHandler; - /** *

    * Feature: @@ -23,7 +23,7 @@ *

  • 属性值支持jframe配置变量${conf.key}
  • *
  • 属性查询优先级,自定义ID->默认组
  • *

    - * + * * @author dzh * @date Nov 17, 2014 4:52:33 PM * @since 1.0 @@ -37,11 +37,7 @@ public class PropsConf { public synchronized void init(String file) throws Exception { if (init) return; - try { - init(new FileInputStream(file)); - } catch (Exception e) { - throw e; - } + init(Files.newInputStream(Paths.get(file))); init = true; } @@ -50,7 +46,7 @@ public synchronized void init(String file) throws Exception { public synchronized void init(InputStream is) throws Exception { if (is == null || init) return; - conf = new HashMap(); + conf = new HashMap<>(); try { Properties p = new Properties(); p.load(is); @@ -58,8 +54,6 @@ public synchronized void init(InputStream is) throws Exception { for (Entry e : p.entrySet()) { conf.put((String) e.getKey(), String.valueOf(e.getValue()).trim()); } - } catch (Exception e) { - throw e; } finally { is.close(); } @@ -67,9 +61,7 @@ public synchronized void init(InputStream is) throws Exception { public synchronized void replace(VarHandler vh) { if (conf.isEmpty()) return; - for (Entry e : conf.entrySet()) { - conf.put(e.getKey(), vh.replace(e.getValue())); - } + conf.replaceAll((k, v) -> vh.replace(v)); } public synchronized String[] getGroupIds() { @@ -79,29 +71,20 @@ public synchronized String[] getGroupIds() { } /** - * - * @param group - * @param key + * + * @param group group id + * @param key key * @return "" if not matched value or value */ public synchronized String getConf(String group, String key) { - if (conf.isEmpty()) return ""; - String val = null; - if (group != null) { - val = conf.get("@" + group + "." + key); - } - - if (val == null) { - val = conf.get(key); - } - return val == null ? "" : val; + return getConf(group, key, ""); } /** - * - * @param group - * @param key - * @param defVal + * + * @param group group id + * @param key key + * @param defVal default value * @return defVal if not matched value or value */ public synchronized String getConf(String group, String key, String defVal) { @@ -114,25 +97,25 @@ public synchronized String getConf(String group, String key, String defVal) { if (val == null) { val = conf.get(key); } - return val == null ? defVal : val; + return val == null || val.isEmpty() ? defVal : val; } public synchronized int getConfInt(String group, String key, String defVal) { String val = getConf(group, key, defVal); - if (val == null) return -1; - return Integer.parseInt(val); + if (val == null || val.isEmpty()) return -1; + return Integer.parseInt(val.trim()); } public synchronized boolean getConfBool(String group, String key, String defVal) { String val = getConf(group, key, defVal); - if (val == null) return false; - return Boolean.parseBoolean(val); + if (val == null || val.isEmpty()) return false; + return Boolean.parseBoolean(val.trim()); } public synchronized long getConfLong(String group, String key, String defVal) { String val = getConf(group, key, defVal); - if (val == null) return -1; - return Long.parseLong(val); + if (val == null || val.isEmpty()) return -1; + return Long.parseLong(val.trim()); } public synchronized Properties clone2Properties() { From ec80d43c0fab299e972db2b1c48bb264edadb18d Mon Sep 17 00:00:00 2001 From: dzh Date: Sun, 22 Jun 2025 23:51:37 +0800 Subject: [PATCH 46/47] fix VarHandler replace --- .../jframe-core/src/main/java/jframe/core/conf/VarHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java b/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java index f707c06..6ca0aba 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java +++ b/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java @@ -39,6 +39,7 @@ public String replace(String input) { * @return 替换后的字符串 */ public String replace(Config config, String input) { + if (input == null || input.isEmpty()) return input; Matcher m = P_VAR.matcher(input); String var = null; String val = null; @@ -50,7 +51,7 @@ public String replace(Config config, String input) { continue; } - input = input.replaceAll("\\$\\{" + var + "}", val); + input = input.replaceAll("\\$\\{" + var + "\\}", val); } return input; } From 35e9039dc295631aa024dc8d30530ebf40e611d1 Mon Sep 17 00:00:00 2001 From: dzh Date: Mon, 23 Jun 2025 00:43:40 +0800 Subject: [PATCH 47/47] opt VarHandler replaceVar --- .../src/main/java/jframe/id/IdField.java | 2 +- .../id/service/SnowflakeIdGenerator.java | 2 +- .../src/main/java/jframe/core/DefFrame.java | 28 ++++++++++--------- .../java/jframe/core/conf/VarHandler.java | 3 ++ .../java/jframe/core/unit/UnitManager.java | 19 ++++++------- .../src/main/java/jframe/launcher/Main.java | 16 +++++------ .../jframe/launcher/util/VarProperties.java | 24 ++++++++-------- 7 files changed, 48 insertions(+), 46 deletions(-) diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java index 4156811..8021420 100644 --- a/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/IdField.java @@ -16,7 +16,7 @@ public interface IdField { String SNOWFLAKE_WORKER_BITS = "snowflake.worker.bits"; String SNOWFLAKE_SEQUENCE_BITS = "snowflake.sequence.bits"; // worker id generation method - String SNOWFLAKE_WORKER_GENERATOR = "SNOWFLAKE.WORKER.generator"; + String SNOWFLAKE_WORKER_GENERATOR = "snowflake.worker.generator"; String SNOWFLAKE_WORKER_ENV_IP = "snowflake.worker.env.ip";//worker's ip environment variable name // zk String SNOWFLAKE_ZK_ID = "snowflake.zk.id"; // jframe-zk curator group id diff --git a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java index 34fc512..9febdfd 100644 --- a/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java +++ b/jframe-plugin/jframe-id/src/main/java/jframe/id/service/SnowflakeIdGenerator.java @@ -110,7 +110,7 @@ public SnowflakeIdGenerator(String epoch, long dataCenterId, long workerId, int this.dataCenterIdOffset = dataCenterId << dataCenterIdShift; this.workerIdOffset = workerId << workerIdShift; - LOG.info("new SnowflakeIdGenerator(epoch={}, dataCenterId={}, workerId={}, timestampBits={}, dataCenterIdBits={}, workerIdBits={}, sequenceBits={})", epoch, dataCenterId, workerId, timestampBits, dataCenterIdBits, workerIdBits, sequenceBits); + LOG.info("SnowflakeIdGenerator(epoch={}, dataCenterId={}, workerId={}, timestampBits={}, dataCenterIdBits={}, workerIdBits={}, sequenceBits={})", epoch, dataCenterId, workerId, timestampBits, dataCenterIdBits, workerIdBits, sequenceBits); // LOG.info("SnowflakeIdGenerator initialized with DataCenterID: {}, workerId: {}", dataCenterId, workerId); } diff --git a/jframe/jframe-core/src/main/java/jframe/core/DefFrame.java b/jframe/jframe-core/src/main/java/jframe/core/DefFrame.java index 293da3b..559f755 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/DefFrame.java +++ b/jframe/jframe-core/src/main/java/jframe/core/DefFrame.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.core; @@ -15,8 +15,8 @@ import jframe.core.unit.UnitManager; /** - * @ThreadSafe * @author dzh + * @ThreadSafe * @date Sep 23, 2013 2:44:01 PM * @since 1.0 */ @@ -46,7 +46,7 @@ public boolean init(Config conf) { _status = FRAME_STATUS.INIT; } - LOG.debug("DefFrame is initing"); + LOG.debug("DefFrame init"); conf.setFrame(this); this._cnf = conf; @@ -94,7 +94,9 @@ public void run() { */ public void stop() { synchronized (_lock) { - if (_status == FRAME_STATUS.STOP) { return; } + if (_status == FRAME_STATUS.STOP) { + return; + } _status = FRAME_STATUS.STOP; } LOG.debug("DefFrame is stopping"); @@ -116,15 +118,15 @@ public FrameEvent waitForStop(long timeout) { FrameEvent event = null; switch (_status) { - case INIT: - event = new FrameEvent(FrameEvent.Init, this); - break; - case START: - event = new FrameEvent(FrameEvent.Start, this); - break; - default: - event = new FrameEvent(FrameEvent.Stop, this); - break; + case INIT: + event = new FrameEvent(FrameEvent.Init, this); + break; + case START: + event = new FrameEvent(FrameEvent.Start, this); + break; + default: + event = new FrameEvent(FrameEvent.Stop, this); + break; } return event; } diff --git a/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java b/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java index 6ca0aba..9351a99 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java +++ b/jframe/jframe-core/src/main/java/jframe/core/conf/VarHandler.java @@ -49,6 +49,9 @@ public String replace(Config config, String input) { if (val == null) { // LOG.warn("Not found variable's value: " + var); continue; + } else if (val.equals(input)) { + // LOG.warn("Variable's value is same as input: " + var); + continue; } input = input.replaceAll("\\$\\{" + var + "\\}", val); diff --git a/jframe/jframe-core/src/main/java/jframe/core/unit/UnitManager.java b/jframe/jframe-core/src/main/java/jframe/core/unit/UnitManager.java index faa9e52..0ba8a6b 100644 --- a/jframe/jframe-core/src/main/java/jframe/core/unit/UnitManager.java +++ b/jframe/jframe-core/src/main/java/jframe/core/unit/UnitManager.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.core.unit; @@ -19,7 +19,7 @@ *

    * UnitManager *

    - * + * * @author dzh * @date Sep 24, 2013 11:07:49 AM * @since 1.0 @@ -43,9 +43,9 @@ public static final UnitManager createManager(Config conf) { /** * register unit, to be unregistered if u exist - * - * @param u - * @return + * + * @param u Unit + * @return Unit * @throws UnitException */ public Unit regUnit(Unit u) throws UnitException { @@ -81,7 +81,7 @@ public Unit regUnit(Unit u) throws UnitException { /** * unregister unit - * + * * @param u * @return * @throws UnitException @@ -123,7 +123,7 @@ public void dispose() { *

    * Initialize Manager and Register Units *

    - * + * * @throws UnitException */ public void start() throws UnitException { @@ -137,9 +137,8 @@ public void start() throws UnitException { /** * load unit from unit.properties - * - * @param file - * @throws UnitException + * + * @param file unit.properties file */ private void loadUnit(String file) throws UnitException { if (file == null) { diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java index ab9edf4..cc7ace4 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/Main.java @@ -1,5 +1,5 @@ /** - * + * */ package jframe.launcher; @@ -13,7 +13,7 @@ import jframe.launcher.api.LauncherException; /** - * + * * @author dzh * @date Oct 10, 2013 4:28:16 PM * @since 1.0 @@ -23,13 +23,14 @@ public class Main { private static final Logger LOG = LoggerFactory.getLogger(Main.class); /** - * - * @param lclazz - * launcher class + * + * @param lclazz launcher class * @return */ public static Launcher createLauncher(String lclazz) throws LauncherException { - if (lclazz == null || "".equals(lclazz)) { throw new LauncherException("Not found launcher class" + lclazz); } + if (lclazz == null || "".equals(lclazz)) { + throw new LauncherException("Not found launcher class" + lclazz); + } try { return (Launcher) Thread.currentThread().getContextClassLoader().loadClass(lclazz).newInstance(); } catch (Exception e) { @@ -59,8 +60,7 @@ static void start(String launcher) { // String fileConfig = // System.getProperty(Config.FILE_CONFIG, appHome + File.separator + "conf" + File.separator + // Config.FILE_CONFIG_NAME); - String fileConfig = - System.getProperty(Config.FILE_CONFIG, String.join(File.separator, appHome, "conf", Config.FILE_CONFIG_NAME)); + String fileConfig = System.getProperty(Config.FILE_CONFIG, String.join(File.separator, appHome, "conf", Config.FILE_CONFIG_NAME)); Config config = l.load(fileConfig); l.launch(config); } catch (Exception e) { diff --git a/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java b/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java index 81a20e5..5eca1c5 100644 --- a/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java +++ b/jframe/jframe-launcher/src/main/java/jframe/launcher/util/VarProperties.java @@ -8,6 +8,7 @@ import java.io.*; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.HashSet; import java.util.Map; import java.util.Properties; @@ -57,7 +58,7 @@ public synchronized void load(String file) throws IOException { public synchronized void load(File file) throws IOException { if (file == null) return; - try (InputStreamReader fis = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) { + try (InputStreamReader fis = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8)) { load(fis); } catch (Exception e) { LOG.warn(e.getMessage()); @@ -85,25 +86,22 @@ private void replaceAllVar() { /** * TODO handle circle key * - * @param key - * @param value - * @keys avoid circle key - * @return + * @param key key + * @param value value + * @param keys set to avoid circle key + * @return value replaced var */ private String replaceVar(String key, String value, Set keys) { if (value == null) return null; - Matcher m = P_VAR.matcher(value); - if (keys.contains(key)) throw new RuntimeException("circle key->" + key); + if (keys.contains(key)) throw new RuntimeException("circle key:" + key); String newVal = value; String var = null; String val = null; try { + keys.add(key); + Matcher m = P_VAR.matcher(value); while (m.find()) { - if (!keys.contains(key)) { - keys.add(key); - } - var = m.group(1); val = replaceVar(var, getProperty(var), keys); if (val == null) { @@ -112,14 +110,14 @@ private String replaceVar(String key, String value, Set keys) { newVal = newVal.replaceAll("\\$\\{" + var + "\\}", val); } - keys.remove(key); - if (containsKey(key)) put(key, newVal); if (LOG.isDebugEnabled()) { LOG.debug("key={}, value={}->{}", key, value, newVal); } } catch (Exception e) { LOG.error("k->{}, v->{}, e->{}", key, value, e.getMessage()); + } finally { + keys.remove(key); } return newVal; }