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.util.List;
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.HttpGet;
36 import org.apache.http.client.methods.HttpPost;
37 import org.apache.http.impl.client.CloseableHttpClient;
38 import org.apache.http.impl.client.HttpClients;
39 import org.apache.http.util.EntityUtils;
40 import org.onap.msb.apiroute.api.DiscoverInfo;
41 import org.onap.msb.apiroute.api.MicroServiceFullInfo;
42 import org.onap.msb.apiroute.api.exception.ExtendedInternalServerErrorException;
43 import org.onap.msb.apiroute.health.ConsulLinkHealthCheck;
44 import org.onap.msb.apiroute.health.RedisHealthCheck;
45 import org.onap.msb.apiroute.wrapper.MicroServiceWrapper;
46 import org.onap.msb.apiroute.wrapper.util.ConfigUtil;
47 import org.onap.msb.apiroute.wrapper.util.HttpClientUtil;
48 import org.onap.msb.apiroute.wrapper.util.JacksonJsonUtil;
49 import org.onap.msb.apiroute.wrapper.util.MicroServiceUtil;
50 import org.onap.msb.apiroute.wrapper.util.RouteUtil;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
54 import com.codahale.metrics.annotation.Timed;
55 import com.codahale.metrics.health.HealthCheck.Result;
57 import io.swagger.annotations.ApiOperation;
58 import io.swagger.annotations.ApiParam;
59 import io.swagger.annotations.ApiResponse;
60 import io.swagger.annotations.ApiResponses;
63 // @Api(tags = {"MSB-Service Resource"})
64 @Produces(MediaType.APPLICATION_JSON)
65 public class MicroServiceResource {
66 private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class);
69 UriInfo uriInfo; // actual uri info
73 @ApiOperation(value = "get all microservices ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class,
74 responseContainer = "List")
75 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR,
76 message = "get microservice List fail", response = String.class)})
77 @Produces(MediaType.APPLICATION_JSON)
79 public List<MicroServiceFullInfo> getMicroService() {
80 return MicroServiceWrapper.getInstance().getAllMicroServiceInstances();
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 MicroServiceFullInfo microServiceFullInfo =
104 createRegistrationMicroserviceInfo(microServiceInfo, request, createOrUpdate, port);
105 String registrationUrl = getUrlForRegistration();
106 Response response = routeRegistration2DiscoveryService(microServiceFullInfo, registrationUrl);
111 * @param microServiceFullInfo
112 * @param registrationUrl
115 private Response routeRegistration2DiscoveryService(MicroServiceFullInfo microServiceFullInfo,
116 String registrationUrl) {
117 CloseableHttpClient httpClient = null;
118 CloseableHttpResponse httpResponse = null;
120 HttpPost httpPost = HttpClientUtil.createHttpPost(registrationUrl,
121 JacksonJsonUtil.beanToJson(microServiceFullInfo));
122 httpClient = HttpClients.createDefault();
123 httpResponse = httpClient.execute(httpPost);
124 String jsonString = EntityUtils.toString(httpResponse.getEntity());
125 return Response.status(httpResponse.getStatusLine().getStatusCode()).entity(jsonString).build();
126 } catch (Exception e) {
127 throw new ExtendedInternalServerErrorException(e.getMessage());
129 HttpClientUtil.closeHttpClient(httpClient);
130 HttpClientUtil.closeHttpResponse(httpResponse);
137 private String getUrlForRegistration() {
138 DiscoverInfo discoverInfo = ConfigUtil.getInstance().getDiscoverInfo();
139 String registrationUrl = new StringBuilder().append("http://").append(discoverInfo)
140 .append(RouteUtil.MSB_ROUTE_URL).toString();
141 return registrationUrl;
145 * @param microServiceInfo
147 * @param createOrUpdate
151 private MicroServiceFullInfo createRegistrationMicroserviceInfo(MicroServiceFullInfo microServiceInfo,
152 HttpServletRequest request, boolean createOrUpdate, String port) {
153 String ip = MicroServiceUtil.getRealIp(request);
154 MicroServiceFullInfo microServiceFullInfo = MicroServiceWrapper.getInstance()
155 .saveMicroServiceInstance(microServiceInfo, createOrUpdate, ip, port);
156 return microServiceFullInfo;
162 @Path("/{serviceName}/version/{version}")
163 @ApiOperation(value = "get one microservice ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class)
164 @ApiResponses(value = {
165 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
166 response = String.class),
167 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
168 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
169 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice fail",
170 response = String.class)})
171 @Produces(MediaType.APPLICATION_JSON)
173 public Response getMicroService(
174 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
175 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version) {
176 String discoveryUrl = getUrlForDiscovery(serviceName, version);
177 return routeDiscovery2DiscoveryService(discoveryUrl);
181 * @param discoveryUrl
184 private Response routeDiscovery2DiscoveryService(String discoveryUrl) {
185 CloseableHttpClient httpClient = null;
186 CloseableHttpResponse httpResponse = null;
188 HttpGet httpGet = HttpClientUtil.createHttpGet(discoveryUrl);
189 httpClient = HttpClients.createDefault();
190 httpResponse = httpClient.execute(httpGet);
191 String jsonString = EntityUtils.toString(httpResponse.getEntity());
192 return Response.status(httpResponse.getStatusLine().getStatusCode()).entity(jsonString).build();
193 } catch (Exception e) {
194 throw new ExtendedInternalServerErrorException(e.getMessage());
196 HttpClientUtil.closeHttpClient(httpClient);
197 HttpClientUtil.closeHttpResponse(httpResponse);
206 private String getUrlForDiscovery(String serviceName, String version) {
207 DiscoverInfo discoverInfo = ConfigUtil.getInstance().getDiscoverInfo();
208 String discoveryUrl = new StringBuilder().append("http://").append(discoverInfo).append(RouteUtil.MSB_ROUTE_URL)
209 .append("/").append(serviceName).append("/version/").append(version).toString();
214 @Path("/{serviceName}/version/{version}")
215 @ApiOperation(value = "update one microservice by serviceName and version", code = HttpStatus.SC_CREATED,
216 response = MicroServiceFullInfo.class)
217 @ApiResponses(value = {
218 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
219 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
220 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update microservice fail",
221 response = String.class),
222 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST,
223 message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)})
224 @Produces(MediaType.APPLICATION_JSON)
226 public Response updateMicroService(
227 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
228 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
229 @ApiParam(value = "microservice Instance Info",
230 required = true) MicroServiceFullInfo microServiceInfo,
231 @Context HttpServletRequest request) {
233 String ip = MicroServiceUtil.getRealIp(request);
234 MicroServiceFullInfo microServiceFullInfo =
235 MicroServiceWrapper.getInstance().saveMicroServiceInstance(microServiceInfo, false, ip, "");
236 return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build();
243 @Path("/{serviceName}/version/{version}/nodes/{ip}/{port}")
244 @ApiOperation(value = "delete single node by serviceName and version and node", code = HttpStatus.SC_NO_CONTENT)
245 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete node succeed "),
246 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "node not found", response = String.class),
247 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
248 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
249 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete node fail",
250 response = String.class)})
251 @Produces(MediaType.APPLICATION_JSON)
253 public void deleteNode(
254 @ApiParam(value = "microservice serviceName",
255 required = true) @PathParam("serviceName") String serviceName,
256 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
257 required = false) @PathParam("version") @DefaultValue("") String version,
258 @ApiParam(value = "ip") @PathParam("ip") String ip,
259 @ApiParam(value = "port") @PathParam("port") String port) {
261 MicroServiceWrapper.getInstance().deleteMicroServiceInstance(serviceName, version, ip, port);
267 @Path("/{serviceName}/version/{version}")
268 @ApiOperation(value = "delete one full microservice by serviceName and version", code = HttpStatus.SC_NO_CONTENT)
269 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete microservice succeed "),
270 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
271 response = String.class),
272 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
273 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
274 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete microservice fail",
275 response = String.class)})
276 @Produces(MediaType.APPLICATION_JSON)
278 public void deleteMicroService(
279 @ApiParam(value = "microservice serviceName",
280 required = true) @PathParam("serviceName") String serviceName,
281 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
282 required = false) @PathParam("version") @DefaultValue("") String version) {
284 MicroServiceWrapper.getInstance().deleteMicroService(serviceName, version);
289 @Path("/{serviceName}/version/{version}/status/{status}")
290 @ApiOperation(value = "update microservice status by serviceName and version", code = HttpStatus.SC_CREATED,
291 response = MicroServiceFullInfo.class)
292 @ApiResponses(value = {
293 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
294 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
295 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
296 response = String.class),
297 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update status fail",
298 response = String.class)})
299 @Produces(MediaType.APPLICATION_JSON)
301 public Response updateServiceStatus(
302 @ApiParam(value = "microservice serviceName",
303 required = true) @PathParam("serviceName") String serviceName,
304 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
305 required = false) @PathParam("version") @DefaultValue("") String version,
306 @ApiParam(value = "status,1:abled 0:disabled") @PathParam("status") String status) {
308 MicroServiceFullInfo microServiceFullInfo =
309 MicroServiceWrapper.getInstance().updateMicroServiceStatus(serviceName, version, status);
311 return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build();
317 @ApiOperation(value = "apigateway healthy check ", code = HttpStatus.SC_OK, response = String.class)
318 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "check fail",
319 response = String.class)})
320 @Produces(MediaType.TEXT_PLAIN)
322 public Response health() {
325 Result rst = RedisHealthCheck.getResult();
326 if (!rst.isHealthy()) {
327 LOGGER.warn("health check failed:" + rst.getMessage());
328 throw new ExtendedInternalServerErrorException(rst.getMessage());
332 rst = ConsulLinkHealthCheck.getResult();
333 if (!rst.isHealthy()) {
334 LOGGER.warn("health check failed:" + rst.getMessage());
335 throw new ExtendedInternalServerErrorException(rst.getMessage());
338 return Response.ok("apigateway healthy check:ok").build();