f38cd85026467d5b41081259710ada35a365dcc5
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ServiceServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.servlets;
22
23 import java.io.BufferedReader;
24 import java.io.ByteArrayInputStream;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.lang.reflect.Type;
28 import java.text.MessageFormat;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33
34 import javax.inject.Singleton;
35 import javax.servlet.ServletContext;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.ws.rs.Consumes;
38 import javax.ws.rs.DELETE;
39 import javax.ws.rs.GET;
40 import javax.ws.rs.HeaderParam;
41 import javax.ws.rs.POST;
42 import javax.ws.rs.PUT;
43 import javax.ws.rs.Path;
44 import javax.ws.rs.PathParam;
45 import javax.ws.rs.Produces;
46 import javax.ws.rs.core.Context;
47 import javax.ws.rs.core.MediaType;
48 import javax.ws.rs.core.Response;
49
50 import org.apache.http.HttpStatus;
51 import org.codehaus.jackson.map.ObjectMapper;
52 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
53 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
54 import org.openecomp.sdc.be.config.BeEcompErrorManager;
55 import org.openecomp.sdc.be.config.Configuration;
56 import org.openecomp.sdc.be.config.ConfigurationManager;
57 import org.openecomp.sdc.be.dao.api.ActionStatus;
58 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
59 import org.openecomp.sdc.be.model.DistributionStatusEnum;
60 import org.openecomp.sdc.be.model.GroupInstanceProperty;
61 import org.openecomp.sdc.be.model.Resource;
62 import org.openecomp.sdc.be.model.Service;
63 import org.openecomp.sdc.be.model.User;
64 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
65 import org.openecomp.sdc.common.api.Constants;
66 import org.openecomp.sdc.common.datastructure.Wrapper;
67 import org.openecomp.sdc.exception.ResponseFormat;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70
71 import com.google.gson.reflect.TypeToken;
72 import com.jcabi.aspects.Loggable;
73 import io.swagger.annotations.Api;
74 import io.swagger.annotations.ApiOperation;
75 import io.swagger.annotations.ApiParam;
76 import io.swagger.annotations.ApiResponse;
77 import io.swagger.annotations.ApiResponses;
78
79 import fj.data.Either;
80
81 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
82 @Path("/v1/catalog")
83 @Api(value = "Service Catalog", description = "Service Servlet")
84 @Singleton
85 public class ServiceServlet extends AbstractValidationsServlet {
86
87         private static Logger log = LoggerFactory.getLogger(ServiceServlet.class.getName());
88
89         @POST
90         @Path("/services")
91         @Consumes(MediaType.APPLICATION_JSON)
92         @Produces(MediaType.APPLICATION_JSON)
93         @ApiOperation(value = "Create Service", httpMethod = "POST", notes = "Returns created service", response = Service.class)
94         @ApiResponses(value = { @ApiResponse(code = 201, message = "Service created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
95                         @ApiResponse(code = 409, message = "Service already exist") })
96         public Response createService(@ApiParam(value = "Service object to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
97
98                 ServletContext context = request.getSession().getServletContext();
99                 String url = request.getMethod() + " " + request.getRequestURI();
100                 log.debug("Start handle request of {}", url);
101
102                 User modifier = new User();
103                 modifier.setUserId(userId);
104                 log.debug("modifier id is {}", userId);
105
106                 Response response = null;
107                 try {
108                         ServiceBusinessLogic businessLogic = getServiceBL(context);
109                         Either<Service, ResponseFormat> convertResponse = parseToService(data, modifier);
110                         if (convertResponse.isRight()) {
111                                 log.debug("failed to parse service");
112                                 response = buildErrorResponse(convertResponse.right().value());
113                                 return response;
114                         }
115
116                         Service service = convertResponse.left().value();
117                         Either<Service, ResponseFormat> actionResponse = businessLogic.createService(service, modifier);
118
119                         if (actionResponse.isRight()) {
120                                 log.debug("Failed to create service");
121                                 response = buildErrorResponse(actionResponse.right().value());
122                                 return response;
123                         }
124
125                         Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
126                         response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result);
127                         return response;
128
129                 } catch (Exception e) {
130                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Service");
131                         log.debug("create service failed with exception", e);
132                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
133                         return response;
134                 }
135         }
136
137         public Either<Service, ResponseFormat> parseToService(String serviceJson, User user) {
138                 return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
139         }
140
141         @GET
142         @Path("/services/validate-name/{serviceName}")
143         @Consumes(MediaType.APPLICATION_JSON)
144         @Produces(MediaType.APPLICATION_JSON)
145         @ApiOperation(value = "validate service name", httpMethod = "GET", notes = "checks if the chosen service name is available ", response = Response.class)
146         @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") })
147         public Response validateServiceName(@PathParam("serviceName") final String serviceName, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
148                 ServletContext context = request.getSession().getServletContext();
149                 String url = request.getMethod() + " " + request.getRequestURI();
150                 log.debug("Start handle request of {}", url);
151
152                 // get modifier id
153                 User modifier = new User();
154                 modifier.setUserId(userId);
155                 log.debug("modifier id is {}", userId);
156                 Response response = null;
157                 try {
158                         ServiceBusinessLogic businessLogic = getServiceBL(context);
159
160                         Either<Map<String, Boolean>, ResponseFormat> actionResponse = businessLogic.validateServiceNameExists(serviceName, userId);
161
162                         if (actionResponse.isRight()) {
163                                 log.debug("failed to get validate service name");
164                                 response = buildErrorResponse(actionResponse.right().value());
165                                 return response;
166                         }
167                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
168                 } catch (Exception e) {
169                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name");
170                         log.debug("validate service name failed with exception", e);
171                         return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
172                 }
173         }
174
175         @GET
176         @Path("/audit-records/{componentType}/{componentUniqueId}")
177         @Consumes(MediaType.APPLICATION_JSON)
178         @Produces(MediaType.APPLICATION_JSON)
179         @ApiOperation(value = "get component audit records", httpMethod = "GET", notes = "get audit records for a service or a resource", response = Response.class)
180         @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") })
181         public Response getComponentAuditRecords(@PathParam("componentType") final String componentType, @PathParam("componentUniqueId") final String componentUniqueId, @Context final HttpServletRequest request,
182                         @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
183                 init(log);
184                 ServletContext context = request.getSession().getServletContext();
185                 String url = request.getMethod() + " " + request.getRequestURI();
186                 log.debug("Start handle request of {}", url);
187
188                 User modifier = new User();
189                 modifier.setUserId(userId);
190                 log.debug("modifier id is {}", userId);
191                 Wrapper<Response> responseWrapper = new Wrapper<Response>();
192                 Wrapper<String> uuidWrapper = new Wrapper<>();
193                 Wrapper<String> versionWrapper = new Wrapper<>();
194                 Wrapper<User> userWrapper = new Wrapper<>();
195                 Wrapper<ComponentTypeEnum> componentWrapper = new Wrapper<ComponentTypeEnum>();
196                 try {
197                         validateUserExist(responseWrapper, userWrapper, userId);
198
199                         if (responseWrapper.isEmpty()) {
200                                 validateComponentType(responseWrapper, componentWrapper, componentType);
201                         }
202
203                         if (responseWrapper.isEmpty()) {
204                                 fillUUIDAndVersion(responseWrapper, uuidWrapper, versionWrapper, userWrapper.getInnerElement(), componentWrapper.getInnerElement(), componentUniqueId, context);
205                         }
206
207                         if (responseWrapper.isEmpty()) {
208                                 Either<List<Map<String, Object>>, ResponseFormat> eitherServiceAudit = getServiceBL(context).getComponentAuditRecords(versionWrapper.getInnerElement(), uuidWrapper.getInnerElement(), userId);
209
210                                 if (eitherServiceAudit.isRight()) {
211                                         Response errorResponse = buildErrorResponse(eitherServiceAudit.right().value());
212                                         responseWrapper.setInnerElement(errorResponse);
213                                 } else {
214                                         List<Map<String, Object>> auditRecords = eitherServiceAudit.left().value();
215                                         Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), auditRecords);
216                                         responseWrapper.setInnerElement(okResponse);
217
218                                 }
219                         }
220
221                 } catch (Exception e) {
222                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name");
223                         log.debug("get Service Audit Records failed with exception", e);
224                         Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
225                         responseWrapper.setInnerElement(errorResponse);
226                 }
227                 return responseWrapper.getInnerElement();
228         }
229
230         private void fillUUIDAndVersion(Wrapper<Response> responseWrapper, Wrapper<String> uuidWrapper, Wrapper<String> versionWrapper, User user, final ComponentTypeEnum componentTypeEnum, final String componentUniqueId, ServletContext context) {
231
232                 if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
233                         Either<Resource, ResponseFormat> eitherResource = getResourceBL(context).getResource(componentUniqueId, user);
234                         if (eitherResource.isLeft()) {
235                                 uuidWrapper.setInnerElement(eitherResource.left().value().getUUID());
236                                 versionWrapper.setInnerElement(eitherResource.left().value().getVersion());
237                         } else {
238                                 responseWrapper.setInnerElement(buildErrorResponse(eitherResource.right().value()));
239                         }
240
241                 } else {
242                         Either<Service, ResponseFormat> eitherService = getServiceBL(context).getService(componentUniqueId, user);
243                         if (eitherService.isLeft()) {
244                                 uuidWrapper.setInnerElement(eitherService.left().value().getUUID());
245                                 versionWrapper.setInnerElement(eitherService.left().value().getVersion());
246                         } else {
247                                 responseWrapper.setInnerElement(buildErrorResponse(eitherService.right().value()));
248
249                         }
250                 }
251         }
252
253         @DELETE
254         @Path("/services/{serviceId}")
255         public Response deleteService(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request) {
256                 ServletContext context = request.getSession().getServletContext();
257                 String url = request.getMethod() + " " + request.getRequestURI();
258                 log.debug("Start handle request of {}", url);
259
260                 // get modifier id
261                 String userId = request.getHeader(Constants.USER_ID_HEADER);
262                 User modifier = new User();
263                 modifier.setUserId(userId);
264                 log.debug("modifier id is {}", userId);
265
266                 Response response = null;
267
268                 try {
269                         String serviceIdLower = serviceId.toLowerCase();
270                         ServiceBusinessLogic businessLogic = getServiceBL(context);
271                         ResponseFormat actionResponse = businessLogic.deleteService(serviceIdLower, modifier);
272
273                         if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
274                                 log.debug("failed to delete service");
275                                 response = buildErrorResponse(actionResponse);
276                                 return response;
277                         }
278                         response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
279                         return response;
280
281                 } catch (Exception e) {
282                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service");
283                         log.debug("delete service failed with exception", e);
284                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
285                         return response;
286
287                 }
288         }
289
290         @DELETE
291         @Path("/services/{serviceName}/{version}")
292         public Response deleteServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("version") final String version, @Context final HttpServletRequest request) {
293                 ServletContext context = request.getSession().getServletContext();
294                 String url = request.getMethod() + " " + request.getRequestURI();
295                 log.debug("Start handle request of {}", url);
296
297                 // get modifier id
298                 String userId = request.getHeader(Constants.USER_ID_HEADER);
299                 User modifier = new User();
300                 modifier.setUserId(userId);
301                 log.debug("modifier id is {}", userId);
302
303                 Response response = null;
304
305                 try {
306                         ServiceBusinessLogic businessLogic = getServiceBL(context);
307                         ResponseFormat actionResponse = businessLogic.deleteServiceByNameAndVersion(serviceName, version, modifier);
308
309                         if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
310                                 log.debug("failed to delete service");
311                                 response = buildErrorResponse(actionResponse);
312                                 return response;
313                         }
314                         response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
315                         return response;
316
317                 } catch (Exception e) {
318                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service");
319                         log.debug("delete service failed with exception", e);
320                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
321                         return response;
322
323                 }
324         }
325
326         @PUT
327         @Path("/services/{serviceId}/metadata")
328         @Consumes(MediaType.APPLICATION_JSON)
329         @Produces(MediaType.APPLICATION_JSON)
330         @ApiOperation(value = "Update Service Metadata", httpMethod = "PUT", notes = "Returns updated service", response = Service.class)
331         @ApiResponses(value = { @ApiResponse(code = 200, message = "Service Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
332         public Response updateServiceMetadata(@PathParam("serviceId") final String serviceId, @ApiParam(value = "Service object to be Updated", required = true) String data, @Context final HttpServletRequest request,
333                         @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
334
335                 ServletContext context = request.getSession().getServletContext();
336                 String url = request.getMethod() + " " + request.getRequestURI();
337                 log.debug("Start handle request of {}", url);
338
339                 User modifier = new User();
340                 modifier.setUserId(userId);
341                 log.debug("modifier id is {}", userId);
342
343                 Response response = null;
344
345                 try {
346                         String serviceIdLower = serviceId.toLowerCase();
347                         ServiceBusinessLogic businessLogic = getServiceBL(context);
348
349                         Either<Service, ResponseFormat> convertResponse = parseToService(data, modifier);
350                         if (convertResponse.isRight()) {
351                                 log.debug("failed to parse service");
352                                 response = buildErrorResponse(convertResponse.right().value());
353                                 return response;
354                         }
355                         Service updatedService = convertResponse.left().value();
356                         Either<Service, ResponseFormat> actionResponse = businessLogic.updateServiceMetadata(serviceIdLower, updatedService, modifier);
357
358                         if (actionResponse.isRight()) {
359                                 log.debug("failed to update service");
360                                 response = buildErrorResponse(actionResponse.right().value());
361                                 return response;
362                         }
363
364                         Service service = actionResponse.left().value();
365                         Object result = RepresentationUtils.toRepresentation(service);
366                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
367
368                 } catch (Exception e) {
369                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata");
370                         log.debug("update service metadata failed with exception", e);
371                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
372                         return response;
373
374                 }
375         }
376         /**
377          * updates group instance property values
378          * Note, than in case of group instance updated successfully, related resourceInstance and containing component modification time will be updated
379          * @param serviceId
380          * @param componentInstanceId
381          * @param groupInstanceId
382          * @param data
383          * @param request
384          * @param userId
385          * @return
386          */
387         @PUT
388         @Path("/{containerComponentType}/{serviceId}/resourceInstance/{componentInstanceId}/groupInstance/{groupInstanceId}")
389         @Consumes(MediaType.APPLICATION_JSON)
390         @Produces(MediaType.APPLICATION_JSON)
391         @ApiOperation(value = "Update Group Instance Property Values", httpMethod = "PUT", notes = "Returns updated group instance", response = Service.class)
392         @ApiResponses(value = { @ApiResponse(code = 200, message = "Group Instance Property Values Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
393         public Response updateGroupInstancePropertyValues(@PathParam("serviceId") final String serviceId,@PathParam("componentInstanceId") final String componentInstanceId, @PathParam("groupInstanceId") final String groupInstanceId, @ApiParam(value = "Group instance object to be Updated", required = true) String data, @Context final HttpServletRequest request,
394                         @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
395
396                 Response response = null;
397                 ServletContext context = request.getSession().getServletContext();
398                 String url = request.getMethod() + " " + request.getRequestURI();
399                 log.debug("Start handle request of {}", url);
400                 
401                 User modifier = new User();
402                 modifier.setUserId(userId);
403                 log.debug("modifier id is {}",userId);
404                 
405                 ServiceBusinessLogic businessLogic;
406                 Either<List<GroupInstanceProperty>, ResponseFormat> actionResponse = null;
407                 try {
408                         List<GroupInstanceProperty> updatedProperties;
409                         Type listType = new TypeToken<ArrayList<GroupInstanceProperty>>(){}.getType();
410                         ArrayList<GroupInstanceProperty> newProperties = gson.fromJson(data, listType);
411                         if (newProperties == null) {
412                                 actionResponse = Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
413                         }
414                         if(actionResponse == null){
415                                 log.debug("Start handle update group instance property values request. Received group instance is {}", groupInstanceId);
416                                 businessLogic = getServiceBL(context);
417                                 actionResponse = businessLogic.updateGroupInstancePropertyValues(modifier, serviceId, componentInstanceId, groupInstanceId, newProperties);
418                                 if(actionResponse.isRight()){
419                                         actionResponse = Either.right(actionResponse.right().value());
420                                 }
421                         }
422                         if(actionResponse.isLeft()){
423                                 updatedProperties = actionResponse.left().value();
424                                 ObjectMapper mapper = new ObjectMapper();
425                                 String result = mapper.writeValueAsString(updatedProperties);
426                                 response =  buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
427                         }
428                         else{
429                                 response = buildErrorResponse(actionResponse.right().value());
430                         }
431                 } catch (Exception e) {
432                         log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
433                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
434                 }
435                 return response;
436         }
437
438         @GET
439         @Path("/services/{serviceId}")
440         @Consumes(MediaType.APPLICATION_JSON)
441         @Produces(MediaType.APPLICATION_JSON)
442         @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns service according to serviceId", response = Service.class)
443         @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") })
444         public Response getServiceById(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
445
446                 ServletContext context = request.getSession().getServletContext();
447                 String url = request.getMethod() + " " + request.getRequestURI();
448                 log.debug("Start handle request of {}", url);
449
450                 // get modifier id
451                 User modifier = new User();
452                 modifier.setUserId(userId);
453                 log.debug("modifier id is {}", userId);
454
455                 Response response = null;
456                 try {
457                         String serviceIdLower = serviceId.toLowerCase();
458                         ServiceBusinessLogic businessLogic = getServiceBL(context);
459                         log.debug("get service with id {}", serviceId);
460                         Either<Service, ResponseFormat> actionResponse = businessLogic.getService(serviceIdLower, modifier);
461
462                         if (actionResponse.isRight()) {
463                                 log.debug("failed to get service");
464                                 response = buildErrorResponse(actionResponse.right().value());
465                                 return response;
466                         }
467
468                         Service service = actionResponse.left().value();
469                         Object result = RepresentationUtils.toRepresentation(service);
470
471                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
472
473                 } catch (Exception e) {
474                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service");
475                         log.debug("get service failed with exception", e);
476                         return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
477
478                 }
479         }
480
481         @GET
482         @Path("/services/serviceName/{serviceName}/serviceVersion/{serviceVersion}")
483         @Consumes(MediaType.APPLICATION_JSON)
484         @Produces(MediaType.APPLICATION_JSON)
485         @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns service according to name and version", response = Service.class)
486         @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") })
487         public Response getServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion, @Context final HttpServletRequest request,
488                         @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
489
490                 ServletContext context = request.getSession().getServletContext();
491                 // get modifier id
492                 User modifier = new User();
493                 modifier.setUserId(userId);
494                 log.debug("modifier id is {}", userId);
495
496                 Response response = null;
497                 try {
498                         ServiceBusinessLogic businessLogic = getServiceBL(context);
499                         Either<Service, ResponseFormat> actionResponse = businessLogic.getServiceByNameAndVersion(serviceName, serviceVersion, userId);
500
501                         if (actionResponse.isRight()) {
502                                 response = buildErrorResponse(actionResponse.right().value());
503                                 return response;
504                         }
505
506                         Service service = actionResponse.left().value();
507                         Object result = RepresentationUtils.toRepresentation(service);
508
509                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
510
511                 } catch (Exception e) {
512                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service by name and version");
513                         log.debug("get service failed with exception", e);
514                         return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
515
516                 }
517         }
518
519         @POST
520         @Path("/services/{serviceId}/distribution-state/{state}")
521         @Consumes(MediaType.APPLICATION_JSON)
522         @Produces(MediaType.APPLICATION_JSON)
523         @ApiOperation(value = "Update Service Distribution State", httpMethod = "POST", notes = "service with the changed distribution status")
524         @ApiResponses(value = { @ApiResponse(code = 200, message = "Service distribution state changed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 403, message = "Service is not available for distribution"),
525                         @ApiResponse(code = 400, message = "Invalid content / Missing content"), @ApiResponse(code = 404, message = "Requested service was not found"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") })
526         public Response updateServiceDistributionState(@ApiParam(value = "DistributionChangeInfo - get comment out of body", required = true) LifecycleChangeInfoWithAction jsonChangeInfo, @PathParam("serviceId") final String serviceId,
527                         @ApiParam(allowableValues = "approve, reject", required = true) @PathParam("state") final String state, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
528
529                 ServletContext context = request.getSession().getServletContext();
530                 String url = request.getMethod() + " " + request.getRequestURI();
531                 log.debug("Start handle request of {}", url);
532
533                 User modifier = new User();
534                 modifier.setUserId(userId);
535                 log.debug("modifier id is {}", userId);
536
537                 Response response = null;
538                 try {
539                         ServiceBusinessLogic businessLogic = getServiceBL(context);
540                         Either<Service, ResponseFormat> actionResponse = businessLogic.changeServiceDistributionState(serviceId, state, jsonChangeInfo, modifier);
541
542                         if (actionResponse.isRight()) {
543                                 log.debug("failed to Update Service Distribution State");
544                                 response = buildErrorResponse(actionResponse.right().value());
545                                 return response;
546                         }
547                         Service service = actionResponse.left().value();
548                         Object result = RepresentationUtils.toRepresentation(service);
549
550                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
551                 } catch (Exception e) {
552                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Distribution State");
553                         log.debug("updateServiceDistributionState failed with exception", e);
554                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
555                         return response;
556                 }
557         }
558
559         @POST
560         @Path("/services/{serviceId}/distribution/{env}/activate")
561         @Consumes(MediaType.APPLICATION_JSON)
562         @Produces(MediaType.APPLICATION_JSON)
563         @ApiOperation(value = "Activate distribution", httpMethod = "POST", notes = "activate distribution")
564         @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 409, message = "Service cannot be distributed due to missing deployment artifacts"), @ApiResponse(code = 404, message = "Requested service was not found"),
565                         @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") })
566         public Response activateDistribution(@PathParam("serviceId") final String serviceId, @PathParam("env") final String env, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
567
568                 ServletContext context = request.getSession().getServletContext();
569                 String url = request.getMethod() + " " + request.getRequestURI();
570                 log.debug("Start handle request of {}", url);
571
572                 User modifier = new User();
573                 modifier.setUserId(userId);
574                 log.debug("modifier id is {}", userId);
575
576                 Response response = null;
577                 try {
578                         ServiceBusinessLogic businessLogic = getServiceBL(context);
579                         Either<Service, ResponseFormat> distResponse = businessLogic.activateDistribution(serviceId, env, modifier, request);
580
581                         if (distResponse.isRight()) {
582                                 log.debug("failed to activate service distribution");
583                                 response = buildErrorResponse(distResponse.right().value());
584                                 return response;
585                         }
586                         Service service = distResponse.left().value();
587                         Object result = RepresentationUtils.toRepresentation(service);
588                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
589                 } catch (Exception e) {
590                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Activate Distribution");
591                         log.debug("activate distribution failed with exception", e);
592                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
593                         return response;
594                 }
595         }
596
597         @POST
598         @Path("/services/{serviceId}/distribution/{did}/markDeployed")
599         @Consumes(MediaType.APPLICATION_JSON)
600         @Produces(MediaType.APPLICATION_JSON)
601         @ApiOperation(value = "Mark distribution as deployed", httpMethod = "POST", notes = "relevant audit record will be created")
602         @ApiResponses(value = { @ApiResponse(code = 200, message = "Service was marked as deployed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 403, message = "Service is not available"),
603                         @ApiResponse(code = 400, message = "Invalid content / Missing content"), @ApiResponse(code = 404, message = "Requested service was not found"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") })
604         public Response markDistributionAsDeployed(@PathParam("serviceId") final String serviceId, @PathParam("did") final String did, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
605
606                 ServletContext context = request.getSession().getServletContext();
607                 String url = request.getMethod() + " " + request.getRequestURI();
608                 log.debug("Start handle request of {}", url);
609
610                 User modifier = new User();
611                 modifier.setUserId(userId);
612                 log.debug("modifier id is {}", userId);
613
614                 Response response = null;
615                 try {
616                         ServiceBusinessLogic businessLogic = getServiceBL(context);
617                         Either<Service, ResponseFormat> distResponse = businessLogic.markDistributionAsDeployed(serviceId, did, modifier);
618
619                         if (distResponse.isRight()) {
620                                 log.debug("failed to mark distribution as deployed");
621                                 response = buildErrorResponse(distResponse.right().value());
622                                 return response;
623                         }
624                         Service service = distResponse.left().value();
625                         Object result = RepresentationUtils.toRepresentation(service);
626                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
627                 } catch (Exception e) {
628                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Mark Distribution As Deployed");
629                         log.debug("mark distribution as deployed failed with exception", e);
630                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
631                         return response;
632                 }
633         }
634
635         @POST
636         @Path("/services/{serviceId}/tempUrlToBeDeleted")
637         @Consumes(MediaType.APPLICATION_JSON)
638         @Produces(MediaType.APPLICATION_JSON)
639         @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") })
640         public Response tempUrlToBeDeleted(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
641
642                 ServletContext context = request.getSession().getServletContext();
643                 String url = request.getMethod() + " " + request.getRequestURI();
644                 log.debug("Start handle request of {}", url);
645
646                 User modifier = new User();
647                 modifier.setUserId(userId);
648                 log.debug("modifier id is {}", userId);
649
650                 Response response = null;
651                 try {
652                         ServiceBusinessLogic businessLogic = getServiceBL(context);
653                         Service service = (businessLogic.getService(serviceId, modifier)).left().value();
654                         Either<Service, ResponseFormat> res = (businessLogic.updateDistributionStatusForActivation(service, modifier, DistributionStatusEnum.DISTRIBUTED));
655
656                         if (res.isRight()) {
657                                 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
658                         }
659                         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null);
660                 } catch (Exception e) {
661                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("tempUrlToBeDeleted");
662                         log.debug("failed with exception", e);
663                         response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
664                         return response;
665                 }
666         }
667
668         @GET
669         @Path("/services/toscatoheat/{artifactName}")
670         @Consumes(MediaType.APPLICATION_JSON)
671         @Produces(MediaType.APPLICATION_OCTET_STREAM)
672         @ApiOperation(value = "Download service artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class)
673         @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"),
674                         @ApiResponse(code = 404, message = "Artifact not found") })
675         public Response downloadServiceArtifact(@PathParam("artifactName") final String artifactName, @Context final HttpServletRequest request) {
676                 Response response = null;
677
678                 try {
679                         log.debug("artifact name = {}", artifactName);
680
681                         Either<byte[], ResponseFormat> executeCommand = executeCommand(artifactName);
682
683                         if (executeCommand.isRight()) {
684                                 log.debug("Failed to convert tosca {} to heat", artifactName);
685                                 ResponseFormat responseFormat = executeCommand.right().value();
686                                 response = buildErrorResponse(responseFormat);
687                         } else {
688                                 log.debug("Succeed to convert tosca {} to heat", artifactName);
689                                 byte[] value = executeCommand.left().value();
690                                 InputStream is = new ByteArrayInputStream(value);
691
692                                 Map<String, String> headers = new HashMap<>();
693                                 String heatFileName;
694                                 if (artifactName.indexOf(".") > -1) {
695                                         heatFileName = artifactName.substring(0, artifactName.indexOf(".")) + ".heat";
696                                 } else {
697                                         heatFileName = artifactName + ".heat";
698                                 }
699                                 headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(heatFileName));
700                                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
701                                 response = buildOkResponse(responseFormat, is, headers);
702                         }
703                         return response;
704
705                 } catch (Exception e) {
706                         log.error("download artifact failed with exception", e);
707                         return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
708                 }
709         }
710
711         private Either<byte[], ResponseFormat> executeCommand(String artifactName) {
712
713                 Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
714                 String toscaFilesDir = configuration.getToscaFilesDir();
715                 if (toscaFilesDir == null) {
716                         toscaFilesDir = "/apps/jetty/base/be/config/tosca";
717                 }
718                 String heatTranslator = configuration.getHeatTranslatorPath();
719                 if (heatTranslator == null) {
720                         heatTranslator = "/home/m98835/heat-translator-0.3.0/heat_translator.py";
721                 }
722
723                 log.debug("toscaFilesDir= {} | heatTranslator= {}", toscaFilesDir, heatTranslator);
724
725                 StringBuffer output = new StringBuffer();
726
727                 String heatHeader = configuration.getHeatEnvArtifactHeader();
728                 String heatFooter = configuration.getHeatEnvArtifactFooter();
729
730                 output.append(heatHeader + "\n");
731
732                 MessageFormat mf = new MessageFormat("python {0} --template-file={1}/{2} --template-type=tosca");
733
734                 log.debug("After creating message format");
735
736                 Object[] objArray = { heatTranslator, toscaFilesDir, artifactName };
737                 String command = null;
738                 try {
739                         command = mf.format(objArray);
740                 } catch (Exception e) {
741                         log.debug("Failed to convert message format", e);
742                 }
743
744                 log.debug("Going to run command {}", command);
745
746                 Process p;
747                 try {
748                         p = Runtime.getRuntime().exec(command);
749                         int waitFor = p.waitFor();
750                         log.debug("waitFor = {}", waitFor);
751
752                         if (waitFor != 0) {
753                                 log.error("Failed runnign the command {}", command);
754                                 return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
755                         }
756
757                         BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
758
759                         String line;
760                         while ((line = reader.readLine()) != null) {
761                                 output.append(line + "\n");
762                         }
763
764                 } catch (Exception e) {
765                         log.error("Failed runnign the command {}", command, e);
766                         e.printStackTrace();
767                         return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
768                 }
769
770                 output.append(heatFooter);
771
772                 return Either.left(output.toString().getBytes());
773
774         }
775
776 }