feat: add agent/env counts to vendor tenant list endpoint

Extend VendorTenantSummary with agentCount, environmentCount, and
agentLimit fields. Fetch counts in parallel using CompletableFuture
per tenant, only calling server API for ACTIVE tenants with RUNNING
servers. Agent limit extracted from license limits JSONB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-10 22:01:02 +02:00
parent a0c12b8ee6
commit d7ce0aaf8c
2 changed files with 41 additions and 14 deletions

View File

@@ -44,7 +44,10 @@ public class VendorTenantController {
String status, String status,
String serverState, String serverState,
String licenseExpiry, String licenseExpiry,
String provisionError String provisionError,
int agentCount,
int environmentCount,
int agentLimit
) {} ) {}
public record VendorTenantDetail( public record VendorTenantDetail(
@@ -59,19 +62,39 @@ public class VendorTenantController {
@GetMapping @GetMapping
public ResponseEntity<List<VendorTenantSummary>> listAll() { public ResponseEntity<List<VendorTenantSummary>> listAll() {
List<VendorTenantSummary> summaries = vendorTenantService.listAll().stream() var tenants = vendorTenantService.listAll();
.map(tenant -> { var futures = tenants.stream().map(tenant -> java.util.concurrent.CompletableFuture.supplyAsync(() -> {
ServerStatus status = vendorTenantService.getServerStatus(tenant); ServerStatus status = vendorTenantService.getServerStatus(tenant);
String licenseExpiry = vendorTenantService String licenseExpiry = vendorTenantService
.getLicenseForTenant(tenant.getId()) .getLicenseForTenant(tenant.getId())
.map(l -> l.getExpiresAt() != null ? l.getExpiresAt().toString() : null) .map(l -> l.getExpiresAt() != null ? l.getExpiresAt().toString() : null)
.orElse(null); .orElse(null);
return new VendorTenantSummary( int agentCount = 0;
tenant.getId(), tenant.getName(), tenant.getSlug(), int environmentCount = 0;
tenant.getTier().name(), tenant.getStatus().name(), int agentLimit = -1;
status.state().name(), licenseExpiry, tenant.getProvisionError() String endpoint = tenant.getServerEndpoint();
); boolean isActive = "ACTIVE".equals(tenant.getStatus().name());
}) if (isActive && endpoint != null && !endpoint.isBlank() && "RUNNING".equals(status.state().name())) {
var serverApi = vendorTenantService.getServerApiClient();
agentCount = serverApi.getAgentCount(endpoint);
environmentCount = serverApi.getEnvironmentCount(endpoint);
}
var license = vendorTenantService.getLicenseForTenant(tenant.getId());
if (license.isPresent() && license.get().getLimits() != null) {
var limits = license.get().getLimits();
if (limits.containsKey("agents")) {
agentLimit = ((Number) limits.get("agents")).intValue();
}
}
return new VendorTenantSummary(
tenant.getId(), tenant.getName(), tenant.getSlug(),
tenant.getTier().name(), tenant.getStatus().name(),
status.state().name(), licenseExpiry, tenant.getProvisionError(),
agentCount, environmentCount, agentLimit
);
})).toList();
List<VendorTenantSummary> summaries = futures.stream()
.map(java.util.concurrent.CompletableFuture::join)
.toList(); .toList();
return ResponseEntity.ok(summaries); return ResponseEntity.ok(summaries);
} }

View File

@@ -184,6 +184,10 @@ public class VendorTenantService {
} }
} }
public ServerApiClient getServerApiClient() {
return serverApiClient;
}
public List<TenantEntity> listAll() { public List<TenantEntity> listAll() {
return tenantService.findAll().stream() return tenantService.findAll().stream()
.filter(t -> t.getStatus() != TenantStatus.DELETED) .filter(t -> t.getStatus() != TenantStatus.DELETED)