Issue-id: OCS-9
[msb/apigateway.git] / msb-core / apiroute / apiroute-service / src / main / java / org / openo / msb / wrapper / consul / Consul.java
1 /**
2  * Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /**
17 * Copyright (C) 2016 ZTE, Inc. and others. All rights reserved. (ZTE)
18 *
19 * Licensed under the Apache License, Version 2.0 (the "License");
20 * you may not use this file except in compliance with the License.
21 * You may obtain a copy of the License at
22 *
23 * http://www.apache.org/licenses/LICENSE-2.0
24 *
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an "AS IS" BASIS,
27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
30 */
31
32 package org.openo.msb.wrapper.consul;
33
34 import java.net.MalformedURLException;
35 import java.net.URL;
36
37 import javax.net.ssl.SSLContext;
38 import javax.ws.rs.client.Client;
39 import javax.ws.rs.client.ClientBuilder;
40
41 import org.openo.msb.wrapper.consul.util.Jackson;
42 import org.openo.msb.wrapper.consul.util.ObjectMapperContextResolver;
43
44 import com.fasterxml.jackson.databind.ObjectMapper;
45 import com.fasterxml.jackson.datatype.guava.GuavaModule;
46 import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
47 import com.google.common.base.Optional;
48 import com.google.common.base.Predicate;
49 import com.google.common.collect.FluentIterable;
50 import com.google.common.net.HostAndPort;
51
52 /**
53  * Client for interacting with the Consul HTTP API.
54  *
55  * @author rfast
56  */
57 public class Consul {
58
59     /**
60      * Default Consul HTTP API host.
61      */
62     public static final String DEFAULT_HTTP_HOST = "localhost";
63
64     /**
65      * Default Consul HTTP API port.
66      */
67     public static final int DEFAULT_HTTP_PORT = 8500;
68
69
70
71
72     private final CatalogClient catalogClient;
73     
74     private final HealthClient healthClient;
75
76
77     /**
78      * Private constructor.
79      *
80      * @param url     The full URL of a running Consul instance.
81      * @param builder JAX-RS client builder instance.
82      */
83     private Consul(String url, ClientBuilder builder, ObjectMapper mapper) {
84
85         if (!FluentIterable.from(builder.getConfiguration().getClasses())
86                       .filter(new Predicate<Class<?>>() {
87                         @Override
88                         public boolean apply(final Class<?> clazz) {
89                             return JacksonJaxbJsonProvider.class.isAssignableFrom(clazz);
90                         }
91                     }).first().isPresent()) {
92             builder.register(JacksonJaxbJsonProvider.class);
93         }
94         final Client client = builder
95                 .register(new ObjectMapperContextResolver(mapper))
96                 .build();
97
98      
99         if(url.endsWith("8500")){
100             this.catalogClient = new CatalogClient(client.target(url).path("v1").path("catalog"));
101             this.healthClient = new HealthClient(client.target(url).path("v1").path("health"));
102             }
103             else{
104                 this.catalogClient = new CatalogClient(client.target(url).path("api").path("catalog").path("v1"));
105                 this.healthClient = new HealthClient(client.target(url).path("api").path("health").path("v1"));   
106             }
107        
108
109 //        agentClient.ping();
110     }
111
112     /**
113      * Creates a new client given a complete URL.
114      *
115      * @deprecated Use {@link Consul.Builder}
116      *
117      * @param url     The Consul API URL.
118      * @param builder The JAX-RS client builder instance.
119      * @return A new client.
120      */
121     @Deprecated
122     public static Consul newClient(String url, ClientBuilder builder, ObjectMapper mapper) {
123         return new Consul(url, builder, mapper);
124     }
125
126     /**
127      * Creates a new client given a host and a port.
128      *
129      * @deprecated Use {@link Consul.Builder}
130      *
131      * @param host    The Consul API hostname or IP.
132      * @param port    The Consul port.
133      * @param builder The JAX-RS client builder instance.
134      * @return A new client.
135      */
136     @Deprecated
137     public static Consul newClient(String host, int port, ClientBuilder builder, ObjectMapper mapper) {
138         try {
139             return new Consul(new URL("http", host, port, "").toString(), builder, mapper);
140         } catch (MalformedURLException e) {
141             throw new ConsulException("Bad Consul URL", e);
142         }
143     }
144
145     /**
146      * Creates a new client given a host and a port.
147      *
148      * @deprecated Use {@link Consul.Builder}
149      *
150      * @param host The Consul API hostname or IP.
151      * @param port The Consul port.
152      * @return A new client.
153      */
154     @Deprecated
155     public static Consul newClient(String host, int port) {
156         return newClient(host, port, ClientBuilder.newBuilder(), Jackson.MAPPER);
157     }
158
159     /**
160      * Creates a new client given a host and a port.
161      *
162      * @deprecated Use {@link Consul.Builder}
163      *
164      * @return A new client.
165      */
166     @Deprecated
167     public static Consul newClient() {
168         return newClient(DEFAULT_HTTP_HOST, DEFAULT_HTTP_PORT);
169     }
170
171    
172     /**
173      * Get the Catalog HTTP client.
174      * <p>
175      * /v1/catalog
176      *
177      * @return The Catalog HTTP client.
178      */
179     public CatalogClient catalogClient() {
180         return catalogClient;
181     }
182     
183     public HealthClient healthClient() {
184         return healthClient;
185     }
186     /**
187      * Creates a new {@link Builder} object.
188      *
189      * @return A new Consul builder.
190      */
191     public static Builder builder() {
192         return new Builder();
193     }
194
195     /**
196      * Builder for {@link Consul} client objects.
197      */
198     public static class Builder {
199         private URL url;
200         private Optional<SSLContext> sslContext = Optional.absent();
201         private ObjectMapper objectMapper = Jackson.MAPPER;
202         private ClientBuilder clientBuilder = ClientBuilder.newBuilder();
203
204         {
205             try {
206                 url = new URL("http", "localhost", 8500, "");
207             } catch (MalformedURLException e) {
208                 throw new RuntimeException(e);
209             }
210         }
211
212         /**
213          * Constructs a new builder.
214          */
215         Builder() {
216
217         }
218
219         /**
220          * Sets the URL from a {@link URL} object.
221          *
222          * @param url The Consul agent URL.
223          * @return The builder.
224          */
225         public Builder withUrl(URL url) {
226             this.url = url;
227
228             return this;
229         }
230
231         /**
232          * Sets the URL from a {@link HostAndPort} object.
233          *
234          * @param hostAndPort The Consul agent host and port.
235          * @return The builder.
236          */
237         public Builder withHostAndPort(HostAndPort hostAndPort) {
238             try {
239                 this.url = new URL("http", hostAndPort.getHostText(), hostAndPort.getPort(), "");
240             } catch (MalformedURLException e) {
241                 throw new RuntimeException(e);
242             }
243
244             return this;
245         }
246
247         /**
248          * Sets the URL from a string.
249          *
250          * @param url The Consul agent URL.
251          * @return The builder.
252          */
253         public Builder withUrl(String url) {
254             try {
255                 this.url = new URL(url);
256             } catch (MalformedURLException e) {
257                 throw new RuntimeException(e);
258             }
259
260             return this;
261         }
262
263         /**
264          * Sets the {@link SSLContext} for the client.
265          *
266          * @param sslContext The SSL context for HTTPS agents.
267          * @return The builder.
268          */
269         public Builder withSslContext(SSLContext sslContext) {
270             this.sslContext = Optional.of(sslContext);
271
272             return this;
273         }
274
275         /**
276          * Sets the {@link ObjectMapper} for the client.
277          *
278          * @param objectMapper The {@link ObjectMapper} to use.
279          * @return The builder.
280          */
281         public Builder withObjectMapper(ObjectMapper objectMapper) {
282             this.objectMapper = objectMapper;
283
284             objectMapper.registerModule(new GuavaModule());
285
286             return this;
287         }
288
289         /**
290          * Sets the JAX-RS {@link ClientBuilder} to use.
291          *
292          * @param clientBuilder The JAX-RS builder.
293          * @return This builder.
294          */
295         public Builder withClientBuilder(ClientBuilder clientBuilder) {
296             this.clientBuilder = clientBuilder;
297
298             return this;
299         }
300
301         /**
302          * Constructs a new {@link Consul} client.
303          *
304          * @return A new Consul client.
305          */
306         public Consul build() {
307             if (this.sslContext.isPresent()) {
308                 this.clientBuilder.sslContext(this.sslContext.get());
309             }
310
311             return new Consul(this.url.toExternalForm(), this.clientBuilder, this.objectMapper);
312         }
313     }
314 }