feat: 发号器

main
13009 2024-07-26 18:50:54 +08:00
parent f1a3762154
commit 944a70d1e7
1 changed files with 180 additions and 0 deletions

View File

@ -0,0 +1,180 @@
package com.czcb.scfs.api.core.http.client;
import com.czcb.scfs.api.core.*;
import com.czcb.scfs.api.core.cipher.*;
import com.czcb.scfs.api.core.http.*;
import com.czcb.scfs.api.core.util.DateTimes;
import com.czcb.scfs.api.core.util.Nonce;
import com.czcb.scfs.api.core.util.Strings;
import com.google.gson.Gson;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockserver.client.MockServerClient;
import org.mockserver.junit.jupiter.MockServerExtension;
import org.mockserver.junit.jupiter.MockServerSettings;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPOutputStream;
import static com.czcb.scfs.api.core.Constants.*;
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
@ExtendWith(MockServerExtension.class)
@MockServerSettings(ports = {8888})
class ApacheHttpclientRequestIdTest {
private MockServerClient client;
@BeforeEach
public void beforeEachLifecyleMethod(MockServerClient client) {
this.client = client;
}
/**
*
*/
private Profile profile() {
PrivateKey privateKey = KeyText.loadTestPrivateKeyRSA();
X509Certificate certificate = KeyText.loadTestRSA();
List<X509Certificate> list = new ArrayList<>();
list.add(certificate);
CertificateProvider certificateProvider = new LocalCertificateProvider(list);
Privacy privacy = new TestPrivacy(privateKey, certificateProvider);
Signature signature = new DefaultSignature(certificateProvider,
new TestSigner(privateKey, "6CDDAA92CAD75998325027647847330C1756291"),
new TestVerifier(certificateProvider),
new DefaultSequencer());
return new TestProfile(
privacy, signature, new DefaultChannel.Builder()
.channelNo("0000")
.appNo("100000")
.build(), new DefaultHttpProfile.Builder()
.online(false)
.logLevel(LogLevel.BASIC)
.compressionEnabled(true)
.host("http://127.0.0.1:8888")
.build()
);
}
@Test
void doRemoteExecuteRequestId() {
TestResponse mockResponse = new TestResponse();
mockResponse.setName("123456");
ApiClient apiClient = mock(mockResponse.toJsonResponse().getBody());
TestRequest request = new TestRequest();
RequestBody requestBody = new JsonRequestBody.Builder()
.body(new Gson().toJson(request))
.build();
HttpRequest httpRequest = new HttpRequest.Builder().httpMethod(HttpMethod.POST)
.url("/mock/xxx")
.parameters(new QueryParameter())
.headers(new HttpHeaders())
.body(requestBody)
.id("00000000000")
.build();
HttpResponse<ApacheHttpclientTest.TestResponse> response = apiClient.exchange(httpRequest, ApacheHttpclientTest.TestResponse.class);
assertThatJson("{\"name\":\"123456\"}").isEqualTo(response.getServiceResponse().toJsonResponse().getBody());
}
private ApiClient mock(String body) {
ApiClient apiClient = ApiClientBuilder.custom()
.profile(profile())
.build();
// 对称密钥
byte[] secret = apiClient.getProfile().getPrivacy().getSecretCipher().getSecretKey();
// 加密响应报文
String responseBody = apiClient.getProfile().getPrivacy().getSecretCipher().encrypt(secret, body.getBytes(StandardCharsets.UTF_8));
// 加密对称密钥
String secretKey = apiClient.getProfile().getPrivacy().getEncryptor().encrypt(Strings.toStr(secret));
org.mockserver.model.HttpResponse mock = response()
.withHeader(NONCE, Nonce.ofNonce())
.withHeader(SECRET_KEY, secretKey)
.withHeader(REQUEST_ID, Nonce.ofNonce())
.withHeader(BANK_CERTIFICATE_SERIAL, "6CDDAA92CAD75998325027647847330C1756291")
.withHeader(CHANNEL_CERTIFICATE_SERIAL, "6CDDAA92CAD75998325027647847330C1756291")
.withHeader(TIMESTAMP, DateTimes.ofTimestamp());
mock.withHeader("Content-Encoding", "gzip");
mock.withBody(compress(responseBody));
String buildAuth = NONCE + "=" + mock.getHeader(NONCE).get(0) + "," +
TIMESTAMP + "=" + mock.getHeader(TIMESTAMP).get(0) + "," +
BANK_CERTIFICATE_SERIAL + "=" + mock.getHeader(BANK_CERTIFICATE_SERIAL).get(0) + "," +
CHANNEL_CERTIFICATE_SERIAL + "=" + mock.getHeader(CHANNEL_CERTIFICATE_SERIAL).get(0) + "," +
SECRET_KEY + "=" + secretKey;
String message = buildAuth + "\n" + responseBody + "\n";
mock.withHeader(SIGNATURE, apiClient.getProfile().getSignature().getSigner().sign(message).getSignature());
client.when(request()
.withHeader("Authorization", "SCFS-SHA256withRSA X-SCFS-Channel-No=0000,X-SCFS-App-No=100000,X-SCFS-Signature=.*")
.withHeader("X-SCFS-Nonce", "00000000000")
.withHeader("X-SCFS-Secret-Key", ".*")
.withHeader("X-SCFS-Serial", "6CDDAA92CAD75998325027647847330C1756291")
.withHeader("X-SCFS-Channel-Serial", "6CDDAA92CAD75998325027647847330C1756291")
.withHeader("X-SCFS-Timestamp", ".*")
.withMethod(HttpMethod.POST.getUpperName())
.withPath("/mock/xxx")
).respond(mock);
return apiClient;
}
public static byte[] compress(String str) {
ByteArrayOutputStream out = null;
GZIPOutputStream gzip = null;
try {
if (str == null || str.isEmpty()) {
return null;
}
out = new ByteArrayOutputStream();
gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes(StandardCharsets.UTF_8));
gzip.finish();
return out.toByteArray();
} catch (Exception e) {
return null;
} finally {
try {
if (out != null) {
out.close();
}
if (gzip != null) {
gzip.close();
}
} catch (Exception ignored) {
}
}
}
public static class TestRequest implements ApiRequest {
}
public static class TestResponse implements ApiResponse {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}