inherit from oparent
[msb/discovery.git] / sdclient / discovery-service / src / main / java / org / onap / msb / sdclient / resources / MicroServiceResource.java
1 /**
2  * Copyright 2016 ZTE, Inc. and others.
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 package org.onap.msb.sdclient.resources;
17
18 import java.net.URI;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Set;
22
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;
37
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;
54
55 import com.codahale.metrics.annotation.Timed;
56 import com.codahale.metrics.health.HealthCheck;
57 import com.codahale.metrics.health.HealthCheck.Result;
58
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;
64
65 @Path("/services")
66 @Api(tags = { "Service Resource" })
67 @Produces(MediaType.APPLICATION_JSON)
68 public class MicroServiceResource {
69
70
71     @Context
72     UriInfo uriInfo; // actual uri info
73     
74
75
76     private static final Logger LOGGER = LoggerFactory.getLogger(MicroServiceResource.class);
77
78     @GET
79     @Path("/")
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)
83     @Timed
84     public List<MicroServiceFullInfo>  getMicroService() {
85         return ConsulServiceWrapper.getInstance().getAllMicroServiceInstances();
86     }
87
88     @POST
89     @Path("/")
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)
96     @Timed
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
102         ) {
103        
104        String ip=DiscoverUtil.getRealIp(request);
105        
106        try {
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());
111       }
112         
113         MicroServiceFullInfo microServiceFullInfo =
114             ConsulServiceWrapper.getInstance().saveMicroServiceInstance(microServiceInfo,
115                     createOrUpdate,ip,is_manual);
116         URI returnURI =
117                 uriInfo.getAbsolutePathBuilder()
118                         .path("/" + microServiceInfo.getServiceName() + "/version/"
119                                 + microServiceInfo.getVersion()).build();
120         return Response.created(returnURI).entity(microServiceFullInfo).build();
121     }
122
123
124
125     @GET
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)
133     @Timed
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
140             ) {
141
142       return ConsulServiceWrapper.getInstance().getMicroServiceForNodes(serviceName, version,ifPassStatus,labels,namespace);
143
144
145     }
146     
147     @GET
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)
155     @Timed
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) {
164
165
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();
168
169
170     }
171
172     @PUT
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)
180     @Timed
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) {
189
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();
193
194     }
195     
196     @PUT
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)
204     @Timed
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) {
210
211         ConsulServiceWrapper.getInstance().healthCheckbyTTL(serviceName,version,namespace,checkNode);
212         return Response.created(uriInfo.getAbsolutePathBuilder().build()).entity(checkNode).build();
213
214     }
215
216    
217
218     @DELETE
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)
227     @Timed
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);
237
238     }
239
240
241     @DELETE
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)
250     @Timed
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) {
256
257       LOGGER.info("[DELETE REQUEST] serviceName:"+serviceName+",version:"+version+",namespace:"+namespace+",protocol:"+protocol);
258       
259       ConsulServiceWrapper.getInstance().deleteMicroService(serviceName, version,namespace);
260
261     }
262
263
264   
265
266    
267  
268    
269
270     // @PUT
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)
277     // @Timed
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)
284     // {
285     //
286     // return MicroServiceWrapper.getInstance().updateMicroServiceStatus(serviceName, version,
287     // status);
288     //
289     // }
290     
291     
292     @GET
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)
300     @Timed
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
306             ) {
307
308
309         return PublishAddressWrapper.getInstance().getPublishaddress(serviceName, version,namespace,wait);
310
311
312     }
313     
314     @GET
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)    
321     @Timed
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) {
325
326
327         return PublishAddressWrapper.getInstance().getApigatewayServiceInfo(namespace, visualRange);
328
329
330     }
331     
332     @GET
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)
340     @Timed
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
346             ) {
347
348
349         return PublishAddressWrapper.getInstance().getAllPublishaddress(serviceName, version, namespace,visualRange);
350
351
352     }
353     
354     
355     @GET
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)
362     @Timed
363     public String[] getTCP_UDP_portRange() {
364
365         return new String[]{ConfigUtil.getInstance().getTcpudpPortRangeStart(),ConfigUtil.getInstance().getTcpudpPortRangeEnd()};
366
367     }
368     
369     @GET
370     @Path("/health")
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)
374     @Timed
375     public Response health() {
376
377         ArrayList<HealthCheck> healthcheckArray = new ArrayList<HealthCheck>();
378
379         // consul link check
380         healthcheckArray.add(new ConsulLinkHealthCheck());
381
382         // begin check
383         for (int i = 0; i < healthcheckArray.size(); i++) {
384             Result rst = healthcheckArray.get(i).execute();
385
386             if (!rst.isHealthy()) {
387                 LOGGER.warn("health check failed:" + rst.getMessage());
388                 throw new ExtendedInternalServerErrorException(rst.getMessage());
389             }
390         }
391
392         return Response.ok("sdclient healthy check:ok").build();
393     }
394
395 }