HealthSummaryService.java
package com.taxonomy.shared.service;
import com.taxonomy.analysis.service.LlmService;
import com.taxonomy.catalog.service.TaxonomyService;
import com.taxonomy.dto.AiAvailabilityLevel;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Aggregates health information from multiple internal status sources into a single dashboard view.
*/
@Service
public class HealthSummaryService {
private final TaxonomyService taxonomyService;
private final LlmService llmService;
private final LocalEmbeddingService embeddingService;
public HealthSummaryService(TaxonomyService taxonomyService,
LlmService llmService,
LocalEmbeddingService embeddingService) {
this.taxonomyService = taxonomyService;
this.llmService = llmService;
this.embeddingService = embeddingService;
}
public Map<String, Object> getSummary() {
var summary = new LinkedHashMap<String, Object>();
summary.put("timestamp", Instant.now().toString());
// Startup status
var startup = new LinkedHashMap<String, Object>();
AppInitializationStateService stateService = taxonomyService.getStateService();
startup.put("initialized", taxonomyService.isInitialized());
startup.put("status", taxonomyService.getInitStatus());
startup.put("phase", stateService.getState().name());
startup.put("phaseMessage", stateService.getMessage());
summary.put("startup", startup);
// AI / LLM status
var ai = new LinkedHashMap<String, Object>();
AiAvailabilityLevel level = llmService.getAvailabilityLevel();
ai.put("available", level != AiAvailabilityLevel.UNAVAILABLE);
ai.put("level", level.name());
ai.put("provider", level != AiAvailabilityLevel.UNAVAILABLE
? llmService.getActiveProviderName() : null);
summary.put("ai", ai);
// Embedding status
var embedding = new LinkedHashMap<String, Object>();
embedding.put("enabled", embeddingService.isEnabled());
embedding.put("available", embeddingService.isAvailable());
summary.put("embedding", embedding);
// Memory
Runtime rt = Runtime.getRuntime();
long heapUsed = rt.totalMemory() - rt.freeMemory();
long heapMax = rt.maxMemory();
var memory = new LinkedHashMap<String, Object>();
memory.put("heapUsedMB", heapUsed / (1024 * 1024));
memory.put("heapMaxMB", heapMax / (1024 * 1024));
memory.put("heapUsagePercent", Math.round((double) heapUsed / heapMax * 100));
summary.put("memory", memory);
// Overall status
boolean allOk = stateService.isReady()
&& level != AiAvailabilityLevel.UNAVAILABLE;
summary.put("overall", allOk ? "UP" : "DEGRADED");
return summary;
}
}