2 * Copyright 2016 ZTE, Inc. and others.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onap.msb.sdclient.resources;
19 import java.util.ArrayList;
20 import java.util.List;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.ws.rs.DELETE;
25 import javax.ws.rs.DefaultValue;
26 import javax.ws.rs.GET;
27 import javax.ws.rs.POST;
28 import javax.ws.rs.PUT;
29 import javax.ws.rs.Path;
30 import javax.ws.rs.PathParam;
31 import javax.ws.rs.Produces;
32 import javax.ws.rs.QueryParam;
33 import javax.ws.rs.core.Context;
34 import javax.ws.rs.core.MediaType;
35 import javax.ws.rs.core.Response;
36 import javax.ws.rs.core.UriInfo;
38 import org.apache.http.HttpStatus;
39 import org.onap.msb.sdclient.core.ConsulResponse;
40 import org.onap.msb.sdclient.core.MicroServiceFullInfo;
41 import org.onap.msb.sdclient.core.MicroServiceInfo;
42 import org.onap.msb.sdclient.core.NodeAddress;
43 import org.onap.msb.sdclient.core.PublishAddress;
44 import org.onap.msb.sdclient.core.PublishFullAddress;
45 import org.onap.msb.sdclient.core.exception.ExtendedInternalServerErrorException;
46 import org.onap.msb.sdclient.health.ConsulLinkHealthCheck;
47 import org.onap.msb.sdclient.wrapper.ConsulServiceWrapper;
48 import org.onap.msb.sdclient.wrapper.PublishAddressWrapper;
49 import org.onap.msb.sdclient.wrapper.util.ConfigUtil;
50 import org.onap.msb.sdclient.wrapper.util.DiscoverUtil;
51 import org.onap.msb.sdclient.wrapper.util.JacksonJsonUtil;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 import com.codahale.metrics.annotation.Timed;
56 import com.codahale.metrics.health.HealthCheck;
57 import com.codahale.metrics.health.HealthCheck.Result;
59 import io.swagger.annotations.Api;
60 import io.swagger.annotations.ApiOperation;
61 import io.swagger.annotations.ApiParam;
62 import io.swagger.annotations.ApiResponse;
63 import io.swagger.annotations.ApiResponses;
66 @Api(tags = { "Service Resource" })
67 @Produces(MediaType.APPLICATION_JSON)
68 public class MicroServiceResource {
72 UriInfo uriInfo; // actual uri info
76 private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class);
80 @ApiOperation(value = "get all microservices ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class, responseContainer = "List")
81 @ApiResponses(value = {@ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, 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, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
93 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "add microservice fail", response = String.class),
94 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)})
95 @Produces(MediaType.APPLICATION_JSON)
97 public Response addMicroService(
98 @ApiParam(value = "MicroServiceInfo Instance Info", required = true) MicroServiceInfo microServiceInfo,
99 @Context HttpServletRequest request,
100 @ApiParam(value = "createOrUpdate", required = false) @QueryParam("createOrUpdate") @DefaultValue("true") boolean createOrUpdate,
101 @ApiParam(value = "is_manual", required = false) @QueryParam("is_manual") @DefaultValue("false") boolean is_manual
104 String ip=DiscoverUtil.getRealIp(request);
107 LOGGER.info("[POST REQUEST] Request IP:"+ip+",Request Param:[createOrUpdate]"+createOrUpdate+",Request Body:"+JacksonJsonUtil.beanToJson(microServiceInfo));
108 } catch (Exception e) {
109 // TODO Auto-generated catch block
110 LOGGER.error("[POST REQUEST] beanToJson is wrong:"+e.getMessage());
113 MicroServiceFullInfo microServiceFullInfo =
114 ConsulServiceWrapper.getInstance().saveMicroServiceInstance(microServiceInfo,
115 createOrUpdate,ip,is_manual);
117 uriInfo.getAbsolutePathBuilder()
118 .path("/" + microServiceInfo.getServiceName() + "/version/"
119 + microServiceInfo.getVersion()).build();
120 return Response.created(returnURI).entity(microServiceFullInfo).build();
126 @Path("/{serviceName}/version/{version}/nodes")
127 @ApiOperation(value = "get one microservice ", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class, responseContainer = "List")
128 @ApiResponses(value = {
129 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found", response = String.class),
130 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
131 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice fail", response = String.class)})
132 @Produces(MediaType.APPLICATION_JSON)
134 public List<MicroServiceFullInfo> getMicroServiceNodes(
135 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
136 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
137 @ApiParam(value = "Format key:value,Multiple use ',' split", required = false) @QueryParam("labels") @DefaultValue("") String labels,
138 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
139 @ApiParam(value = "if true then only query passing services", required = false) @QueryParam("ifPassStatus") @DefaultValue("true")boolean ifPassStatus
142 return ConsulServiceWrapper.getInstance().getMicroServiceForNodes(serviceName, version,ifPassStatus,labels,namespace);
148 @Path("/{serviceName}/version/{version}")
149 @ApiOperation(value = "get one microservice nodes", code = HttpStatus.SC_OK, response = MicroServiceFullInfo.class)
150 @ApiResponses(value = {
151 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found", response = String.class),
152 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
153 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get microservice fail", response = String.class)})
154 @Produces(MediaType.APPLICATION_JSON)
156 public Response getMicroService(
157 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
158 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
159 @ApiParam(value = "Format key:value,Multiple use ',' split", required = false) @QueryParam("labels") @DefaultValue("") String labels,
160 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
161 @ApiParam(value = "if true then only query passing services", required = false) @QueryParam("ifPassStatus") @DefaultValue("true")boolean ifPassStatus,
162 @ApiParam(value = "wait", required = false) @QueryParam("wait") @DefaultValue("") String wait,
163 @ApiParam(value = "index", required = false) @QueryParam("index") @DefaultValue("") String index) {
166 ConsulResponse<MicroServiceFullInfo> serviceResponse= ConsulServiceWrapper.getInstance().getMicroServiceInstance(serviceName, version,ifPassStatus,wait,index,labels,namespace);
167 return Response.ok(serviceResponse.getResponse()).header("X-Consul-Index", serviceResponse.getIndex()).build();
173 @Path("/{serviceName}/version/{version}")
174 @ApiOperation(value = "update one microservice by serviceName and version", code = HttpStatus.SC_CREATED, response = MicroServiceFullInfo.class)
175 @ApiResponses(value = {
176 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
177 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "update microservice fail", response = String.class),
178 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable MicroServiceInfo JSON REQUEST", response = String.class)})
179 @Produces(MediaType.APPLICATION_JSON)
181 public Response updateMicroService(
182 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
183 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
184 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
185 @ApiParam(value = "microservice Instance Info", required = true) MicroServiceInfo microServiceInfo,
186 @Context HttpServletRequest request,
187 @ApiParam(value = "protocol", required = false) @QueryParam("protocol") @DefaultValue("") String protocol,
188 @ApiParam(value = "is_manual", required = false, hidden = true ) @QueryParam("is_manual") @DefaultValue("false") boolean is_manual) {
190 String ip=DiscoverUtil.getRealIp(request);
191 MicroServiceFullInfo microServiceFullInfo =ConsulServiceWrapper.getInstance().updateMicroServiceInstance(serviceName,version,namespace,microServiceInfo,ip,is_manual);
192 return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(microServiceFullInfo).build();
197 @Path("/{serviceName}/version/{version}/ttl")
198 @ApiOperation(value = "passing one microservice health check by ttl", code = HttpStatus.SC_CREATED, response = NodeAddress.class)
199 @ApiResponses(value = {
200 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
201 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "health check by ttl fail", response = String.class),
202 @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = "Unprocessable CheckNode JSON REQUEST", response = String.class)})
203 @Produces(MediaType.APPLICATION_JSON)
205 public Response healthCheckbyTTL(
206 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
207 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
208 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
209 @ApiParam(value = "CheckNode Instance Info", required = true) NodeAddress checkNode) {
211 ConsulServiceWrapper.getInstance().healthCheckbyTTL(serviceName,version,namespace,checkNode);
212 return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(checkNode).build();
219 @Path("/{serviceName}/version/{version}/nodes/{ip}/{port}")
220 @ApiOperation(value = "delete single node by serviceName and version and node", code = HttpStatus.SC_NO_CONTENT)
221 @ApiResponses(value = {
222 @ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete node succeed "),
223 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "node not found", response = String.class),
224 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
225 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete node fail", response = String.class)})
226 @Produces(MediaType.APPLICATION_JSON)
228 public void deleteNode(
229 @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName") String serviceName,
230 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version,
231 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
232 @ApiParam(value = "ip") @PathParam("ip") String ip,
233 @ApiParam(value = "port") @PathParam("port") String port,
234 @ApiParam(value = "protocol", required = false) @QueryParam("protocol") @DefaultValue("") String protocol) {
235 LOGGER.info("[DELETE NODE REQUEST] serviceName:"+serviceName+",version:"+version+",namespace:"+namespace+",protocol:"+protocol+",ip:"+ip+",port:"+port);
236 ConsulServiceWrapper.getInstance().deleteMicroServiceInstance(serviceName, version, namespace,ip,port);
242 @Path("/{serviceName}/version/{version}")
243 @ApiOperation(value = "delete one full microservice by serviceName and version", code = HttpStatus.SC_NO_CONTENT)
244 @ApiResponses(value = {
245 @ApiResponse(code = HttpStatus.SC_NO_CONTENT, message = "delete microservice succeed "),
246 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "microservice not found", response = String.class),
247 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
248 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "delete microservice fail", response = String.class)})
249 @Produces(MediaType.APPLICATION_JSON)
251 public void deleteMicroService(
252 @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName") String serviceName,
253 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"", required = false) @PathParam("version") @DefaultValue("") String version,
254 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
255 @ApiParam(value = "protocol", required = false) @QueryParam("protocol") @DefaultValue("") String protocol) {
257 LOGGER.info("[DELETE REQUEST] serviceName:"+serviceName+",version:"+version+",namespace:"+namespace+",protocol:"+protocol);
259 ConsulServiceWrapper.getInstance().deleteMicroService(serviceName, version,namespace);
271 // @Path("/{serviceName}/version/{version}/status/{status}")
272 // @ApiOperation(value = "update one microservice's status by serviceName and version",
273 // response = RouteResult.class)
274 // @ApiResponses(value = {@ApiResponse(code = 500, message =
275 // "update microservice status error ")})
276 // @Produces(MediaType.APPLICATION_JSON)
278 // public RouteResult updateMicroServiceStatus(
279 // @ApiParam(value = "microservice serviceName", required = true) @PathParam("serviceName")
280 // String serviceName,
281 // @ApiParam(value = "microservice version", required = false) @PathParam("version")
282 // @DefaultValue("") String version,
283 // @ApiParam(value = "microservice status", required = true) @PathParam("status") String status)
286 // return MicroServiceWrapper.getInstance().updateMicroServiceStatus(serviceName, version,
293 @Path("/{serviceName}/version/{version}/publishaddress")
294 @ApiOperation(value = "get one microservice's inner publishaddress", code = HttpStatus.SC_OK, response = PublishAddress.class)
295 @ApiResponses(value = {
296 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "publishaddress not found", response = String.class),
297 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
298 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get publishaddress fail", response = String.class)})
299 @Produces(MediaType.APPLICATION_JSON)
301 public PublishAddress getPublishaddress(
302 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
303 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
304 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
305 @ApiParam(value = "Waiting time,Scope: 5-300, unit: second", required = false) @QueryParam("wait") @DefaultValue("0") int wait
309 return PublishAddressWrapper.getInstance().getPublishaddress(serviceName, version,namespace,wait);
315 @Path("/apigatewayserviceinfo")
316 @ApiOperation(value = "get apigateway AddressInfo", code = HttpStatus.SC_OK,response = MicroServiceFullInfo.class, responseContainer = "List")
317 @ApiResponses(value = {
318 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "apigateway ServiceInfo not found", response = String.class),
319 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get apigateway ServiceInfo fail", response = String.class)})
320 @Produces(MediaType.APPLICATION_JSON)
322 public Set<MicroServiceFullInfo> getApigatewayServiceInfo(
323 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
324 @ApiParam(value = "visualRange", required = false) @QueryParam("visualRange") @DefaultValue("1") String visualRange) {
327 return PublishAddressWrapper.getInstance().getApigatewayServiceInfo(namespace, visualRange);
333 @Path("/{serviceName}/version/{version}/allpublishaddress")
334 @ApiOperation(value = "get one microservice's all publishaddress", code = HttpStatus.SC_OK, response = PublishFullAddress.class, responseContainer = "List")
335 @ApiResponses(value = {
336 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "publishaddress not found", response = String.class),
337 @ApiResponse(code = HttpStatus.SC_UNPROCESSABLE_ENTITY, message = "Unprocessable MicroServiceInfo Entity ", response = String.class),
338 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get publishaddress fail", response = String.class)})
339 @Produces(MediaType.APPLICATION_JSON)
341 public Set<PublishFullAddress> getAllPublishaddress(
342 @ApiParam(value = "microservice serviceName") @PathParam("serviceName") String serviceName,
343 @ApiParam(value = "microservice version,if the version is empty, please enter \"null\"") @PathParam("version") @DefaultValue("") String version,
344 @ApiParam(value = "namespace", required = false) @QueryParam("namespace") @DefaultValue("") String namespace,
345 @ApiParam(value = "outSystem:0,inSystem:1,all:0|1(default)", required = false) @QueryParam("visualRange") @DefaultValue("0|1") String visualRange
349 return PublishAddressWrapper.getInstance().getAllPublishaddress(serviceName, version, namespace,visualRange);
356 @Path("/tcpudpportrange")
357 @ApiOperation(value = "get tcp and udp port range", code = HttpStatus.SC_OK,response = String.class, responseContainer = "List")
358 @ApiResponses(value = {
359 @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = "port range not found", response = String.class),
360 @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "get port range fail", response = String.class)})
361 @Produces(MediaType.APPLICATION_JSON)
363 public String[] getTCP_UDP_portRange() {
365 return new String[]{ConfigUtil.getInstance().getTcpudpPortRangeStart(),ConfigUtil.getInstance().getTcpudpPortRangeEnd()};
371 @ApiOperation(value = "sdclient healthy check ", code = HttpStatus.SC_OK, response = String.class)
372 @ApiResponses(value = { @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = "check fail", response = String.class) })
373 @Produces(MediaType.TEXT_PLAIN)
375 public Response health() {
377 ArrayList<HealthCheck> healthcheckArray = new ArrayList<HealthCheck>();
380 healthcheckArray.add(new ConsulLinkHealthCheck());
383 for (int i = 0; i < healthcheckArray.size(); i++) {
384 Result rst = healthcheckArray.get(i).execute();
386 if (!rst.isHealthy()) {
387 LOGGER.warn("health check failed:" + rst.getMessage());
388 throw new ExtendedInternalServerErrorException(rst.getMessage());
392 return Response.ok("sdclient healthy check:ok").build();