All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vertx.servicediscovery.ServiceDiscovery Maven / Gradle / Ivy

/*
 * 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;

import io.vertx.codegen.annotations.Fluent;
import io.vertx.codegen.annotations.Nullable;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.servicediscovery.impl.DiscoveryImpl;
import io.vertx.servicediscovery.spi.ServiceExporter;
import io.vertx.servicediscovery.spi.ServiceImporter;
import io.vertx.servicediscovery.utils.ClassLoaderUtils;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;

/**
 * Service Discovery main entry point.
 * 

* The service discovery is an infrastructure that let you publish and find `services`. A `service` is a discoverable * functionality. It can be qualified by its type, metadata, and location. So a `service` can be a database, a * service proxy, a HTTP endpoint. It does not have to be a vert.x entity, but can be anything. Each service is * described by a {@link Record}. *

* The service discovery implements the interactions defined in the service-oriented computing. And to some extend, * also provides the dynamic service-oriented computing interaction. So, application can react to arrival and * departure of services. *

* A service provider can: *

* * publish a service record * * un-publish a published record * * update the status of a published service (down, out of service...) *

* A service consumer can: *

* * lookup for services * * bind to a selected service (it gets a {@link ServiceReference}) and use it * * release the service once the consumer is done with it * * listen for arrival, departure and modification of services. *

* Consumer would 1) lookup for service record matching their need, 2) retrieve the {@link ServiceReference} that give access * to the service, 3) get a service object to access the service, 4) release the service object once done. *

* A state above, the central piece of information shared by the providers and consumers are {@link Record records}. *

* Providers and consumers must create their own {@link ServiceDiscovery} instance. These instances are collaborating * in background (distributed structure) to keep the set of services in sync. * * @author Clement Escoffier */ @VertxGen public interface ServiceDiscovery { /** * Creates an instance of {@link ServiceDiscovery}. * * @param vertx the vert.x instance * @param options the discovery options * @return the created service discovery instance. */ static ServiceDiscovery create(Vertx vertx, ServiceDiscoveryOptions options) { return new DiscoveryImpl(vertx, options); } /** * Creates a new instance of {@link ServiceDiscovery} using the default configuration. * * @param vertx the vert.x instance * @return the created instance */ static ServiceDiscovery create(Vertx vertx) { return create(vertx, new ServiceDiscoveryOptions()); } /** * Constant for type field of usage events. * * @see #EVENT_TYPE_BIND * @see #EVENT_TYPE_RELEASE */ String EVENT_TYPE = "type"; /** * Constant for event type `Bind`. * * @see #EVENT_TYPE */ String EVENT_TYPE_BIND = "bind"; /** * Constant for event type `Release`. * * @see #EVENT_TYPE */ String EVENT_TYPE_RELEASE = "release"; /** * Constant for record field of usage events. */ String EVENT_RECORD = "record"; /** * Constant for id field of usage events. */ String EVENT_ID = "id"; /** * Gets a service reference from the given record. * * @param record the chosen record * @return the service reference, that allows retrieving the service object. Once called the service reference is * cached, and need to be released. */ ServiceReference getReference(Record record); /** * Gets a service reference from the given record, the reference is configured with the given json object. * * @param record the chosen record * @param configuration the configuration * @return the service reference, that allows retrieving the service object. Once called the service reference is * cached, and need to be released. */ ServiceReference getReferenceWithConfiguration(Record record, JsonObject configuration); /** * Releases the service reference. * * @param reference the reference to release, must not be {@code null} * @return whether or not the reference has been released. */ boolean release(ServiceReference reference); /** * Registers a discovery service importer. Importers let you integrate other discovery technologies in this service * discovery. * * @param importer the service importer * @param configuration the optional configuration * @return a future notified when the importer has finished its initialization and * initial imports */ Future registerServiceImporter(ServiceImporter importer, JsonObject configuration); /** * Registers a discovery bridge. Exporters let you integrate other discovery technologies in this service * discovery. * * @param exporter the service exporter * @param configuration the optional configuration * @return a future notified when the exporter has been correctly initialized. */ Future registerServiceExporter(ServiceExporter exporter, JsonObject configuration); /** * Closes the service discovery */ void close(); /** * Publishes a record. * * @param record the record * @return a future notified when the operation has completed (successfully or not). In case of success, * the passed record has a registration id required to modify and un-register the service. */ Future publish(Record record); /** * Un-publishes a record. * * @param id the registration id * @return a future notified when the operation has completed (successfully or not). */ Future unpublish(String id); /** * Lookups for a single record. *

* Filters are expressed using a Json object. Each entry of the given filter will be checked against the record. * All entry must match exactly the record. The entry can use the special "*" value to denotes a requirement on the * key, but not on the value. *

* Let's take some example: *

   *   { "name" = "a" } => matches records with name set fo "a"
   *   { "color" = "*" } => matches records with "color" set
   *   { "color" = "red" } => only matches records with "color" set to "red"
   *   { "color" = "red", "name" = "a"} => only matches records with name set to "a", and color set to "red"
   * 
*

* If the filter is not set ({@code null} or empty), it accepts all records. *

* This method returns the first matching record. * * @param filter the filter. * @return a future notified when the lookup has been completed. When there are no matching record, the * operation succeeds, but the async result has no result ({@code null}). */ Future<@Nullable Record> getRecord(JsonObject filter); /** * Looks up for a single record by its registration {@code id}. *

* When there are no matching record, the operation succeeds, but the async result has no result ({@code null}). * * @param id the registration id * @return a future notified when the lookup has been completed * @see Record#getRegistration() */ Future<@Nullable Record> getRecord(String id); /** * Lookups for a single record. *

* The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it * as an {@code accept} method of a filter. This method return a record passing the filter. *

* This method only looks for records with a {@code UP} status. * * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records * @return a future notified when the lookup has been completed. When there are no matching * record, the operation succeed, but the async result has no result. */ Future<@Nullable Record> getRecord(Function filter); /** * Lookups for a single record. *

* The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it * as an {@code accept} method of a filter. This method return a record passing the filter. *

* Unlike {@link #getRecord(Function)}, this method may accept records with a {@code OUT OF SERVICE} * status, if the {@code includeOutOfService} parameter is set to {@code true}. * * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records * @param includeOutOfService whether or not the filter accepts {@code OUT OF SERVICE} records * @return a future notified when the lookup has been completed. When there are no matching * record, the operation succeed, but the async result has no result. */ Future<@Nullable Record> getRecord(Function filter, boolean includeOutOfService); /** * Lookups for a set of records. Unlike {@link #getRecord(JsonObject)}, this method returns all matching * records. * * @param filter the filter - see {@link #getRecord(JsonObject)} * @return a future notified when the lookup has been completed. When there are no matching record, the * operation succeed, but the async result has an empty list as result. */ Future> getRecords(JsonObject filter); /** * Lookups for a set of records. Unlike {@link #getRecord(Function)}, this method returns all matching * records. *

* The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it * as an {@code accept} method of a filter. This method return a record passing the filter. *

* This method only looks for records with a {@code UP} status. * * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records * @return a future notified when the lookup has been completed. When there are no matching record, the * operation succeed, but the async result has an empty list as result. */ Future> getRecords(Function filter); /** * Lookups for a set of records. Unlike {@link #getRecord(Function)}, this method returns all matching * records. *

* The filter is a {@link Function} taking a {@link Record} as argument and returning a boolean. You should see it * as an {@code accept} method of a filter. This method return a record passing the filter. *

* Unlike {@link #getRecords(Function)}, this method may accept records with a {@code OUT OF SERVICE} * status, if the {@code includeOutOfService} parameter is set to {@code true}. * * @param filter the filter, must not be {@code null}. To return all records, use a function accepting all records * @param includeOutOfService whether the filter accepts {@code OUT OF SERVICE} records * @return a future notified when the lookup has been completed. When there are no matching record, the * operation succeed, but the async result has an empty list as result. */ Future> getRecords(Function filter, boolean includeOutOfService); /** * Updates the given record. The record must has been published, and has it's registration id set. * * @param record the updated record * @return a future notified when the lookup has been completed. */ Future update(Record record); /** * @return the set of service references retrieved by this service discovery. */ Set bindings(); /** * @return the discovery options. Modifying the returned object would not update the discovery service * configuration. This object should be considered as read-only. */ ServiceDiscoveryOptions options(); /** * Release the service object retrieved using {@code get} methods from the service type interface. * It searches for the reference associated with the given object and release it. * * @param discovery the service discovery * @param svcObject the service object */ static void releaseServiceObject(ServiceDiscovery discovery, Object svcObject) { Objects.requireNonNull(discovery); Objects.requireNonNull(svcObject); Object svc = ClassLoaderUtils.extractDelegate(svcObject); if (svc == null) { svc = svcObject; } Collection references = discovery.bindings(); Object finalSvc = svc; references.stream().filter(ref -> ref.isHolding(finalSvc)).forEach(ServiceReference::release); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy