diff options
Diffstat (limited to 'msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul')
35 files changed, 5129 insertions, 0 deletions
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java new file mode 100644 index 0000000..576bf9b --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/CatalogClient.java @@ -0,0 +1,285 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul; + +import static org.openo.msb.wrapper.consul.util.ClientUtil.response; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.model.catalog.CatalogNode; +import org.openo.msb.wrapper.consul.model.catalog.CatalogService; +import org.openo.msb.wrapper.consul.model.health.Node; +import org.openo.msb.wrapper.consul.option.CatalogOptions; +import org.openo.msb.wrapper.consul.option.QueryOptions; + +/** + * HTTP Client for /v1/catalog/ endpoints or api/catalog/v1 by openresty + */ +public class CatalogClient { + + private static final GenericType<List<String>> TYPE_STRING_LIST = new GenericType<List<String>>() {}; + private static final GenericType<List<Node>> TYPE_NODE_LIST = new GenericType<List<Node>>() {}; + private static final GenericType<Map<String, List<String>>> TYPE_SERVICES_MAP = new GenericType<Map<String, List<String>>>() {}; + private static final GenericType<List<CatalogService>> TYPE_CATALOG_SERVICE_LIST = new GenericType<List<CatalogService>>() {}; + private static final GenericType<CatalogNode> TYPE_CATALOG_NODE = new GenericType<CatalogNode>() {}; + + private final WebTarget webTarget; + + /** + * Constructs an instance of this class. + * + * @param webTarget The {@link javax.ws.rs.client.WebTarget} to base requests from. + */ + CatalogClient(WebTarget webTarget) { + this.webTarget = webTarget; + } + + /** + * Retrieves all datacenters. + * + * GET /v1/catalog/datacenters + * + * @return A list of datacenter names. + */ + public List<String> getDatacenters() { + return webTarget.path("datacenters").request() + .accept(MediaType.APPLICATION_JSON_TYPE).get(TYPE_STRING_LIST); + } + + /** + * Retrieves all nodes. + * + * GET /v1/catalog/nodes + * + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse<List<Node>> getNodes() { + return getNodes(null, QueryOptions.BLANK); + } + + /** + * Retrieves all nodes for a given datacenter. + * + * GET /v1/catalog/nodes?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse<List<Node>> getNodes(CatalogOptions catalogOptions) { + return getNodes(catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves all nodes with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/nodes + * + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse<List<Node>> getNodes(QueryOptions queryOptions) { + return getNodes(null, queryOptions); + } + + /** + * Retrieves all nodes for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/nodes?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link org.openo.msb.wrapper.consul.model.health.Node} objects. + */ + public ConsulResponse<List<Node>> getNodes(CatalogOptions catalogOptions, QueryOptions queryOptions) { + return response(webTarget.path("nodes"), catalogOptions, queryOptions, TYPE_NODE_LIST); + } + + /** + * Retrieves all services for a given datacenter. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse<Map<String, List<String>>> getServices() { + return getServices(null, QueryOptions.BLANK); + } + + /** + * Retrieves all services for a given datacenter. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse<Map<String, List<String>>> getServices(CatalogOptions catalogOptions) { + return getServices(catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves all services for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse<Map<String, List<String>>> getServices(QueryOptions queryOptions) { + return getServices(null, queryOptions); + } + + /** + * Retrieves all services for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/services?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a map of service name to list of tags. + */ + public ConsulResponse<Map<String, List<String>>> getServices(CatalogOptions catalogOptions, QueryOptions queryOptions) { + return response(webTarget.path("services"), catalogOptions, queryOptions, TYPE_SERVICES_MAP); + } + + public void getService(QueryOptions queryOptions, ConsulResponseCallback<Map<String, List<String>>> callback) { + response(webTarget.path("services"), CatalogOptions.BLANK, + queryOptions, TYPE_SERVICES_MAP, callback); + } + + /** + * Retrieves a single service. + * + * GET /v1/catalog/service/{service} + * + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<List<CatalogService>> getService(String service) { + return getService(service, null, QueryOptions.BLANK); + } + + /** + * Retrieves a single service for a given datacenter. + * + * GET /v1/catalog/service/{service}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<List<CatalogService>> getService(String service, CatalogOptions catalogOptions) { + return getService(service, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves a single service with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/service/{service} + * + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<List<CatalogService>> getService(String service, QueryOptions queryOptions) { + return getService(service, null, queryOptions); + } + + public void getService(String service, QueryOptions queryOptions, ConsulResponseCallback<List<CatalogService>> callback) { + + response(webTarget.path("service").path(service), CatalogOptions.BLANK, + queryOptions, TYPE_CATALOG_SERVICE_LIST, callback); + } + + + + /** + * Retrieves a single service for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/service/{service}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing + * {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<List<CatalogService>> getService(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions) { + return response(webTarget.path("service").path(service), catalogOptions, queryOptions, + TYPE_CATALOG_SERVICE_LIST); + } + + /** + * Retrieves a single node. + * + * GET /v1/catalog/node/{node} + * + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<CatalogNode> getNode(String node) { + return getNode(node, null, QueryOptions.BLANK); + } + + /** + * Retrieves a single node for a given datacenter. + * + * GET /v1/catalog/node/{node}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<CatalogNode> getNode(String node, CatalogOptions catalogOptions) { + return getNode(node, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves a single node with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/node/{node} + * + * @param queryOptions The Query Options to use. + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<CatalogNode> getNode(String node, QueryOptions queryOptions) { + return getNode(node, null, queryOptions); + } + + /** + * Retrieves a single node for a given datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/catalog/node/{node}?dc={datacenter} + * + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A list of matching {@link org.openo.msb.wrapper.consul.model.catalog.CatalogService} objects. + */ + public ConsulResponse<CatalogNode> getNode(String node, CatalogOptions catalogOptions, QueryOptions queryOptions) { + return response(webTarget.path("node").path(node), catalogOptions, queryOptions, + TYPE_CATALOG_NODE); + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java new file mode 100644 index 0000000..2a55b7f --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/Consul.java @@ -0,0 +1,299 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; + +import org.openo.msb.wrapper.consul.util.Jackson; +import org.openo.msb.wrapper.consul.util.ObjectMapperContextResolver; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.guava.GuavaModule; +import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import com.google.common.net.HostAndPort; + +/** + * Client for interacting with the Consul HTTP API. + * + * @author rfast + */ +public class Consul { + + /** + * Default Consul HTTP API host. + */ + public static final String DEFAULT_HTTP_HOST = "localhost"; + + /** + * Default Consul HTTP API port. + */ + public static final int DEFAULT_HTTP_PORT = 8500; + + + + + private final CatalogClient catalogClient; + + private final HealthClient healthClient; + + + /** + * Private constructor. + * + * @param url The full URL of a running Consul instance. + * @param builder JAX-RS client builder instance. + */ + private Consul(String url, ClientBuilder builder, ObjectMapper mapper) { + + if (!FluentIterable.from(builder.getConfiguration().getClasses()) + .filter(new Predicate<Class<?>>() { + @Override + public boolean apply(final Class<?> clazz) { + return JacksonJaxbJsonProvider.class.isAssignableFrom(clazz); + } + }).first().isPresent()) { + builder.register(JacksonJaxbJsonProvider.class); + } + final Client client = builder + .register(new ObjectMapperContextResolver(mapper)) + .build(); + + + if(url.endsWith("8500")){ + this.catalogClient = new CatalogClient(client.target(url).path("v1").path("catalog")); + this.healthClient = new HealthClient(client.target(url).path("v1").path("health")); + } + else{ + this.catalogClient = new CatalogClient(client.target(url).path("api").path("catalog").path("v1")); + this.healthClient = new HealthClient(client.target(url).path("api").path("health").path("v1")); + } + + +// agentClient.ping(); + } + + /** + * Creates a new client given a complete URL. + * + * @deprecated Use {@link Consul.Builder} + * + * @param url The Consul API URL. + * @param builder The JAX-RS client builder instance. + * @return A new client. + */ + @Deprecated + public static Consul newClient(String url, ClientBuilder builder, ObjectMapper mapper) { + return new Consul(url, builder, mapper); + } + + /** + * Creates a new client given a host and a port. + * + * @deprecated Use {@link Consul.Builder} + * + * @param host The Consul API hostname or IP. + * @param port The Consul port. + * @param builder The JAX-RS client builder instance. + * @return A new client. + */ + @Deprecated + public static Consul newClient(String host, int port, ClientBuilder builder, ObjectMapper mapper) { + try { + return new Consul(new URL("http", host, port, "").toString(), builder, mapper); + } catch (MalformedURLException e) { + throw new ConsulException("Bad Consul URL", e); + } + } + + /** + * Creates a new client given a host and a port. + * + * @deprecated Use {@link Consul.Builder} + * + * @param host The Consul API hostname or IP. + * @param port The Consul port. + * @return A new client. + */ + @Deprecated + public static Consul newClient(String host, int port) { + return newClient(host, port, ClientBuilder.newBuilder(), Jackson.MAPPER); + } + + /** + * Creates a new client given a host and a port. + * + * @deprecated Use {@link Consul.Builder} + * + * @return A new client. + */ + @Deprecated + public static Consul newClient() { + return newClient(DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT); + } + + + /** + * Get the Catalog HTTP client. + * <p> + * /v1/catalog + * + * @return The Catalog HTTP client. + */ + public CatalogClient catalogClient() { + return catalogClient; + } + + public HealthClient healthClient() { + return healthClient; + } + /** + * Creates a new {@link Builder} object. + * + * @return A new Consul builder. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link Consul} client objects. + */ + public static class Builder { + private URL url; + private Optional<SSLContext> sslContext = Optional.absent(); + private ObjectMapper objectMapper = Jackson.MAPPER; + private ClientBuilder clientBuilder = ClientBuilder.newBuilder(); + + { + try { + url = new URL("http", "localhost", 8500, ""); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + /** + * Constructs a new builder. + */ + Builder() { + + } + + /** + * Sets the URL from a {@link URL} object. + * + * @param url The Consul agent URL. + * @return The builder. + */ + public Builder withUrl(URL url) { + this.url = url; + + return this; + } + + /** + * Sets the URL from a {@link HostAndPort} object. + * + * @param hostAndPort The Consul agent host and port. + * @return The builder. + */ + public Builder withHostAndPort(HostAndPort hostAndPort) { + try { + this.url = new URL("http", hostAndPort.getHostText(), hostAndPort.getPort(), ""); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + + return this; + } + + /** + * Sets the URL from a string. + * + * @param url The Consul agent URL. + * @return The builder. + */ + public Builder withUrl(String url) { + try { + this.url = new URL(url); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + + return this; + } + + /** + * Sets the {@link SSLContext} for the client. + * + * @param sslContext The SSL context for HTTPS agents. + * @return The builder. + */ + public Builder withSslContext(SSLContext sslContext) { + this.sslContext = Optional.of(sslContext); + + return this; + } + + /** + * Sets the {@link ObjectMapper} for the client. + * + * @param objectMapper The {@link ObjectMapper} to use. + * @return The builder. + */ + public Builder withObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + + objectMapper.registerModule(new GuavaModule()); + + return this; + } + + /** + * Sets the JAX-RS {@link ClientBuilder} to use. + * + * @param clientBuilder The JAX-RS builder. + * @return This builder. + */ + public Builder withClientBuilder(ClientBuilder clientBuilder) { + this.clientBuilder = clientBuilder; + + return this; + } + + /** + * Constructs a new {@link Consul} client. + * + * @return A new Consul client. + */ + public Consul build() { + if (this.sslContext.isPresent()) { + this.clientBuilder.sslContext(this.sslContext.get()); + } + + return new Consul(this.url.toExternalForm(), this.clientBuilder, this.objectMapper); + } + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java new file mode 100644 index 0000000..ce08ac9 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/ConsulException.java @@ -0,0 +1,42 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul; + +/** + * Wraps an exception thrown whilst interacting with the Consul API. + */ +public class ConsulException extends RuntimeException { + + /** + * Constructs an instance of this class. + * + * @param message The exception message. + */ + public ConsulException(String message) { + super(message); + } + + /** + * Constructs an instance of this class. + * + * @param message The exception message. + * @param throwable The wrapped {@link java.lang.Throwable} object. + */ + public ConsulException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java new file mode 100644 index 0000000..1d4c00a --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/HealthClient.java @@ -0,0 +1,247 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul; + +import static org.openo.msb.wrapper.consul.util.ClientUtil.response; + +import java.util.List; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; + +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.model.health.ServiceHealth; +import org.openo.msb.wrapper.consul.option.CatalogOptions; +import org.openo.msb.wrapper.consul.option.QueryOptions; + +/** + * HTTP Client for /v1/health/ endpoints. + */ +public class HealthClient { + + + private static final GenericType<List<ServiceHealth>> TYPE_SERVICE_HEALTH_LIST = + new GenericType<List<ServiceHealth>>() {}; + + private final WebTarget webTarget; + + /** + * Constructs an instance of this class. + * + * @param webTarget The {@link javax.ws.rs.client.WebTarget} to base requests from. + */ + HealthClient(WebTarget webTarget) { + this.webTarget = webTarget; + } + + + + /** + * Retrieves the healthchecks for all healthy service instances. + * + * GET /v1/health/service/{service}?passing + * + * @param service The service to query. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getHealthyServiceInstances(String service) { + return getHealthyServiceInstances(service, null, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all healthy service instances in a given datacenter. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getHealthyServiceInstances(String service, CatalogOptions catalogOptions) { + return getHealthyServiceInstances(service, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all healthy service instances with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?passing + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getHealthyServiceInstances(String service, QueryOptions queryOptions) { + return getHealthyServiceInstances(service, null, queryOptions); + } + + /** + * Retrieves the healthchecks for all healthy service instances in a given datacenter with + * {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getHealthyServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions) { + return response(webTarget.path("service").path(service).queryParam("passing", "true"), + catalogOptions, queryOptions, TYPE_SERVICE_HEALTH_LIST); + } + + /** + * Asynchronously retrieves the healthchecks for all healthy service instances in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * Experimental. + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getHealthyServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions, + ConsulResponseCallback<List<ServiceHealth>> callback) { + response(webTarget.path("service").path(service).queryParam("passing", "true"), + catalogOptions, queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); + } + + /** + * Asynchronously retrieves the healthchecks for all healthy service instances in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter}&passing + * + * Experimental. + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getHealthyServiceInstances(String service, QueryOptions queryOptions, + ConsulResponseCallback<List<ServiceHealth>> callback) { + response(webTarget.path("service").path(service).queryParam("passing", "true"), + CatalogOptions.BLANK, queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); + } + + /** + * Retrieves the healthchecks for all nodes. + * + * GET /v1/health/service/{service} + * + * @param service The service to query. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getAllServiceInstances(String service) { + return getAllServiceInstances(service, null, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all nodes in a given datacenter. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getAllServiceInstances(String service, CatalogOptions catalogOptions) { + return getAllServiceInstances(service, catalogOptions, QueryOptions.BLANK); + } + + /** + * Retrieves the healthchecks for all nodes with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service} + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getAllServiceInstances(String service, QueryOptions queryOptions) { + return getAllServiceInstances(service, null, queryOptions); + } + + /** + * Retrieves the healthchecks for all nodes in a given datacenter with + * {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing a list of + * {@link com.orbitz.consul.model.health.HealthCheck} objects. + */ + public ConsulResponse<List<ServiceHealth>> getAllServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions) { + return response(webTarget.path("service").path(service), catalogOptions, queryOptions, + TYPE_SERVICE_HEALTH_LIST); + } + + /** + * Asynchronously retrieves the healthchecks for all nodes in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * Experimental. + * + * @param service The service to query. + * @param catalogOptions The catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getAllServiceInstances(String service, CatalogOptions catalogOptions, + QueryOptions queryOptions, + ConsulResponseCallback<List<ServiceHealth>> callback) { + response(webTarget.path("service").path(service), catalogOptions, queryOptions, + TYPE_SERVICE_HEALTH_LIST, callback); + } + + /** + * Asynchronously retrieves the healthchecks for all nodes in a given + * datacenter with {@link org.openo.msb.wrapper.consul.option.QueryOptions}. + * + * GET /v1/health/service/{service}?dc={datacenter} + * + * Experimental. + * + * @param service The service to query. + * @param queryOptions The Query Options to use. + * @param callback Callback implemented by callee to handle results. + */ + public void getAllServiceInstances(String service, QueryOptions queryOptions, + ConsulResponseCallback<List<ServiceHealth>> callback) { + response(webTarget.path("service").path(service), CatalogOptions.BLANK, + queryOptions, TYPE_SERVICE_HEALTH_LIST, callback); + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java new file mode 100644 index 0000000..1db3cc5 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/async/ConsulResponseCallback.java @@ -0,0 +1,42 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.async; + +import org.openo.msb.wrapper.consul.model.ConsulResponse; + +/** + * For API calls that support long-polling, this callback is used to handle + * the result on success or failure for an async HTTP call. + * + * @param <T> The Response type. + */ +public interface ConsulResponseCallback<T> { + + /** + * Callback for a successful {@link org.openo.msb.wrapper.consul.model.ConsulResponse}. + * + * @param consulResponse The Consul response. + */ + void onComplete(ConsulResponse<T> consulResponse); + + /** + * Callback for an unsuccessful request. + * + * @param throwable The exception thrown. + */ + void onFailure(Throwable throwable); +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java new file mode 100644 index 0000000..8cafab4 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/CatalogCache.java @@ -0,0 +1,70 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.cache;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.openo.msb.wrapper.consul.CatalogClient;
+import org.openo.msb.wrapper.consul.async.ConsulResponseCallback;
+import org.openo.msb.wrapper.consul.model.catalog.CatalogService;
+
+import com.google.common.base.Function;
+
+public class CatalogCache extends ConsulCache<String, CatalogService>{
+
+ private final String serviceName;
+
+ private CatalogCache(Function<CatalogService, String> keyConversion,
+ ConsulCache.CallbackConsumer<CatalogService> callbackConsumer,String serviceName) {
+ super(keyConversion, callbackConsumer);
+ this.serviceName=serviceName;
+ // TODO Auto-generated constructor stub
+ }
+
+
+ public static CatalogCache newCache(
+ final CatalogClient catalogClient,
+ final String serviceName,
+ final int watchSeconds){
+ Function<CatalogService,String> keyExtractor = new Function<CatalogService, String>() {
+ @Override
+ public String apply(CatalogService input) {
+ //return input.getKey().substring(rootPath.length() + 1);
+ return input.getServiceId();
+ }
+ };
+
+ final CallbackConsumer<CatalogService> callbackConsumer = new CallbackConsumer<CatalogService>() {
+ @Override
+ public void consume(BigInteger index, ConsulResponseCallback<List<CatalogService>> callback) {
+ catalogClient.getService(serviceName, watchParams(index, watchSeconds),callback);
+ }
+ };
+
+
+ return new CatalogCache(keyExtractor, callbackConsumer,serviceName);
+
+
+ }
+
+ public String getServiceName(){
+ return this.serviceName;
+ }
+
+
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java new file mode 100644 index 0000000..e7494fa --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache.java @@ -0,0 +1,230 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.cache; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; + +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.option.QueryOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static com.google.common.base.Preconditions.checkState; + +/** + * A cache structure that can provide an up-to-date read-only + * map backed by consul data + * + * @param <V> + */ +public class ConsulCache<K, V> { + + enum State {latent, starting, started, stopped } + + private final static Logger LOGGER = LoggerFactory.getLogger(ConsulCache.class); + + private final AtomicReference<BigInteger> latestIndex = new AtomicReference<BigInteger>(null); + private final AtomicReference<ImmutableMap<K, V>> lastResponse = new AtomicReference<ImmutableMap<K, V>>(ImmutableMap.<K, V>of()); + private final AtomicReference<State> state = new AtomicReference<State>(State.latent); + private final CountDownLatch initLatch = new CountDownLatch(1); + private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + private final CopyOnWriteArrayList<Listener<K, V>> listeners = new CopyOnWriteArrayList<Listener<K, V>>(); + + private final Function<V, K> keyConversion; + private final CallbackConsumer<V> callBackConsumer; + private final ConsulResponseCallback<List<V>> responseCallback; + + ConsulCache( + Function<V, K> keyConversion, + CallbackConsumer<V> callbackConsumer) { + this(keyConversion, callbackConsumer, 10, TimeUnit.SECONDS); + } + + ConsulCache( + Function<V, K> keyConversion, + CallbackConsumer<V> callbackConsumer, + final long backoffDelayQty, + final TimeUnit backoffDelayUnit) { + + this.keyConversion = keyConversion; + this.callBackConsumer = callbackConsumer; + + this.responseCallback = new ConsulResponseCallback<List<V>>() { + @Override + public void onComplete(ConsulResponse<List<V>> consulResponse) { + + if (!isRunning()) { + return; + } + updateIndex(consulResponse); + ImmutableMap<K, V> full = convertToMap(consulResponse); + + boolean changed = !full.equals(lastResponse.get()); +// LOGGER.info("node changed:"+changed+"----"+full); + if (changed) { + // changes + lastResponse.set(full); + } + + if (changed) { + for (Listener<K, V> l : listeners) { + l.notify(full); + } + } + + if (state.compareAndSet(State.starting, State.started)) { + initLatch.countDown(); + } + runCallback(); + } + + @Override + public void onFailure(Throwable throwable) { + + if (!isRunning()) { + return; + } + LOGGER.error(String.format("Error getting response from consul. will retry in %d %s", backoffDelayQty, backoffDelayUnit), throwable); + + executorService.schedule(new Runnable() { + @Override + public void run() { + runCallback(); + } + }, backoffDelayQty, backoffDelayUnit); + } + }; + } + + public void start() throws Exception { + checkState(state.compareAndSet(State.latent, State.starting),"Cannot transition from state %s to %s", state.get(), State.starting); + runCallback(); + } + + public void stop() throws Exception { + State previous = state.getAndSet(State.stopped); + if (previous != State.stopped) { + executorService.shutdownNow(); + } + } + + private void runCallback() { + if (isRunning()) { + callBackConsumer.consume(latestIndex.get(), responseCallback); + } + } + + private boolean isRunning() { + return state.get() == State.started || state.get() == State.starting; + } + + public boolean awaitInitialized(long timeout, TimeUnit unit) throws InterruptedException { + return initLatch.await(timeout, unit); + } + + public ImmutableMap<K, V> getMap() { + return lastResponse.get(); + } + + @VisibleForTesting + ImmutableMap<K, V> convertToMap(final ConsulResponse<List<V>> response) { + if (response == null || response.getResponse() == null || response.getResponse().isEmpty()) { + return ImmutableMap.of(); + } + + final ImmutableMap.Builder<K, V> builder = ImmutableMap.builder(); + final Set<K> keySet = new HashSet<>(); + for (final V v : response.getResponse()) { + final K key = keyConversion.apply(v); + if (key != null) { + if (!keySet.contains(key)) { + builder.put(key, v); + } else { + System.out.println(key.toString()); + LOGGER.warn("Duplicate service encountered. May differ by tags. Try using more specific tags? " + key.toString()); + } + } + keySet.add(key); + } + return builder.build(); + } + + private void updateIndex(ConsulResponse<List<V>> consulResponse) { + if (consulResponse != null && consulResponse.getIndex() != null) { + this.latestIndex.set(consulResponse.getIndex()); + } + } + + protected static QueryOptions watchParams(BigInteger index, int blockSeconds) { + if (index == null) { + return QueryOptions.BLANK; + } else { + return QueryOptions.blockSeconds(blockSeconds, index).build(); + } + } + + /** + * passed in by creators to vary the content of the cached values + * + * @param <V> + */ + protected interface CallbackConsumer<V> { + void consume(BigInteger index, ConsulResponseCallback<List<V>> callback); + } + + /** + * Implementers can register a listener to receive + * a new map when it changes + * + * @param <V> + */ + public interface Listener<K, V> { + void notify(Map<K, V> newValues); + } + + public boolean addListener(Listener<K, V> listener) { + boolean added = listeners.add(listener); + if (state.get() == State.started) { + listener.notify(lastResponse.get()); + } + return added; + } + + public boolean removeListener(Listener<K, V> listener) { + return listeners.remove(listener); + } + + @VisibleForTesting + protected State getState() { + return state.get(); + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java new file mode 100644 index 0000000..84fd8ec --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ConsulCache4Map.java @@ -0,0 +1,258 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.cache;
+
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.openo.msb.wrapper.consul.async.ConsulResponseCallback;
+import org.openo.msb.wrapper.consul.model.ConsulResponse;
+import org.openo.msb.wrapper.consul.model.catalog.CatalogService;
+import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo;
+import org.openo.msb.wrapper.consul.option.QueryOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * A cache structure that can provide an up-to-date read-only
+ * map backed by consul data
+ *
+ * @param <V>
+ */
+public class ConsulCache4Map<K, V> {
+
+ enum State {latent, starting, started, stopped }
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ConsulCache4Map.class);
+
+ private final AtomicReference<BigInteger> latestIndex = new AtomicReference<BigInteger>(null);
+ private final AtomicReference<ImmutableList<ServiceInfo>> lastResponse = new AtomicReference<ImmutableList<ServiceInfo>>(ImmutableList.<ServiceInfo>of());
+ private final AtomicReference<State> state = new AtomicReference<State>(State.latent);
+ private final CountDownLatch initLatch = new CountDownLatch(1);
+ private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+ private final CopyOnWriteArrayList<Listener<K, V>> listeners = new CopyOnWriteArrayList<Listener<K, V>>();
+
+ private final CallbackConsumer<V> callBackConsumer;
+ private final ConsulResponseCallback<Map<String,List<String>>> responseCallback;
+
+ ConsulCache4Map(CallbackConsumer<V> callbackConsumer) {
+ this( callbackConsumer, 10, TimeUnit.SECONDS);
+ }
+
+ ConsulCache4Map(
+ CallbackConsumer<V> callbackConsumer,
+ final long backoffDelayQty,
+ final TimeUnit backoffDelayUnit) {
+
+ this.callBackConsumer = callbackConsumer;
+
+ this.responseCallback = new ConsulResponseCallback<Map<String,List<String>>>() {
+ @Override
+ public void onComplete(ConsulResponse<Map<String,List<String>>> consulResponse) {
+
+ if (!isRunning()) {
+ return;
+ }
+ updateIndex(consulResponse);
+ ImmutableList<ServiceInfo> full = convertToList(consulResponse);
+ List<ServiceInfo> oldList=lastResponse.get();
+ boolean changed = !full.equals(lastResponse.get());
+// LOGGER.info("service changed:"+changed+"----"+full);
+ if (changed) {
+ // changes
+ lastResponse.set(full);
+ }
+
+ if (changed) {
+ for (Listener<K, V> l : listeners) {
+ l.notify(oldList,full);
+ }
+ }
+
+ if (state.compareAndSet(State.starting, State.started)) {
+ initLatch.countDown();
+ }
+ runCallback();
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+
+ if (!isRunning()) {
+ return;
+ }
+ LOGGER.error(String.format("Error getting response from consul. will retry in %d %s", backoffDelayQty, backoffDelayUnit), throwable);
+
+ executorService.schedule(new Runnable() {
+ @Override
+ public void run() {
+ runCallback();
+ }
+ }, backoffDelayQty, backoffDelayUnit);
+ }
+ };
+ }
+
+ public void start() throws Exception {
+ checkState(state.compareAndSet(State.latent, State.starting),"Cannot transition from state %s to %s", state.get(), State.starting);
+ runCallback();
+ }
+
+ public void stop() throws Exception {
+ State previous = state.getAndSet(State.stopped);
+ if (previous != State.stopped) {
+ executorService.shutdownNow();
+ }
+ }
+
+ private void runCallback() {
+ if (isRunning()) {
+ callBackConsumer.consume(latestIndex.get(), responseCallback);
+ }
+ }
+
+ private boolean isRunning() {
+ return state.get() == State.started || state.get() == State.starting;
+ }
+
+ public boolean awaitInitialized(long timeout, TimeUnit unit) throws InterruptedException {
+ return initLatch.await(timeout, unit);
+ }
+
+ public ImmutableList<ServiceInfo> getMap() {
+ return lastResponse.get();
+ }
+
+ @VisibleForTesting
+ ImmutableList<ServiceInfo> convertToList(final ConsulResponse<Map<String,List<String>>> response) {
+ if (response == null || response.getResponse() == null || response.getResponse().isEmpty()) {
+ return ImmutableList.of();
+ }
+
+ final ImmutableList.Builder<ServiceInfo> builder = ImmutableList.builder();
+ final Set<String> keySet = new HashSet<>();
+
+ for(Map.Entry<String,List<String>> entry : response.getResponse().entrySet()) {
+
+ String key = entry.getKey();
+
+ if (key != null && !"consul".equals(key)) {
+ if (!keySet.contains(key)) {
+ ServiceInfo serviceInfo=new ServiceInfo();
+ serviceInfo.setServiceName(key);
+
+ List<String> value=entry.getValue();
+ for(String tag:value){
+
+ if(tag.startsWith("version")){
+ String version;
+ if(tag.split(":").length==2)
+ {
+ version = tag.split(":")[1];
+ }
+ else{
+ version="";
+ }
+
+ serviceInfo.setVersion(version);
+ break;
+ }
+ }
+
+ builder.add(serviceInfo);
+ } else {
+ System.out.println(key.toString());
+ LOGGER.warn("Duplicate service encountered. May differ by tags. Try using more specific tags? " + key.toString());
+ }
+ }
+ keySet.add(key);
+
+ }
+
+
+ return builder.build();
+ }
+
+ private void updateIndex(ConsulResponse<Map<String,List<String>>> consulResponse) {
+ if (consulResponse != null && consulResponse.getIndex() != null) {
+ this.latestIndex.set(consulResponse.getIndex());
+ }
+ }
+
+ protected static QueryOptions watchParams(BigInteger index, int blockSeconds) {
+ if (index == null) {
+ return QueryOptions.BLANK;
+ } else {
+ return QueryOptions.blockSeconds(blockSeconds, index).build();
+ }
+ }
+
+ /**
+ * passed in by creators to vary the content of the cached values
+ *
+ * @param <V>
+ */
+ protected interface CallbackConsumer<V> {
+ void consume(BigInteger index, ConsulResponseCallback<Map<String,List<String>>> callback);
+ }
+
+ /**
+ * Implementers can register a listener to receive
+ * a new map when it changes
+ *
+ * @param <V>
+ */
+ public interface Listener<K, V> {
+ void notify(List<ServiceInfo> oldValues,List<ServiceInfo> newValues);
+ }
+
+ public boolean addListener(Listener<K, V> listener) {
+ boolean added = listeners.add(listener);
+ if (state.get() == State.started) {
+ listener.notify(lastResponse.get(),lastResponse.get());
+ }
+ return added;
+ }
+
+ public boolean removeListener(Listener<K, V> listener) {
+ return listeners.remove(listener);
+ }
+
+ @VisibleForTesting
+ protected State getState() {
+ return state.get();
+ }
+
+
+
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java new file mode 100644 index 0000000..0134eeb --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/HealthCache.java @@ -0,0 +1,70 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.cache;
+
+import java.math.BigInteger;
+import java.util.List;
+
+import org.openo.msb.wrapper.consul.HealthClient;
+import org.openo.msb.wrapper.consul.async.ConsulResponseCallback;
+import org.openo.msb.wrapper.consul.model.health.ServiceHealth;
+
+import com.google.common.base.Function;
+
+public class HealthCache extends ConsulCache<String, ServiceHealth>{
+
+ private final String serviceName;
+
+ private HealthCache(Function<ServiceHealth, String> keyConversion,
+ ConsulCache.CallbackConsumer<ServiceHealth> callbackConsumer,String serviceName) {
+ super(keyConversion, callbackConsumer);
+ this.serviceName=serviceName;
+ // TODO Auto-generated constructor stub
+ }
+
+
+ public static HealthCache newCache(
+ final HealthClient healthClient,
+ final String serviceName,
+ final int watchSeconds){
+ Function<ServiceHealth,String> keyExtractor = new Function<ServiceHealth, String>() {
+ @Override
+ public String apply(ServiceHealth input) {
+ //return input.getKey().substring(rootPath.length() + 1);
+ return input.getService().getId();
+ }
+ };
+
+ final CallbackConsumer<ServiceHealth> callbackConsumer = new CallbackConsumer<ServiceHealth>() {
+ @Override
+ public void consume(BigInteger index, ConsulResponseCallback<List<ServiceHealth>> callback) {
+ healthClient.getHealthyServiceInstances(serviceName, watchParams(index, watchSeconds),callback);
+ }
+ };
+
+
+ return new HealthCache(keyExtractor, callbackConsumer,serviceName);
+
+
+ }
+
+ public String getServiceName(){
+ return this.serviceName;
+ }
+
+
+}
\ No newline at end of file diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java new file mode 100644 index 0000000..80cdb7b --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/cache/ServiceCache.java @@ -0,0 +1,50 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.cache;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Map;
+
+import org.openo.msb.wrapper.consul.CatalogClient;
+import org.openo.msb.wrapper.consul.async.ConsulResponseCallback;
+
+public class ServiceCache extends ConsulCache4Map<String, Map<String, List<String>>> {
+ private ServiceCache( ConsulCache4Map.CallbackConsumer<Map<String, List<String>>> callbackConsumer) {
+ super(callbackConsumer);
+ // TODO Auto-generated constructor stub
+ }
+
+
+ public static ServiceCache newCache(
+ final CatalogClient catalogClient,
+ final int watchSeconds){
+
+
+ final CallbackConsumer<Map<String, List<String>>> callbackConsumer = new CallbackConsumer<Map<String, List<String>>>() {
+ @Override
+ public void consume(BigInteger index, ConsulResponseCallback<Map<String, List<String>>> callback) {
+ catalogClient.getService(watchParams(index, watchSeconds),callback);
+ }
+ };
+
+
+ return new ServiceCache(callbackConsumer);
+
+
+ }
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java new file mode 100644 index 0000000..7d3b2e2 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/ConsulResponse.java @@ -0,0 +1,80 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.model; + +import com.google.common.base.Objects; + +import java.math.BigInteger; + +public class ConsulResponse<T> { + + private final T response; + private final long lastContact; + private final boolean knownLeader; + private final BigInteger index; + + public ConsulResponse(T response, long lastContact, boolean knownLeader, BigInteger index) { + this.response = response; + this.lastContact = lastContact; + this.knownLeader = knownLeader; + this.index = index; + } + + public T getResponse() { + return response; + } + + public long getLastContact() { + return lastContact; + } + + public boolean isKnownLeader() { + return knownLeader; + } + + public BigInteger getIndex() { + return index; + } + + @Override + public String toString() { + return "ConsulResponse{" + + "response=" + response + + ", lastContact=" + lastContact + + ", knownLeader=" + knownLeader + + ", index=" + index + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ConsulResponse that = (ConsulResponse) o; + + return Objects.equal(this.response, that.response) && + Objects.equal(this.lastContact, that.lastContact) && + Objects.equal(this.knownLeader, that.knownLeader) && + Objects.equal(this.index, that.index); + } + + @Override + public int hashCode() { + return Objects.hashCode(response, lastContact, knownLeader, index); + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java new file mode 100644 index 0000000..1221c08 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogNode.java @@ -0,0 +1,41 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.model.catalog; + +import java.util.Map; + +import org.openo.msb.wrapper.consul.model.health.Node; +import org.openo.msb.wrapper.consul.model.health.Service; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(as = ImmutableCatalogNode.class) +@JsonDeserialize(as = ImmutableCatalogNode.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class CatalogNode { + + @JsonProperty("Node") + public abstract Node getNode(); + + @JsonProperty("Services") + public abstract Map<String, Service> getServices(); + +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java new file mode 100644 index 0000000..5951fa7 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/CatalogService.java @@ -0,0 +1,52 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.model.catalog; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(as = ImmutableCatalogService.class) +@JsonDeserialize(as = ImmutableCatalogService.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class CatalogService { + + @JsonProperty("Node") + public abstract String getNode(); + + @JsonProperty("Address") + public abstract String getAddress(); + + @JsonProperty("ServiceName") + public abstract String getServiceName(); + + @JsonProperty("ServiceID") + public abstract String getServiceId(); + + @JsonProperty("ServiceAddress") + public abstract String getServiceAddress(); + + @JsonProperty("ServicePort") + public abstract int getServicePort(); + + @JsonProperty("ServiceTags") + public abstract List<String> getServiceTags(); +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java new file mode 100644 index 0000000..f504168 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogNode.java @@ -0,0 +1,306 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.model.catalog;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Generated;
+
+import org.openo.msb.wrapper.consul.model.health.Node;
+import org.openo.msb.wrapper.consul.model.health.Service;
+
+/**
+ * Immutable implementation of {@link CatalogNode}.
+ * <p>
+ * Use the builder to create immutable instances:
+ * {@code ImmutableCatalogNode.builder()}.
+ */
+@SuppressWarnings("all")
+@Generated({"Immutables.generator", "CatalogNode"})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class ImmutableCatalogNode extends CatalogNode {
+ private final Node node;
+ private final ImmutableMap<String, Service> services;
+
+ private ImmutableCatalogNode(
+ Node node,
+ ImmutableMap<String, Service> services) {
+ this.node = node;
+ this.services = services;
+ }
+
+ /**
+ * @return The value of the {@code node} attribute
+ */
+ @JsonProperty(value = "Node")
+ @Override
+ public Node getNode() {
+ return node;
+ }
+
+ /**
+ * @return The value of the {@code services} attribute
+ */
+ @JsonProperty(value = "Services")
+ @Override
+ public ImmutableMap<String, Service> getServices() {
+ return services;
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link CatalogNode#getNode() node} attribute.
+ * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for node
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableCatalogNode withNode(Node value) {
+ if (this.node == value) return this;
+ return new ImmutableCatalogNode(Preconditions.checkNotNull(value, "node"), this.services);
+ }
+
+ /**
+ * Copy the current immutable object by replacing the {@link CatalogNode#getServices() services} map with the specified map.
+ * Nulls are not permitted as keys or values.
+ * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
+ * @param entries The entries to be added to the services map
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableCatalogNode withServices(Map<String, ? extends Service> entries) {
+ if (this.services == entries) return this;
+ ImmutableMap<String, Service> value = ImmutableMap.copyOf(entries);
+ return new ImmutableCatalogNode(this.node, value);
+ }
+
+ /**
+ * This instance is equal to all instances of {@code ImmutableCatalogNode} that have equal attribute values.
+ * @return {@code true} if {@code this} is equal to {@code another} instance
+ */
+ @Override
+ public boolean equals(Object another) {
+ if (this == another) return true;
+ return another instanceof ImmutableCatalogNode
+ && equalTo((ImmutableCatalogNode) another);
+ }
+
+ private boolean equalTo(ImmutableCatalogNode another) {
+ return node.equals(another.node)
+ && services.equals(another.services);
+ }
+
+ /**
+ * Computes a hash code from attributes: {@code node}, {@code services}.
+ * @return hashCode value
+ */
+ @Override
+ public int hashCode() {
+ int h = 31;
+ h = h * 17 + node.hashCode();
+ h = h * 17 + services.hashCode();
+ return h;
+ }
+
+ /**
+ * Prints the immutable value {@code CatalogNode...} with all non-generated
+ * and non-auxiliary attribute values.
+ * @return A string representation of the value
+ */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper("CatalogNode")
+ .add("node", node)
+ .add("services", services)
+ .toString();
+ }
+
+ /**
+ * Utility type used to correctly read immutable object from JSON representation.
+ * @deprecated Do not use this type directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonDeserialize
+ static final class Json extends CatalogNode {
+ Node node;
+ Map<String, Service> services;
+ @JsonProperty(value = "Node")
+ public void setNode(Node node) {
+ this.node = node;
+ }
+ @JsonProperty(value = "Services")
+ public void setServices(Map<String, Service> services) {
+ this.services = services;
+ }
+ @Override
+ public Node getNode() { throw new UnsupportedOperationException(); }
+ @Override
+ public Map<String, Service> getServices() { throw new UnsupportedOperationException(); }
+ }
+
+ /**
+ * @param json A JSON-bindable data structure
+ * @return An immutable value type
+ * @deprecated Do not use this method directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonCreator
+ static ImmutableCatalogNode fromJson(Json json) {
+ ImmutableCatalogNode.Builder builder = ImmutableCatalogNode.builder();
+ if (json.node != null) {
+ builder.node(json.node);
+ }
+ if (json.services != null) {
+ builder.putAllServices(json.services);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Creates an immutable copy of a {@link CatalogNode} value.
+ * Uses accessors to get values to initialize the new immutable instance.
+ * If an instance is already immutable, it is returned as is.
+ * @param instance The instance to copy
+ * @return A copied immutable CatalogNode instance
+ */
+ public static ImmutableCatalogNode copyOf(CatalogNode instance) {
+ if (instance instanceof ImmutableCatalogNode) {
+ return (ImmutableCatalogNode) instance;
+ }
+ return ImmutableCatalogNode.builder()
+ .from(instance)
+ .build();
+ }
+
+ /**
+ * Creates a builder for {@link ImmutableCatalogNode ImmutableCatalogNode}.
+ * @return A new ImmutableCatalogNode builder
+ */
+ public static ImmutableCatalogNode.Builder builder() {
+ return new ImmutableCatalogNode.Builder();
+ }
+
+ /**
+ * Builds instances of type {@link ImmutableCatalogNode ImmutableCatalogNode}.
+ * Initialize attributes and then invoke the {@link #build()} method to create an
+ * immutable instance.
+ * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
+ * but instead used immediately to create instances.</em>
+ */
+ public static final class Builder {
+ private static final long INIT_BIT_NODE = 0x1L;
+ private long initBits = 0x1;
+
+ private Node node;
+ private ImmutableMap.Builder<String, Service> servicesBuilder = ImmutableMap.builder();
+
+ private Builder() {
+ }
+
+ /**
+ * Fill a builder with attribute values from the provided {@code CatalogNode} instance.
+ * Regular attribute values will be replaced with those from the given instance.
+ * Absent optional values will not replace present values.
+ * Collection elements and entries will be added, not replaced.
+ * @param instance The instance from which to copy values
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder from(CatalogNode instance) {
+ Preconditions.checkNotNull(instance, "instance");
+ node(instance.getNode());
+ putAllServices(instance.getServices());
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link CatalogNode#getNode() node} attribute.
+ * @param node The value for node
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder node(Node node) {
+ this.node = Preconditions.checkNotNull(node, "node");
+ initBits &= ~INIT_BIT_NODE;
+ return this;
+ }
+
+ /**
+ * Put one entry to the {@link CatalogNode#getServices() services} map.
+ * @param key The key in the services map
+ * @param value The associated value in the services map
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder putServices(String key, Service value) {
+ servicesBuilder.put(key, value);
+ return this;
+ }
+
+ /**
+ * Put one entry to the {@link CatalogNode#getServices() services} map. Nulls are not permitted
+ * @param entry The key and value entry
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder putServices(Map.Entry<String, ? extends Service> entry) {
+ servicesBuilder.put(entry);
+ return this;
+ }
+
+ /**
+ * Sets or replaces all mappings from the specified map as entries for the {@link CatalogNode#getServices() services} map. Nulls are not permitted
+ * @param entries The entries that will be added to the services map
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder services(Map<String, ? extends Service> entries) {
+ servicesBuilder = ImmutableMap.builder();
+ return putAllServices(entries);
+ }
+
+ /**
+ * Put all mappings from the specified map as entries to {@link CatalogNode#getServices() services} map. Nulls are not permitted
+ * @param entries The entries that will be added to the services map
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder putAllServices(Map<String, ? extends Service> entries) {
+ servicesBuilder.putAll(entries);
+ return this;
+ }
+
+ /**
+ * Builds a new {@link ImmutableCatalogNode ImmutableCatalogNode}.
+ * @return An immutable instance of CatalogNode
+ * @throws java.lang.IllegalStateException if any required attributes are missing
+ */
+ public ImmutableCatalogNode build() throws IllegalStateException {
+ if (initBits != 0) {
+ throw new IllegalStateException(formatRequiredAttributesMessage());
+ }
+ return new ImmutableCatalogNode(node, servicesBuilder.build());
+ }
+
+ private String formatRequiredAttributesMessage() {
+ List<String> attributes = Lists.newArrayList();
+ if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node");
+ return "Cannot build CatalogNode, some of required attributes are not set " + attributes;
+ }
+ }
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java new file mode 100644 index 0000000..33d0e03 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ImmutableCatalogService.java @@ -0,0 +1,626 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.model.catalog;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import java.util.List;
+import javax.annotation.Generated;
+
+/**
+ * Immutable implementation of {@link CatalogService}.
+ * <p>
+ * Use the builder to create immutable instances:
+ * {@code ImmutableCatalogService.builder()}.
+ */
+@SuppressWarnings("all")
+@Generated({"Immutables.generator", "CatalogService"})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class ImmutableCatalogService extends CatalogService {
+ private final String node;
+ private final String address;
+ private final String serviceName;
+ private final String serviceId;
+ private final String serviceAddress;
+ private final int servicePort;
+ private final ImmutableList<String> serviceTags;
+
+ private ImmutableCatalogService(
+ String node,
+ String address,
+ String serviceName,
+ String serviceId,
+ String serviceAddress,
+ int servicePort,
+ ImmutableList<String> serviceTags) {
+ this.node = node;
+ this.address = address;
+ this.serviceName = serviceName;
+ this.serviceId = serviceId;
+ this.serviceAddress = serviceAddress;
+ this.servicePort = servicePort;
+ this.serviceTags = serviceTags;
+ }
+
+ /**
+ * @return The value of the {@code node} attribute
+ */
+ @JsonProperty(value = "Node")
+ @Override
+ public String getNode() {
+ return node;
+ }
+
+ /**
+ * @return The value of the {@code address} attribute
+ */
+ @JsonProperty(value = "Address")
+ @Override
+ public String getAddress() {
+ return address;
+ }
+
+ /**
+ * @return The value of the {@code serviceName} attribute
+ */
+ @JsonProperty(value = "ServiceName")
+ @Override
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ /**
+ * @return The value of the {@code serviceId} attribute
+ */
+ @JsonProperty(value = "ServiceID")
+ @Override
+ public String getServiceId() {
+ return serviceId;
+ }
+
+ /**
+ * @return The value of the {@code serviceAddress} attribute
+ */
+ @JsonProperty(value = "ServiceAddress")
+ @Override
+ public String getServiceAddress() {
+ return serviceAddress;
+ }
+
+ /**
+ * @return The value of the {@code servicePort} attribute
+ */
+ @JsonProperty(value = "ServicePort")
+ @Override
+ public int getServicePort() {
+ return servicePort;
+ }
+
+ /**
+ * @return The value of the {@code serviceTags} attribute
+ */
+ @JsonProperty(value = "ServiceTags")
+ @Override
+ public ImmutableList<String> getServiceTags() {
+ return serviceTags;
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link CatalogService#getNode() node} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for node
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableCatalogService withNode(String value) {
+ if (this.node.equals(value)) return this;
+ return new ImmutableCatalogService(
+ Preconditions.checkNotNull(value, "node"),
+ this.address,
+ this.serviceName,
+ this.serviceId,
+ this.serviceAddress,
+ this.servicePort,
+ this.serviceTags);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link CatalogService#getAddress() address} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for address
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableCatalogService withAddress(String value) {
+ if (this.address.equals(value)) return this;
+ return new ImmutableCatalogService(
+ this.node,
+ Preconditions.checkNotNull(value, "address"),
+ this.serviceName,
+ this.serviceId,
+ this.serviceAddress,
+ this.servicePort,
+ this.serviceTags);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceName() serviceName} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for serviceName
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableCatalogService withServiceName(String value) {
+ if (this.serviceName.equals(value)) return this;
+ return new ImmutableCatalogService(
+ this.node,
+ this.address,
+ Preconditions.checkNotNull(value, "serviceName"),
+ this.serviceId,
+ this.serviceAddress,
+ this.servicePort,
+ this.serviceTags);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceId() serviceId} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for serviceId
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableCatalogService withServiceId(String value) {
+ if (this.serviceId.equals(value)) return this;
+ return new ImmutableCatalogService(
+ this.node,
+ this.address,
+ this.serviceName,
+ Preconditions.checkNotNull(value, "serviceId"),
+ this.serviceAddress,
+ this.servicePort,
+ this.serviceTags);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link CatalogService#getServiceAddress() serviceAddress} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for serviceAddress
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableCatalogService withServiceAddress(String value) {
+ if (this.serviceAddress.equals(value)) return this;
+ return new ImmutableCatalogService(
+ this.node,
+ this.address,
+ this.serviceName,
+ this.serviceId,
+ Preconditions.checkNotNull(value, "serviceAddress"),
+ this.servicePort,
+ this.serviceTags);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link CatalogService#getServicePort() servicePort} attribute.
+ * A value equality check is used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for servicePort
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableCatalogService withServicePort(int value) {
+ if (this.servicePort == value) return this;
+ return new ImmutableCatalogService(
+ this.node,
+ this.address,
+ this.serviceName,
+ this.serviceId,
+ this.serviceAddress,
+ value,
+ this.serviceTags);
+ }
+
+ /**
+ * Copy the current immutable object with elements that replace the content of {@link CatalogService#getServiceTags() serviceTags}.
+ * @param elements The elements to set
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableCatalogService withServiceTags(String... elements) {
+ ImmutableList<String> newValue = ImmutableList.copyOf(elements);
+ return new ImmutableCatalogService(
+ this.node,
+ this.address,
+ this.serviceName,
+ this.serviceId,
+ this.serviceAddress,
+ this.servicePort,
+ newValue);
+ }
+
+ /**
+ * Copy the current immutable object with elements that replace the content of {@link CatalogService#getServiceTags() serviceTags}.
+ * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
+ * @param elements An iterable of serviceTags elements to set
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableCatalogService withServiceTags(Iterable<String> elements) {
+ if (this.serviceTags == elements) return this;
+ ImmutableList<String> newValue = ImmutableList.copyOf(elements);
+ return new ImmutableCatalogService(
+ this.node,
+ this.address,
+ this.serviceName,
+ this.serviceId,
+ this.serviceAddress,
+ this.servicePort,
+ newValue);
+ }
+
+ /**
+ * This instance is equal to all instances of {@code ImmutableCatalogService} that have equal attribute values.
+ * @return {@code true} if {@code this} is equal to {@code another} instance
+ */
+ @Override
+ public boolean equals(Object another) {
+ if (this == another) return true;
+ return another instanceof ImmutableCatalogService
+ && equalTo((ImmutableCatalogService) another);
+ }
+
+ private boolean equalTo(ImmutableCatalogService another) {
+ return node.equals(another.node)
+ && address.equals(another.address)
+ && serviceName.equals(another.serviceName)
+ && serviceId.equals(another.serviceId)
+ && serviceAddress.equals(another.serviceAddress)
+ && servicePort == another.servicePort
+ && serviceTags.equals(another.serviceTags);
+ }
+
+ /**
+ * Computes a hash code from attributes: {@code node}, {@code address}, {@code serviceName}, {@code serviceId}, {@code serviceAddress}, {@code servicePort}, {@code serviceTags}.
+ * @return hashCode value
+ */
+ @Override
+ public int hashCode() {
+ int h = 31;
+ h = h * 17 + node.hashCode();
+ h = h * 17 + address.hashCode();
+ h = h * 17 + serviceName.hashCode();
+ h = h * 17 + serviceId.hashCode();
+ h = h * 17 + serviceAddress.hashCode();
+ h = h * 17 + servicePort;
+ h = h * 17 + serviceTags.hashCode();
+ return h;
+ }
+
+ /**
+ * Prints the immutable value {@code CatalogService...} with all non-generated
+ * and non-auxiliary attribute values.
+ * @return A string representation of the value
+ */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper("CatalogService")
+ .add("node", node)
+ .add("address", address)
+ .add("serviceName", serviceName)
+ .add("serviceId", serviceId)
+ .add("serviceAddress", serviceAddress)
+ .add("servicePort", servicePort)
+ .add("serviceTags", serviceTags)
+ .toString();
+ }
+
+ /**
+ * Utility type used to correctly read immutable object from JSON representation.
+ * @deprecated Do not use this type directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonDeserialize
+ static final class Json extends CatalogService {
+ String node;
+ String address;
+ String serviceName;
+ String serviceId;
+ String serviceAddress;
+ Integer servicePort;
+ List<String> serviceTags = ImmutableList.of();
+ @JsonProperty(value = "Node")
+ public void setNode(String node) {
+ this.node = node;
+ }
+ @JsonProperty(value = "Address")
+ public void setAddress(String address) {
+ this.address = address;
+ }
+ @JsonProperty(value = "ServiceName")
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+ @JsonProperty(value = "ServiceID")
+ public void setServiceId(String serviceId) {
+ this.serviceId = serviceId;
+ }
+ @JsonProperty(value = "ServiceAddress")
+ public void setServiceAddress(String serviceAddress) {
+ this.serviceAddress = serviceAddress;
+ }
+ @JsonProperty(value = "ServicePort")
+ public void setServicePort(int servicePort) {
+ this.servicePort = servicePort;
+ }
+ @JsonProperty(value = "ServiceTags")
+ public void setServiceTags(List<String> serviceTags) {
+ this.serviceTags = serviceTags;
+ }
+ @Override
+ public String getNode() { throw new UnsupportedOperationException(); }
+ @Override
+ public String getAddress() { throw new UnsupportedOperationException(); }
+ @Override
+ public String getServiceName() { throw new UnsupportedOperationException(); }
+ @Override
+ public String getServiceId() { throw new UnsupportedOperationException(); }
+ @Override
+ public String getServiceAddress() { throw new UnsupportedOperationException(); }
+ @Override
+ public int getServicePort() { throw new UnsupportedOperationException(); }
+ @Override
+ public List<String> getServiceTags() { throw new UnsupportedOperationException(); }
+ }
+
+ /**
+ * @param json A JSON-bindable data structure
+ * @return An immutable value type
+ * @deprecated Do not use this method directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonCreator
+ static ImmutableCatalogService fromJson(Json json) {
+ ImmutableCatalogService.Builder builder = ImmutableCatalogService.builder();
+ if (json.node != null) {
+ builder.node(json.node);
+ }
+ if (json.address != null) {
+ builder.address(json.address);
+ }
+ if (json.serviceName != null) {
+ builder.serviceName(json.serviceName);
+ }
+ if (json.serviceId != null) {
+ builder.serviceId(json.serviceId);
+ }
+ if (json.serviceAddress != null) {
+ builder.serviceAddress(json.serviceAddress);
+ }
+ if (json.servicePort != null) {
+ builder.servicePort(json.servicePort);
+ }
+ if (json.serviceTags != null) {
+ builder.addAllServiceTags(json.serviceTags);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Creates an immutable copy of a {@link CatalogService} value.
+ * Uses accessors to get values to initialize the new immutable instance.
+ * If an instance is already immutable, it is returned as is.
+ * @param instance The instance to copy
+ * @return A copied immutable CatalogService instance
+ */
+ public static ImmutableCatalogService copyOf(CatalogService instance) {
+ if (instance instanceof ImmutableCatalogService) {
+ return (ImmutableCatalogService) instance;
+ }
+ return ImmutableCatalogService.builder()
+ .from(instance)
+ .build();
+ }
+
+ /**
+ * Creates a builder for {@link ImmutableCatalogService ImmutableCatalogService}.
+ * @return A new ImmutableCatalogService builder
+ */
+ public static ImmutableCatalogService.Builder builder() {
+ return new ImmutableCatalogService.Builder();
+ }
+
+ /**
+ * Builds instances of type {@link ImmutableCatalogService ImmutableCatalogService}.
+ * Initialize attributes and then invoke the {@link #build()} method to create an
+ * immutable instance.
+ * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
+ * but instead used immediately to create instances.</em>
+ */
+ public static final class Builder {
+ private static final long INIT_BIT_NODE = 0x1L;
+ private static final long INIT_BIT_ADDRESS = 0x2L;
+ private static final long INIT_BIT_SERVICE_NAME = 0x4L;
+ private static final long INIT_BIT_SERVICE_ID = 0x8L;
+ private static final long INIT_BIT_SERVICE_ADDRESS = 0x10L;
+ private static final long INIT_BIT_SERVICE_PORT = 0x20L;
+ private long initBits = 0x3f;
+
+ private String node;
+ private String address;
+ private String serviceName;
+ private String serviceId;
+ private String serviceAddress;
+ private int servicePort;
+ private ImmutableList.Builder<String> serviceTagsBuilder = ImmutableList.builder();
+
+ private Builder() {
+ }
+
+ /**
+ * Fill a builder with attribute values from the provided {@code CatalogService} instance.
+ * Regular attribute values will be replaced with those from the given instance.
+ * Absent optional values will not replace present values.
+ * Collection elements and entries will be added, not replaced.
+ * @param instance The instance from which to copy values
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder from(CatalogService instance) {
+ Preconditions.checkNotNull(instance, "instance");
+ node(instance.getNode());
+ address(instance.getAddress());
+ serviceName(instance.getServiceName());
+ serviceId(instance.getServiceId());
+ serviceAddress(instance.getServiceAddress());
+ servicePort(instance.getServicePort());
+ addAllServiceTags(instance.getServiceTags());
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link CatalogService#getNode() node} attribute.
+ * @param node The value for node
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder node(String node) {
+ this.node = Preconditions.checkNotNull(node, "node");
+ initBits &= ~INIT_BIT_NODE;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link CatalogService#getAddress() address} attribute.
+ * @param address The value for address
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder address(String address) {
+ this.address = Preconditions.checkNotNull(address, "address");
+ initBits &= ~INIT_BIT_ADDRESS;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link CatalogService#getServiceName() serviceName} attribute.
+ * @param serviceName The value for serviceName
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder serviceName(String serviceName) {
+ this.serviceName = Preconditions.checkNotNull(serviceName, "serviceName");
+ initBits &= ~INIT_BIT_SERVICE_NAME;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link CatalogService#getServiceId() serviceId} attribute.
+ * @param serviceId The value for serviceId
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder serviceId(String serviceId) {
+ this.serviceId = Preconditions.checkNotNull(serviceId, "serviceId");
+ initBits &= ~INIT_BIT_SERVICE_ID;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link CatalogService#getServiceAddress() serviceAddress} attribute.
+ * @param serviceAddress The value for serviceAddress
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder serviceAddress(String serviceAddress) {
+ this.serviceAddress = Preconditions.checkNotNull(serviceAddress, "serviceAddress");
+ initBits &= ~INIT_BIT_SERVICE_ADDRESS;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link CatalogService#getServicePort() servicePort} attribute.
+ * @param servicePort The value for servicePort
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder servicePort(int servicePort) {
+ this.servicePort = servicePort;
+ initBits &= ~INIT_BIT_SERVICE_PORT;
+ return this;
+ }
+
+ /**
+ * Adds one element to {@link CatalogService#getServiceTags() serviceTags} list.
+ * @param element A serviceTags element
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder addServiceTags(String element) {
+ serviceTagsBuilder.add(element);
+ return this;
+ }
+
+ /**
+ * Adds elements to {@link CatalogService#getServiceTags() serviceTags} list.
+ * @param elements An array of serviceTags elements
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder addServiceTags(String... elements) {
+ serviceTagsBuilder.add(elements);
+ return this;
+ }
+
+ /**
+ * Sets or replaces all elements for {@link CatalogService#getServiceTags() serviceTags} list.
+ * @param elements An iterable of serviceTags elements
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder serviceTags(Iterable<String> elements) {
+ serviceTagsBuilder = ImmutableList.builder();
+ return addAllServiceTags(elements);
+ }
+
+ /**
+ * Adds elements to {@link CatalogService#getServiceTags() serviceTags} list.
+ * @param elements An iterable of serviceTags elements
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder addAllServiceTags(Iterable<String> elements) {
+ serviceTagsBuilder.addAll(elements);
+ return this;
+ }
+
+ /**
+ * Builds a new {@link ImmutableCatalogService ImmutableCatalogService}.
+ * @return An immutable instance of CatalogService
+ * @throws java.lang.IllegalStateException if any required attributes are missing
+ */
+ public ImmutableCatalogService build() throws IllegalStateException {
+ if (initBits != 0) {
+ throw new IllegalStateException(formatRequiredAttributesMessage());
+ }
+ return new ImmutableCatalogService(
+ node,
+ address,
+ serviceName,
+ serviceId,
+ serviceAddress,
+ servicePort,
+ serviceTagsBuilder.build());
+ }
+
+ private String formatRequiredAttributesMessage() {
+ List<String> attributes = Lists.newArrayList();
+ if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node");
+ if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address");
+ if ((initBits & INIT_BIT_SERVICE_NAME) != 0) attributes.add("serviceName");
+ if ((initBits & INIT_BIT_SERVICE_ID) != 0) attributes.add("serviceId");
+ if ((initBits & INIT_BIT_SERVICE_ADDRESS) != 0) attributes.add("serviceAddress");
+ if ((initBits & INIT_BIT_SERVICE_PORT) != 0) attributes.add("servicePort");
+ return "Cannot build CatalogService, some of required attributes are not set " + attributes;
+ }
+ }
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java new file mode 100644 index 0000000..657af12 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/catalog/ServiceInfo.java @@ -0,0 +1,63 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.model.catalog;
+
+import com.google.common.base.Objects;
+
+public class ServiceInfo {
+
+ private String serviceName;
+
+ private String version="";
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ @Override
+ public boolean equals(Object other)
+ {
+ if(this == other)
+ return true;
+ if(other instanceof ServiceInfo)
+ {
+ ServiceInfo that = (ServiceInfo)other;
+ return Objects.equal(serviceName, that.serviceName) && Objects.equal(version, that.version);
+ } else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(serviceName, version);
+ }
+
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java new file mode 100644 index 0000000..8499ac3 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableNode.java @@ -0,0 +1,266 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.model.health;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import java.util.List;
+import javax.annotation.Generated;
+
+/**
+ * Immutable implementation of {@link Node}.
+ * <p>
+ * Use the builder to create immutable instances:
+ * {@code ImmutableNode.builder()}.
+ */
+@SuppressWarnings("all")
+@Generated({"Immutables.generator", "Node"})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class ImmutableNode extends Node {
+ private final String node;
+ private final String address;
+
+ private ImmutableNode(String node, String address) {
+ this.node = node;
+ this.address = address;
+ }
+
+ /**
+ * @return The value of the {@code node} attribute
+ */
+ @JsonProperty(value = "Node")
+ @Override
+ public String getNode() {
+ return node;
+ }
+
+ /**
+ * @return The value of the {@code address} attribute
+ */
+ @JsonProperty(value = "Address")
+ @Override
+ public String getAddress() {
+ return address;
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link Node#getNode() node} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for node
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableNode withNode(String value) {
+ if (this.node.equals(value)) return this;
+ return new ImmutableNode(Preconditions.checkNotNull(value, "node"), this.address);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link Node#getAddress() address} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for address
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableNode withAddress(String value) {
+ if (this.address.equals(value)) return this;
+ return new ImmutableNode(this.node, Preconditions.checkNotNull(value, "address"));
+ }
+
+ /**
+ * This instance is equal to all instances of {@code ImmutableNode} that have equal attribute values.
+ * @return {@code true} if {@code this} is equal to {@code another} instance
+ */
+ @Override
+ public boolean equals(Object another) {
+ if (this == another) return true;
+ return another instanceof ImmutableNode
+ && equalTo((ImmutableNode) another);
+ }
+
+ private boolean equalTo(ImmutableNode another) {
+ return node.equals(another.node)
+ && address.equals(another.address);
+ }
+
+ /**
+ * Computes a hash code from attributes: {@code node}, {@code address}.
+ * @return hashCode value
+ */
+ @Override
+ public int hashCode() {
+ int h = 31;
+ h = h * 17 + node.hashCode();
+ h = h * 17 + address.hashCode();
+ return h;
+ }
+
+ /**
+ * Prints the immutable value {@code Node...} with all non-generated
+ * and non-auxiliary attribute values.
+ * @return A string representation of the value
+ */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper("Node")
+ .add("node", node)
+ .add("address", address)
+ .toString();
+ }
+
+ /**
+ * Utility type used to correctly read immutable object from JSON representation.
+ * @deprecated Do not use this type directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonDeserialize
+ static final class Json extends Node {
+ String node;
+ String address;
+ @JsonProperty(value = "Node")
+ public void setNode(String node) {
+ this.node = node;
+ }
+ @JsonProperty(value = "Address")
+ public void setAddress(String address) {
+ this.address = address;
+ }
+ @Override
+ public String getNode() { throw new UnsupportedOperationException(); }
+ @Override
+ public String getAddress() { throw new UnsupportedOperationException(); }
+ }
+
+ /**
+ * @param json A JSON-bindable data structure
+ * @return An immutable value type
+ * @deprecated Do not use this method directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonCreator
+ static ImmutableNode fromJson(Json json) {
+ ImmutableNode.Builder builder = ImmutableNode.builder();
+ if (json.node != null) {
+ builder.node(json.node);
+ }
+ if (json.address != null) {
+ builder.address(json.address);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Creates an immutable copy of a {@link Node} value.
+ * Uses accessors to get values to initialize the new immutable instance.
+ * If an instance is already immutable, it is returned as is.
+ * @param instance The instance to copy
+ * @return A copied immutable Node instance
+ */
+ public static ImmutableNode copyOf(Node instance) {
+ if (instance instanceof ImmutableNode) {
+ return (ImmutableNode) instance;
+ }
+ return ImmutableNode.builder()
+ .from(instance)
+ .build();
+ }
+
+ /**
+ * Creates a builder for {@link ImmutableNode ImmutableNode}.
+ * @return A new ImmutableNode builder
+ */
+ public static ImmutableNode.Builder builder() {
+ return new ImmutableNode.Builder();
+ }
+
+ /**
+ * Builds instances of type {@link ImmutableNode ImmutableNode}.
+ * Initialize attributes and then invoke the {@link #build()} method to create an
+ * immutable instance.
+ * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
+ * but instead used immediately to create instances.</em>
+ */
+ public static final class Builder {
+ private static final long INIT_BIT_NODE = 0x1L;
+ private static final long INIT_BIT_ADDRESS = 0x2L;
+ private long initBits = 0x3;
+
+ private String node;
+ private String address;
+
+ private Builder() {
+ }
+
+ /**
+ * Fill a builder with attribute values from the provided {@code Node} instance.
+ * Regular attribute values will be replaced with those from the given instance.
+ * Absent optional values will not replace present values.
+ * @param instance The instance from which to copy values
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder from(Node instance) {
+ Preconditions.checkNotNull(instance, "instance");
+ node(instance.getNode());
+ address(instance.getAddress());
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link Node#getNode() node} attribute.
+ * @param node The value for node
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder node(String node) {
+ this.node = Preconditions.checkNotNull(node, "node");
+ initBits &= ~INIT_BIT_NODE;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link Node#getAddress() address} attribute.
+ * @param address The value for address
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder address(String address) {
+ this.address = Preconditions.checkNotNull(address, "address");
+ initBits &= ~INIT_BIT_ADDRESS;
+ return this;
+ }
+
+ /**
+ * Builds a new {@link ImmutableNode ImmutableNode}.
+ * @return An immutable instance of Node
+ * @throws java.lang.IllegalStateException if any required attributes are missing
+ */
+ public ImmutableNode build() throws IllegalStateException {
+ if (initBits != 0) {
+ throw new IllegalStateException(formatRequiredAttributesMessage());
+ }
+ return new ImmutableNode(node, address);
+ }
+
+ private String formatRequiredAttributesMessage() {
+ List<String> attributes = Lists.newArrayList();
+ if ((initBits & INIT_BIT_NODE) != 0) attributes.add("node");
+ if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address");
+ return "Cannot build Node, some of required attributes are not set " + attributes;
+ }
+ }
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java new file mode 100644 index 0000000..70eabf2 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ImmutableService.java @@ -0,0 +1,478 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.model.health;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import java.util.List;
+import javax.annotation.Generated;
+
+/**
+ * Immutable implementation of {@link Service}.
+ * <p>
+ * Use the builder to create immutable instances:
+ * {@code ImmutableService.builder()}.
+ */
+@SuppressWarnings("all")
+@Generated({"Immutables.generator", "Service"})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class ImmutableService extends Service {
+ private final String id;
+ private final String service;
+ private final ImmutableList<String> tags;
+ private final String address;
+ private final int port;
+
+ private ImmutableService(
+ String id,
+ String service,
+ ImmutableList<String> tags,
+ String address,
+ int port) {
+ this.id = id;
+ this.service = service;
+ this.tags = tags;
+ this.address = address;
+ this.port = port;
+ }
+
+ /**
+ * @return The value of the {@code id} attribute
+ */
+ @JsonProperty(value = "ID")
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @return The value of the {@code service} attribute
+ */
+ @JsonProperty(value = "Service")
+ @Override
+ public String getService() {
+ return service;
+ }
+
+ /**
+ * @return The value of the {@code tags} attribute
+ */
+ @JsonProperty(value = "Tags")
+ @JsonDeserialize(as = ImmutableList.class, contentAs = String.class)
+ @Override
+ public ImmutableList<String> getTags() {
+ return tags;
+ }
+
+ /**
+ * @return The value of the {@code address} attribute
+ */
+ @JsonProperty(value = "Address")
+ @Override
+ public String getAddress() {
+ return address;
+ }
+
+ /**
+ * @return The value of the {@code port} attribute
+ */
+ @JsonProperty(value = "Port")
+ @Override
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link Service#getId() id} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for id
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableService withId(String value) {
+ if (this.id.equals(value)) return this;
+ return new ImmutableService(
+ Preconditions.checkNotNull(value, "id"),
+ this.service,
+ this.tags,
+ this.address,
+ this.port);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link Service#getService() service} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for service
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableService withService(String value) {
+ if (this.service.equals(value)) return this;
+ return new ImmutableService(
+ this.id,
+ Preconditions.checkNotNull(value, "service"),
+ this.tags,
+ this.address,
+ this.port);
+ }
+
+ /**
+ * Copy the current immutable object with elements that replace the content of {@link Service#getTags() tags}.
+ * @param elements The elements to set
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableService withTags(String... elements) {
+ ImmutableList<String> newValue = ImmutableList.copyOf(elements);
+ return new ImmutableService(this.id, this.service, newValue, this.address, this.port);
+ }
+
+ /**
+ * Copy the current immutable object with elements that replace the content of {@link Service#getTags() tags}.
+ * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
+ * @param elements An iterable of tags elements to set
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableService withTags(Iterable<String> elements) {
+ if (this.tags == elements) return this;
+ ImmutableList<String> newValue = ImmutableList.copyOf(elements);
+ return new ImmutableService(this.id, this.service, newValue, this.address, this.port);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link Service#getAddress() address} attribute.
+ * An equals check used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for address
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableService withAddress(String value) {
+ if (this.address.equals(value)) return this;
+ return new ImmutableService(
+ this.id,
+ this.service,
+ this.tags,
+ Preconditions.checkNotNull(value, "address"),
+ this.port);
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link Service#getPort() port} attribute.
+ * A value equality check is used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for port
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableService withPort(int value) {
+ if (this.port == value) return this;
+ return new ImmutableService(this.id, this.service, this.tags, this.address, value);
+ }
+
+ /**
+ * This instance is equal to all instances of {@code ImmutableService} that have equal attribute values.
+ * @return {@code true} if {@code this} is equal to {@code another} instance
+ */
+ @Override
+ public boolean equals(Object another) {
+ if (this == another) return true;
+ return another instanceof ImmutableService
+ && equalTo((ImmutableService) another);
+ }
+
+ private boolean equalTo(ImmutableService another) {
+ return id.equals(another.id)
+ && service.equals(another.service)
+ && tags.equals(another.tags)
+ && address.equals(another.address)
+ && port == another.port;
+ }
+
+ /**
+ * Computes a hash code from attributes: {@code id}, {@code service}, {@code tags}, {@code address}, {@code port}.
+ * @return hashCode value
+ */
+ @Override
+ public int hashCode() {
+ int h = 31;
+ h = h * 17 + id.hashCode();
+ h = h * 17 + service.hashCode();
+ h = h * 17 + tags.hashCode();
+ h = h * 17 + address.hashCode();
+ h = h * 17 + port;
+ return h;
+ }
+
+ /**
+ * Prints the immutable value {@code Service...} with all non-generated
+ * and non-auxiliary attribute values.
+ * @return A string representation of the value
+ */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper("Service")
+ .add("id", id)
+ .add("service", service)
+ .add("tags", tags)
+ .add("address", address)
+ .add("port", port)
+ .toString();
+ }
+
+ /**
+ * Utility type used to correctly read immutable object from JSON representation.
+ * @deprecated Do not use this type directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonDeserialize
+ static final class Json extends Service {
+ String id;
+ String service;
+ List<String> tags = ImmutableList.of();
+ String address;
+ Integer port;
+ @JsonProperty(value = "ID")
+ public void setId(String id) {
+ this.id = id;
+ }
+ @JsonProperty(value = "Service")
+ public void setService(String service) {
+ this.service = service;
+ }
+ @JsonProperty(value = "Tags")
+ @JsonDeserialize(as = ImmutableList.class, contentAs = String.class)
+ public void setTags(List<String> tags) {
+ this.tags = tags;
+ }
+ @JsonProperty(value = "Address")
+ public void setAddress(String address) {
+ this.address = address;
+ }
+ @JsonProperty(value = "Port")
+ public void setPort(int port) {
+ this.port = port;
+ }
+ @Override
+ public String getId() { throw new UnsupportedOperationException(); }
+ @Override
+ public String getService() { throw new UnsupportedOperationException(); }
+ @Override
+ public List<String> getTags() { throw new UnsupportedOperationException(); }
+ @Override
+ public String getAddress() { throw new UnsupportedOperationException(); }
+ @Override
+ public int getPort() { throw new UnsupportedOperationException(); }
+ }
+
+ /**
+ * @param json A JSON-bindable data structure
+ * @return An immutable value type
+ * @deprecated Do not use this method directly, it exists only for the <em>Jackson</em>-binding infrastructure
+ */
+ @Deprecated
+ @JsonCreator
+ static ImmutableService fromJson(Json json) {
+ ImmutableService.Builder builder = ImmutableService.builder();
+ if (json.id != null) {
+ builder.id(json.id);
+ }
+ if (json.service != null) {
+ builder.service(json.service);
+ }
+ if (json.tags != null) {
+ builder.addAllTags(json.tags);
+ }
+ if (json.address != null) {
+ builder.address(json.address);
+ }
+ if (json.port != null) {
+ builder.port(json.port);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Creates an immutable copy of a {@link Service} value.
+ * Uses accessors to get values to initialize the new immutable instance.
+ * If an instance is already immutable, it is returned as is.
+ * @param instance The instance to copy
+ * @return A copied immutable Service instance
+ */
+ public static ImmutableService copyOf(Service instance) {
+ if (instance instanceof ImmutableService) {
+ return (ImmutableService) instance;
+ }
+ return ImmutableService.builder()
+ .from(instance)
+ .build();
+ }
+
+ /**
+ * Creates a builder for {@link ImmutableService ImmutableService}.
+ * @return A new ImmutableService builder
+ */
+ public static ImmutableService.Builder builder() {
+ return new ImmutableService.Builder();
+ }
+
+ /**
+ * Builds instances of type {@link ImmutableService ImmutableService}.
+ * Initialize attributes and then invoke the {@link #build()} method to create an
+ * immutable instance.
+ * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
+ * but instead used immediately to create instances.</em>
+ */
+ public static final class Builder {
+ private static final long INIT_BIT_ID = 0x1L;
+ private static final long INIT_BIT_SERVICE = 0x2L;
+ private static final long INIT_BIT_ADDRESS = 0x4L;
+ private static final long INIT_BIT_PORT = 0x8L;
+ private long initBits = 0xf;
+
+ private String id;
+ private String service;
+ private ImmutableList.Builder<String> tagsBuilder = ImmutableList.builder();
+ private String address;
+ private int port;
+
+ private Builder() {
+ }
+
+ /**
+ * Fill a builder with attribute values from the provided {@code Service} instance.
+ * Regular attribute values will be replaced with those from the given instance.
+ * Absent optional values will not replace present values.
+ * Collection elements and entries will be added, not replaced.
+ * @param instance The instance from which to copy values
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder from(Service instance) {
+ Preconditions.checkNotNull(instance, "instance");
+ id(instance.getId());
+ service(instance.getService());
+ addAllTags(instance.getTags());
+ address(instance.getAddress());
+ port(instance.getPort());
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link Service#getId() id} attribute.
+ * @param id The value for id
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder id(String id) {
+ this.id = Preconditions.checkNotNull(id, "id");
+ initBits &= ~INIT_BIT_ID;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link Service#getService() service} attribute.
+ * @param service The value for service
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder service(String service) {
+ this.service = Preconditions.checkNotNull(service, "service");
+ initBits &= ~INIT_BIT_SERVICE;
+ return this;
+ }
+
+ /**
+ * Adds one element to {@link Service#getTags() tags} list.
+ * @param element A tags element
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder addTags(String element) {
+ tagsBuilder.add(element);
+ return this;
+ }
+
+ /**
+ * Adds elements to {@link Service#getTags() tags} list.
+ * @param elements An array of tags elements
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder addTags(String... elements) {
+ tagsBuilder.add(elements);
+ return this;
+ }
+
+ /**
+ * Sets or replaces all elements for {@link Service#getTags() tags} list.
+ * @param elements An iterable of tags elements
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder tags(Iterable<String> elements) {
+ tagsBuilder = ImmutableList.builder();
+ return addAllTags(elements);
+ }
+
+ /**
+ * Adds elements to {@link Service#getTags() tags} list.
+ * @param elements An iterable of tags elements
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder addAllTags(Iterable<String> elements) {
+ tagsBuilder.addAll(elements);
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link Service#getAddress() address} attribute.
+ * @param address The value for address
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder address(String address) {
+ this.address = Preconditions.checkNotNull(address, "address");
+ initBits &= ~INIT_BIT_ADDRESS;
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link Service#getPort() port} attribute.
+ * @param port The value for port
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder port(int port) {
+ this.port = port;
+ initBits &= ~INIT_BIT_PORT;
+ return this;
+ }
+
+ /**
+ * Builds a new {@link ImmutableService ImmutableService}.
+ * @return An immutable instance of Service
+ * @throws java.lang.IllegalStateException if any required attributes are missing
+ */
+ public ImmutableService build() throws IllegalStateException {
+ if (initBits != 0) {
+ throw new IllegalStateException(formatRequiredAttributesMessage());
+ }
+ return new ImmutableService(id, service, tagsBuilder.build(), address, port);
+ }
+
+ private String formatRequiredAttributesMessage() {
+ List<String> attributes = Lists.newArrayList();
+ if ((initBits & INIT_BIT_ID) != 0) attributes.add("id");
+ if ((initBits & INIT_BIT_SERVICE) != 0) attributes.add("service");
+ if ((initBits & INIT_BIT_ADDRESS) != 0) attributes.add("address");
+ if ((initBits & INIT_BIT_PORT) != 0) attributes.add("port");
+ return "Cannot build Service, some of required attributes are not set " + attributes;
+ }
+ }
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java new file mode 100644 index 0000000..83e6632 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Node.java @@ -0,0 +1,35 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.model.health; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(as = ImmutableNode.class) +@JsonDeserialize(as = ImmutableNode.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class Node { + + @JsonProperty("Node") + public abstract String getNode(); + + @JsonProperty("Address") + public abstract String getAddress(); +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java new file mode 100644 index 0000000..379e9f1 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/Service.java @@ -0,0 +1,48 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.model.health; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.collect.ImmutableList; + + +@JsonSerialize(as = ImmutableService.class) +@JsonDeserialize(as = ImmutableService.class) +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class Service { + + @JsonProperty("ID") + public abstract String getId(); + + @JsonProperty("Service") + public abstract String getService(); + + @JsonProperty("Tags") + @JsonDeserialize(as = ImmutableList.class, contentAs = String.class) + public abstract List<String> getTags(); + + @JsonProperty("Address") + public abstract String getAddress(); + + @JsonProperty("Port") + public abstract int getPort(); +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java new file mode 100644 index 0000000..d353b55 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/model/health/ServiceHealth.java @@ -0,0 +1,73 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.model.health; + +import org.openo.msb.wrapper.consul.model.catalog.ServiceInfo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Objects; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ServiceHealth { + + @JsonProperty("Node") + public Node node; + + @JsonProperty("Service") + public Service service; + + public Node getNode() { + return node; + } + + public void setNode(Node node) { + this.node = node; + } + + public Service getService() { + return service; + } + + public void setService(Service service) { + this.service = service; + } + + @Override + public boolean equals(Object other) + { + if(this == other) + return true; + if(other instanceof ServiceHealth) + { + ServiceHealth that = (ServiceHealth)other; + return Objects.equal(node, that.node) && Objects.equal(service, that.service); + } else + { + return false; + } + } + + @Override + public int hashCode() { + return Objects.hashCode(node, service); + } + + + +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java new file mode 100644 index 0000000..34972fe --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/CatalogOptions.java @@ -0,0 +1,39 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.option; + +import static org.openo.msb.wrapper.consul.option.Options.optionallyAdd; + +import javax.ws.rs.client.WebTarget; + +import com.google.common.base.Optional; + + +public abstract class CatalogOptions implements ParamAdder { + + public abstract Optional<String> getDatacenter(); + public abstract Optional<String> getTag(); + + public static final CatalogOptions BLANK = ImmutableCatalogOptions.builder().build(); + + @Override + public final WebTarget apply(final WebTarget input) { + WebTarget added = optionallyAdd(input, "dc", getDatacenter()); + added = optionallyAdd(added, "tag", getTag()); + return added; + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java new file mode 100644 index 0000000..52afa00 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ConsistencyMode.java @@ -0,0 +1,21 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.option; + +public enum ConsistencyMode { + DEFAULT, STALE, CONSISTENT +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java new file mode 100644 index 0000000..35eda18 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableCatalogOptions.java @@ -0,0 +1,251 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.option;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import javax.annotation.Generated;
+
+/**
+ * Immutable implementation of {@link CatalogOptions}.
+ * <p>
+ * Use the builder to create immutable instances:
+ * {@code ImmutableCatalogOptions.builder()}.
+ */
+@SuppressWarnings("all")
+@Generated({"Immutables.generator", "CatalogOptions"})
+public final class ImmutableCatalogOptions extends CatalogOptions {
+ private final Optional<String> datacenter;
+ private final Optional<String> tag;
+
+ private ImmutableCatalogOptions(
+ Optional<String> datacenter,
+ Optional<String> tag) {
+ this.datacenter = datacenter;
+ this.tag = tag;
+ }
+
+ /**
+ * @return The value of the {@code datacenter} attribute
+ */
+ @Override
+ public Optional<String> getDatacenter() {
+ return datacenter;
+ }
+
+ /**
+ * @return The value of the {@code tag} attribute
+ */
+ @Override
+ public Optional<String> getTag() {
+ return tag;
+ }
+
+ /**
+ * Copy the current immutable object by setting a <i>present</i> value for the optional {@link CatalogOptions#getDatacenter() datacenter} attribute.
+ * @param value The value for datacenter
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableCatalogOptions withDatacenter(String value) {
+ Optional<String> newValue = Optional.of(value);
+ return new ImmutableCatalogOptions(newValue, this.tag);
+ }
+
+ /**
+ * Copy the current immutable object by setting an optional value for the {@link CatalogOptions#getDatacenter() datacenter} attribute.
+ * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}.
+ * @param optional A value for datacenter
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableCatalogOptions withDatacenter(Optional<String> optional) {
+ Optional<String> value = Preconditions.checkNotNull(optional, "datacenter");
+ if (this.datacenter == value) return this;
+ return new ImmutableCatalogOptions(value, this.tag);
+ }
+
+ /**
+ * Copy the current immutable object by setting a <i>present</i> value for the optional {@link CatalogOptions#getTag() tag} attribute.
+ * @param value The value for tag
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableCatalogOptions withTag(String value) {
+ Optional<String> newValue = Optional.of(value);
+ return new ImmutableCatalogOptions(this.datacenter, newValue);
+ }
+
+ /**
+ * Copy the current immutable object by setting an optional value for the {@link CatalogOptions#getTag() tag} attribute.
+ * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}.
+ * @param optional A value for tag
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableCatalogOptions withTag(Optional<String> optional) {
+ Optional<String> value = Preconditions.checkNotNull(optional, "tag");
+ if (this.tag == value) return this;
+ return new ImmutableCatalogOptions(this.datacenter, value);
+ }
+
+ /**
+ * This instance is equal to all instances of {@code ImmutableCatalogOptions} that have equal attribute values.
+ * @return {@code true} if {@code this} is equal to {@code another} instance
+ */
+ @Override
+ public boolean equals(Object another) {
+ if (this == another) return true;
+ return another instanceof ImmutableCatalogOptions
+ && equalTo((ImmutableCatalogOptions) another);
+ }
+
+ private boolean equalTo(ImmutableCatalogOptions another) {
+ return datacenter.equals(another.datacenter)
+ && tag.equals(another.tag);
+ }
+
+ /**
+ * Computes a hash code from attributes: {@code datacenter}, {@code tag}.
+ * @return hashCode value
+ */
+ @Override
+ public int hashCode() {
+ int h = 31;
+ h = h * 17 + datacenter.hashCode();
+ h = h * 17 + tag.hashCode();
+ return h;
+ }
+
+ /**
+ * Prints the immutable value {@code CatalogOptions...} with all non-generated
+ * and non-auxiliary attribute values.
+ * @return A string representation of the value
+ */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper("CatalogOptions")
+ .add("datacenter", datacenter)
+ .add("tag", tag)
+ .toString();
+ }
+
+ /**
+ * Creates an immutable copy of a {@link CatalogOptions} value.
+ * Uses accessors to get values to initialize the new immutable instance.
+ * If an instance is already immutable, it is returned as is.
+ * @param instance The instance to copy
+ * @return A copied immutable CatalogOptions instance
+ */
+ public static ImmutableCatalogOptions copyOf(CatalogOptions instance) {
+ if (instance instanceof ImmutableCatalogOptions) {
+ return (ImmutableCatalogOptions) instance;
+ }
+ return ImmutableCatalogOptions.builder()
+ .from(instance)
+ .build();
+ }
+
+ /**
+ * Creates a builder for {@link ImmutableCatalogOptions ImmutableCatalogOptions}.
+ * @return A new ImmutableCatalogOptions builder
+ */
+ public static ImmutableCatalogOptions.Builder builder() {
+ return new ImmutableCatalogOptions.Builder();
+ }
+
+ /**
+ * Builds instances of type {@link ImmutableCatalogOptions ImmutableCatalogOptions}.
+ * Initialize attributes and then invoke the {@link #build()} method to create an
+ * immutable instance.
+ * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
+ * but instead used immediately to create instances.</em>
+ */
+ public static final class Builder {
+ private Optional<String> datacenter = Optional.absent();
+ private Optional<String> tag = Optional.absent();
+
+ private Builder() {
+ }
+
+ /**
+ * Fill a builder with attribute values from the provided {@code CatalogOptions} instance.
+ * Regular attribute values will be replaced with those from the given instance.
+ * Absent optional values will not replace present values.
+ * @param instance The instance from which to copy values
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder from(CatalogOptions instance) {
+ Preconditions.checkNotNull(instance, "instance");
+ Optional<String> datacenterOptional = instance.getDatacenter();
+ if (datacenterOptional.isPresent()) {
+ datacenter(datacenterOptional);
+ }
+ Optional<String> tagOptional = instance.getTag();
+ if (tagOptional.isPresent()) {
+ tag(tagOptional);
+ }
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link CatalogOptions#getDatacenter() datacenter} to datacenter.
+ * @param datacenter The value for datacenter
+ * @return {@code this} builder for chained invocation
+ */
+ public final Builder datacenter(String datacenter) {
+ this.datacenter = Optional.of(datacenter);
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link CatalogOptions#getDatacenter() datacenter} to datacenter.
+ * @param datacenter The value for datacenter
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder datacenter(Optional<String> datacenter) {
+ this.datacenter = Preconditions.checkNotNull(datacenter, "datacenter");
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link CatalogOptions#getTag() tag} to tag.
+ * @param tag The value for tag
+ * @return {@code this} builder for chained invocation
+ */
+ public final Builder tag(String tag) {
+ this.tag = Optional.of(tag);
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link CatalogOptions#getTag() tag} to tag.
+ * @param tag The value for tag
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder tag(Optional<String> tag) {
+ this.tag = Preconditions.checkNotNull(tag, "tag");
+ return this;
+ }
+
+ /**
+ * Builds a new {@link ImmutableCatalogOptions ImmutableCatalogOptions}.
+ * @return An immutable instance of CatalogOptions
+ * @throws java.lang.IllegalStateException if any required attributes are missing
+ */
+ public ImmutableCatalogOptions build() throws IllegalStateException {
+ return new ImmutableCatalogOptions(datacenter, tag);
+ }
+ }
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java new file mode 100644 index 0000000..87a0f8a --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ImmutableQueryOptions.java @@ -0,0 +1,531 @@ +/**
+* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
+*
+* 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
+*
+* http://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 org.openo.msb.wrapper.consul.option;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.primitives.Booleans;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import javax.annotation.Generated;
+
+/**
+ * Immutable implementation of {@link QueryOptions}.
+ * <p>
+ * Use the builder to create immutable instances:
+ * {@code ImmutableQueryOptions.builder()}.
+ */
+@SuppressWarnings("all")
+@Generated({"Immutables.generator", "QueryOptions"})
+public final class ImmutableQueryOptions extends QueryOptions {
+ private final Optional<String> wait;
+ private final Optional<String> token;
+ private final Optional<BigInteger> index;
+ private final Optional<String> near;
+ private final ConsistencyMode consistencyMode;
+ private final boolean isBlocking;
+ private final boolean hasToken;
+
+ private ImmutableQueryOptions(ImmutableQueryOptions.Builder builder) {
+ this.wait = builder.wait;
+ this.token = builder.token;
+ this.index = builder.index;
+ this.near = builder.near;
+ if (builder.consistencyMode != null) {
+ initShim.consistencyMode(builder.consistencyMode);
+ }
+ this.consistencyMode = initShim.getConsistencyMode();
+ this.isBlocking = initShim.isBlocking();
+ this.hasToken = initShim.hasToken();
+ this.initShim = null;
+ }
+
+ private ImmutableQueryOptions(
+ Optional<String> wait,
+ Optional<String> token,
+ Optional<BigInteger> index,
+ Optional<String> near,
+ ConsistencyMode consistencyMode) {
+ this.wait = wait;
+ this.token = token;
+ this.index = index;
+ this.near = near;
+ this.consistencyMode = consistencyMode;
+ initShim.consistencyMode(consistencyMode);
+ this.isBlocking = initShim.isBlocking();
+ this.hasToken = initShim.hasToken();
+ this.initShim = null;
+ }
+
+ private static final int STAGE_INITIALIZING = -1;
+ private static final int STAGE_UNINITIALIZED = 0;
+ private static final int STAGE_INITIALIZED = 1;
+ private volatile InitShim initShim = new InitShim();
+
+ private final class InitShim {
+ private ConsistencyMode consistencyMode;
+ private byte consistencyModeStage;
+
+ ConsistencyMode getConsistencyMode() {
+ if (consistencyModeStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
+ if (consistencyModeStage == STAGE_UNINITIALIZED) {
+ consistencyModeStage = STAGE_INITIALIZING;
+ this.consistencyMode = Preconditions.checkNotNull(ImmutableQueryOptions.super.getConsistencyMode(), "consistencyMode");
+ consistencyModeStage = STAGE_INITIALIZED;
+ }
+ return consistencyMode;
+ }
+
+ ConsistencyMode consistencyMode(ConsistencyMode value) {
+ this.consistencyMode = value;
+ consistencyModeStage = STAGE_INITIALIZED;
+ return value;
+ }
+ private boolean isBlocking;
+ private byte isBlockingStage;
+
+ boolean isBlocking() {
+ if (isBlockingStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
+ if (isBlockingStage == STAGE_UNINITIALIZED) {
+ isBlockingStage = STAGE_INITIALIZING;
+ this.isBlocking = ImmutableQueryOptions.super.isBlocking();
+ isBlockingStage = STAGE_INITIALIZED;
+ }
+ return isBlocking;
+ }
+ private boolean hasToken;
+ private byte hasTokenStage;
+
+ boolean hasToken() {
+ if (hasTokenStage == STAGE_INITIALIZING) throw new IllegalStateException(formatInitCycleMessage());
+ if (hasTokenStage == STAGE_UNINITIALIZED) {
+ hasTokenStage = STAGE_INITIALIZING;
+ this.hasToken = ImmutableQueryOptions.super.hasToken();
+ hasTokenStage = STAGE_INITIALIZED;
+ }
+ return hasToken;
+ }
+
+ private String formatInitCycleMessage() {
+ ArrayList<String> attributes = Lists.newArrayList();
+ if (consistencyModeStage == STAGE_INITIALIZING) attributes.add("consistencyMode");
+ if (isBlockingStage == STAGE_INITIALIZING) attributes.add("isBlocking");
+ if (hasTokenStage == STAGE_INITIALIZING) attributes.add("hasToken");
+ return "Cannot build QueryOptions, attribute initializers form cycle" + attributes;
+ }
+ }
+
+ /**
+ * @return The value of the {@code wait} attribute
+ */
+ @Override
+ public Optional<String> getWait() {
+ return wait;
+ }
+
+ /**
+ * @return The value of the {@code token} attribute
+ */
+ @Override
+ public Optional<String> getToken() {
+ return token;
+ }
+
+ /**
+ * @return The value of the {@code index} attribute
+ */
+ @Override
+ public Optional<BigInteger> getIndex() {
+ return index;
+ }
+
+ /**
+ * @return The value of the {@code near} attribute
+ */
+ @Override
+ public Optional<String> getNear() {
+ return near;
+ }
+
+ /**
+ * @return The value of the {@code consistencyMode} attribute
+ */
+ @Override
+ public ConsistencyMode getConsistencyMode() {
+ return initShim != null
+ ? initShim.getConsistencyMode()
+ : consistencyMode;
+ }
+
+ /**
+ * @return The computed-at-construction value of the {@code isBlocking} attribute
+ */
+ @Override
+ public boolean isBlocking() {
+ return initShim != null
+ ? initShim.isBlocking()
+ : isBlocking;
+ }
+
+ /**
+ * @return The computed-at-construction value of the {@code hasToken} attribute
+ */
+ @Override
+ public boolean hasToken() {
+ return initShim != null
+ ? initShim.hasToken()
+ : hasToken;
+ }
+
+ /**
+ * Copy the current immutable object by setting a <i>present</i> value for the optional {@link QueryOptions#getWait() wait} attribute.
+ * @param value The value for wait
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withWait(String value) {
+ Optional<String> newValue = Optional.of(value);
+ return validate(new ImmutableQueryOptions(newValue, this.token, this.index, this.near, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getWait() wait} attribute.
+ * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}.
+ * @param optional A value for wait
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withWait(Optional<String> optional) {
+ Optional<String> value = Preconditions.checkNotNull(optional, "wait");
+ if (this.wait == value) return this;
+ return validate(new ImmutableQueryOptions(value, this.token, this.index, this.near, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting a <i>present</i> value for the optional {@link QueryOptions#getToken() token} attribute.
+ * @param value The value for token
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withToken(String value) {
+ Optional<String> newValue = Optional.of(value);
+ return validate(new ImmutableQueryOptions(this.wait, newValue, this.index, this.near, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getToken() token} attribute.
+ * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}.
+ * @param optional A value for token
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withToken(Optional<String> optional) {
+ Optional<String> value = Preconditions.checkNotNull(optional, "token");
+ if (this.token == value) return this;
+ return validate(new ImmutableQueryOptions(this.wait, value, this.index, this.near, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting a <i>present</i> value for the optional {@link QueryOptions#getIndex() index} attribute.
+ * @param value The value for index
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withIndex(BigInteger value) {
+ Optional<BigInteger> newValue = Optional.of(value);
+ return validate(new ImmutableQueryOptions(this.wait, this.token, newValue, this.near, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getIndex() index} attribute.
+ * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}.
+ * @param optional A value for index
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withIndex(Optional<BigInteger> optional) {
+ Optional<BigInteger> value = Preconditions.checkNotNull(optional, "index");
+ if (this.index == value) return this;
+ return validate(new ImmutableQueryOptions(this.wait, this.token, value, this.near, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting a <i>present</i> value for the optional {@link QueryOptions#getNear() near} attribute.
+ * @param value The value for near
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withNear(String value) {
+ Optional<String> newValue = Optional.of(value);
+ return validate(new ImmutableQueryOptions(this.wait, this.token, this.index, newValue, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting an optional value for the {@link QueryOptions#getNear() near} attribute.
+ * A shallow reference equality check on the optional value is used to prevent copying of the same value by returning {@code this}.
+ * @param optional A value for near
+ * @return A modified copy of {@code this} object
+ */
+ public final ImmutableQueryOptions withNear(Optional<String> optional) {
+ Optional<String> value = Preconditions.checkNotNull(optional, "near");
+ if (this.near == value) return this;
+ return validate(new ImmutableQueryOptions(this.wait, this.token, this.index, value, this.consistencyMode));
+ }
+
+ /**
+ * Copy the current immutable object by setting a value for the {@link QueryOptions#getConsistencyMode() consistencyMode} attribute.
+ * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
+ * @param value A new value for consistencyMode
+ * @return A modified copy of the {@code this} object
+ */
+ public final ImmutableQueryOptions withConsistencyMode(ConsistencyMode value) {
+ if (this.consistencyMode == value) return this;
+ return validate(new ImmutableQueryOptions(
+ this.wait,
+ this.token,
+ this.index,
+ this.near,
+ Preconditions.checkNotNull(value, "consistencyMode")));
+ }
+
+ /**
+ * This instance is equal to all instances of {@code ImmutableQueryOptions} that have equal attribute values.
+ * @return {@code true} if {@code this} is equal to {@code another} instance
+ */
+ @Override
+ public boolean equals(Object another) {
+ if (this == another) return true;
+ return another instanceof ImmutableQueryOptions
+ && equalTo((ImmutableQueryOptions) another);
+ }
+
+ private boolean equalTo(ImmutableQueryOptions another) {
+ return wait.equals(another.wait)
+ && token.equals(another.token)
+ && index.equals(another.index)
+ && near.equals(another.near)
+ && consistencyMode.equals(another.consistencyMode)
+ && isBlocking == another.isBlocking
+ && hasToken == another.hasToken;
+ }
+
+ /**
+ * Computes a hash code from attributes: {@code wait}, {@code token}, {@code index}, {@code near}, {@code consistencyMode}, {@code isBlocking}, {@code hasToken}.
+ * @return hashCode value
+ */
+ @Override
+ public int hashCode() {
+ int h = 31;
+ h = h * 17 + wait.hashCode();
+ h = h * 17 + token.hashCode();
+ h = h * 17 + index.hashCode();
+ h = h * 17 + near.hashCode();
+ h = h * 17 + consistencyMode.hashCode();
+ h = h * 17 + Booleans.hashCode(isBlocking);
+ h = h * 17 + Booleans.hashCode(hasToken);
+ return h;
+ }
+
+ /**
+ * Prints the immutable value {@code QueryOptions...} with all non-generated
+ * and non-auxiliary attribute values.
+ * @return A string representation of the value
+ */
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper("QueryOptions")
+ .add("wait", wait)
+ .add("token", token)
+ .add("index", index)
+ .add("near", near)
+ .add("consistencyMode", consistencyMode)
+ .add("isBlocking", isBlocking)
+ .add("hasToken", hasToken)
+ .toString();
+ }
+
+ private static ImmutableQueryOptions validate(ImmutableQueryOptions instance) {
+ instance.validate();
+ return instance;
+ }
+
+ /**
+ * Creates an immutable copy of a {@link QueryOptions} value.
+ * Uses accessors to get values to initialize the new immutable instance.
+ * If an instance is already immutable, it is returned as is.
+ * @param instance The instance to copy
+ * @return A copied immutable QueryOptions instance
+ */
+ public static ImmutableQueryOptions copyOf(QueryOptions instance) {
+ if (instance instanceof ImmutableQueryOptions) {
+ return (ImmutableQueryOptions) instance;
+ }
+ return ImmutableQueryOptions.builder()
+ .from(instance)
+ .build();
+ }
+
+ /**
+ * Creates a builder for {@link ImmutableQueryOptions ImmutableQueryOptions}.
+ * @return A new ImmutableQueryOptions builder
+ */
+ public static ImmutableQueryOptions.Builder builder() {
+ return new ImmutableQueryOptions.Builder();
+ }
+
+ /**
+ * Builds instances of type {@link ImmutableQueryOptions ImmutableQueryOptions}.
+ * Initialize attributes and then invoke the {@link #build()} method to create an
+ * immutable instance.
+ * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
+ * but instead used immediately to create instances.</em>
+ */
+ public static final class Builder {
+ private Optional<String> wait = Optional.absent();
+ private Optional<String> token = Optional.absent();
+ private Optional<BigInteger> index = Optional.absent();
+ private Optional<String> near = Optional.absent();
+ private ConsistencyMode consistencyMode;
+
+ private Builder() {
+ }
+
+ /**
+ * Fill a builder with attribute values from the provided {@code QueryOptions} instance.
+ * Regular attribute values will be replaced with those from the given instance.
+ * Absent optional values will not replace present values.
+ * @param instance The instance from which to copy values
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder from(QueryOptions instance) {
+ Preconditions.checkNotNull(instance, "instance");
+ Optional<String> waitOptional = instance.getWait();
+ if (waitOptional.isPresent()) {
+ wait(waitOptional);
+ }
+ Optional<String> tokenOptional = instance.getToken();
+ if (tokenOptional.isPresent()) {
+ token(tokenOptional);
+ }
+ Optional<BigInteger> indexOptional = instance.getIndex();
+ if (indexOptional.isPresent()) {
+ index(indexOptional);
+ }
+ Optional<String> nearOptional = instance.getNear();
+ if (nearOptional.isPresent()) {
+ near(nearOptional);
+ }
+ consistencyMode(instance.getConsistencyMode());
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getWait() wait} to wait.
+ * @param wait The value for wait
+ * @return {@code this} builder for chained invocation
+ */
+ public final Builder wait(String wait) {
+ this.wait = Optional.of(wait);
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getWait() wait} to wait.
+ * @param wait The value for wait
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder wait(Optional<String> wait) {
+ this.wait = Preconditions.checkNotNull(wait, "wait");
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getToken() token} to token.
+ * @param token The value for token
+ * @return {@code this} builder for chained invocation
+ */
+ public final Builder token(String token) {
+ this.token = Optional.of(token);
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getToken() token} to token.
+ * @param token The value for token
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder token(Optional<String> token) {
+ this.token = Preconditions.checkNotNull(token, "token");
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getIndex() index} to index.
+ * @param index The value for index
+ * @return {@code this} builder for chained invocation
+ */
+ public final Builder index(BigInteger index) {
+ this.index = Optional.of(index);
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getIndex() index} to index.
+ * @param index The value for index
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder index(Optional<BigInteger> index) {
+ this.index = Preconditions.checkNotNull(index, "index");
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getNear() near} to near.
+ * @param near The value for near
+ * @return {@code this} builder for chained invocation
+ */
+ public final Builder near(String near) {
+ this.near = Optional.of(near);
+ return this;
+ }
+
+ /**
+ * Initializes the optional value {@link QueryOptions#getNear() near} to near.
+ * @param near The value for near
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder near(Optional<String> near) {
+ this.near = Preconditions.checkNotNull(near, "near");
+ return this;
+ }
+
+ /**
+ * Initializes the value for the {@link QueryOptions#getConsistencyMode() consistencyMode} attribute.
+ * <p><em>If not set, this attribute will have a default value as returned by the initializer of {@link QueryOptions#getConsistencyMode() consistencyMode}.</em>
+ * @param consistencyMode The value for consistencyMode
+ * @return {@code this} builder for use in a chained invocation
+ */
+ public final Builder consistencyMode(ConsistencyMode consistencyMode) {
+ this.consistencyMode = Preconditions.checkNotNull(consistencyMode, "consistencyMode");
+ return this;
+ }
+
+ /**
+ * Builds a new {@link ImmutableQueryOptions ImmutableQueryOptions}.
+ * @return An immutable instance of QueryOptions
+ * @throws java.lang.IllegalStateException if any required attributes are missing
+ */
+ public ImmutableQueryOptions build() throws IllegalStateException {
+ return ImmutableQueryOptions.validate(new ImmutableQueryOptions(this));
+ }
+ }
+}
diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java new file mode 100644 index 0000000..bccdd5c --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/Options.java @@ -0,0 +1,29 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.option; + +import com.google.common.base.Optional; + +import javax.ws.rs.client.WebTarget; + +public class Options { + private Options(){}; + + static <T> WebTarget optionallyAdd(WebTarget input, String key, Optional<T> val) { + return val.isPresent() ? input.queryParam(key, val.get()) : input; + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java new file mode 100644 index 0000000..56f97f6 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/ParamAdder.java @@ -0,0 +1,23 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.option; + +import com.google.common.base.Function; + +import javax.ws.rs.client.WebTarget; + +public interface ParamAdder extends Function<WebTarget, WebTarget> {} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java new file mode 100644 index 0000000..63d201e --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/option/QueryOptions.java @@ -0,0 +1,100 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.option; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.openo.msb.wrapper.consul.option.Options.optionallyAdd; + +import java.math.BigInteger; + +import javax.ws.rs.client.WebTarget; + +import com.google.common.base.Optional; + +/** + * Container for common query options used by the Consul API. + */ + +public abstract class QueryOptions implements ParamAdder { + + public static final QueryOptions BLANK = ImmutableQueryOptions.builder().build(); + + public abstract Optional<String> getWait(); + public abstract Optional<String> getToken(); + public abstract Optional<BigInteger> getIndex(); + public abstract Optional<String> getNear(); + + + public ConsistencyMode getConsistencyMode() { + return ConsistencyMode.DEFAULT; + } + + + public boolean isBlocking() { + return getWait().isPresent(); + } + + + public boolean hasToken() { + return getToken().isPresent(); + } + + + void validate() { + if (isBlocking()) { + checkArgument(getIndex().isPresent(), "If wait is specified, index must also be specified"); + } + } + + public static ImmutableQueryOptions.Builder blockSeconds(int seconds, BigInteger index) { + return blockBuilder("s", seconds, index); + } + + public static ImmutableQueryOptions.Builder blockMinutes(int minutes, BigInteger index) { + return blockBuilder("m", minutes, index); + } + + private static ImmutableQueryOptions.Builder blockBuilder(String identifier, int qty, BigInteger index) { + return ImmutableQueryOptions.builder() + .wait(String.format("%s%s", qty, identifier)) + .index(index); + } + + @Override + public WebTarget apply(WebTarget input) { + + WebTarget added = input; + switch (getConsistencyMode()) { + case CONSISTENT: + added = added.queryParam("consistent", ""); + break; + case STALE: + added = added.queryParam("stale", ""); + break; + } + + if (isBlocking()) { + added = added.queryParam("wait", getWait().get()) + .queryParam("index", String.valueOf(getIndex().get())); + } + + added = optionallyAdd(added, "token", getToken()); + added = optionallyAdd(added, "near", getToken()); + + return added; + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java new file mode 100644 index 0000000..58af732 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Base64EncodingDeserializer.java @@ -0,0 +1,45 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.google.common.base.Optional; +import com.google.common.io.BaseEncoding; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; + +/** + * For use with JSON fields that Consul Base 64 encodes. + */ +public class Base64EncodingDeserializer extends JsonDeserializer<Optional<String>> { + + /** + * {@inheritDoc} + */ + @Override + public Optional<String> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String value = p.getValueAsString(); + + if (StringUtils.isNotEmpty(value)) { + return Optional.of(new String(BaseEncoding.base64().decode(value))); + } + return Optional.absent(); + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java new file mode 100644 index 0000000..ab184c1 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ClientUtil.java @@ -0,0 +1,246 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.util; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import javax.ws.rs.ServerErrorException; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openo.msb.wrapper.consul.ConsulException; +import org.openo.msb.wrapper.consul.async.ConsulResponseCallback; +import org.openo.msb.wrapper.consul.model.ConsulResponse; +import org.openo.msb.wrapper.consul.option.CatalogOptions; +import org.openo.msb.wrapper.consul.option.ParamAdder; +import org.openo.msb.wrapper.consul.option.QueryOptions; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +/** + * A collection of stateless utility methods for use in constructing + * requests and responses to the Consul HTTP API. + */ +public class ClientUtil { + + /** + * Applies all key/values from the params map to query string parameters. + * + * @param webTarget The JAX-RS target to apply the query parameters. + * @param params Map of parameters. + * @return The new target with the parameters applied. + */ + public static WebTarget queryParams(WebTarget webTarget, Map<String, String> params) { + WebTarget target = webTarget; + + if(params != null) { + for(Map.Entry<String, String> entry : params.entrySet()) { + target = target.queryParam(entry.getKey(), entry.getValue()); + } + } + + return target; + } + + /** + * Given a {@link org.openo.msb.wrapper.consul.option.ParamAdder} object, adds the + * appropriate query string parameters to the request being built. + * + * @param webTarget The base {@link javax.ws.rs.client.WebTarget}. + * @param paramAdder will add specific params to the target. + * @return A {@link javax.ws.rs.client.WebTarget} with all appropriate query + * string parameters. + */ + public static WebTarget addParams(WebTarget webTarget, ParamAdder paramAdder) { + return paramAdder == null ? webTarget : paramAdder.apply(webTarget); + } + + /** + * Generates a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} for a specific datacenter, + * set of {@link org.openo.msb.wrapper.consul.option.QueryOptions}, and a result type. + * + * @param target The base {@link javax.ws.rs.client.WebTarget}. + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param type The generic type to marshall the resulting data to. + * @param <T> The result type. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse}. + */ + public static <T> ConsulResponse<T> response(WebTarget target, CatalogOptions catalogOptions, + QueryOptions queryOptions, + GenericType<T> type) { + target = addParams(target, catalogOptions); + target = addParams(target, queryOptions); + + return response(target, type); + } + + /** + * Generates a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} for a specific datacenter, + * set of {@link org.openo.msb.wrapper.consul.option.QueryOptions}, and a result type. + * + * @param target The base {@link javax.ws.rs.client.WebTarget}. + * @param catalogOptions Catalog specific options to use. + * @param queryOptions The Query Options to use. + * @param type The generic type to marshall the resulting data to. + * @param <T> The result type. + */ + public static <T> void response(WebTarget target, CatalogOptions catalogOptions, + QueryOptions queryOptions, + GenericType<T> type, + ConsulResponseCallback<T> callback) { + + target = addParams(target, catalogOptions); + target = addParams(target, queryOptions); + + response(target, type, callback); + } + + /** + * Given a {@link javax.ws.rs.client.WebTarget} object and a type to marshall + * the result JSON into, complete the HTTP GET request. + * + * @param webTarget The JAX-RS target. + * @param responseType The class to marshall the JSON into. + * @param <T> The class to marshall the JSON into. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} containing the result. + */ + public static <T> ConsulResponse<T> response(WebTarget webTarget, GenericType<T> responseType) { + Response response = webTarget.request().accept(MediaType.APPLICATION_JSON_TYPE).get(); + + return consulResponse(responseType, response); + } + + /** + * Given a {@link javax.ws.rs.client.WebTarget} object and a type to marshall + * the result JSON into, complete the HTTP GET request. + * + * @param webTarget The JAX-RS target. + * @param responseType The class to marshall the JSON into. + * @param callback The callback object to handle the result on a different thread. + * @param <T> The class to marshall the JSON into. + */ + public static <T> void response(WebTarget webTarget, final GenericType<T> responseType, + final ConsulResponseCallback<T> callback) { + webTarget.request().accept(MediaType.APPLICATION_JSON_TYPE).async().get(new InvocationCallback<Response>() { + + @Override + public void completed(Response response) { + try { + callback.onComplete(consulResponse(responseType, response)); + } catch (Exception ex) { + callback.onFailure(ex); + } + } + + @Override + public void failed(Throwable throwable) { + callback.onFailure(throwable); + } + }); + } + + /** + * Extracts Consul specific headers and adds them to a {@link org.openo.msb.wrapper.consul.model.ConsulResponse} + * object, which also contains the returned JSON entity. + * + * @param responseType The class to marshall the JSON to. + * @param response The HTTP response. + * @param <T> The class to marshall the JSON to. + * @return A {@link org.openo.msb.wrapper.consul.model.ConsulResponse} object. + */ + private static <T> ConsulResponse<T> consulResponse(GenericType<T> responseType, Response response) { + handleErrors(response); + + String indexHeaderValue = response.getHeaderString("X-Consul-Index"); + String lastContactHeaderValue = response.getHeaderString("X-Consul-Lastcontact"); + String knownLeaderHeaderValue = response.getHeaderString("X-Consul-Knownleader"); + + BigInteger index = new BigInteger(indexHeaderValue); + long lastContact = lastContactHeaderValue == null ? -1 : Long.valueOf(lastContactHeaderValue); + boolean knownLeader = knownLeaderHeaderValue == null ? false : Boolean.valueOf(knownLeaderHeaderValue); + + ConsulResponse<T> consulResponse = new ConsulResponse<T>(readResponse(response, responseType), lastContact, knownLeader, index); + + response.close(); + + return consulResponse; + } + + /** + * Converts a {@link Response} object to the generic type provided, or an empty + * representation if appropriate + * + * @param response response + * @param responseType response type + * @param <T> + * @return the re + */ + private static <T> T readResponse(Response response, GenericType<T> responseType) { + if (response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { + // would be nice I knew a better way to do this + if (responseType.getRawType() == List.class) { + return (T) ImmutableList.of(); + } else if (responseType.getRawType() == Optional.class) { + return (T) Optional.absent(); + } else if(responseType.getRawType() == Map.class) { + return (T) ImmutableMap.of(); + } else { + // Not sure if this case will be reached, but if it is it'll be nice to know + throw new IllegalStateException("Cannot determine empty representation for " + responseType.getRawType()); + } + } + return response.readEntity(responseType); + } + + /** + * Since Consul returns plain text when an error occurs, check for + * unsuccessful HTTP status code, and throw an exception with the text + * from Consul as the message. + * + * @param response The HTTP response. + */ + public static void handleErrors(Response response) { + + if (response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL + || response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { + // not an error + return; + } + + try { + final String message = response.hasEntity() ? response.readEntity(String.class) : null; + if (response.getStatusInfo().getFamily() == Response.Status.Family.SERVER_ERROR) { + throw new ServerErrorException(message, response); + } else { + throw new WebApplicationException(message, response); + } + } catch (Exception e) { + throw new ConsulException(e.getLocalizedMessage(), e); + } finally { + response.close(); + } + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java new file mode 100644 index 0000000..64feeac --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/Jackson.java @@ -0,0 +1,34 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.guava.GuavaModule; + +public class Jackson { + + public static final ObjectMapper MAPPER = newObjectMapper(); + + private static ObjectMapper newObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new GuavaModule()); + return mapper; + } + + private Jackson() {} + +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java new file mode 100644 index 0000000..c438967 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/ObjectMapperContextResolver.java @@ -0,0 +1,35 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.util; + +import javax.ws.rs.ext.ContextResolver; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> { + + private final ObjectMapper objectMapper; + public ObjectMapperContextResolver(final ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @Override + public ObjectMapper getContext(final Class<?> type) { + return objectMapper; + } + +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java new file mode 100644 index 0000000..17438f9 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsDeserializer.java @@ -0,0 +1,43 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; + +/** + * Deserializes Consul time values with "s" suffix to {@link Long} objects. + */ +public class SecondsDeserializer extends JsonDeserializer<Long> { + + @Override + public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + String value = p.getValueAsString(); + + if (StringUtils.isNotEmpty(value)) { + value = value.replaceAll("[a-zA-Z]", ""); + return Long.valueOf(value); + } else { + return null; + } + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java new file mode 100644 index 0000000..1420e18 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/SecondsSerializer.java @@ -0,0 +1,34 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * Serializes a time field (e.g. TTL) as seconds. + */ +public class SecondsSerializer extends JsonSerializer<Long> { + + @Override + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(String.format("%ss", value)); + } +} diff --git a/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java new file mode 100644 index 0000000..802c048 --- /dev/null +++ b/msb-core/apiroute/apiroute-service/src/main/java/org/openo/msb/wrapper/consul/util/UnsignedLongDeserializer.java @@ -0,0 +1,37 @@ +/** +* Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE) +* +* 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 +* +* http://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 org.openo.msb.wrapper.consul.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.google.common.primitives.UnsignedLongs; + +import java.io.IOException; + +/** + * @author sgardner + * @since 2015.02.28 + */ +public class UnsignedLongDeserializer extends JsonDeserializer<Long> { + @Override + public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + String sValue = jp.getValueAsString(); + return UnsignedLongs.decode(sValue); + } +} |