/*
 * Copyright (c) 2011-2016 The original author or authors
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 *
 *      The Eclipse Public License is available at
 *      http://www.eclipse.org/legal/epl-v10.html
 *
 *      The Apache License v2.0 is available at
 *      http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */

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;

Allows publishing the vert.x service discovery as a REST endpoint. It supports retrieving services, but also publish, withdraw and modify services.
Author:Clement Escoffier
/** * Allows publishing the vert.x service discovery as a REST endpoint. It supports retrieving services, * but also publish, withdraw and modify services. * * @author <a href="http://escoffier.me">Clement Escoffier</a> */
public class ServiceDiscoveryRestEndpoint { public static final String DEFAULT_ROOT = "/discovery"; private final ServiceDiscovery discovery;
Creates the REST endpoint using the default root (/discovery).
Params:
  • router – the vert.x web router
  • discovery – the service discovery instance
Returns:the created endpoint
/** * Creates the REST endpoint using the default root ({@code /discovery}). * * @param router the vert.x web router * @param discovery the service discovery instance * @return the created endpoint */
public static ServiceDiscoveryRestEndpoint create(Router router, ServiceDiscovery discovery) { return new ServiceDiscoveryRestEndpoint(router, discovery, DEFAULT_ROOT); }
Creates the REST endpoint using the given root.
Params:
  • router – the vert.x web router
  • discovery – the service discovery instance
  • root – the endpoint path (root)
Returns:the created endpoint
/** * Creates the REST endpoint using the given root. * * @param router the vert.x web router * @param discovery the service discovery instance * @param root the endpoint path (root) * @return the created endpoint */
public static ServiceDiscoveryRestEndpoint create(Router router, ServiceDiscovery discovery, String root) { return new ServiceDiscoveryRestEndpoint(router, discovery, root); }
Params:
  • router – the router
  • discovery – the service discovery instance
  • root – the root
/** * Creates a new {@link ServiceDiscoveryRestEndpoint}. * * @param router the router * @param discovery the service discovery instance * @param root the root */
private ServiceDiscoveryRestEndpoint(Router router, ServiceDiscovery discovery, String root) { Objects.requireNonNull(router); Objects.requireNonNull(discovery); Objects.requireNonNull(root); this.discovery = discovery; registerRoutes(router, root); }
Registers the routes.
Params:
  • router – the router
  • root – the root
/** * Registers the routes. * * @param router the router * @param root the root */
private void registerRoutes(Router router, String root) { // Get all and query router.get(root).handler(this::all); // Get one router.get(root + "/:uuid").handler(this::one); // Unpublish router.delete(root + "/:uuid").handler(this::unpublish); // Publish router.route().handler(BodyHandler.create()); router.post(root).handler(this::publish); // Update 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())); } }); } }