request id
parent
04ec5ee891
commit
92beab28c1
|
|
@ -5,7 +5,6 @@ import com.czcb.scfs.api.core.http.HttpHeaders;
|
||||||
import com.czcb.scfs.api.core.http.HttpRequest;
|
import com.czcb.scfs.api.core.http.HttpRequest;
|
||||||
import com.czcb.scfs.api.core.http.OriginalResponse;
|
import com.czcb.scfs.api.core.http.OriginalResponse;
|
||||||
import com.czcb.scfs.api.core.util.DateTimes;
|
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.czcb.scfs.api.core.util.Strings;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -33,7 +32,7 @@ public class DefaultCredential implements Credential {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addNecessityCustomizeHeaders(HttpRequest request) {
|
private void addNecessityCustomizeHeaders(HttpRequest request) {
|
||||||
request.getHttpHeaders().addHeader(NONCE, Nonce.ofNonce());
|
request.getHttpHeaders().addHeader(NONCE, request.getId());
|
||||||
request.getHttpHeaders().addHeader(TIMESTAMP, DateTimes.ofTimestamp());
|
request.getHttpHeaders().addHeader(TIMESTAMP, DateTimes.ofTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.czcb.scfs.api.core.Profile;
|
||||||
import com.czcb.scfs.api.core.exception.TimestampException;
|
import com.czcb.scfs.api.core.exception.TimestampException;
|
||||||
import com.czcb.scfs.api.core.exception.ValidationException;
|
import com.czcb.scfs.api.core.exception.ValidationException;
|
||||||
import com.czcb.scfs.api.core.http.HttpLogger;
|
import com.czcb.scfs.api.core.http.HttpLogger;
|
||||||
|
import com.czcb.scfs.api.core.http.HttpRequest;
|
||||||
import com.czcb.scfs.api.core.http.OriginalResponse;
|
import com.czcb.scfs.api.core.http.OriginalResponse;
|
||||||
import com.czcb.scfs.api.core.util.Strings;
|
import com.czcb.scfs.api.core.util.Strings;
|
||||||
|
|
||||||
|
|
@ -36,7 +37,7 @@ public final class DefaultValidator implements Validator {
|
||||||
return httpCode < HTTP_OK || httpCode >= HTTP_MULT_CHOICE;
|
return httpCode < HTTP_OK || httpCode >= HTTP_MULT_CHOICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateTimestamp(OriginalResponse response) {
|
private void validateTimestamp(HttpRequest request, OriginalResponse response) {
|
||||||
try {
|
try {
|
||||||
String timestamp = response.getHttpHeaders().getHeader(TIMESTAMP);
|
String timestamp = response.getHttpHeaders().getHeader(TIMESTAMP);
|
||||||
if (Strings.isEmpty(timestamp)) {
|
if (Strings.isEmpty(timestamp)) {
|
||||||
|
|
@ -51,19 +52,19 @@ public final class DefaultValidator implements Validator {
|
||||||
timestamp, response.getHttpHeaders().getHeader(REQUEST_ID)));
|
timestamp, response.getHttpHeaders().getHeader(REQUEST_ID)));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
httpLogger.logResponseError(response);
|
httpLogger.logResponseError(request, response);
|
||||||
throw new TimestampException(e.getMessage(), e);
|
throw new TimestampException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate(OriginalResponse response, Channel channel) {
|
public void validate(HttpRequest request, OriginalResponse response, Channel channel) {
|
||||||
if (isInvalidHttpCode(response.getStatusCode())) {
|
if (isInvalidHttpCode(response.getStatusCode())) {
|
||||||
httpLogger.logHttpStatus(response);
|
httpLogger.logHttpStatus(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验时间戳
|
// 校验时间戳
|
||||||
validateTimestamp(response);
|
validateTimestamp(request, response);
|
||||||
|
|
||||||
// 请求头包含 SecretKey 进行验签
|
// 请求头包含 SecretKey 进行验签
|
||||||
if (!headerContainsSecretKey(response)) {
|
if (!headerContainsSecretKey(response)) {
|
||||||
|
|
@ -80,7 +81,7 @@ public final class DefaultValidator implements Validator {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!verifier.verify(null, message, signature)) {
|
if (!verifier.verify(null, message, signature)) {
|
||||||
httpLogger.logResponseError(response);
|
httpLogger.logResponseError(request, response);
|
||||||
throw new ValidationException(String.format("响应校验失败, 签名校验未通过, Request-Id=%s",
|
throw new ValidationException(String.format("响应校验失败, 签名校验未通过, Request-Id=%s",
|
||||||
response.getHttpHeaders().getHeader(REQUEST_ID)));
|
response.getHttpHeaders().getHeader(REQUEST_ID)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.czcb.scfs.api.core.cipher;
|
package com.czcb.scfs.api.core.cipher;
|
||||||
|
|
||||||
import com.czcb.scfs.api.core.Channel;
|
import com.czcb.scfs.api.core.Channel;
|
||||||
|
import com.czcb.scfs.api.core.http.HttpRequest;
|
||||||
import com.czcb.scfs.api.core.http.OriginalResponse;
|
import com.czcb.scfs.api.core.http.OriginalResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -12,5 +13,5 @@ public interface Validator {
|
||||||
/**
|
/**
|
||||||
* 验证返回是否合法
|
* 验证返回是否合法
|
||||||
*/
|
*/
|
||||||
void validate(OriginalResponse response, Channel channel);
|
void validate(HttpRequest request, OriginalResponse response, Channel channel);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,18 +68,19 @@ public abstract class AbstractApiClient implements ApiClient {
|
||||||
// 实际调用
|
// 实际调用
|
||||||
originalResponse = doRemoteExecute(newRequest);
|
originalResponse = doRemoteExecute(newRequest);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
httpLogger.logRemoteError(newRequest, e.getMessage());
|
||||||
throw new ApiClientException(e);
|
throw new ApiClientException(e);
|
||||||
} finally {
|
} finally {
|
||||||
watch.stop();
|
watch.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验响应
|
// 校验响应
|
||||||
OriginalResponse resultfulResponse = validateResponse(originalResponse);
|
OriginalResponse resultfulResponse = validateResponse(newRequest, originalResponse);
|
||||||
|
|
||||||
// 解析返回数据
|
// 解析返回数据
|
||||||
HttpResponse<T> httpResponse = assembleHttpResponse(resultfulResponse, responseClass);
|
HttpResponse<T> httpResponse = assembleHttpResponse(resultfulResponse, responseClass);
|
||||||
// 打印响应结果
|
// 打印响应结果
|
||||||
httpLogger.logResponse(originalResponse, httpResponse, watch.getLastTaskTimeMillis());
|
httpLogger.logResponse(newRequest, originalResponse, httpResponse, watch.getLastTaskTimeMillis());
|
||||||
return httpResponse;
|
return httpResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,6 +95,7 @@ public abstract class AbstractApiClient implements ApiClient {
|
||||||
request = httpRequestEncrypt(request);
|
request = httpRequestEncrypt(request);
|
||||||
// 组合请求数据
|
// 组合请求数据
|
||||||
HttpRequest.Builder builder = new HttpRequest.Builder()
|
HttpRequest.Builder builder = new HttpRequest.Builder()
|
||||||
|
.id(request.getId())
|
||||||
.url(fullUrlPattern(request))
|
.url(fullUrlPattern(request))
|
||||||
.httpMethod(request.getHttpMethod())
|
.httpMethod(request.getHttpMethod())
|
||||||
.addHeader(AUTHORIZATION, getAuthorization(request))
|
.addHeader(AUTHORIZATION, getAuthorization(request))
|
||||||
|
|
@ -172,8 +174,8 @@ public abstract class AbstractApiClient implements ApiClient {
|
||||||
* @param originalResponse OriginalResponse
|
* @param originalResponse OriginalResponse
|
||||||
* @return OriginalResponse
|
* @return OriginalResponse
|
||||||
*/
|
*/
|
||||||
private OriginalResponse validateResponse(OriginalResponse originalResponse) {
|
private OriginalResponse validateResponse(HttpRequest request, OriginalResponse originalResponse) {
|
||||||
validator.validate(originalResponse, getProfile().getChannel());
|
validator.validate(request, originalResponse, getProfile().getChannel());
|
||||||
return originalResponse;
|
return originalResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,19 +28,19 @@ public class HttpLogger {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("请求行:{} {} {}", request.getHttpMethod(), request.getUrl(), httpVersion);
|
logger.info("[{}] 请求行:{} {} {}", request.getId(), request.getHttpMethod(), request.getUrl(), httpVersion);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
request.getHttpHeaders().getHeaders().forEach((k, v) -> sb.append(k).append("=").append(v).append(";"));
|
request.getHttpHeaders().getHeaders().forEach((k, v) -> sb.append(k).append("=").append(v).append(";"));
|
||||||
logger.info("请求头:{}", Strings.removeSuffix(sb.toString(), ";"));
|
logger.info("[{}] 请求头:{}", request.getId(), Strings.removeSuffix(sb.toString(), ";"));
|
||||||
|
|
||||||
if (request.getRequestBody() instanceof EncryptRequestBody) {
|
if (request.getRequestBody() instanceof EncryptRequestBody) {
|
||||||
EncryptRequestBody body = (EncryptRequestBody) request.getRequestBody();
|
EncryptRequestBody body = (EncryptRequestBody) request.getRequestBody();
|
||||||
logger.info("请求原始报文:{}", Strings.toStr(body.getOriginalBody()));
|
logger.info("[{}] 请求原始报文:{}", request.getId(), Strings.toStr(body.getOriginalBody()));
|
||||||
logger.info("请求加密报文:{}", Strings.toStr(body.getBody()));
|
logger.info("[{}] 请求加密报文:{}", request.getId(), Strings.toStr(body.getBody()));
|
||||||
} else if (request.getRequestBody() instanceof JsonRequestBody) {
|
} else if (request.getRequestBody() instanceof JsonRequestBody) {
|
||||||
JsonRequestBody body = (JsonRequestBody) request.getRequestBody();
|
JsonRequestBody body = (JsonRequestBody) request.getRequestBody();
|
||||||
logger.info("请求原始报文:{}", Strings.toStr(body.getBody()));
|
logger.info("[{}] 请求原始报文:{}", request.getId(), Strings.toStr(body.getBody()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,19 +52,19 @@ public class HttpLogger {
|
||||||
* @param duration 请求耗时
|
* @param duration 请求耗时
|
||||||
* @param <T> 返回类型
|
* @param <T> 返回类型
|
||||||
*/
|
*/
|
||||||
protected <T> void logResponse(OriginalResponse originalResponse, HttpResponse<T> response, long duration) {
|
protected <T> void logResponse(HttpRequest request, OriginalResponse originalResponse, HttpResponse<T> response, long duration) {
|
||||||
if (!logEnabled) {
|
if (!logEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("响应行:{} {}", originalResponse.getVersion(), originalResponse.getStatusCode());
|
logger.info("[{}] 响应行:{} {}", request.getId(), originalResponse.getVersion(), originalResponse.getStatusCode());
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
response.getHttpHeaders().getHeaders().forEach((k, v) -> sb.append(k).append("=").append(v).append(";"));
|
response.getHttpHeaders().getHeaders().forEach((k, v) -> sb.append(k).append("=").append(v).append(";"));
|
||||||
logger.info("响应头:{}", Strings.removeSuffix(sb.toString(), ";"));
|
logger.info("[{}] 响应头:{}", request.getId(), Strings.removeSuffix(sb.toString(), ";"));
|
||||||
logger.info("响应原始报文:{}", Strings.toStr(response.getOriginalBody()));
|
logger.info("[{}] 响应原始报文:{}", request.getId(), Strings.toStr(response.getOriginalBody()));
|
||||||
logger.info("响应解密报文:{}", Json.toJson(response.getServiceResponse()));
|
logger.info("[{}] 响应解密报文:{}", request.getId(), Json.toJson(response.getServiceResponse()));
|
||||||
|
|
||||||
logger.info("请求-响应耗时(毫秒):{}", duration);
|
logger.info("[{}] 请求-响应耗时(毫秒):{}", request.getId(), duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -72,15 +72,19 @@ public class HttpLogger {
|
||||||
*
|
*
|
||||||
* @param originalResponse 响应数据
|
* @param originalResponse 响应数据
|
||||||
*/
|
*/
|
||||||
public void logResponseError(OriginalResponse originalResponse) {
|
public void logResponseError(HttpRequest request, OriginalResponse originalResponse) {
|
||||||
logger.info("响应:{} {}", originalResponse.getVersion(), originalResponse.getStatusCode());
|
logger.error("[{}] 响应:{} {}", request.getId(), originalResponse.getVersion(), originalResponse.getStatusCode());
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
originalResponse.getHttpHeaders().getHeaders().forEach((k, v) -> sb.append(k).append("=").append(v).append(";"));
|
originalResponse.getHttpHeaders().getHeaders().forEach((k, v) -> sb.append(k).append("=").append(v).append(";"));
|
||||||
logger.info("响应头:{}", Strings.removeSuffix(sb.toString(), ";"));
|
logger.error("[{}] 响应头:{}", request.getId(), Strings.removeSuffix(sb.toString(), ";"));
|
||||||
logger.info("响应原始报文:{}", Strings.toStr((originalResponse.getBody())));
|
logger.error("[{}] 响应原始报文:{}", request.getId(), Strings.toStr((originalResponse.getBody())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logHttpStatus(OriginalResponse response) {
|
public void logHttpStatus(OriginalResponse response) {
|
||||||
// TODO 打印状态码说明
|
// TODO 打印状态码说明
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void logRemoteError(HttpRequest newRequest, String message) {
|
||||||
|
logger.error("[{}] 远程调用异常:{}", newRequest.getId(), message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
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;
|
||||||
|
|
||||||
|
|
@ -14,6 +17,9 @@ import static java.util.Objects.requireNonNull;
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
public class HttpRequest {
|
public class HttpRequest {
|
||||||
|
// 请求Id
|
||||||
|
private final String id;
|
||||||
|
|
||||||
// http 请求方法
|
// http 请求方法
|
||||||
private final HttpMethod httpMethod;
|
private final HttpMethod httpMethod;
|
||||||
// 地址
|
// 地址
|
||||||
|
|
@ -27,6 +33,10 @@ public class HttpRequest {
|
||||||
// 是否开启压缩
|
// 是否开启压缩
|
||||||
private final boolean compression;
|
private final boolean compression;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
public HttpMethod getHttpMethod() {
|
public HttpMethod getHttpMethod() {
|
||||||
return httpMethod;
|
return httpMethod;
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +63,7 @@ public class HttpRequest {
|
||||||
|
|
||||||
public Builder newBuilder() {
|
public Builder newBuilder() {
|
||||||
return new Builder()
|
return new Builder()
|
||||||
|
.id(this.id)
|
||||||
.httpMethod(this.httpMethod)
|
.httpMethod(this.httpMethod)
|
||||||
.url(this.url)
|
.url(this.url)
|
||||||
.headers(this.httpHeaders)
|
.headers(this.httpHeaders)
|
||||||
|
|
@ -62,6 +73,7 @@ public class HttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest(Builder builder) {
|
private HttpRequest(Builder builder) {
|
||||||
|
this.id = builder.id;
|
||||||
this.httpMethod = builder.httpMethod;
|
this.httpMethod = builder.httpMethod;
|
||||||
this.url = builder.url;
|
this.url = builder.url;
|
||||||
this.parameters = builder.parameters;
|
this.parameters = builder.parameters;
|
||||||
|
|
@ -71,6 +83,7 @@ public class HttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
private String id;
|
||||||
private HttpMethod httpMethod;
|
private HttpMethod httpMethod;
|
||||||
private String url;
|
private String url;
|
||||||
private HttpHeaders headers = new HttpHeaders();
|
private HttpHeaders headers = new HttpHeaders();
|
||||||
|
|
@ -160,6 +173,17 @@ public class HttpRequest {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求id
|
||||||
|
*
|
||||||
|
* @param id id
|
||||||
|
* @return Builder
|
||||||
|
*/
|
||||||
|
public Builder id(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建HttpRequest
|
* 构建HttpRequest
|
||||||
*
|
*
|
||||||
|
|
@ -169,6 +193,10 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,13 @@
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<version>2.7.16</version>
|
<version>2.7.16</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue