/*
 * Copyright 2017-2020 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.micronaut.discovery;

import io.micronaut.core.convert.value.ConvertibleValues;
import io.micronaut.core.util.StringUtils;
import io.micronaut.health.HealthStatus;
import io.micronaut.http.HttpHeaders;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

Represents a remote service discovered by the underlying discovery implementation.

Author:Graeme Rocher
Since:1.0
/** * <p>Represents a remote service discovered by the underlying discovery implementation.</p> * * @author Graeme Rocher * @since 1.0 */
public interface ServiceInstance {
Constant to represent the group of the service contained with getMetadata().
/** * Constant to represent the group of the service contained with {@link #getMetadata()}. */
String GROUP = "group";
Constant to represent the zone of the service contained with getMetadata().
/** * Constant to represent the zone of the service contained with {@link #getMetadata()}. */
String ZONE = "zone";
Constant to represent the region of the service contained with getMetadata().
/** * Constant to represent the region of the service contained with {@link #getMetadata()}. */
String REGION = "region";
Returns:The identifier of the service used for purposes of service discovery
/** * @return The identifier of the service used for purposes of service discovery */
String getId();
Returns:The service URI
/** * @return The service URI */
URI getURI();
Returns:The HealthStatus of the instance
/** * @return The {@link HealthStatus} of the instance */
default HealthStatus getHealthStatus() { return HealthStatus.UP; }
Returns:The ID of the instance
/** * @return The ID of the instance */
default Optional<String> getInstanceId() { return Optional.empty(); }
Returns the availability zone to use. A zone is, for example, the AWS availability zone.
Returns:The zone to use
/** * Returns the availability zone to use. A zone is, for example, the AWS availability zone. * * @return The zone to use */
default Optional<String> getZone() { return getMetadata().get(ZONE, String.class); }
Returns the region to use. A region is, for example, the AWS region
Returns:The region
/** * Returns the region to use. A region is, for example, the AWS region * * @return The region */
default Optional<String> getRegion() { return getMetadata().get(REGION, String.class); }
Returns the application group. For example, the AWS auto-scaling group.
Returns:The group to use
/** * Returns the application group. For example, the AWS auto-scaling group. * * @return The group to use */
default Optional<String> getGroup() { return getMetadata().get(GROUP, String.class); }
Returns:The service metadata
/** * @return The service metadata */
default ConvertibleValues<String> getMetadata() { return ConvertibleValues.empty(); }
Returns:The service host
/** * @return The service host */
default String getHost() { return getURI().getHost(); }
Returns:Is the service instance available over a secure connection
/** * @return Is the service instance available over a secure connection */
default boolean isSecure() { String scheme = getURI().getScheme(); return scheme != null && scheme.equalsIgnoreCase("https"); }
Returns:The service port
/** * @return The service port */
default int getPort() { return getURI().getPort(); }
Resolve a URI relative to this service instance.
Params:
  • relativeURI – The relative URI
Returns:The relative URI
/** * Resolve a URI relative to this service instance. * * @param relativeURI The relative URI * @return The relative URI */
default URI resolve(URI relativeURI) { URI thisUri = getURI(); // if the URI features credentials strip this out if (StringUtils.isNotEmpty(thisUri.getUserInfo())) { try { thisUri = new URI(thisUri.getScheme(), null, thisUri.getHost(), thisUri.getPort(), thisUri.getPath(), thisUri.getQuery(), thisUri.getFragment()); } catch (URISyntaxException e) { throw new IllegalStateException("ServiceInstance URI is invalid: " + e.getMessage(), e); } } String rawQuery = thisUri.getRawQuery(); if (StringUtils.isNotEmpty(rawQuery)) { return thisUri.resolve(relativeURI + "?" + rawQuery); } else { return thisUri.resolve(relativeURI); } }
Construct a new ServiceInstance for the given ID and URL.
Params:
  • id – The ID
  • url – The URL
Returns:The instance
/** * Construct a new {@link ServiceInstance} for the given ID and URL. * * @param id The ID * @param url The URL * @return The instance */
static ServiceInstance of(String id, URL url) { try { URI uri = url.toURI(); return of(id, uri); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid URI argument: " + url); } }
Construct a new ServiceInstance for the given ID and URL.
Params:
  • id – The ID
  • uri – The URI
Returns:The instance
/** * Construct a new {@link ServiceInstance} for the given ID and URL. * * @param id The ID * @param uri The URI * @return The instance */
static ServiceInstance of(String id, URI uri) { return new ServiceInstance() { @Override public String getId() { return id; } @Override public URI getURI() { return uri; } @Override public ConvertibleValues<String> getMetadata() { String userInfo = uri.getUserInfo(); if (userInfo == null) { return ServiceInstance.super.getMetadata(); } else { Map<String, String> metadata = new HashMap<>(1); metadata.put(HttpHeaders.AUTHORIZATION_INFO, userInfo); return ConvertibleValues.of(metadata); } } }; }
Construct a new ServiceInstance for the given ID, host and port using the HTTP scheme.
Params:
  • id – The ID
  • host – The host
  • port – The port
Returns:The instance
/** * Construct a new {@link ServiceInstance} for the given ID, host and port using the HTTP scheme. * * @param id The ID * @param host The host * @param port The port * @return The instance */
static ServiceInstance of(String id, String host, int port) { return new ServiceInstance() { @Override public String getId() { return id; } @Override public URI getURI() { return URI.create("http://" + host + ":" + port); } }; }
A builder to builder a ServiceInstance.
Params:
  • id – The id
  • uri – The URI
Returns:The builder
/** * A builder to builder a {@link ServiceInstance}. * * @param id The id * @param uri The URI * @return The builder */
static Builder builder(String id, URI uri) { return new DefaultServiceInstance(id, uri); }
A builder for building ServiceInstance references.
/** * A builder for building {@link ServiceInstance} references. */
interface Builder {
Sets the instance id.
Params:
  • id – The instance id
Returns:This builder
/** * Sets the instance id. * * @param id The instance id * @return This builder */
Builder instanceId(String id);
Sets the zone.
Params:
  • zone – The zone
Returns:This builder
/** * Sets the zone. * * @param zone The zone * @return This builder */
Builder zone(String zone);
Sets the region.
Params:
  • region – The region
Returns:This builder
/** * Sets the region. * * @param region The region * @return This builder */
Builder region(String region);
Sets the application group.
Params:
  • group – The group
Returns:This builder
/** * Sets the application group. * * @param group The group * @return This builder */
Builder group(String group);
Sets the application status.
Params:
  • status – The status
Returns:This builder
/** * Sets the application status. * * @param status The status * @return This builder */
Builder status(HealthStatus status);
Sets the application metadata.
Params:
  • metadata – The metadata
Returns:This builder
/** * Sets the application metadata. * * @param metadata The metadata * @return This builder */
Builder metadata(Map<String, String> metadata);
Returns:The instance
/** * @return The instance */
ServiceInstance build(); } }