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
14 package org.onap.msb.sdclient.resources;
17 import java.util.ArrayList;
18 import java.util.List;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.ws.rs.DELETE;
23 import javax.ws.rs.DefaultValue;
24 import javax.ws.rs.GET;
25 import javax.ws.rs.POST;
26 import javax.ws.rs.PUT;
27 import javax.ws.rs.Path;
28 import javax.ws.rs.PathParam;
29 import javax.ws.rs.Produces;
30 import javax.ws.rs.QueryParam;
31 import javax.ws.rs.core.Context;
32 import javax.ws.rs.core.MediaType;
33 import javax.ws.rs.core.Response;
34 import javax.ws.rs.core.UriInfo;
36 import org.apache.http.HttpStatus;
37 import org.onap.msb.sdclient.core.ConsulResponse;
38 import org.onap.msb.sdclient.core.MicroServiceFullInfo;
39 import org.onap.msb.sdclient.core.MicroServiceInfo;
40 import org.onap.msb.sdclient.core.NodeAddress;
41 import org.onap.msb.sdclient.core.PublishAddress;
42 import org.onap.msb.sdclient.core.PublishFullAddress;
43 import org.onap.msb.sdclient.core.exception.ExtendedInternalServerErrorException;
44 import org.onap.msb.sdclient.health.ConsulLinkHealthCheck;
45 import org.onap.msb.sdclient.wrapper.ConsulServiceWrapper;
46 import org.onap.msb.sdclient.wrapper.PublishAddressWrapper;
47 import org.onap.msb.sdclient.wrapper.util.ConfigUtil;
48 import org.onap.msb.sdclient.wrapper.util.DiscoverUtil;
49 import org.onap.msb.sdclient.wrapper.util.JacksonJsonUtil;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
53 import com.codahale.metrics.annotation.Timed;
54 import com.codahale.metrics.health.HealthCheck;
55 import com.codahale.metrics.health.HealthCheck.Result;
57 import io.swagger.annotations.Api;
58 import io.swagger.annotations.ApiOperation;
59 import io.swagger.annotations.ApiParam;
60 import io.swagger.annotations.ApiResponse;
61 import io.swagger.annotations.ApiResponses;
64 @Api(tags = {"Service Resource"})
65 @Produces(MediaType.APPLICATION_JSON)
66 public class MicroServiceResource {
70 UriInfo uriInfo; // actual uri info
74 private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class);
78 @ApiOperation(value = "get all microservices ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class,
79 responseContainer = "List")
80 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR,
81 message = "get microservice List fail", response = String.class)})
82 @Produces(MediaType.APPLICATION_JSON)
84 public List<MicroServiceFullInfo> getMicroService() {
85 return ConsulServiceWrapper.getInstance().getAllMicroServiceInstances();
90 @ApiOperation(value = "add one microservice ", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class)
91 @ApiResponses(value = {
92 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
93 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
94 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "add microservice fail",
95 response = String.class),
96 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST,
97 message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)})
98 @Produces(MediaType.APPLICATION_JSON)
100 public Response addMicroService(
101 @ApiParam(value = "MicroServiceInfo Instance Info",
102 required = true) MicroServiceInfo microServiceInfo,
103 @Context HttpServletRequest request,
104 @ApiParam(value = "createOrUpdate",
105 required = false) @QueryParam("createOrUpdate") @DefaultValue("true") boolean createOrUpdate,
106 @ApiParam(value = "is_manual",
107 required = false) @QueryParam("is_manual") @DefaultValue("false") boolean is_manual) {
108 LOGGER.error("**** json string:" + microServiceInfo);
109 String ip = DiscoverUtil.getRealIp(request);
112 LOGGER.info("[POST REQUEST] Request IP:" + ip + ",Request Param:[createOrUpdate]" + createOrUpdate
113 + ",Request Body:" + JacksonJsonUtil.beanToJson(microServiceInfo));
114 } catch (Exception e) {
115 // TODO Auto-generated catch block
116 LOGGER.error("[POST REQUEST] beanToJson is wrong:" + e.getMessage());
119 MicroServiceFullInfo microServiceFullInfo = ConsulServiceWrapper.getInstance()
120 .saveMicroServiceInstance(microServiceInfo, createOrUpdate, ip, is_manual);
121 URI returnURI = uriInfo.getAbsolutePathBuilder()
122 .path("/" + microServiceInfo.getServiceName() + "/version/" + microServiceInfo.getVersion())
124 return Response.created(returnURI).entity(microServiceFullInfo).build();
130 @Path("/{serviceName}/version/{version}/nodes")
131 @ApiOperation(value = "get one microservice ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class,
132 responseContainer = "List")
133 @ApiResponses(value = {
134 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
135 response = String.class),
136 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
137 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
138 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice fail",
139 response = String.class)})
140 @Produces(MediaType.APPLICATION_JSON)
142 public List<MicroServiceFullInfo> getMicroServiceNodes(
143 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
144 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
145 @ApiParam(value = "Format key:value,Multiple use ',' split",
146 required = false) @QueryParam("labels") @DefaultValue("") String labels,
147 @ApiParam(value = "namespace",
148 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
149 @ApiParam(value = "if true then only query passing services",
150 required = false) @QueryParam("ifPassStatus") @DefaultValue("true") boolean ifPassStatus) {
152 return ConsulServiceWrapper.getInstance().getMicroServiceForNodes(serviceName, version, ifPassStatus, labels,
159 @Path("/{serviceName}/version/{version}")
160 @ApiOperation(value = "get one microservice nodes", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class)
161 @ApiResponses(value = {
162 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
163 response = String.class),
164 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
165 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
166 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice fail",
167 response = String.class)})
168 @Produces(MediaType.APPLICATION_JSON)
170 public Response getMicroService(
171 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
172 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
173 @ApiParam(value = "Format key:value,Multiple use ',' split",
174 required = false) @QueryParam("labels") @DefaultValue("") String labels,
175 @ApiParam(value = "namespace",
176 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
177 @ApiParam(value = "if true then only query passing services",
178 required = false) @QueryParam("ifPassStatus") @DefaultValue("true") boolean ifPassStatus,
179 @ApiParam(value = "wait", required = false) @QueryParam("wait") @DefaultValue("") String wait,
180 @ApiParam(value = "index", required = false) @QueryParam("index") @DefaultValue("") String index) {
183 ConsulResponse<MicroServiceFullInfo> serviceResponse = ConsulServiceWrapper.getInstance()
184 .getMicroServiceInstance(serviceName, version, ifPassStatus, wait, index, labels, namespace);
185 return Response.ok(serviceResponse.getResponse()).header("X-Consul-Index", serviceResponse.getIndex()).build();
191 @Path("/{serviceName}/version/{version}")
192 @ApiOperation(value = "update one microservice by serviceName and version", code = HttpStatus.SC_CREATED,
193 response = MicroServiceFullInfo.class)
194 @ApiResponses(value = {
195 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
196 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
197 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update microservice fail",
198 response = String.class),
199 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST,
200 message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)})
201 @Produces(MediaType.APPLICATION_JSON)
203 public Response updateMicroService(
204 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
205 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
206 @ApiParam(value = "namespace",
207 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
208 @ApiParam(value = "microservice Instance Info", required = true) MicroServiceInfo microServiceInfo,
209 @Context HttpServletRequest request,
210 @ApiParam(value = "protocol",
211 required = false) @QueryParam("protocol") @DefaultValue("") String protocol,
212 @ApiParam(value = "is_manual", required = false,
213 hidden = true) @QueryParam("is_manual") @DefaultValue("false") boolean is_manual) {
215 String ip = DiscoverUtil.getRealIp(request);
216 MicroServiceFullInfo microServiceFullInfo = ConsulServiceWrapper.getInstance()
217 .updateMicroServiceInstance(serviceName, version, namespace, microServiceInfo, ip, is_manual);
218 return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build();
223 @Path("/{serviceName}/version/{version}/ttl")
224 @ApiOperation(value = "passing one microservice health check by ttl", code = HttpStatus.SC_CREATED,
225 response = NodeAddress.class)
226 @ApiResponses(value = {
227 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
228 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
229 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "health check by ttl fail",
230 response = String.class),
231 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable CheckNode JSON REQUEST",
232 response = String.class)})
233 @Produces(MediaType.APPLICATION_JSON)
235 public Response healthCheckbyTTL(
236 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
237 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
238 @ApiParam(value = "namespace",
239 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
240 @ApiParam(value = "CheckNode Instance Info", required = true) NodeAddress checkNode) {
242 ConsulServiceWrapper.getInstance().healthCheckbyTTL(serviceName, version, namespace, checkNode);
243 return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(checkNode).build();
250 @Path("/{serviceName}/version/{version}/nodes/{ip}/{port}")
251 @ApiOperation(value = "delete single node by serviceName and version and node", code = HttpStatus.SC_NO_CONTENT)
252 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete node succeed "),
253 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "node not found", response = String.class),
254 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
255 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
256 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete node fail",
257 response = String.class)})
258 @Produces(MediaType.APPLICATION_JSON)
260 public void deleteNode(
261 @ApiParam(value = "microservice serviceName",
262 required = true) @PathParam("serviceName") String serviceName,
263 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
264 required = false) @PathParam("version") @DefaultValue("") String version,
265 @ApiParam(value = "namespace",
266 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
267 @ApiParam(value = "ip") @PathParam("ip") String ip,
268 @ApiParam(value = "port") @PathParam("port") String port, @ApiParam(value = "protocol",
269 required = false) @QueryParam("protocol") @DefaultValue("") String protocol) {
270 LOGGER.info("[DELETE NODE REQUEST] serviceName:" + serviceName + ",version:" + version + ",namespace:"
271 + namespace + ",protocol:" + protocol + ",ip:" + ip + ",port:" + port);
272 ConsulServiceWrapper.getInstance().deleteMicroServiceInstance(serviceName, version, namespace, ip, port);
278 @Path("/{serviceName}/version/{version}")
279 @ApiOperation(value = "delete one full microservice by serviceName and version", code = HttpStatus.SC_NO_CONTENT)
280 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete microservice succeed "),
281 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found",
282 response = String.class),
283 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
284 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
285 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete microservice fail",
286 response = String.class)})
287 @Produces(MediaType.APPLICATION_JSON)
289 public void deleteMicroService(
290 @ApiParam(value = "microservice serviceName",
291 required = true) @PathParam("serviceName") String serviceName,
292 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"",
293 required = false) @PathParam("version") @DefaultValue("") String version,
294 @ApiParam(value = "namespace",
295 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
296 @ApiParam(value = "protocol",
297 required = false) @QueryParam("protocol") @DefaultValue("") String protocol) {
299 LOGGER.info("[DELETE REQUEST] serviceName:" + serviceName + ",version:" + version + ",namespace:" + namespace
300 + ",protocol:" + protocol);
302 ConsulServiceWrapper.getInstance().deleteMicroService(serviceName, version, namespace);
309 // @Path("/{serviceName}/version/{version}/status/{status}")
310 // @ApiOperation(value = "update one microservice's status by serviceName and version",
311 // response = RouteResult.class)
312 // @ApiResponses(value = {@ApiResponse(code = 500, message =
313 // "update microservice status error ")})
314 // @Produces(MediaType.APPLICATION_JSON)
316 // public RouteResult updateMicroServiceStatus(
317 // @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName")
318 // String serviceName,
319 // @ApiParam(value = "microservice version", required = false) @PathParam("version")
320 // @DefaultValue("") String version,
321 // @ApiParam(value = "microservice status", required = true) @PathParam("status") String status)
324 // return MicroServiceWrapper.getInstance().updateMicroServiceStatus(serviceName, version,
331 @Path("/{serviceName}/version/{version}/publishaddress")
332 @ApiOperation(value = "get one microservice's inner publishaddress", code = HttpStatus.SC_OK,
333 response = PublishAddress.class)
334 @ApiResponses(value = {
335 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "publishaddress not found",
336 response = String.class),
337 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
338 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
339 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get publishaddress fail",
340 response = String.class)})
341 @Produces(MediaType.APPLICATION_JSON)
343 public PublishAddress getPublishaddress(
344 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
345 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
346 @ApiParam(value = "namespace",
347 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
348 @ApiParam(value = "Waiting time,Scope: 5-300, unit: second",
349 required = false) @QueryParam("wait") @DefaultValue("0") int wait) {
352 return PublishAddressWrapper.getInstance().getPublishaddress(serviceName, version, namespace, wait);
358 @Path("/apigatewayserviceinfo")
359 @ApiOperation(value = "get apigateway AddressInfo", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class,
360 responseContainer = "List")
361 @ApiResponses(value = {
362 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "apigateway ServiceInfo not found",
363 response = String.class),
364 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR,
365 message = "get apigateway ServiceInfo fail", response = String.class)})
366 @Produces(MediaType.APPLICATION_JSON)
368 public Set<MicroServiceFullInfo> getApigatewayServiceInfo(
369 @ApiParam(value = "namespace",
370 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
371 @ApiParam(value = "visualRange",
372 required = false) @QueryParam("visualRange") @DefaultValue("1") String visualRange) {
375 return PublishAddressWrapper.getInstance().getApigatewayServiceInfo(namespace, visualRange);
381 @Path("/{serviceName}/version/{version}/allpublishaddress")
382 @ApiOperation(value = "get one microservice's all publishaddress", code = HttpStatus.SC_OK,
383 response = PublishFullAddress.class, responseContainer = "List")
384 @ApiResponses(value = {
385 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "publishaddress not found",
386 response = String.class),
387 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY,
388 message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
389 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get publishaddress fail",
390 response = String.class)})
391 @Produces(MediaType.APPLICATION_JSON)
393 public Set<PublishFullAddress> getAllPublishaddress(
394 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
395 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
396 @ApiParam(value = "namespace",
397 required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
398 @ApiParam(value = "outSystem:0,inSystem:1,all:0|1(default)",
399 required = false) @QueryParam("visualRange") @DefaultValue("0|1") String visualRange) {
402 return PublishAddressWrapper.getInstance().getAllPublishaddress(serviceName, version, namespace, visualRange);
409 @Path("/tcpudpportrange")
410 @ApiOperation(value = "get tcp and udp port range", code = HttpStatus.SC_OK, response = String.class,
411 responseContainer = "List")
412 @ApiResponses(value = {
413 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "port range not found",
414 response = String.class),
415 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get port range fail",
416 response = String.class)})
417 @Produces(MediaType.APPLICATION_JSON)
419 public String[] getTCP_UDP_portRange() {
421 return new String[] {ConfigUtil.getInstance().getTcpudpPortRangeStart(),
422 ConfigUtil.getInstance().getTcpudpPortRangeEnd()};
428 @ApiOperation(value = "sdclient healthy check ", code = HttpStatus.SC_OK, response = String.class)
429 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "check fail",
430 response = String.class)})
431 @Produces(MediaType.TEXT_PLAIN)
433 public Response health() {
435 ArrayList<HealthCheck> healthcheckArray = new ArrayList<HealthCheck>();
438 healthcheckArray.add(new ConsulLinkHealthCheck());
441 for (int i = 0; i < healthcheckArray.size(); i++) {
442 Result rst = healthcheckArray.get(i).execute();
444 if (!rst.isHealthy()) {
445 LOGGER.warn("health check failed:" + rst.getMessage());
446 throw new ExtendedInternalServerErrorException(rst.getMessage());
450 return Response.ok("sdclient healthy check:ok").build();