package io.vertx.ext.healthchecks.impl;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import java.util.*;
import static io.vertx.ext.healthchecks.impl.StatusHelper.isUp;
class DefaultCompositeProcedure implements CompositeProcedure {
private Map<String, Procedure> children = new HashMap<>();
@Override
public DefaultCompositeProcedure add(String name, Procedure check) {
Objects.requireNonNull(name);
Objects.requireNonNull(check);
synchronized (this) {
children.put(name, check);
}
return this;
}
@Override
public synchronized boolean remove(String name) {
Objects.requireNonNull(name);
return children.remove(name) != null;
}
@Override
public synchronized Procedure get(String name) {
return children.get(name);
}
@Override
public void check(Handler<JsonObject> resultHandler) {
Map<String, Procedure> copy = new HashMap<>();
synchronized (this) {
copy.putAll(children);
}
JsonObject result = new JsonObject();
JsonArray checks = new JsonArray();
result.put("checks", checks);
Map<String, Promise<JsonObject>> tasks = new HashMap<>();
List<Future> completed = new ArrayList<>();
for (Map.Entry<String, Procedure> entry : copy.entrySet()) {
Promise<JsonObject> promise = Promise.promise();
completed.add(promise.future());
tasks.put(entry.getKey(), promise);
entry.getValue().check(promise::complete);
}
CompositeFuture.join(completed)
.setHandler(ar -> {
boolean success = true;
for (Map.Entry<String, Promise<JsonObject>> entry : tasks.entrySet()) {
Future<JsonObject> json = entry.getValue().future();
boolean up = isUp(json);
success = success && up;
JsonObject r = new JsonObject()
.put("id", json.result().getString("id", entry.getKey()))
.put("status", up ? "UP" : "DOWN");
if (json.result() != null) {
JsonObject data = json.result().getJsonObject("data");
JsonArray children = json.result().getJsonArray("checks");
if (data != null) {
data.remove("result");
r.put("data", data);
} else if (children != null) {
r.put("checks", children);
}
}
checks.add(r);
}
if (success) {
result.put("outcome", "UP");
} else {
result.put("outcome", "DOWN");
}
resultHandler.handle(result);
});
}
}