package com.xuqm.update.service; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.*; import org.springframework.stereotype.Service; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; import java.util.LinkedHashMap; import java.util.Map; @Service public class ConnectivityValidationService { private final HttpClient httpClient = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(5)) .build(); private final ObjectMapper objectMapper = new ObjectMapper(); public void validateCallbackUrl(String url, String label) { if (url == null || url.isBlank()) { return; } try { Map body = new LinkedHashMap<>(); body.put("probe", true); body.put("label", label); body.put("timestamp", System.currentTimeMillis()); String payload = objectMapper.writeValueAsString(body); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .timeout(Duration.ofSeconds(5)) .header("Content-Type", "application/json") .header("X-Xuqm-Connectivity-Check", "true") .POST(HttpRequest.BodyPublishers.ofString(payload)) .build(); HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); int status = response.statusCode(); if (status < 200 || status >= 400) { throw new IllegalStateException("connectivity check failed with HTTP " + status); } } catch (Exception e) { throw new IllegalArgumentException("cannot connect to " + label + ": " + url, e); } } }