AdminController.java 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package com.adx.tencent.httpapi;
  2. import com.adx.tencent.baidu.ConversionClient;
  3. import com.adx.tencent.baidu.model.ConversionQuery;
  4. import com.adx.tencent.conversionsync.ConversionSyncRunner;
  5. import com.adx.tencent.conversionsync.ConversionSyncService;
  6. import com.adx.tencent.conversionsync.RetryService;
  7. import org.springframework.http.HttpStatus;
  8. import org.springframework.lang.Nullable;
  9. import org.springframework.web.bind.annotation.*;
  10. import org.springframework.web.server.ResponseStatusException;
  11. import java.util.List;
  12. import java.util.Map;
  13. /**
  14. * 管理接口:手动触发转化同步和回调重试。
  15. */
  16. @RestController
  17. @RequestMapping("/admin")
  18. public class AdminController {
  19. private final ConversionClient conversionClient;
  20. private final ConversionSyncRunner conversionSyncRunner;
  21. private final ConversionSyncService conversionSyncer;
  22. private final RetryService retryService;
  23. public AdminController(ConversionClient conversionClient,
  24. @Nullable ConversionSyncRunner conversionSyncRunner,
  25. @Nullable ConversionSyncService conversionSyncer,
  26. @Nullable RetryService retryService) {
  27. this.conversionClient = conversionClient;
  28. this.conversionSyncRunner = conversionSyncRunner;
  29. this.conversionSyncer = conversionSyncer;
  30. this.retryService = retryService;
  31. }
  32. @PostMapping("/conversions/query")
  33. public Object queryConversions(@RequestBody ConversionQuery query) throws Exception {
  34. return conversionClient.queryPayments(query);
  35. }
  36. @PostMapping("/conversions/sync")
  37. public Object syncConversions(@RequestBody ConversionQuery query) throws Exception {
  38. if (conversionSyncer == null) {
  39. throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,
  40. "conversion syncer is not configured");
  41. }
  42. return conversionSyncer.syncTencentConversions(query);
  43. }
  44. @PostMapping("/conversions/backfill")
  45. public Object backfillConversions(@RequestBody(required = false) Map<String, Object> body) throws Exception {
  46. if (conversionSyncRunner == null) {
  47. throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,
  48. "conversion sync runner is not configured");
  49. }
  50. List<Integer> offsets = parseOffsets(body);
  51. return conversionSyncRunner.runForOffsets(offsets);
  52. }
  53. @PostMapping("/callbacks/retry")
  54. public Object retryCallbacks(@RequestBody Map<String, Object> body) {
  55. if (retryService == null) {
  56. throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,
  57. "callback retryer is not configured");
  58. }
  59. int limit = toInt(body.get("limit"));
  60. return retryService.retryTencentCallbacks(limit);
  61. }
  62. private static int toInt(Object v) {
  63. if (v == null) return 0;
  64. if (v instanceof Number n) return n.intValue();
  65. try { return Integer.parseInt(v.toString()); } catch (NumberFormatException e) { return 0; }
  66. }
  67. private static List<Integer> parseOffsets(Map<String, Object> body) {
  68. if (body == null || body.isEmpty()) {
  69. return defaultBackfillOffsets();
  70. }
  71. Object raw = body.get("offsets");
  72. if (!(raw instanceof Iterable<?> iterable)) {
  73. return defaultBackfillOffsets();
  74. }
  75. List<Integer> offsets = new java.util.ArrayList<>();
  76. for (Object item : iterable) {
  77. offsets.add(toInt(item));
  78. }
  79. return offsets.isEmpty() ? defaultBackfillOffsets() : offsets;
  80. }
  81. private static List<Integer> defaultBackfillOffsets() {
  82. return List.of(-1, -2, -3, -4, -5, -6, -7);
  83. }
  84. }