package io.vertx.servicediscovery.rest;
import io.vertx.core.json.Json;
import io.vertx.core.json.JsonObject;
import io.vertx.servicediscovery.ServiceDiscovery;
import io.vertx.servicediscovery.Record;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Objects;
public class ServiceDiscoveryRestEndpoint {
public static final String DEFAULT_ROOT = "/discovery";
private final ServiceDiscovery discovery;
public static ServiceDiscoveryRestEndpoint create(Router router, ServiceDiscovery discovery) {
return new ServiceDiscoveryRestEndpoint(router, discovery, DEFAULT_ROOT);
}
public static ServiceDiscoveryRestEndpoint create(Router router, ServiceDiscovery discovery, String root) {
return new ServiceDiscoveryRestEndpoint(router, discovery, root);
}
private ServiceDiscoveryRestEndpoint(Router router, ServiceDiscovery discovery, String root) {
Objects.requireNonNull(router);
Objects.requireNonNull(discovery);
Objects.requireNonNull(root);
this.discovery = discovery;
registerRoutes(router, root);
}
private void registerRoutes(Router router, String root) {
router.get(root).handler(this::all);
router.get(root + "/:uuid").handler(this::one);
router.delete(root + "/:uuid").handler(this::unpublish);
router.route().handler(BodyHandler.create());
router.post(root).handler(this::publish);
router.put(root + "/:uuid").handler(this::update);
}
private void update(RoutingContext routingContext) {
String uuid = routingContext.request().getParam("uuid");
JsonObject json = routingContext.getBodyAsJson();
Record record = new Record(json);
if (!uuid.equals(record.getRegistration())) {
routingContext.fail(400);
return;
}
discovery.update(record, ar -> {
if (ar.failed()) {
routingContext.fail(ar.cause());
} else {
routingContext.response().setStatusCode(200)
.putHeader("Content-Type", "application/json")
.end(ar.result().toJson().toString());
}
});
}
private void unpublish(RoutingContext routingContext) {
String uuid = routingContext.request().getParam("uuid");
discovery.unpublish(uuid, ar -> {
if (ar.failed()) {
routingContext.fail(ar.cause());
} else {
routingContext.response().setStatusCode(204).end();
}
});
}
private void one(RoutingContext routingContext) {
discovery.getRecord(new JsonObject().put("registration", routingContext.request().getParam("uuid")), ar -> {
if (ar.failed()) {
routingContext.fail(ar.cause());
} else {
if (ar.result() == null) {
routingContext.response().setStatusCode(404).end();
} else {
routingContext.response().setStatusCode(200)
.putHeader("Content-Type", "application/json")
.end(ar.result().toJson().toString());
}
}
});
}
private void publish(RoutingContext routingContext) {
JsonObject json = routingContext.getBodyAsJson();
Record record = new Record(json);
discovery.publish(record, ar -> {
if (ar.failed()) {
routingContext.fail(ar.cause());
} else {
routingContext.response().setStatusCode(201)
.putHeader("Content-Type", "application/json")
.end(ar.result().toJson().toString());
}
});
}
private void all(RoutingContext routingContext) {
String query = routingContext.request().params().get("query");
JsonObject filter = new JsonObject();
if (query != null) {
try {
String decoded = URLDecoder.decode(query, "UTF-8");
filter = new JsonObject(decoded);
} catch (UnsupportedEncodingException e) {
routingContext.fail(e);
return;
}
}
discovery.getRecords(filter, ar -> {
if (ar.failed()) {
routingContext.fail(ar.cause());
} else {
routingContext.response().setStatusCode(200)
.putHeader("Content-Type", "application/json")
.end(Json.encode(ar.result()));
}
});
}
}