|
|
@@ -18,7 +18,6 @@ import java.time.Duration;
|
|
|
import java.time.Instant;
|
|
|
import java.util.Base64;
|
|
|
import java.util.LinkedHashMap;
|
|
|
-import java.util.List;
|
|
|
import java.util.Locale;
|
|
|
import java.util.Map;
|
|
|
import java.util.UUID;
|
|
|
@@ -34,12 +33,13 @@ public class BaiduRtaService {
|
|
|
private final String sspid;
|
|
|
private final String eKey;
|
|
|
private final String tuPrefix;
|
|
|
- private final List<String> honorOrderIds;
|
|
|
- private final List<String> vivoOrderIds;
|
|
|
+ private final RtaOrderResolver orderResolver;
|
|
|
private final HttpClient httpClient;
|
|
|
private final ObjectMapper objectMapper;
|
|
|
|
|
|
- public BaiduRtaService(AppProperties props, ObjectMapper objectMapper) {
|
|
|
+ public BaiduRtaService(AppProperties props,
|
|
|
+ ObjectMapper objectMapper,
|
|
|
+ RtaOrderResolver orderResolver) {
|
|
|
this.enabled = props.isRtaEnabled();
|
|
|
this.endpoint = props.getRtaEndpoint();
|
|
|
this.timeout = props.getRtaTimeout() == null ? Duration.ofMillis(800) : props.getRtaTimeout();
|
|
|
@@ -50,8 +50,7 @@ public class BaiduRtaService {
|
|
|
String configuredEKey = trimToNull(props.getRtaEKey());
|
|
|
this.eKey = configuredEKey != null ? configuredEKey : trimToNull(props.getBaiduAuctionPriceEKey());
|
|
|
this.tuPrefix = trimToNull(props.getRtaTuPrefix());
|
|
|
- this.honorOrderIds = props.getHonorRtaOrderIds() == null ? List.of() : props.getHonorRtaOrderIds();
|
|
|
- this.vivoOrderIds = props.getVivoRtaOrderIds() == null ? List.of() : props.getVivoRtaOrderIds();
|
|
|
+ this.orderResolver = orderResolver;
|
|
|
this.httpClient = HttpClient.newBuilder().connectTimeout(this.timeout).build();
|
|
|
this.objectMapper = objectMapper;
|
|
|
}
|
|
|
@@ -66,15 +65,23 @@ public class BaiduRtaService {
|
|
|
if (!enabled) {
|
|
|
return BaiduRtaDecision.bypass();
|
|
|
}
|
|
|
- MediaConfig config = mediaConfig(media);
|
|
|
- if (config == null || endpoint == null || endpoint.isBlank() || customerName == null || sspid == null || eKey == null) {
|
|
|
+ if (!supportsMedia(media) || endpoint == null || endpoint.isBlank() || customerName == null || sspid == null || eKey == null) {
|
|
|
log.warn("[RTA][{}] skipped: missing global config", mediaLabel(media));
|
|
|
return BaiduRtaDecision.bypass();
|
|
|
}
|
|
|
String tu = buildTu(tagId);
|
|
|
- if (tu == null || config.orderIds.isEmpty() || appId == null || appId.isBlank()) {
|
|
|
- log.warn("[RTA][{}] skipped: missing media config | tu={} orderIds={} appId={}",
|
|
|
- mediaLabel(media), tu, config.orderIds, appId);
|
|
|
+ String requestOrderId = trimToNull(orderResolver == null ? null : orderResolver.resolveOrderId(tagId));
|
|
|
+ Map<String, Object> requestPreview = buildRequestPreview(appId, tagId, platform, params, ip, userAgent, tu, requestOrderId, null, null);
|
|
|
+ if (tu == null || appId == null || appId.isBlank()) {
|
|
|
+ log.warn("[RTA][{}] skipped: missing tag config | tagId={} tu={} appId={}",
|
|
|
+ mediaLabel(media), tagId, tu, appId);
|
|
|
+ log.info("[RTA][{}][request-preview] {}", mediaLabel(media), toJson(requestPreview));
|
|
|
+ log.info("[RTA][{}][response-preview] {}", mediaLabel(media), toJson(Map.of(
|
|
|
+ "applied", false,
|
|
|
+ "matched", true,
|
|
|
+ "reason", "missing tag config",
|
|
|
+ "latencyMs", 0
|
|
|
+ )));
|
|
|
return BaiduRtaDecision.bypass();
|
|
|
}
|
|
|
|
|
|
@@ -82,27 +89,12 @@ public class BaiduRtaService {
|
|
|
String requestId = UUID.randomUUID().toString().replace("-", "");
|
|
|
String timestamp = String.valueOf(Instant.now().getEpochSecond());
|
|
|
int os = rtaOs(platform);
|
|
|
- String requestOrderIds = String.join(",", config.orderIds);
|
|
|
- Map<String, Object> body = new LinkedHashMap<>();
|
|
|
- body.put("customerName", customerName);
|
|
|
- body.put("sspid", sspid);
|
|
|
- body.put("appsid", appId);
|
|
|
- body.put("tu", tu);
|
|
|
+ Map<String, Object> body = buildRequestPreview(appId, tagId, platform, params, ip, userAgent, tu, requestOrderId, requestId, timestamp);
|
|
|
body.put("sign", sign(timestamp, requestId));
|
|
|
- body.put("order_id", requestOrderIds);
|
|
|
- body.put("os", os);
|
|
|
- putIfNotBlank(body, "oaid", androidOaid(params, platform));
|
|
|
- putIfNotBlank(body, "idfa_md5", iosIdfaMd5(params, platform));
|
|
|
- putIfNotBlank(body, "idfa", iosIdfa(params, platform));
|
|
|
- putIfNotBlank(body, "caid_md5", iosCaidMd5(params, platform));
|
|
|
- putIfNotBlank(body, "caid", iosCaid(params, platform));
|
|
|
- putIfNotBlank(body, "ip", trimToNull(ip));
|
|
|
- putIfNotBlank(body, "ua", trimToNull(userAgent));
|
|
|
- body.put("request_id", requestId);
|
|
|
- body.put("timestamp", timestamp);
|
|
|
|
|
|
try {
|
|
|
String requestBody = objectMapper.writeValueAsString(body);
|
|
|
+ log.info("[RTA][{}][request] {}", mediaLabel(media), requestBody);
|
|
|
HttpRequest request = HttpRequest.newBuilder()
|
|
|
.uri(URI.create(endpoint))
|
|
|
.timeout(timeout)
|
|
|
@@ -111,9 +103,10 @@ public class BaiduRtaService {
|
|
|
.build();
|
|
|
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
|
|
|
long latencyMs = (System.nanoTime() - startedAt) / 1_000_000L;
|
|
|
+ log.info("[RTA][{}][response] status={} body={}", mediaLabel(media), response.statusCode(), response.body());
|
|
|
if (response.statusCode() != 200) {
|
|
|
log.warn("[RTA][{}] httpStatus={} requestId={} body={}", mediaLabel(media), response.statusCode(), requestId, response.body());
|
|
|
- return BaiduRtaDecision.of(false, null, requestId, tu, requestOrderIds, null, latencyMs, "httpStatus=" + response.statusCode());
|
|
|
+ return BaiduRtaDecision.of(false, null, requestId, tu, requestOrderId, null, latencyMs, "httpStatus=" + response.statusCode());
|
|
|
}
|
|
|
JsonNode root = objectMapper.readTree(response.body());
|
|
|
Integer code = root.hasNonNull("code") ? root.get("code").asInt() : null;
|
|
|
@@ -121,20 +114,56 @@ public class BaiduRtaService {
|
|
|
boolean matched = code != null && code == 200 && orderIds != null && !orderIds.isBlank();
|
|
|
log.info("[RTA][{}] requestId={} code={} matched={} orderIds={} latencyMs={}",
|
|
|
mediaLabel(media), requestId, code, matched, orderIds, latencyMs);
|
|
|
- return BaiduRtaDecision.of(matched, code, requestId, tu, requestOrderIds, orderIds, latencyMs, null);
|
|
|
+ return BaiduRtaDecision.of(matched, code, requestId, tu, requestOrderId, orderIds, latencyMs, null);
|
|
|
} catch (Exception e) {
|
|
|
long latencyMs = (System.nanoTime() - startedAt) / 1_000_000L;
|
|
|
log.warn("[RTA][{}] request failed | requestId={} error={}", mediaLabel(media), requestId, e.getMessage());
|
|
|
- return BaiduRtaDecision.of(false, null, requestId, tu, requestOrderIds, null, latencyMs, e.getMessage());
|
|
|
+ return BaiduRtaDecision.of(false, null, requestId, tu, requestOrderId, null, latencyMs, e.getMessage());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private MediaConfig mediaConfig(String media) {
|
|
|
- return switch (media) {
|
|
|
- case "honor" -> new MediaConfig(honorOrderIds);
|
|
|
- case "vivo" -> new MediaConfig(vivoOrderIds);
|
|
|
- default -> null;
|
|
|
- };
|
|
|
+ private Map<String, Object> buildRequestPreview(String appId,
|
|
|
+ String tagId,
|
|
|
+ String platform,
|
|
|
+ Map<String, String> params,
|
|
|
+ String ip,
|
|
|
+ String userAgent,
|
|
|
+ String tu,
|
|
|
+ String requestOrderId,
|
|
|
+ String requestId,
|
|
|
+ String timestamp) {
|
|
|
+ int os = rtaOs(platform);
|
|
|
+ Map<String, Object> body = new LinkedHashMap<>();
|
|
|
+ body.put("customerName", customerName);
|
|
|
+ body.put("sspid", sspid);
|
|
|
+ body.put("appsid", trimToNull(appId));
|
|
|
+ body.put("tagId", trimToNull(tagId));
|
|
|
+ body.put("platform", trimToNull(platform));
|
|
|
+ body.put("tu", tu);
|
|
|
+ putIfNotBlank(body, "order_id", requestOrderId);
|
|
|
+ body.put("os", os);
|
|
|
+ putIfNotBlank(body, "oaid", androidOaid(params, platform));
|
|
|
+ putIfNotBlank(body, "idfa_md5", iosIdfaMd5(params, platform));
|
|
|
+ putIfNotBlank(body, "idfa", iosIdfa(params, platform));
|
|
|
+ putIfNotBlank(body, "caid_md5", iosCaidMd5(params, platform));
|
|
|
+ putIfNotBlank(body, "caid", iosCaid(params, platform));
|
|
|
+ putIfNotBlank(body, "ip", trimToNull(ip));
|
|
|
+ putIfNotBlank(body, "ua", trimToNull(userAgent));
|
|
|
+ putIfNotBlank(body, "request_id", requestId);
|
|
|
+ putIfNotBlank(body, "timestamp", timestamp);
|
|
|
+ return body;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String toJson(Object value) {
|
|
|
+ try {
|
|
|
+ return objectMapper.writeValueAsString(value);
|
|
|
+ } catch (Exception e) {
|
|
|
+ return String.valueOf(value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static boolean supportsMedia(String media) {
|
|
|
+ return "honor".equals(media) || "vivo".equals(media);
|
|
|
}
|
|
|
|
|
|
private String buildTu(String tagId) {
|
|
|
@@ -233,7 +262,4 @@ public class BaiduRtaService {
|
|
|
String trimmed = value.trim();
|
|
|
return trimmed.isEmpty() ? null : trimmed;
|
|
|
}
|
|
|
-
|
|
|
- private record MediaConfig(List<String> orderIds) {
|
|
|
- }
|
|
|
}
|