feat: 어댑터/인터페이스/클라이언트 버킷 상태 모니터링 API 추가

- InflowTargetBucketController: 버킷 상태 조회 REST API
  GET /manage/inflow/adapter/bucket-status
  GET /manage/inflow/adapter/{adapterId}/bucket-status
  GET /manage/inflow/interface/bucket-status
  GET /manage/inflow/interface/{interfaceId}/bucket-status
  GET /manage/inflow/client/bucket-status
  GET /manage/inflow/client/{clientId}/bucket-status
- InflowTargetBucketService: DualInflowControlManager 에서 버킷 상태 조회
- TargetBucketStatusDTO: 어댑터/인터페이스/클라이언트 공통 버킷 상태 DTO

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
curry772
2026-04-29 14:59:26 +09:00
parent 4d479e4fd6
commit 5f24bacd48
3 changed files with 254 additions and 0 deletions
@@ -0,0 +1,121 @@
package com.eactive.eai.manage.inflow;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import com.eactive.eai.common.inflow.InflowControlManager;
import com.eactive.eai.common.inflow.InflowTargetVO;
import com.eactive.eai.common.inflow.dual.DualCustomBucket;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
/**
* 어댑터/인터페이스/클라이언트 버킷 상태 조회 서비스.
*
* DualInflowControlManager 가 활성화된 경우에만 동작한다.
* InflowControlManager 가 기본 구현체인 경우 빈 목록 또는 null 을 반환한다.
*/
@Service
public class InflowTargetBucketService {
// -------------------------------------------------------------------------
// 어댑터
// -------------------------------------------------------------------------
public TargetBucketStatusDTO getAdapterBucketStatus(String adapterId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return null;
DualCustomBucket bucket = manager.getAdapterBucket(adapterId);
if (bucket == null) return null;
return toDto(adapterId, "ADAPTER", bucket);
}
public List<TargetBucketStatusDTO> getAllAdapterBucketStatus() {
DualInflowControlManager manager = getDualManager();
if (manager == null) return new ArrayList<>();
return toDtoList("ADAPTER", manager.getAdapterBucketMap());
}
// -------------------------------------------------------------------------
// 인터페이스
// -------------------------------------------------------------------------
public TargetBucketStatusDTO getInterfaceBucketStatus(String interfaceId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return null;
DualCustomBucket bucket = manager.getInterfaceBucket(interfaceId);
if (bucket == null) return null;
return toDto(interfaceId, "INTERFACE", bucket);
}
public List<TargetBucketStatusDTO> getAllInterfaceBucketStatus() {
DualInflowControlManager manager = getDualManager();
if (manager == null) return new ArrayList<>();
return toDtoList("INTERFACE", manager.getInterfaceBucketMap());
}
// -------------------------------------------------------------------------
// 클라이언트
// -------------------------------------------------------------------------
public TargetBucketStatusDTO getClientBucketStatus(String clientId) {
DualInflowControlManager manager = getDualManager();
if (manager == null) return null;
DualCustomBucket bucket = manager.getClientBucket(clientId);
if (bucket == null) return null;
return toDto(clientId, "CLIENT", bucket);
}
public List<TargetBucketStatusDTO> getAllClientBucketStatus() {
DualInflowControlManager manager = getDualManager();
if (manager == null) return new ArrayList<>();
return toDtoList("CLIENT", manager.getClientBucketMap());
}
// -------------------------------------------------------------------------
// Private helpers
// -------------------------------------------------------------------------
private DualInflowControlManager getDualManager() {
InflowControlManager base = InflowControlManager.getInstance();
return (base instanceof DualInflowControlManager) ? (DualInflowControlManager) base : null;
}
private TargetBucketStatusDTO toDto(String targetId, String targetType, DualCustomBucket bucket) {
InflowTargetVO vo = bucket.getInflowTargetVo();
List<GroupBucketStatusDTO.BucketInfo> buckets = new ArrayList<>();
if (vo.getThresholdPerSecond() > 0) {
long capacity = vo.getThresholdPerSecond();
long available = bucket.getPerSecondAvailableTokens();
if (available < 0) available = capacity;
buckets.add(new GroupBucketStatusDTO.BucketInfo(
"perSecond", capacity, Math.min(available, capacity), "SEC"));
}
if (vo.getThreshold() > 0) {
long capacity = vo.getThreshold();
long available = bucket.getThresholdAvailableTokens();
if (available < 0) available = capacity;
buckets.add(new GroupBucketStatusDTO.BucketInfo(
"threshold", capacity, Math.min(available, capacity), vo.getThresholdTimeUnit()));
}
TargetBucketStatusDTO dto = new TargetBucketStatusDTO();
dto.setTargetId(targetId);
dto.setTargetType(targetType);
dto.setActivate(vo.isActivate());
dto.setBuckets(buckets);
return dto;
}
private List<TargetBucketStatusDTO> toDtoList(String targetType, Map<String, DualCustomBucket> bucketMap) {
List<TargetBucketStatusDTO> result = new ArrayList<>();
for (Map.Entry<String, DualCustomBucket> entry : bucketMap.entrySet()) {
result.add(toDto(entry.getKey(), targetType, entry.getValue()));
}
return result;
}
}