Task 3-2: Health Check Endpoint cho JMS Listener Status
Phase: 3 - Dynamic Queue Priority: Low Module:
batchDepends on: task-3-1 Reference:docs/BountyHunter-Backend/details/feature-game-room-management/SPEC.md
Background
Không có cách nào để biết nhanh số lượng listeners đang chạy, listener nào đang down, hay số queues đã được register. Cần endpoint để ops team có thể inspect.
Tasks
File mới: batch/actuator/JmsListenerHealthIndicator.java
DI Note:
JmsListenerEndpointRegistrylà một Spring bean tự động được tạo khi dùng@EnableJms. Inject vào constructor — đây là cách Spring khuyến nghị choHealthIndicatorimplementations. Không cần@Autowiredannotation khi có duy nhất 1 constructor.Clarification: Tên bean
jmsListenerHealthtrong/actuator/healthresponse được Spring tự động derive từ tên class:JmsListenerHealthIndicator→jmsListenerHealth. Không cần cấu hình thêm.Import cần thiết: -
org.springframework.boot.actuate.health.HealthIndicator-org.springframework.boot.actuate.health.Health-org.springframework.jms.config.JmsListenerEndpointRegistry-org.springframework.jms.listener.MessageListenerContainer
@Component
public class JmsListenerHealthIndicator implements HealthIndicator {
private final JmsListenerEndpointRegistry registry;
// Constructor injection — Spring auto-injects JmsListenerEndpointRegistry bean
public JmsListenerHealthIndicator(JmsListenerEndpointRegistry registry) {
this.registry = registry;
}
@Override
public Health health() {
Collection<MessageListenerContainer> containers = registry.getListenerContainers();
long runningCount = containers.stream().filter(MessageListenerContainer::isRunning).count();
long stoppedCount = containers.size() - runningCount;
Map<String, Object> details = new LinkedHashMap<>();
details.put("total", containers.size());
details.put("running", runningCount);
details.put("stopped", stoppedCount);
if (stoppedCount > 0) {
// List stopped listener IDs để ops team biết listener nào bị down
List<String> stoppedIds = registry.getListenerContainerIds().stream()
.filter(id -> !registry.getListenerContainer(id).isRunning())
.collect(Collectors.toList());
details.put("stopped_ids", stoppedIds);
return Health.down().withDetails(details).build();
}
return Health.up().withDetails(details).build();
}
}
- [ ] Tạo file tại đúng package path:
com.figpop.batch.actuator - [ ] Verify accessible tại
GET /actuator/health→ response chứajmsListenerHealthcomponent - [ ] Đảm bảo
management.endpoint.health.show-details=alwaystrongapplication.yamlnếu muốn thấy details
Verification / Acceptance Criteria
- [ ]
GET /actuator/healthtrả về HTTP 200 vớijmsListenerHealth.status: "UP"khi tất cả listeners running - [ ] Khi dừng 1 listener thủ công (hoặc simulate stopped container),
GET /actuator/healthtrả vềstatus: "DOWN"vớistopped_idsliệt kê ID bị dừng - [ ]
details.total= tổng số listeners đã đăng ký (bao gồm cả listeners được đăng ký dynamically từ task-3-1) - [ ]
details.running+details.stopped=details.total(số học đúng) - [ ] Unit test: mock registry với 3 running + 1 stopped → verify
Health.down()vớistopped_ids= [stoppedId] - [ ] Unit test: mock registry với tất cả running → verify
Health.up() - [ ] Class compile được với Spring Boot Actuator dependency (kiểm tra
pom.xmlcủa modulebatch)
Files to Create
batch/src/main/java/com/figpop/batch/actuator/JmsListenerHealthIndicator.java