package com.xuqm.im.service; import com.fasterxml.jackson.databind.JsonNode; import com.xuqm.common.exception.BusinessException; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component public class ImAppSecretClient { private final RestTemplate restTemplate = new RestTemplate(); private final Map cache = new ConcurrentHashMap<>(); @Value("${im.tenant-service-url:http://192.168.116.9:8081}") private String tenantServiceUrl; @Value("${im.internal-token:xuqm-internal-token}") private String internalToken; public String getAppSecret(String appId) { return cache.computeIfAbsent(appId, this::fetchAppSecret); } private String fetchAppSecret(String appId) { String url = UriComponentsBuilder.fromHttpUrl(tenantServiceUrl) .path("/api/internal/sdk/apps/{appId}/secret") .buildAndExpand(appId) .toUriString(); HttpHeaders headers = new HttpHeaders(); headers.set("X-Internal-Token", internalToken); try { ResponseEntity response = restTemplate.exchange( url, HttpMethod.GET, new HttpEntity<>(headers), JsonNode.class ); JsonNode body = response.getBody(); if (response.getStatusCode().is2xxSuccessful() && body != null && body.path("code").asInt() == 200) { return body.path("data").path("appSecret").asText(null); } } catch (RestClientException e) { throw new BusinessException(502, "Failed to resolve app secret: " + e.getMessage()); } throw new BusinessException(502, "Failed to resolve app secret for appId: " + appId); } }