io.github.lucasepe.core.rest.Breezy Maven / Gradle / Ivy
package io.github.lucasepe.core.rest;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.*;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Breezy {
private static final Logger LOG = Logger.getLogger(Breezy.class.getName());
private static final String ROOT_PATH = "/";
public static Function> invoke() {
return (api) -> {
for (Node node : api.nodes) {
if (!node.shouldTry()) {
LOG.log(Level.WARNING, String.format("node %1$s not ready", node));
continue;
}
LOG.log(Level.FINE, String.format("trying node %1$s", node));
final HttpUrl.Builder url = Objects.requireNonNull(HttpUrl.parse(node.getUrl())).newBuilder();
url.encodedPath(Breezy.path().apply(api));
final Map params = Breezy.queryParams().apply(api);
for (Map.Entry entry : params.entrySet()) {
url.addQueryParameter(entry.getKey(), entry.getValue());
}
LOG.log(Level.FINE, String.format("=> %1$s %2$s", api.query.verb, url));
HttpRequest request = null;
try {
request = new HttpRequest(url.build().toString(), api.query.verb.toString());
for (Map.Entry entry : api.headers.entrySet()) {
request.header(entry.getKey(), entry.getValue());
}
if (api.query.hasBody()) {
final String payload = api.alterBodyFunction.apply(api.query.getBody());
LOG.log(Level.FINE, String.format("=> %1$s", payload));
request.contentType(HttpRequest.CONTENT_TYPE_JSON);
request.send(payload);
}
final int code = request.code();
final String message = request.message();
LOG.log(Level.FINEST, String.format("server response code: %1$d, message: %2$s", code, message));
node.succeeded();
final String body = request.body();
LOG.log(Level.FINE, String.format("<= %1$s", body));
if ((code >= 200) && (code < 300)) {
return Optional.ofNullable(body);
}
throw new ApiException(code, message, body);
} catch (HttpRequest.HttpRequestException err) {
if (err.getCause() instanceof ConnectException) {
LOG.log(Level.SEVERE, String.format("failed to reach url: %1$s", node), err);
node.failed();
} else if (err.getCause() instanceof UnknownHostException) {
LOG.log(Level.SEVERE, String.format("invalid or unknown host: %1$s", node), err);
node.failed();
} else {
throw err;
}
} finally {
if (request != null) {
request.disconnect();
}
}
}
throw new RuntimeException(
String.format("could not connect to any of the nodes: %1$s", Arrays.toString(api.nodes)));
};
}
public static Function path() {
return (api) -> {
if ((api == null) || api.query.uri.equals(ROOT_PATH)) {
return ROOT_PATH;
}
final String format = api.query.uri.startsWith(ROOT_PATH) ? "http://localhost%1$s" : "http://localhost/%1$s";
final HttpUrl url = HttpUrl.parse(String.format(format, api.query.uri));
return (url != null) ? url.encodedPath() : ROOT_PATH;
};
}
public static Function> queryParams() {
return (api) -> {
if ((api == null) || (api.query.uri.equals("/"))) {
return Collections.emptyMap();
}
final String format = api.query.uri.startsWith(ROOT_PATH) ? "http://localhost%1$s" : "http://localhost/%1$s";
final HttpUrl url = HttpUrl.parse(String.format(format, api.query.uri));
if (url == null) {
return Collections.emptyMap();
}
final Map result = new HashMap<>();
final Set params = url.queryParameterNames();
for (String name: params) {
result.put(name, url.queryParameter(name));
}
return result;
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy