1 /*******************************************************************************
2 * Copyright 2016-2017 ZTE, Inc. and others.
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
13 ******************************************************************************/
14 package org.onap.msb.apiroute.resources;
16 import java.io.IOException;
18 import javax.servlet.http.HttpServletRequest;
19 import javax.ws.rs.DELETE;
20 import javax.ws.rs.DefaultValue;
21 import javax.ws.rs.GET;
22 import javax.ws.rs.POST;
23 import javax.ws.rs.PUT;
24 import javax.ws.rs.Path;
25 import javax.ws.rs.PathParam;
26 import javax.ws.rs.Produces;
27 import javax.ws.rs.QueryParam;
28 import javax.ws.rs.core.Context;
29 import javax.ws.rs.core.MediaType;
30 import javax.ws.rs.core.Response;
31 import javax.ws.rs.core.UriInfo;
33 import org.apache.http.HttpStatus;
34 import org.apache.http.client.methods.CloseableHttpResponse;
35 import org.apache.http.client.methods.HttpDelete;
36 import org.apache.http.client.methods.HttpGet;
37 import org.apache.http.client.methods.HttpPost;
38 import org.apache.http.client.methods.HttpPut;
39 import org.apache.http.impl.client.CloseableHttpClient;
40 import org.apache.http.impl.client.HttpClients;
41 import org.apache.http.util.EntityUtils;
42 import org.onap.msb.apiroute.api.DiscoverInfo;
43 import org.onap.msb.apiroute.api.MicroServiceFullInfo;
44 import org.onap.msb.apiroute.api.exception.ExtendedInternalServerErrorException;
45 import org.onap.msb.apiroute.health.ConsulLinkHealthCheck;
46 import org.onap.msb.apiroute.health.RedisHealthCheck;
47 import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
48 import org.onap.msb.apiroute.wrapper.util.HttpClientUtil;
49 import org.onap.msb.apiroute.wrapper.util.RouteUtil;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
53 import com.codahale.metrics.annotation.Timed;
54 import com.codahale.metrics.health.HealthCheck.Result;
56 import io.swagger.annotations.ApiOperation;
57 import io.swagger.annotations.ApiParam;
58 import io.swagger.annotations.ApiResponse;
59 import io.swagger.annotations.ApiResponses;
62 // @Api(tags = {"MSB-Service Resource"})
63 @Produces(MediaType.APPLICATION_JSON)
64 public class MicroServiceResource {
65 private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class);
68 UriInfo uriInfo; // actual uri info
72 @ApiOperation(value = "get all microservices ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class,
73 responseContainer = "List")
74 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR,
75 message = "get microservice List fail", response = String.class)})
76 @Produces(MediaType.APPLICATION_JSON)
78 public Response getMicroService() {
79 String resourceUrl = "/";
80 return routeHttpGet2DiscoveryService(resourceUrl);
85 @ApiOperation(value = "add one microservice ", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class)
86 @ApiResponses(value = {
87 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
88 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
89 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "add microservice fail",
90 response = String.class),
91 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST,
92 message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)})
93 @Produces(MediaType.APPLICATION_JSON)
95 public Response addMicroService(
96 @ApiParam(value = "MicroServiceInfo Instance Info",
97 required = true) MicroServiceFullInfo microServiceInfo,
98 @Context HttpServletRequest request,
99 @ApiParam(value = "createOrUpdate",
100 required = false) @QueryParam("createOrUpdate") @DefaultValue("true") boolean createOrUpdate,
101 @ApiParam(value = "port", required = false) @QueryParam("port") @DefaultValue("") String port)
103 return routeRegistration2DiscoveryService(microServiceInfo);
107 @Path("/{serviceName}/version/{version}")
108 @ApiOperation(value = "get one microservice ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class)
109 @ApiResponses(value = {
110 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
111 response = String.class),
112 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
113 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
114 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice fail",
115 response = String.class)})
116 @Produces(MediaType.APPLICATION_JSON)
118 public Response getMicroService(
119 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
120 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version) {
121 String resourceUrl = new StringBuilder("/").append(serviceName).append("/version/").append(version).toString();
122 return routeHttpGet2DiscoveryService(resourceUrl);
126 @Path("/{serviceName}/version/{version}")
127 @ApiOperation(value = "update one microservice by serviceName and version", code = HttpStatus.SC_CREATED,
128 response = MicroServiceFullInfo.class)
129 @ApiResponses(value = {
130 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
131 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
132 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update microservice fail",
133 response = String.class),
134 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST,
135 message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)})
136 @Produces(MediaType.APPLICATION_JSON)
138 public Response updateMicroService(
139 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
140 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
141 @ApiParam(value = "microservice Instance Info",
142 required = true) MicroServiceFullInfo microServiceInfo,
143 @Context HttpServletRequest request) {
145 String resourceUrl = new StringBuilder("/").append(serviceName).append("/version/").append(version).toString();
146 return routeHttpPut2DiscoveryService(resourceUrl, microServiceInfo);
150 @Path("/{serviceName}/version/{version}/nodes/{ip}/{port}")
151 @ApiOperation(value = "delete single node by serviceName and version and node", code = HttpStatus.SC_NO_CONTENT)
152 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete node succeed "),
153 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "node not found", response = String.class),
154 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
155 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
156 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete node fail",
157 response = String.class)})
158 @Produces(MediaType.APPLICATION_JSON)
160 public Response deleteNode(
161 @ApiParam(value = "microservice serviceName",
162 required = true) @PathParam("serviceName") String serviceName,
163 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
164 required = false) @PathParam("version") @DefaultValue("") String version,
165 @ApiParam(value = "ip") @PathParam("ip") String ip,
166 @ApiParam(value = "port") @PathParam("port") String port) {
168 String resourceUrl = new StringBuilder("/").append(serviceName).append("/version/").append(version)
169 .append("/nodes/").append(ip).append("/").append(port).toString();
170 return routeHttpDelete2DiscoveryService(resourceUrl);
174 @Path("/{serviceName}/version/{version}")
175 @ApiOperation(value = "delete one full microservice by serviceName and version", code = HttpStatus.SC_NO_CONTENT)
176 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete microservice succeed "),
177 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
178 response = String.class),
179 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
180 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
181 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete microservice fail",
182 response = String.class)})
183 @Produces(MediaType.APPLICATION_JSON)
185 public Response deleteMicroService(
186 @ApiParam(value = "microservice serviceName",
187 required = true) @PathParam("serviceName") String serviceName,
188 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
189 required = false) @PathParam("version") @DefaultValue("") String version) {
190 String resourceUrl = new StringBuilder("/").append(serviceName).append("/version/").append(version).toString();
191 return routeHttpDelete2DiscoveryService(resourceUrl);
195 @Path("/{serviceName}/version/{version}/status/{status}")
196 @ApiOperation(value = "update microservice status by serviceName and version", code = HttpStatus.SC_CREATED,
197 response = MicroServiceFullInfo.class)
198 @ApiResponses(value = {
199 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
200 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
201 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
202 response = String.class),
203 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update status fail",
204 response = String.class)})
205 @Produces(MediaType.APPLICATION_JSON)
207 public Response updateServiceStatus(
208 @ApiParam(value = "microservice serviceName",
209 required = true) @PathParam("serviceName") String serviceName,
210 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
211 required = false) @PathParam("version") @DefaultValue("") String version,
212 @ApiParam(value = "status,1:abled 0:disabled") @PathParam("status") String status) {
213 String resourceUrl = new StringBuilder("/").append(serviceName).append("/version/").append(version)
214 .append("/status/").append(status).toString();
215 return this.routeHttpPut2DiscoveryService(resourceUrl);
219 * @param discoveryUrl
222 private Response routeHttpDelete2DiscoveryService(String resourceUrl) {
223 String discoveryServiceUrl = getDiscoveryServiceUrl();
224 String fullUrl = new StringBuilder(discoveryServiceUrl).append(resourceUrl).toString();
225 CloseableHttpClient httpClient = null;
226 CloseableHttpResponse httpResponse = null;
228 httpClient = HttpClients.createDefault();
229 HttpDelete httpDelete = new HttpDelete(fullUrl);
230 httpResponse = httpClient.execute(httpDelete);
231 return cloneHttpResponse(httpResponse);
232 } catch (Exception e) {
233 throw new ExtendedInternalServerErrorException(e.getMessage());
235 HttpClientUtil.closeHttpClient(httpClient, httpResponse);
240 * @param discoveryUrl
243 private Response routeHttpPut2DiscoveryService(String resourceUrl, Object bean) {
244 String discoveryServiceUrl = getDiscoveryServiceUrl();
245 String fullUrl = new StringBuilder(discoveryServiceUrl).append(resourceUrl).toString();
246 CloseableHttpClient httpClient = null;
247 CloseableHttpResponse httpResponse = null;
249 HttpPut httpPut = HttpClientUtil.createHttpPut(fullUrl, bean);
250 httpClient = HttpClients.createDefault();
251 httpResponse = httpClient.execute(httpPut);
252 return cloneHttpResponse(httpResponse);
253 } catch (Exception e) {
254 throw new ExtendedInternalServerErrorException(e.getMessage());
256 HttpClientUtil.closeHttpClient(httpClient, httpResponse);
261 * @param discoveryUrl
264 private Response routeHttpPut2DiscoveryService(String resourceUrl) {
265 String discoveryServiceUrl = getDiscoveryServiceUrl();
266 String fullUrl = new StringBuilder(discoveryServiceUrl).append(resourceUrl).toString();
267 CloseableHttpClient httpClient = null;
268 CloseableHttpResponse httpResponse = null;
270 HttpPut httpPut = HttpClientUtil.createHttpPut(fullUrl);
271 httpClient = HttpClients.createDefault();
272 httpResponse = httpClient.execute(httpPut);
273 return cloneHttpResponse(httpResponse);
274 } catch (Exception e) {
275 throw new ExtendedInternalServerErrorException(e.getMessage());
277 HttpClientUtil.closeHttpClient(httpClient, httpResponse);
282 * @param discoveryUrl
285 private Response routeHttpGet2DiscoveryService(String resourceUrl) {
286 String discoveryServiceUrl = getDiscoveryServiceUrl();
287 String fullUrl = new StringBuilder(discoveryServiceUrl).append(resourceUrl).toString();
288 CloseableHttpClient httpClient = null;
289 CloseableHttpResponse httpResponse = null;
291 HttpGet httpGet = HttpClientUtil.createHttpGet(fullUrl);
292 httpClient = HttpClients.createDefault();
293 httpResponse = httpClient.execute(httpGet);
294 return cloneHttpResponse(httpResponse);
295 } catch (Exception e) {
296 throw new ExtendedInternalServerErrorException(e.getMessage());
298 HttpClientUtil.closeHttpClient(httpClient, httpResponse);
303 * @param microServiceFullInfo
304 * @param registrationUrl
307 private Response routeRegistration2DiscoveryService(MicroServiceFullInfo microServiceFullInfo) {
308 String registrationUrl = getDiscoveryServiceUrl();
309 CloseableHttpClient httpClient = null;
310 CloseableHttpResponse httpResponse = null;
312 HttpPost httpPost = HttpClientUtil.createHttpPost(registrationUrl, microServiceFullInfo);
313 httpClient = HttpClients.createDefault();
314 httpResponse = httpClient.execute(httpPost);
315 return cloneHttpResponse(httpResponse);
316 } catch (Exception e) {
317 throw new ExtendedInternalServerErrorException(e.getMessage());
319 HttpClientUtil.closeHttpClient(httpClient, httpResponse);
324 * @param httpResponse
326 * @throws IOException
328 private Response cloneHttpResponse(CloseableHttpResponse httpResponse) throws IOException {
329 String jsonString = EntityUtils.toString(httpResponse.getEntity());
330 Response response = Response.status(httpResponse.getStatusLine().getStatusCode()).entity(jsonString).build();
337 private String getDiscoveryServiceUrl() {
338 DiscoverInfo discoverInfo = ConfigUtil.getInstance().getDiscoverInfo();
339 String registrationUrl = new StringBuilder().append("http://").append(discoverInfo)
340 .append(RouteUtil.MSB_ROUTE_URL).toString();
341 return registrationUrl;
344 // Discovery service doesn't provide this API, so requests to this URL are not routed to
348 @ApiOperation(value = "apigateway healthy check ", code = HttpStatus.SC_OK, response = String.class)
349 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "check fail",
350 response = String.class)})
351 @Produces(MediaType.TEXT_PLAIN)
353 public Response health() {
356 Result rst = RedisHealthCheck.getResult();
357 if (!rst.isHealthy()) {
358 LOGGER.warn("health check failed:" + rst.getMessage());
359 throw new ExtendedInternalServerErrorException(rst.getMessage());
363 rst = ConsulLinkHealthCheck.getResult();
364 if (!rst.isHealthy()) {
365 LOGGER.warn("health check failed:" + rst.getMessage());
366 throw new ExtendedInternalServerErrorException(rst.getMessage());
369 return Response.ok("apigateway healthy check:ok").build();