package org.apereo.cas.monitor;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * Simple health check monitor that reports the overall health as the greatest reported
 * {@link StatusCode} of an arbitrary number of individual checks.
 *
 * @author Marvin S. Addison
 * @since 3.5.0
 */
public class HealthCheckMonitor implements Monitor<HealthStatus> {
    /**
     * Individual monitors that comprise health check.
     */
    private final Set<Monitor> monitors;

    public HealthCheckMonitor(final Set<Monitor> monitors) {
        this.monitors = monitors;
    }

    @Override
    public String getName() {
        return HealthCheckMonitor.class.getSimpleName();
    }

    @Override
    public HealthStatus observe() {
        final Map<String, Status> results = new LinkedHashMap<>(this.monitors.size());
        final StatusCode[] code = {StatusCode.UNKNOWN};
        final Status[] result = new Status[1];
        this.monitors.stream().forEach(monitor -> {
            try {
                result[0] = monitor.observe();
                final StatusCode resCode = result[0].getCode();
                if (resCode.value() > code[0].value()) {
                    code[0] = resCode;
                }
            } catch (final Exception e) {
                code[0] = StatusCode.ERROR;
                result[0] = new Status(code[0], e.getClass().getSimpleName() + ": " + e.getMessage());
            }
            results.put(monitor.getName(), result[0]);
        });

        return new HealthStatus(code[0], results);
    }
}

@@ -26,16 +26,45 @@
 nitor;%0A%0A
+import java.util.Comparator;%0A
 import j
@@ -130,16 +130,52 @@
 til.Set;
+%0Aimport java.util.stream.Collectors;
 %0A%0A/**%0A *
@@ -867,115 +867,241 @@
 s = 
-new LinkedHashMap%3C%3E(this.monitors.size());%0A        fin
+this.monitors.stream().collect(Collectors.toMap(Monitor::getName, HealthCheckMonitor::getResultOf,%0A                (v1, v2) -%3E %7Bthrow new Illeg
 al
- 
 Stat
-usCode%5B%5D code = %7BStatusCode.UNKNOWN%7D
+eException(String.format(%22Duplicate key %25s%22, v1));%7D, LinkedHashMap::new))
 ;%0A
+%0A
         
 fina
@@ -1100,163 +1100,204 @@
     
-final 
+return new HealthStatus(getWorst
 Status
-%5B%5D 
+From(
 result
- = new Status%5B1%5D
+s), results)
 ;%0A    
+%7D%0A%0A
     
-this.monitors.stream().forEach(monitor -%3E %7B%0A            try %7B%0A                result%5B0%5D = monitor.observe
+private static StatusCode getWorstStatusFrom(final Map%3CString, Status%3E results) %7B%0A        return results.values().stream
 ()
-;
 %0A   
@@ -1313,55 +1313,29 @@
     
-final StatusCode resCode = result%5B0%5D.
+.map(Status::
 getCode
-();
+)
 %0A   
@@ -1351,48 +1351,56 @@
     
-if (resCode.value() %3E code%5B0%5D.
+.max(Comparator.comparingInt(StatusCode::
 value
-(
 ))
- %7B
 %0A   
@@ -1416,370 +1416,309 @@
     
-    code%5B0%5D = resCode
+.orElse(StatusCode.UNKNOWN)
 ;%0A    
+%7D%0A%0A
     
-        %7D%0A            %7D catch (final Exception e) %7B%0A                code%5B0%5D = StatusCode.ERROR;%0A                result%5B0%5D = new Status(code%5B0%5D, e.getClass().getSimpleName() + %22: %22 + e.getMessage());%0A            %7D%0A            results.put(monitor.getName(), result%5B0%5D);%0A        %7D);%0A%0A        return new HealthStatus(code%5B0%5D, results);
+private static Status getResultOf(final Monitor monitor) %7B%0A        try %7B%0A            return monitor.observe();%0A        %7D catch (final Exception e) %7B%0A            return new Status(StatusCode.ERROR, e.getClass().getSimpleName() + %22: %22 + e.getMessage());%0A        %7D
 %0A   

Move to a more functional-cleaner code (#2311)