feat: 发号器
parent
da1b7b0351
commit
f1a3762154
|
|
@ -19,9 +19,11 @@ import static java.util.Objects.requireNonNull;
|
||||||
*/
|
*/
|
||||||
public class DefaultCredential implements Credential {
|
public class DefaultCredential implements Credential {
|
||||||
private final Signer signer;
|
private final Signer signer;
|
||||||
|
private final Sequencer sequencer;
|
||||||
|
|
||||||
public DefaultCredential(Signer signer) {
|
public DefaultCredential(Signer signer, Sequencer sequencer) {
|
||||||
this.signer = requireNonNull(signer);
|
this.signer = requireNonNull(signer);
|
||||||
|
this.sequencer = requireNonNull(sequencer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -34,7 +36,7 @@ public class DefaultCredential implements Credential {
|
||||||
|
|
||||||
private void addNecessityCustomizeHeaders(HttpRequest request, Channel channel, Signer signer) {
|
private void addNecessityCustomizeHeaders(HttpRequest request, Channel channel, Signer signer) {
|
||||||
request.getHttpHeaders().addHeader(CHANNEL_CERTIFICATE_SERIAL, signer.getCertificateSerial());
|
request.getHttpHeaders().addHeader(CHANNEL_CERTIFICATE_SERIAL, signer.getCertificateSerial());
|
||||||
request.getHttpHeaders().addHeader(NONCE, request.getId());
|
request.getHttpHeaders().addHeader(NONCE, Objects.isNull(request.getId()) ? sequencer.next() : request.getId());
|
||||||
request.getHttpHeaders().addHeader(TIMESTAMP, DateTimes.ofTimestamp());
|
request.getHttpHeaders().addHeader(TIMESTAMP, DateTimes.ofTimestamp());
|
||||||
|
|
||||||
if (channel.isChannelGroupMode()) {
|
if (channel.isChannelGroupMode()) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.czcb.scfs.api.core.cipher;
|
||||||
|
|
||||||
|
import com.czcb.scfs.api.core.util.DateTimes;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wangwei
|
||||||
|
* @since 2024/7/26
|
||||||
|
*/
|
||||||
|
public class DefaultSequencer implements Sequencer {
|
||||||
|
private final SecureRandom secureRandom = new SecureRandom();
|
||||||
|
private final AtomicInteger number = new AtomicInteger(1);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() {
|
||||||
|
return String.format("%s%s%s", getCurrentDate(), getRandomStr(), getNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCurrentDate() {
|
||||||
|
return DateTimes.of("yyyyMMdd");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRandomStr() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
sb.append(secureRandom.nextInt(9));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer getNumber() {
|
||||||
|
return number.getAndIncrement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,12 +11,14 @@ public class DefaultSignature implements Signature {
|
||||||
private final Credential credential;
|
private final Credential credential;
|
||||||
private final Signer signer;
|
private final Signer signer;
|
||||||
private final Verifier verifier;
|
private final Verifier verifier;
|
||||||
|
private final Sequencer sequencer;
|
||||||
|
|
||||||
public DefaultSignature(CertificateProvider certificateProvider, Signer signer, Verifier verifier) {
|
public DefaultSignature(CertificateProvider certificateProvider, Signer signer, Verifier verifier, Sequencer sequencer) {
|
||||||
this.certificateProvider = certificateProvider;
|
this.certificateProvider = certificateProvider;
|
||||||
this.signer = signer;
|
this.signer = signer;
|
||||||
this.verifier = verifier;
|
this.verifier = verifier;
|
||||||
this.credential = new DefaultCredential(this.signer);
|
this.credential = new DefaultCredential(signer, sequencer);
|
||||||
|
this.sequencer = sequencer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -38,4 +40,9 @@ public class DefaultSignature implements Signature {
|
||||||
public Verifier getVerifier() {
|
public Verifier getVerifier() {
|
||||||
return verifier;
|
return verifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Sequencer getSequencer() {
|
||||||
|
return sequencer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.czcb.scfs.api.core.cipher;
|
||||||
|
|
||||||
|
import com.czcb.scfs.api.core.validation.Length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发号器
|
||||||
|
*
|
||||||
|
* @author wangwei
|
||||||
|
* @since 2024/7/26
|
||||||
|
*/
|
||||||
|
public interface Sequencer {
|
||||||
|
|
||||||
|
@Length(max = 32)
|
||||||
|
String next();
|
||||||
|
}
|
||||||
|
|
@ -28,4 +28,11 @@ public interface Signature {
|
||||||
* @return Verifier
|
* @return Verifier
|
||||||
*/
|
*/
|
||||||
Verifier getVerifier();
|
Verifier getVerifier();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发号器
|
||||||
|
*
|
||||||
|
* @return Sequencer
|
||||||
|
*/
|
||||||
|
Sequencer getSequencer();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
package com.czcb.scfs.api.core.http;
|
package com.czcb.scfs.api.core.http;
|
||||||
|
|
||||||
import com.czcb.scfs.api.core.util.Nonce;
|
|
||||||
import com.czcb.scfs.api.core.util.Strings;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
@ -193,10 +190,6 @@ public class HttpRequest {
|
||||||
requireNonNull(this.httpMethod);
|
requireNonNull(this.httpMethod);
|
||||||
requireNonNull(this.url);
|
requireNonNull(this.url);
|
||||||
|
|
||||||
if (Strings.isEmpty(this.id)) {
|
|
||||||
this.id = Nonce.ofNonce();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Objects.isNull(this.headers)) {
|
if (Objects.isNull(this.headers)) {
|
||||||
this.headers = new HttpHeaders();
|
this.headers = new HttpHeaders();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.czcb.scfs.api.core.validation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.*;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wangwei
|
||||||
|
* @since 2024/7/9
|
||||||
|
*/
|
||||||
|
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface Length {
|
||||||
|
String message() default "";
|
||||||
|
|
||||||
|
int min() default 0;
|
||||||
|
|
||||||
|
int max() default 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.czcb.scfs.api.core.cipher;
|
||||||
|
|
||||||
|
import com.czcb.scfs.api.core.util.DateTimes;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class DefaultSequencerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void next() {
|
||||||
|
Sequencer sequencer = new DefaultSequencer();
|
||||||
|
String next = sequencer.next();
|
||||||
|
Assertions.assertNotNull(next);
|
||||||
|
|
||||||
|
Assertions.assertEquals(25, next.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNextDate() {
|
||||||
|
Sequencer sequencer = new DefaultSequencer();
|
||||||
|
String next = sequencer.next();
|
||||||
|
Assertions.assertNotNull(next);
|
||||||
|
String text = DateTimes.ofTransDate().replace("-", "");
|
||||||
|
Assertions.assertTrue(next.startsWith(text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,11 +20,13 @@ class DefaultSignatureTest {
|
||||||
|
|
||||||
Signer signer = new TestSigner(KeyText.loadTestPrivateKeyRSA(), "");
|
Signer signer = new TestSigner(KeyText.loadTestPrivateKeyRSA(), "");
|
||||||
Verifier verifier = new TestVerifier(provider);
|
Verifier verifier = new TestVerifier(provider);
|
||||||
DefaultSignature signature = new DefaultSignature(provider, signer, verifier);
|
DefaultSignature signature = new DefaultSignature(provider, signer, verifier, new DefaultSequencer());
|
||||||
|
|
||||||
Assertions.assertNotNull(signature.getCertificateProvider());
|
Assertions.assertNotNull(signature.getCertificateProvider());
|
||||||
Assertions.assertNotNull(signature.getSigner());
|
Assertions.assertNotNull(signature.getSigner());
|
||||||
Assertions.assertNotNull(signature.getCredential());
|
Assertions.assertNotNull(signature.getCredential());
|
||||||
Assertions.assertNotNull(signature.getVerifier());
|
Assertions.assertNotNull(signature.getVerifier());
|
||||||
|
Assertions.assertNotNull(signature.getSequencer());
|
||||||
|
Assertions.assertNotNull(signature.getSequencer().next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +35,7 @@ class DefaultValidatorTest {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider), new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy,
|
privacy,
|
||||||
|
|
@ -62,7 +62,7 @@ class DefaultValidatorTest {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "823CF3E310F2E2ED1AF85506E74A95DC4301006FDEF2FD019953FAF4DE12A8BF"),
|
new TestSigner(privateKey, "823CF3E310F2E2ED1AF85506E74A95DC4301006FDEF2FD019953FAF4DE12A8BF"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider), new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy,
|
privacy,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,10 @@ class ApiClientBuilderTest {
|
||||||
list.add(certificate);
|
list.add(certificate);
|
||||||
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider, new TestSigner(privateKey, ""), new TestVerifier(certificateProvider));
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
|
new TestSigner(privateKey, ""),
|
||||||
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy,
|
privacy,
|
||||||
|
|
@ -106,7 +109,10 @@ class ApiClientBuilderTest {
|
||||||
list.add(certificate);
|
list.add(certificate);
|
||||||
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider, new TestSigner(privateKey, ""), new TestVerifier(certificateProvider));
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
|
new TestSigner(privateKey, ""),
|
||||||
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy,
|
privacy,
|
||||||
|
|
@ -126,7 +132,10 @@ class ApiClientBuilderTest {
|
||||||
list.add(certificate);
|
list.add(certificate);
|
||||||
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider, new TestSigner(privateKey, ""), new TestVerifier(certificateProvider));
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
|
new TestSigner(privateKey, ""),
|
||||||
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy,
|
privacy,
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,13 @@ class HttpRequestTest {
|
||||||
.url("/aa")
|
.url("/aa")
|
||||||
.build();
|
.build();
|
||||||
Assertions.assertNotNull(httpRequest.getHttpHeaders());
|
Assertions.assertNotNull(httpRequest.getHttpHeaders());
|
||||||
|
|
||||||
|
httpRequest = new HttpRequest.Builder()
|
||||||
|
.httpMethod(HttpMethod.GET)
|
||||||
|
.url("/aa")
|
||||||
|
.headers(null)
|
||||||
|
.build();
|
||||||
|
Assertions.assertNotNull(httpRequest.getHttpHeaders());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -85,6 +92,18 @@ class HttpRequestTest {
|
||||||
Assertions.assertNull(httpRequest.getHttpHeaders().getHeader("Accept-Encoding"));
|
Assertions.assertNull(httpRequest.getHttpHeaders().getHeader("Accept-Encoding"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void id() {
|
||||||
|
HttpRequest httpRequest = new HttpRequest.Builder()
|
||||||
|
.httpMethod(HttpMethod.GET)
|
||||||
|
.url("/aa")
|
||||||
|
.id("3333")
|
||||||
|
.compression(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Assertions.assertEquals("3333", httpRequest.getId());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void newBuilder() {
|
void newBuilder() {
|
||||||
HttpRequest httpRequest = new HttpRequest.Builder()
|
HttpRequest httpRequest = new HttpRequest.Builder()
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@ class ApacheHttpclientGroupTest {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ class ApacheHttpclientProxyTest {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ class ApacheHttpclientTest {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ class ApacheHttpclientTestProxyTest {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@ class ApacheHttpclientV2Test {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@ class ApacheHttpclientV3Test {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@ class ApacheHttpclientValidTest {
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider,
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
new TestSigner(privateKey, "823CF3E310F2E2ED1AF85506E74A95DC4301006FDEF2FD019953FAF4DE12A8BF"),
|
new TestSigner(privateKey, "823CF3E310F2E2ED1AF85506E74A95DC4301006FDEF2FD019953FAF4DE12A8BF"),
|
||||||
new TestVerifier(certificateProvider));
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ public class RsaProfile extends AbstractProfile {
|
||||||
private Signature signature;
|
private Signature signature;
|
||||||
private Channel channel;
|
private Channel channel;
|
||||||
private HttpProfile httpProfile;
|
private HttpProfile httpProfile;
|
||||||
|
private Sequencer sequencer;
|
||||||
|
|
||||||
public Builder privateKey(PrivateKey privateKey) {
|
public Builder privateKey(PrivateKey privateKey) {
|
||||||
this.privateKey = privateKey;
|
this.privateKey = privateKey;
|
||||||
|
|
@ -65,15 +66,25 @@ public class RsaProfile extends AbstractProfile {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder sequencer(Sequencer sequencer) {
|
||||||
|
this.sequencer = sequencer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public RsaProfile build() {
|
public RsaProfile build() {
|
||||||
requireNonNull(this.channel);
|
requireNonNull(this.channel);
|
||||||
|
|
||||||
|
if (Objects.isNull(this.sequencer)) {
|
||||||
|
this.sequencer = new DefaultSequencer();
|
||||||
|
}
|
||||||
|
|
||||||
CertificateProvider certificateProvider = new LocalCertificateProvider(certificates);
|
CertificateProvider certificateProvider = new LocalCertificateProvider(certificates);
|
||||||
this.privacy = new RsaPrivacy(privateKey, certificateProvider);
|
this.privacy = new RsaPrivacy(privateKey, certificateProvider);
|
||||||
X509Certificate certificate = certificateProvider.getAvailableCertificate();
|
X509Certificate certificate = certificateProvider.getAvailableCertificate();
|
||||||
this.signature = new DefaultSignature(certificateProvider,
|
this.signature = new DefaultSignature(certificateProvider,
|
||||||
new RsaSigner(privateKey, certificate.getSerialNumber().toString(HEX)),
|
new RsaSigner(privateKey, certificate.getSerialNumber().toString(HEX)),
|
||||||
new RsaVerifier(certificateProvider));
|
new RsaVerifier(certificateProvider),
|
||||||
|
this.sequencer);
|
||||||
|
|
||||||
httpProfile(httpProfile);
|
httpProfile(httpProfile);
|
||||||
if (Objects.isNull(httpProfile)) {
|
if (Objects.isNull(httpProfile)) {
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,10 @@ public class MockResponse {
|
||||||
list.add(certificate);
|
list.add(certificate);
|
||||||
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
|
||||||
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
|
||||||
Signature signature = new DefaultSignature(certificateProvider, new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"), new TestVerifier(certificateProvider));
|
Signature signature = new DefaultSignature(certificateProvider,
|
||||||
|
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
|
||||||
|
new TestVerifier(certificateProvider),
|
||||||
|
new DefaultSequencer());
|
||||||
|
|
||||||
return new TestProfile(
|
return new TestProfile(
|
||||||
privacy, signature, new DefaultChannel.Builder()
|
privacy, signature, new DefaultChannel.Builder()
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ public final class SmProfile extends AbstractProfile {
|
||||||
private Signature signature;
|
private Signature signature;
|
||||||
private Channel channel;
|
private Channel channel;
|
||||||
private HttpProfile httpProfile;
|
private HttpProfile httpProfile;
|
||||||
|
private Sequencer sequencer;
|
||||||
|
|
||||||
public Builder privateKey(PrivateKey privateKey) {
|
public Builder privateKey(PrivateKey privateKey) {
|
||||||
this.privateKey = privateKey;
|
this.privateKey = privateKey;
|
||||||
|
|
@ -81,9 +82,18 @@ public final class SmProfile extends AbstractProfile {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder sequencer(Sequencer sequencer) {
|
||||||
|
this.sequencer = sequencer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public SmProfile build() {
|
public SmProfile build() {
|
||||||
Objects.requireNonNull(this.channel);
|
Objects.requireNonNull(this.channel);
|
||||||
|
|
||||||
|
if (Objects.isNull(this.sequencer)) {
|
||||||
|
this.sequencer = new DefaultSequencer();
|
||||||
|
}
|
||||||
|
|
||||||
// 证书加载器
|
// 证书加载器
|
||||||
CertificateProvider certificateProvider = new LocalCertificateProvider(certificates);
|
CertificateProvider certificateProvider = new LocalCertificateProvider(certificates);
|
||||||
// 加密器
|
// 加密器
|
||||||
|
|
@ -91,7 +101,8 @@ public final class SmProfile extends AbstractProfile {
|
||||||
// 签名器
|
// 签名器
|
||||||
this.signature = new DefaultSignature(certificateProvider,
|
this.signature = new DefaultSignature(certificateProvider,
|
||||||
new Sm2Signer(privateKey, certificateSerial),
|
new Sm2Signer(privateKey, certificateSerial),
|
||||||
new Sm2Verifier(certificateProvider));
|
new Sm2Verifier(certificateProvider),
|
||||||
|
this.sequencer);
|
||||||
|
|
||||||
httpProfile(httpProfile);
|
httpProfile(httpProfile);
|
||||||
if (Objects.isNull(httpProfile)) {
|
if (Objects.isNull(httpProfile)) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package com.czcb.scfs.spring.boot.starter;
|
||||||
|
|
||||||
import com.czcb.scfs.api.core.ApiClient;
|
import com.czcb.scfs.api.core.ApiClient;
|
||||||
import com.czcb.scfs.api.core.Profile;
|
import com.czcb.scfs.api.core.Profile;
|
||||||
|
import com.czcb.scfs.api.core.cipher.DefaultSequencer;
|
||||||
|
import com.czcb.scfs.api.core.cipher.Sequencer;
|
||||||
import com.czcb.scfs.api.core.http.ApiClientBuilder;
|
import com.czcb.scfs.api.core.http.ApiClientBuilder;
|
||||||
import com.czcb.scfs.api.service.echo.EchoService;
|
import com.czcb.scfs.api.service.echo.EchoService;
|
||||||
import com.czcb.scfs.api.service.v2.account.AccountService;
|
import com.czcb.scfs.api.service.v2.account.AccountService;
|
||||||
|
|
@ -18,7 +20,7 @@ import com.czcb.scfs.api.service.v2.ocr.OcrService;
|
||||||
import com.czcb.scfs.api.service.v2.pay.PayService;
|
import com.czcb.scfs.api.service.v2.pay.PayService;
|
||||||
import com.czcb.scfs.api.service.v2.sms.SmsService;
|
import com.czcb.scfs.api.service.v2.sms.SmsService;
|
||||||
import com.czcb.scfs.api.service.v2.trans.TransService;
|
import com.czcb.scfs.api.service.v2.trans.TransService;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
@ -49,16 +51,25 @@ public class ScfsAutoConfiguration {
|
||||||
* 心跳检查
|
* 心跳检查
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(EchoService.class)
|
@ConditionalOnMissingBean
|
||||||
public EchoService echoService(ApiClient apiClient) {
|
public EchoService echoService(ApiClient apiClient) {
|
||||||
return new EchoService(apiClient);
|
return new EchoService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发号器
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public Sequencer sequencer() {
|
||||||
|
return new DefaultSequencer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账户相关
|
* 账户相关
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(AccountService.class)
|
@ConditionalOnMissingBean
|
||||||
public AccountService accountService(ApiClient apiClient) {
|
public AccountService accountService(ApiClient apiClient) {
|
||||||
return new AccountService(apiClient);
|
return new AccountService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +78,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 账单相关
|
* 账单相关
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(BillService.class)
|
@ConditionalOnMissingBean
|
||||||
public BillService billService(ApiClient apiClient) {
|
public BillService billService(ApiClient apiClient) {
|
||||||
return new BillService(apiClient);
|
return new BillService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +87,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 白名单
|
* 白名单
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(BmdService.class)
|
@ConditionalOnMissingBean
|
||||||
public BmdService bmdService(ApiClient apiClient) {
|
public BmdService bmdService(ApiClient apiClient) {
|
||||||
return new BmdService(apiClient);
|
return new BmdService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +96,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 公共数据
|
* 公共数据
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(CommunalDataService.class)
|
@ConditionalOnMissingBean
|
||||||
public CommunalDataService communalDataService(ApiClient apiClient) {
|
public CommunalDataService communalDataService(ApiClient apiClient) {
|
||||||
return new CommunalDataService(apiClient);
|
return new CommunalDataService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +106,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 人脸识别
|
* 人脸识别
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(FaceService.class)
|
@ConditionalOnMissingBean
|
||||||
public FaceService faceService(ApiClient apiClient) {
|
public FaceService faceService(ApiClient apiClient) {
|
||||||
return new FaceService(apiClient);
|
return new FaceService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +115,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 文件上传下载
|
* 文件上传下载
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(FileService.class)
|
@ConditionalOnMissingBean
|
||||||
public FileService fileService(ApiClient apiClient) {
|
public FileService fileService(ApiClient apiClient) {
|
||||||
return new FileService(apiClient);
|
return new FileService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +124,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 贷款类
|
* 贷款类
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(LoanService.class)
|
@ConditionalOnMissingBean
|
||||||
public LoanService loanService(ApiClient apiClient) {
|
public LoanService loanService(ApiClient apiClient) {
|
||||||
return new LoanService(apiClient);
|
return new LoanService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +133,7 @@ public class ScfsAutoConfiguration {
|
||||||
* OCR识别
|
* OCR识别
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(OcrService.class)
|
@ConditionalOnMissingBean
|
||||||
public OcrService ocrService(ApiClient apiClient) {
|
public OcrService ocrService(ApiClient apiClient) {
|
||||||
return new OcrService(apiClient);
|
return new OcrService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +142,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 支付类
|
* 支付类
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(PayService.class)
|
@ConditionalOnMissingBean
|
||||||
public PayService payService(ApiClient apiClient) {
|
public PayService payService(ApiClient apiClient) {
|
||||||
return new PayService(apiClient);
|
return new PayService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +151,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 短信类
|
* 短信类
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(SmsService.class)
|
@ConditionalOnMissingBean
|
||||||
public SmsService smsService(ApiClient apiClient) {
|
public SmsService smsService(ApiClient apiClient) {
|
||||||
return new SmsService(apiClient);
|
return new SmsService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +160,7 @@ public class ScfsAutoConfiguration {
|
||||||
* 交易类
|
* 交易类
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(TransService.class)
|
@ConditionalOnMissingBean
|
||||||
public TransService transService(ApiClient apiClient) {
|
public TransService transService(ApiClient apiClient) {
|
||||||
return new TransService(apiClient);
|
return new TransService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
@ -158,19 +169,19 @@ public class ScfsAutoConfiguration {
|
||||||
* 发票类
|
* 发票类
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(InvoiceService.class)
|
@ConditionalOnMissingBean
|
||||||
public InvoiceService invoiceService(ApiClient apiClient) {
|
public InvoiceService invoiceService(ApiClient apiClient) {
|
||||||
return new InvoiceService(apiClient);
|
return new InvoiceService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(ProjectService.class)
|
@ConditionalOnMissingBean
|
||||||
public ProjectService projectService(ApiClient apiClient) {
|
public ProjectService projectService(ApiClient apiClient) {
|
||||||
return new ProjectService(apiClient);
|
return new ProjectService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(OrderService.class)
|
@ConditionalOnMissingBean
|
||||||
public OrderService orderService(ApiClient apiClient) {
|
public OrderService orderService(ApiClient apiClient) {
|
||||||
return new OrderService(apiClient);
|
return new OrderService(apiClient);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,11 @@ class ScfsAutoConfigurationTest {
|
||||||
Assertions.assertNotNull(configuration.echoService(apiClient()));
|
Assertions.assertNotNull(configuration.echoService(apiClient()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sequencer() {
|
||||||
|
Assertions.assertNotNull(configuration.sequencer());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void accountService() {
|
void accountService() {
|
||||||
Assertions.assertNotNull(configuration.accountService(apiClient()));
|
Assertions.assertNotNull(configuration.accountService(apiClient()));
|
||||||
|
|
@ -126,4 +131,19 @@ class ScfsAutoConfigurationTest {
|
||||||
void transService() {
|
void transService() {
|
||||||
Assertions.assertNotNull(configuration.transService(apiClient()));
|
Assertions.assertNotNull(configuration.transService(apiClient()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void invoiceService() {
|
||||||
|
Assertions.assertNotNull(configuration.invoiceService(apiClient()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void projectService() {
|
||||||
|
Assertions.assertNotNull(configuration.projectService(apiClient()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void orderService() {
|
||||||
|
Assertions.assertNotNull(configuration.orderService(apiClient()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
package com.czcb.scfs.api.test.service;
|
package com.czcb.scfs.api.test.service;
|
||||||
|
|
||||||
import com.czcb.scfs.api.service.v2.invoice.InvoiceService;
|
import com.czcb.scfs.api.service.v2.invoice.InvoiceService;
|
||||||
import com.czcb.scfs.api.service.v2.invoice.model.InvoiceDepositQueryRequest;
|
import com.czcb.scfs.api.service.v2.invoice.model.*;
|
||||||
import com.czcb.scfs.api.service.v2.invoice.model.InvoiceDepositQueryResponse;
|
|
||||||
import com.czcb.scfs.api.service.v2.invoice.model.InvoiceInfoSaveRequest;
|
|
||||||
import com.czcb.scfs.api.service.v2.invoice.model.InvoiceSettleMatchRequest;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
|
@ -60,4 +57,17 @@ class InvoiceServiceTest {
|
||||||
InvoiceDepositQueryResponse response = invoiceService.invoiceDepositQuery(request);
|
InvoiceDepositQueryResponse response = invoiceService.invoiceDepositQuery(request);
|
||||||
System.out.println(response);
|
System.out.println(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void invoiceSettleRepay() {
|
||||||
|
InvoiceSettleRepayRequest request = new InvoiceSettleRepayRequest();
|
||||||
|
request.setChannelNo("1039");
|
||||||
|
request.setAppNo("21");
|
||||||
|
request.setSerialNo("123456");
|
||||||
|
request.setTransDate("2024-07-24");
|
||||||
|
request.setTransTradeTime("2024-07-24 15:52:11");
|
||||||
|
|
||||||
|
InvoiceSettleRepayResponse response = invoiceService.invoiceSettleRepay(request);
|
||||||
|
System.out.println(response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,19 @@
|
||||||
package com.czcb.scfs.api.test.service;
|
package com.czcb.scfs.api.test.service;
|
||||||
|
|
||||||
|
import com.czcb.scfs.api.service.v2.loan.LoanService;
|
||||||
|
import com.czcb.scfs.api.service.v2.loan.model.ApplyPersonRequest;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
class LoanServiceTest {
|
class LoanServiceTest {
|
||||||
|
@Resource
|
||||||
|
private LoanService loanService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void applyPerson() {
|
||||||
|
loanService.applyPerson(new ApplyPersonRequest());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue