From 8af2c047b3139cf7fe096ec4d19b8db07fc2330a Mon Sep 17 00:00:00 2001 From: 13009 Date: Wed, 3 Jul 2024 14:47:07 +0800 Subject: [PATCH] feat: channel group --- .../com/czcb/scfs/api/core/ApiRequest.java | 21 +++++- .../java/com/czcb/scfs/api/core/Channel.java | 5 ++ .../com/czcb/scfs/api/core/Constants.java | 1 + .../czcb/scfs/api/core/DefaultChannel.java | 25 +++++++ .../api/core/cipher/DefaultCredential.java | 33 ++++++++-- .../api/core/http/EncryptRequestBody.java | 8 +++ .../scfs/api/core/http/FileRequestBody.java | 8 +++ .../scfs/api/core/http/JsonRequestBody.java | 28 +++++++- .../czcb/scfs/api/core/http/RequestBody.java | 13 ++++ .../czcb/scfs/api/core/util/DateTimes.java | 9 ++- .../czcb/scfs/api/core/util/ObjReflect.java | 31 +++++++++ .../com/czcb/scfs/api/core/util/Strings.java | 17 +++-- .../scfs/api/core/DefaultChannelTest.java | 33 ++++++++++ .../core/JsonRequestBodyApiRequestTest.java | 65 +++++++++++++++++++ .../api/core/http/ApiClientBuilderTest.java | 2 +- .../api/core/http/EncryptRequestBodyTest.java | 2 + .../api/core/http/FileRequestBodyTest.java | 3 + .../api/core/http/JsonRequestBodyTest.java | 30 ++++++++- .../scfs/api/core/util/DateTimesTest.java | 6 ++ .../com/czcb/scfs/api/core/util/NetTest.java | 2 - .../scfs/api/core/util/ObjReflectTest.java | 46 +++++++++++++ .../czcb/scfs/api/core/util/StringsTest.java | 10 +++ .../v2/loan/model/ApplyNotifyResponse.java | 4 +- .../starter/AbstractAutoConfiguration.java | 11 +++- .../starter/ScfsApiGatewayProperties.java | 4 ++ .../boot/starter/RsaConfigurationTest.java | 3 +- .../starter/ScfsApiGatewayPropertiesTest.java | 7 +- .../boot/starter/SmConfigurationTest.java | 2 +- .../czcb/scfs/api/test/ApiGatewayTest.java | 7 -- 29 files changed, 401 insertions(+), 35 deletions(-) create mode 100644 scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/ObjReflect.java create mode 100644 scfs-api-core/src/test/java/com/czcb/scfs/api/core/JsonRequestBodyApiRequestTest.java create mode 100644 scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/ObjReflectTest.java diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/ApiRequest.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/ApiRequest.java index 2dcbd0e..f5d0ed6 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/ApiRequest.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/ApiRequest.java @@ -2,8 +2,15 @@ package com.czcb.scfs.api.core; import com.czcb.scfs.api.core.http.JsonRequestBody; import com.czcb.scfs.api.core.util.Json; +import com.czcb.scfs.api.core.util.ObjReflect; +import com.czcb.scfs.api.core.util.Strings; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import static com.czcb.scfs.api.core.Constants.APP_NO; +import static com.czcb.scfs.api.core.Constants.CHANNEL_NO; /** * @author wangwei @@ -11,6 +18,18 @@ import java.io.Serializable; */ public interface ApiRequest extends Serializable { default JsonRequestBody toJsonRequest() { - return new JsonRequestBody.Builder().body(Json.toJson(this)).build(); + final Map params = new HashMap<>(); + + String channelNoValue = ObjReflect.getValueAsString(this, "channelNo"); + if (Strings.isNotEmpty(channelNoValue)) { + params.put(CHANNEL_NO, channelNoValue); + } + + String appNoValue = ObjReflect.getValueAsString(this, "appNo"); + if (Strings.isNotEmpty(appNoValue)) { + params.put(APP_NO, appNoValue); + } + + return new JsonRequestBody.Builder().body(Json.toJson(this)).extraParams(params).build(); } } diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Channel.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Channel.java index c6d649c..0c6e0da 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Channel.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Channel.java @@ -15,4 +15,9 @@ public interface Channel { * @return 渠道编号 */ String getChannelNo(); + + /** + * @return true/false + */ + boolean isChannelGroupMode(); } diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Constants.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Constants.java index fb176fd..2b3b57f 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Constants.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/Constants.java @@ -24,6 +24,7 @@ public final class Constants { public static final String CHANNEL_CERTIFICATE_SERIAL = "X-SCFS-Channel-Serial"; // http 自定义字段 public static final String TIMESTAMP = "X-SCFS-Timestamp"; + public static final String CHANNEL_GROUP = "X-SCFS-Channel-Group"; public static final String NONCE = "X-SCFS-Nonce"; public static final String SECRET_KEY = "X-SCFS-Secret-Key"; public static final String REQUEST_ID = "X-SCFS-Request-Id"; diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/DefaultChannel.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/DefaultChannel.java index ab6f430..ccb09cc 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/DefaultChannel.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/DefaultChannel.java @@ -16,9 +16,15 @@ public final class DefaultChannel implements Channel { */ private final String channelNo; + /** + * 渠道聚合模式 + */ + private final boolean channelGroupMode; + private DefaultChannel(Builder builder) { this.appNo = builder.appNo; this.channelNo = builder.channelNo; + this.channelGroupMode = builder.channelGroupMode; } public String getAppNo() { @@ -29,6 +35,11 @@ public final class DefaultChannel implements Channel { return channelNo; } + @Override + public boolean isChannelGroupMode() { + return channelGroupMode; + } + public static class Builder { /** * 应用编号 @@ -39,6 +50,10 @@ public final class DefaultChannel implements Channel { * 渠道号 */ private String channelNo; + /** + * 渠道聚合模式 默认false + */ + private boolean channelGroupMode = false; public Builder appNo(String appNo) { this.appNo = appNo; @@ -50,6 +65,16 @@ public final class DefaultChannel implements Channel { return this; } + public Builder enableChannelGroupMode() { + this.channelGroupMode = true; + return this; + } + + public Builder disableChannelGroupMode() { + this.channelGroupMode = false; + return this; + } + public DefaultChannel build() { requireNonNull(channelNo, "渠道编号不能为空"); requireNonNull(appNo, "应用编号不能为空"); diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/cipher/DefaultCredential.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/cipher/DefaultCredential.java index ec83de1..39860fa 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/cipher/DefaultCredential.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/cipher/DefaultCredential.java @@ -8,6 +8,7 @@ import com.czcb.scfs.api.core.util.DateTimes; import com.czcb.scfs.api.core.util.Strings; import java.util.Map; +import java.util.Objects; import static com.czcb.scfs.api.core.Constants.*; import static java.util.Objects.requireNonNull; @@ -26,15 +27,19 @@ public class DefaultCredential implements Credential { @Override public String buildRequestAuthorization(HttpRequest request, Channel channel) { // 添加请求必要头部 - addNecessityCustomizeHeaders(signer, request); + addNecessityCustomizeHeaders(request, channel, signer); // 认证串 - return String.format("SCFS-%s %s", signer.getAlgorithm(), authorizationMessage(channel, buildRequestSignature(request))); + return String.format("SCFS-%s %s", signer.getAlgorithm(), authorizationMessage(request, channel, buildRequestSignature(request))); } - private void addNecessityCustomizeHeaders(Signer signer, HttpRequest request) { + private void addNecessityCustomizeHeaders(HttpRequest request, Channel channel, Signer signer) { request.getHttpHeaders().addHeader(CHANNEL_CERTIFICATE_SERIAL, signer.getCertificateSerial()); request.getHttpHeaders().addHeader(NONCE, request.getId()); request.getHttpHeaders().addHeader(TIMESTAMP, DateTimes.ofTimestamp()); + + if (channel.isChannelGroupMode()) { + request.getHttpHeaders().addHeader(CHANNEL_GROUP, channel.getChannelNo()); + } } private SignatureResult buildRequestSignature(HttpRequest request) { @@ -75,13 +80,29 @@ public class DefaultCredential implements Credential { requestBody + "\n"; } - private String authorizationMessage(Channel channel, SignatureResult result) { + private String authorizationMessage(HttpRequest request, Channel channel, SignatureResult result) { // 认证串 - return CHANNEL_NO + "=" + channel.getChannelNo() + "," + - APP_NO + "=" + channel.getAppNo() + "," + + return CHANNEL_NO + "=" + getChannelNo(request, channel) + "," + + APP_NO + "=" + getAppNo(request, channel) + "," + SIGNATURE + "=" + result.getSignature(); } + private String getChannelNo(HttpRequest request, Channel channel) { + if (channel.isChannelGroupMode()) { + return Strings.toStr(Objects.requireNonNull(request.getRequestBody().getExtraParams().get(CHANNEL_NO))); + } + + return channel.getChannelNo(); + } + + private String getAppNo(HttpRequest request, Channel channel) { + if (channel.isChannelGroupMode()) { + return Strings.toStr(Objects.requireNonNull(request.getRequestBody().getExtraParams().get(APP_NO))); + } + + return channel.getAppNo(); + } + @Override public String buildResponseMessage(OriginalResponse response, Channel channel) { String signatureHeader = getSignatureHeader(response.getHttpHeaders()); diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/EncryptRequestBody.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/EncryptRequestBody.java index fb402aa..3a7fb81 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/EncryptRequestBody.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/EncryptRequestBody.java @@ -2,6 +2,9 @@ package com.czcb.scfs.api.core.http; import com.czcb.scfs.api.core.util.Strings; +import java.util.Collections; +import java.util.Map; + /** * @author wangwei * @since 2.0.0 @@ -31,6 +34,11 @@ public class EncryptRequestBody implements RequestBody { return MediaType.TEXT_PLAIN.getValue(); } + @Override + public Map getExtraParams() { + return Collections.emptyMap(); + } + public static class Builder { private byte[] body; private byte[] originalBody; diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/FileRequestBody.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/FileRequestBody.java index 91a8cc1..5264f17 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/FileRequestBody.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/FileRequestBody.java @@ -2,6 +2,9 @@ package com.czcb.scfs.api.core.http; import com.czcb.scfs.api.core.util.Strings; +import java.util.Collections; +import java.util.Map; + import static java.util.Objects.requireNonNull; /** @@ -25,6 +28,11 @@ public class FileRequestBody implements RequestBody { return MediaType.TEXT_PLAIN.getValue(); } + @Override + public Map getExtraParams() { + return Collections.emptyMap(); + } + public static class Builder { private byte[] body; diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/JsonRequestBody.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/JsonRequestBody.java index 1bcaf0d..f076851 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/JsonRequestBody.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/JsonRequestBody.java @@ -2,6 +2,11 @@ package com.czcb.scfs.api.core.http; import com.czcb.scfs.api.core.util.Strings; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + import static java.util.Objects.requireNonNull; /** @@ -9,10 +14,14 @@ import static java.util.Objects.requireNonNull; * @since 2.0.0 */ public class JsonRequestBody implements RequestBody { + // 请求内容 private final byte[] body; + // 额外参数 + private final Map extraParams; - private JsonRequestBody(byte[] body) { + private JsonRequestBody(byte[] body, Map extraParams) { this.body = body; + this.extraParams = extraParams; } @Override @@ -25,8 +34,14 @@ public class JsonRequestBody implements RequestBody { return MediaType.APPLICATION_JSON.getValue(); } + @Override + public Map getExtraParams() { + return Collections.unmodifiableMap(extraParams); + } + public static class Builder { private byte[] body; + private Map extraParams; public Builder body(String body) { this.body = Strings.toBytes(body); @@ -38,10 +53,19 @@ public class JsonRequestBody implements RequestBody { return this; } + public Builder extraParams(Map extraParams) { + this.extraParams = extraParams; + return this; + } + public JsonRequestBody build() { requireNonNull(body); - return new JsonRequestBody(body); + if (Objects.isNull(extraParams)) { + this.extraParams = new HashMap<>(); + } + + return new JsonRequestBody(body, extraParams); } } } diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/RequestBody.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/RequestBody.java index 20b6ffe..a445941 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/RequestBody.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/http/RequestBody.java @@ -1,12 +1,25 @@ package com.czcb.scfs.api.core.http; +import java.util.Map; + /** * @author wangwei * @since 2.0.0 */ public interface RequestBody { + /** + * @return 请求内容 + */ byte[] getBody(); + /** + * @return 请内类型 + */ String getContentType(); + + /** + * @return 额外参数 + */ + Map getExtraParams(); } diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/DateTimes.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/DateTimes.java index 7876fc0..9a07d6e 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/DateTimes.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/DateTimes.java @@ -8,6 +8,9 @@ import java.util.Date; import java.util.Objects; public final class DateTimes { + public static final String NORMAL_DATE_TIME = "yyyy-MM-dd HH:mm:ss"; + public static final String NORMAL_DATE = "yyyy-MM-dd"; + private DateTimes() { } @@ -21,17 +24,17 @@ public final class DateTimes { } public static String ofNow() { - return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()); + return DateTimeFormatter.ofPattern(NORMAL_DATE_TIME).format(LocalDateTime.now()); } public static String ofPatternDate(Date date) { Objects.requireNonNull(date, "date is null"); LocalDateTime dateTime = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime(); - return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(dateTime); + return DateTimeFormatter.ofPattern(NORMAL_DATE_TIME).format(dateTime); } public static String ofNowDate() { - return DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()); + return DateTimeFormatter.ofPattern(NORMAL_DATE).format(LocalDateTime.now()); } } diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/ObjReflect.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/ObjReflect.java new file mode 100644 index 0000000..46da48a --- /dev/null +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/ObjReflect.java @@ -0,0 +1,31 @@ +package com.czcb.scfs.api.core.util; + +import java.lang.reflect.Field; + +/** + * @author wangwei + * @date 2024/7/3 + */ +public class ObjReflect { + private ObjReflect() { + } + + public static Object getValue(Object obj, String fieldName) { + try { + Field field = obj.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(obj); + } catch (Exception e) { + return null; + } + } + + public static String getValueAsString(Object obj, String fieldName) { + Object value = getValue(obj, fieldName); + if (value == null) { + return null; + } + + return value.toString(); + } +} diff --git a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/Strings.java b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/Strings.java index 017d9b4..ab796df 100644 --- a/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/Strings.java +++ b/scfs-api-core/src/main/java/com/czcb/scfs/api/core/util/Strings.java @@ -2,6 +2,7 @@ package com.czcb.scfs.api.core.util; import com.czcb.scfs.api.core.exception.EncodingException; +import java.math.BigDecimal; import java.math.BigInteger; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -39,10 +40,6 @@ public class Strings { return value; } - public static String toStr(byte[] bytes) { - return new String(bytes, StandardCharsets.UTF_8); - } - /** * 移除字符串后缀 */ @@ -114,4 +111,16 @@ public class Strings { return String.format("%s,%s", DateTimes.ofPatternDate(certificate.getNotBefore()), DateTimes.ofPatternDate(certificate.getNotAfter())); } + + public static String toStr(Object data) { + if (data instanceof String || data instanceof Integer) { + return data.toString(); + } else if (data instanceof BigDecimal) { + return ((BigDecimal) data).toPlainString(); + } else if (data instanceof byte[]) { + return new String((byte[]) data, StandardCharsets.UTF_8); + } + + return null; + } } diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/DefaultChannelTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/DefaultChannelTest.java index 9b986ad..58f5bb9 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/DefaultChannelTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/DefaultChannelTest.java @@ -3,6 +3,8 @@ package com.czcb.scfs.api.core; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; + class DefaultChannelTest { @Test @@ -20,5 +22,36 @@ class DefaultChannelTest { DefaultChannel.Builder builder2 = new DefaultChannel.Builder().appNo("0000"); Assertions.assertThrows(NullPointerException.class, builder2::build); + Assertions.assertFalse(channel.isChannelGroupMode()); + } + + @Test + void testChannelGroupMode() { + Channel channel = new DefaultChannel.Builder() + .appNo("123456") + .channelNo("0000") + .enableChannelGroupMode() + .build(); + + Assertions.assertTrue(channel.isChannelGroupMode()); + + channel = new DefaultChannel.Builder() + .appNo("123456") + .channelNo("0000") + .disableChannelGroupMode() + .build(); + + Assertions.assertFalse(channel.isChannelGroupMode()); + } + + @Test + void testChannelJson() { + Channel channel = new DefaultChannel.Builder() + .appNo("123456") + .channelNo("0000") + .enableChannelGroupMode() + .build(); + + assertThatJson("{\"channelNo\":\"0000\",\"appNo\":\"123456\",\"channelGroupMode\":true}").isEqualTo(channel); } } \ No newline at end of file diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/JsonRequestBodyApiRequestTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/JsonRequestBodyApiRequestTest.java new file mode 100644 index 0000000..444f384 --- /dev/null +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/JsonRequestBodyApiRequestTest.java @@ -0,0 +1,65 @@ +package com.czcb.scfs.api.core; + +import com.czcb.scfs.api.core.http.JsonRequestBody; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author wangwei + * @date 2024/7/3 + */ +class JsonRequestBodyApiRequestTest { + + @Test + void toJsonRequestTest() { + ReflectionModel model = new ReflectionModel(); + model.setName("test"); + model.setAppNo("1001"); + model.setChannelNo("2000"); + JsonRequestBody body = model.toJsonRequest(); + Assertions.assertNotNull(body.getExtraParams()); + Assertions.assertFalse(body.getExtraParams().isEmpty()); + + Assertions.assertEquals("1001", body.getExtraParams().get("X-SCFS-App-No")); + Assertions.assertEquals("2000", body.getExtraParams().get("X-SCFS-Channel-No")); + } + + + @Test + void toJsonRequestNullTest() { + ReflectionModel model = new ReflectionModel(); + JsonRequestBody body = model.toJsonRequest(); + Assertions.assertNotNull(body.getExtraParams()); + Assertions.assertTrue(body.getExtraParams().isEmpty()); + } + + static class ReflectionModel implements ApiRequest { + private String name; + private String channelNo; + private String appNo; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getChannelNo() { + return channelNo; + } + + public void setChannelNo(String channelNo) { + this.channelNo = channelNo; + } + + public String getAppNo() { + return appNo; + } + + public void setAppNo(String appNo) { + this.appNo = appNo; + } + } +} diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/ApiClientBuilderTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/ApiClientBuilderTest.java index aec43c7..cf0dbf3 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/ApiClientBuilderTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/ApiClientBuilderTest.java @@ -58,7 +58,7 @@ class ApiClientBuilderTest { Assertions.assertNotNull(profile.getPrivacy()); Assertions.assertNotNull(profile.getSignature()); - assertThatJson("{\"channelNo\":\"000000\",\"appNo\":\"111111\"}").isEqualTo(profile.getChannel()); + assertThatJson("{\"appNo\":\"111111\",\"channelNo\":\"000000\",\"channelGroupMode\":false}").isEqualTo(profile.getChannel()); assertThatJson("{\"host\":\"http://127.0.0.1:8888\"," + "\"connPool\":{\"maxRequests\":64,\"maxRequestPerHost\":64,\"connectTimeout\":10,\"socketTimeout\":60}," + "\"headers\":{}," + diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/EncryptRequestBodyTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/EncryptRequestBodyTest.java index db488f5..e17f5d7 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/EncryptRequestBodyTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/EncryptRequestBodyTest.java @@ -14,6 +14,8 @@ class EncryptRequestBodyTest { .build(); Assertions.assertArrayEquals("123456".getBytes(StandardCharsets.UTF_8), requestBody.getBody()); + Assertions.assertNotNull(requestBody.getExtraParams()); + Assertions.assertTrue(requestBody.getExtraParams().isEmpty()); } @Test diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/FileRequestBodyTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/FileRequestBodyTest.java index 6ace128..4177cae 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/FileRequestBodyTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/FileRequestBodyTest.java @@ -21,6 +21,9 @@ class FileRequestBodyTest { .build(); Assertions.assertArrayEquals("123".getBytes(StandardCharsets.UTF_8), requestBody.getBody()); + + Assertions.assertNotNull(requestBody.getExtraParams()); + Assertions.assertTrue(requestBody.getExtraParams().isEmpty()); } @Test diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/JsonRequestBodyTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/JsonRequestBodyTest.java index 726eaea..e95b1da 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/JsonRequestBodyTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/http/JsonRequestBodyTest.java @@ -4,6 +4,8 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; class JsonRequestBodyTest { @@ -19,9 +21,35 @@ class JsonRequestBodyTest { @Test void getContentType() { JsonRequestBody requestBody = new JsonRequestBody.Builder() - .body("123") + .body("123".getBytes(StandardCharsets.UTF_8)) .build(); Assertions.assertEquals("application/json", requestBody.getContentType()); } + + @Test + void metaNull() { + JsonRequestBody requestBody = new JsonRequestBody.Builder() + .extraParams(null) + .body("11") + .build(); + + Assertions.assertNotNull(requestBody.getExtraParams()); + Assertions.assertTrue(requestBody.getExtraParams().isEmpty()); + Map m = requestBody.getExtraParams(); + Assertions.assertThrows(UnsupportedOperationException.class, () -> m.put("key", "value")); + } + + @Test + void meta() { + Map m = new HashMap<>(); + m.put("key", "111"); + JsonRequestBody requestBody = new JsonRequestBody.Builder() + .extraParams(m) + .body("11") + .build(); + + Assertions.assertFalse(requestBody.getExtraParams().isEmpty()); + Assertions.assertEquals("111", requestBody.getExtraParams().get("key")); + } } \ No newline at end of file diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/DateTimesTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/DateTimesTest.java index 1626b9d..0510a7b 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/DateTimesTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/DateTimesTest.java @@ -34,4 +34,10 @@ class DateTimesTest { String text = "2024-01-01 12:10:21"; Assertions.assertEquals(text, DateTimes.ofPatternDate(format.parse(text))); } + + @Test + void testFmt() { + Assertions.assertEquals("yyyy-MM-dd HH:mm:ss", DateTimes.NORMAL_DATE_TIME); + Assertions.assertEquals("yyyy-MM-dd", DateTimes.NORMAL_DATE); + } } \ No newline at end of file diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/NetTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/NetTest.java index 4ad3ffc..d26e9e4 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/NetTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/NetTest.java @@ -1,7 +1,5 @@ package com.czcb.scfs.api.core.util; -import static org.junit.jupiter.api.Assertions.*; - class NetTest { } \ No newline at end of file diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/ObjReflectTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/ObjReflectTest.java new file mode 100644 index 0000000..d35e6af --- /dev/null +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/ObjReflectTest.java @@ -0,0 +1,46 @@ +package com.czcb.scfs.api.core.util; + +import com.czcb.scfs.api.core.ApiRequest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Objects; + +class ObjReflectTest { + + @Test + void getValue() { + ReflectionModel model = new ReflectionModel(); + model.setName("test"); + Assertions.assertNotNull(ObjReflect.getValue(model, "name")); + Assertions.assertEquals("test", ObjReflect.getValue(model, "name")); + } + + @Test + void getValueIsNull() { + ReflectionModel model = new ReflectionModel(); + Assertions.assertNull(ObjReflect.getValue(model, "key")); + } + + @Test + void getValueAsString() { + ReflectionModel model = new ReflectionModel(); + model.setName("test"); + Assertions.assertEquals("test", ObjReflect.getValueAsString(model, "name")); + Assertions.assertTrue(Objects.requireNonNull(ObjReflect.getValueAsString(model, "name")).getClass().isAssignableFrom(String.class)); + + Assertions.assertNull(ObjReflect.getValueAsString(model, "name2")); + } + + static class ReflectionModel implements ApiRequest { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} \ No newline at end of file diff --git a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/StringsTest.java b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/StringsTest.java index 2f2178d..4fdcba0 100644 --- a/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/StringsTest.java +++ b/scfs-api-core/src/test/java/com/czcb/scfs/api/core/util/StringsTest.java @@ -5,6 +5,7 @@ import com.czcb.scfs.api.core.exception.EncodingException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.cert.X509Certificate; @@ -102,4 +103,13 @@ class StringsTest { X509Certificate certificate = KeyText.loadTestRSA(); Assertions.assertEquals("2024-02-13 17:52:40,2034-02-10 17:52:40", Strings.timeRange(certificate)); } + + @Test + void testToStr() { + Assertions.assertNull(Strings.toStr(null)); + Assertions.assertEquals("11", Strings.toStr(new BigDecimal("11"))); + Assertions.assertEquals("33", Strings.toStr("33")); + Assertions.assertEquals("88", Strings.toStr(88)); + Assertions.assertEquals("111", Strings.toStr("111".getBytes(StandardCharsets.UTF_8))); + } } \ No newline at end of file diff --git a/scfs-api-service/src/main/java/com/czcb/scfs/api/service/v2/loan/model/ApplyNotifyResponse.java b/scfs-api-service/src/main/java/com/czcb/scfs/api/service/v2/loan/model/ApplyNotifyResponse.java index 3f923fd..e5f92aa 100644 --- a/scfs-api-service/src/main/java/com/czcb/scfs/api/service/v2/loan/model/ApplyNotifyResponse.java +++ b/scfs-api-service/src/main/java/com/czcb/scfs/api/service/v2/loan/model/ApplyNotifyResponse.java @@ -1,6 +1,6 @@ package com.czcb.scfs.api.service.v2.loan.model; -import com.czcb.scfs.api.core.ApiRequest; +import com.czcb.scfs.api.core.ApiResponse; import com.google.gson.annotations.SerializedName; import lombok.Data; import lombok.experimental.Accessors; @@ -13,7 +13,7 @@ import lombok.experimental.Accessors; */ @Data @Accessors(chain = true) -public class ApplyNotifyResponse implements ApiRequest { +public class ApplyNotifyResponse implements ApiResponse { /** * 000000:表示成功 */ diff --git a/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/AbstractAutoConfiguration.java b/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/AbstractAutoConfiguration.java index b5a3cb8..0c89c01 100644 --- a/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/AbstractAutoConfiguration.java +++ b/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/AbstractAutoConfiguration.java @@ -49,9 +49,14 @@ public abstract class AbstractAutoConfiguration { } protected Channel getChannel() { - return new DefaultChannel.Builder() + DefaultChannel.Builder builder = new DefaultChannel.Builder() .channelNo(getProperties().getChannel().getChannelNo()) - .appNo(getProperties().getChannel().getAppNo()) - .build(); + .appNo(getProperties().getChannel().getAppNo()); + + if (getProperties().getChannel().isChannelGroupMode()) { + builder.enableChannelGroupMode(); + } + + return builder.build(); } } diff --git a/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayProperties.java b/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayProperties.java index e95e46a..8c298ca 100644 --- a/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayProperties.java +++ b/scfs-api-spring-boot-starter/src/main/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayProperties.java @@ -53,6 +53,10 @@ public class ScfsApiGatewayProperties { */ private String appNo; + /** + * 渠道聚合模式,默认false + */ + private boolean channelGroupMode = false; } @Data diff --git a/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/RsaConfigurationTest.java b/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/RsaConfigurationTest.java index ecc0f63..62ffc0a 100644 --- a/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/RsaConfigurationTest.java +++ b/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/RsaConfigurationTest.java @@ -46,6 +46,7 @@ class RsaConfigurationTest { ScfsApiGatewayProperties.Channel channel = new ScfsApiGatewayProperties.Channel(); channel.setChannelNo("000000"); channel.setAppNo("111111"); + channel.setChannelGroupMode(false); properties.setChannel(channel); ScfsApiGatewayProperties.Cipher cipher = new ScfsApiGatewayProperties.Cipher(); @@ -72,7 +73,7 @@ class RsaConfigurationTest { rsaConfiguration = new RsaConfiguration(properties()); RsaProfile profile = rsaConfiguration.rsaProfile(); Assertions.assertNotNull(profile); - assertThatJson("{\"channelNo\":\"000000\",\"appNo\":\"111111\"}").isEqualTo(profile.getChannel()); + assertThatJson("{\"appNo\":\"111111\",\"channelNo\":\"000000\",\"channelGroupMode\":false}").isEqualTo(profile.getChannel()); assertThatJson("{\"host\":\"http://127.0.0.1\",\"connPool\":{\"maxRequests\":100,\"maxRequestPerHost\":100,\"connectTimeout\":100,\"socketTimeout\":100},\"headers\":{\"aa\":\"123456\"},\"proxy\":{\"enabled\":true,\"host\":\"128.0.0.1\",\"port\":\"1000\",\"username\":\"name\",\"password\":\"123456\",\"scheme\":\"https\"}}\n") .isEqualTo(profile.getHttpProfile()); } diff --git a/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayPropertiesTest.java b/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayPropertiesTest.java index 6733058..42f02c1 100644 --- a/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayPropertiesTest.java +++ b/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/ScfsApiGatewayPropertiesTest.java @@ -39,7 +39,12 @@ class ScfsApiGatewayPropertiesTest { properties.setChannel(channel); Assertions.assertNotNull(properties.getChannel()); - assertThatJson("{\"channelNo\":\"000000\",\"appNo\":\"111111\"}").isEqualTo(properties.getChannel()); + Assertions.assertFalse(channel.isChannelGroupMode()); + + assertThatJson("{\"channelNo\":\"000000\",\"appNo\":\"111111\",\"channelGroupMode\":false}").isEqualTo(properties.getChannel()); + + channel.setChannelGroupMode(true); + assertThatJson("{\"channelNo\":\"000000\",\"appNo\":\"111111\",\"channelGroupMode\":true}").isEqualTo(properties.getChannel()); } @Test diff --git a/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/SmConfigurationTest.java b/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/SmConfigurationTest.java index dd6d894..29ea65f 100644 --- a/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/SmConfigurationTest.java +++ b/scfs-api-spring-boot-starter/src/test/java/com/czcb/scfs/spring/boot/starter/SmConfigurationTest.java @@ -75,7 +75,7 @@ class SmConfigurationTest { smConfiguration = new SmConfiguration(properties()); SmProfile smProfile = smConfiguration.smProfile(); Assertions.assertNotNull(smProfile); - assertThatJson("{\"channelNo\":\"000000\",\"appNo\":\"111111\"}").isEqualTo(smProfile.getChannel()); + assertThatJson("{\"appNo\":\"111111\",\"channelNo\":\"000000\",\"channelGroupMode\":false}").isEqualTo(smProfile.getChannel()); assertThatJson("{\"host\":\"http://127.0.0.1\",\"connPool\":{\"maxRequests\":100,\"maxRequestPerHost\":100,\"connectTimeout\":100,\"socketTimeout\":100},\"headers\":{\"aa\":\"123456\"},\"proxy\":{\"enabled\":true,\"host\":\"128.0.0.1\",\"port\":\"1000\",\"username\":\"name\",\"password\":\"123456\",\"scheme\":\"https\"}}\n") .isEqualTo(smProfile.getHttpProfile()); } diff --git a/scfs-api-test/src/test/java/com/czcb/scfs/api/test/ApiGatewayTest.java b/scfs-api-test/src/test/java/com/czcb/scfs/api/test/ApiGatewayTest.java index 5694601..dbb8275 100644 --- a/scfs-api-test/src/test/java/com/czcb/scfs/api/test/ApiGatewayTest.java +++ b/scfs-api-test/src/test/java/com/czcb/scfs/api/test/ApiGatewayTest.java @@ -1,18 +1,13 @@ package com.czcb.scfs.api.test; -import com.czcb.scfs.api.core.util.Compression; import com.czcb.scfs.api.core.util.Nonce; import com.czcb.scfs.api.core.util.PemFile; import com.czcb.scfs.api.service.v2.account.AccountService; import com.czcb.scfs.api.service.v2.account.model.QueryBalanceRequest; import com.czcb.scfs.api.service.v2.account.model.QueryBalanceResponse; -import com.czcb.scfs.api.service.v2.file.FileService; -import com.czcb.scfs.api.service.v2.file.model.UploadFileRequest; -import com.czcb.scfs.api.service.v2.file.model.UploadFileResponse; import com.czcb.scfs.api.service.v2.sms.SmsService; import com.czcb.scfs.api.service.v2.sms.model.SendVerifySignRequest; import com.tencent.kona.KonaProvider; -import org.assertj.core.util.Lists; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @@ -33,7 +28,6 @@ class ApiGatewayTest { private AccountService accountService; - @Resource private SmsService service; @@ -52,7 +46,6 @@ class ApiGatewayTest { } - @Test void testPath() throws Exception { String path = "C:\\Users\\Administrator.CZCB-20230627EN\\Downloads\\密钥工具\\20240411182951\\sm2_certificate.pem";