Initial OpenECOMP SDC commit
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / AttributeServlet.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 javax.inject.Singleton;
24 import javax.servlet.ServletContext;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.ws.rs.Consumes;
27 import javax.ws.rs.DELETE;
28 import javax.ws.rs.HeaderParam;
29 import javax.ws.rs.POST;
30 import javax.ws.rs.PUT;
31 import javax.ws.rs.Path;
32 import javax.ws.rs.PathParam;
33 import javax.ws.rs.Produces;
34 import javax.ws.rs.core.Context;
35 import javax.ws.rs.core.MediaType;
36 import javax.ws.rs.core.Response;
37
38 import org.openecomp.sdc.be.components.impl.AttributeBusinessLogic;
39 import org.openecomp.sdc.be.config.BeEcompErrorManager;
40 import org.openecomp.sdc.be.dao.api.ActionStatus;
41 import org.openecomp.sdc.be.model.AttributeDefinition;
42 import org.openecomp.sdc.be.model.User;
43 import org.openecomp.sdc.common.api.Constants;
44 import org.openecomp.sdc.common.datastructure.Wrapper;
45 import org.openecomp.sdc.exception.ResponseFormat;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 import com.google.gson.Gson;
50 import com.google.gson.GsonBuilder;
51 import com.jcabi.aspects.Loggable;
52 import com.wordnik.swagger.annotations.Api;
53 import com.wordnik.swagger.annotations.ApiOperation;
54 import com.wordnik.swagger.annotations.ApiParam;
55 import com.wordnik.swagger.annotations.ApiResponse;
56 import com.wordnik.swagger.annotations.ApiResponses;
57
58 import fj.data.Either;
59
60 /**
61  * Web Servlet for actions on Attributes
62  * 
63  * @author mshitrit
64  *
65  */
66 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
67 @Path("/v1/catalog")
68 @Api(value = "Resource Attribute Servlet", description = "Resource Attribute Servlet")
69 @Singleton
70 public class AttributeServlet extends AbstractValidationsServlet {
71         private static Logger log = LoggerFactory.getLogger(AttributeServlet.class.getName());
72
73         /**
74          * Creates new Attribute on a resource with given resource ID
75          * 
76          * @param resourceId
77          * @param data
78          * @param request
79          * @param userId
80          * @return
81          */
82         @POST
83         @Path("resources/{resourceId}/attributes")
84         @Consumes(MediaType.APPLICATION_JSON)
85         @Produces(MediaType.APPLICATION_JSON)
86         @ApiOperation(value = "Create Resource Attribute", httpMethod = "POST", notes = "Returns created resource attribute", response = Response.class)
87         @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource property created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
88                         @ApiResponse(code = 409, message = "Resource attribute already exist") })
89         public Response createAttribute(@ApiParam(value = "resource id to update with new attribute", required = true) @PathParam("resourceId") final String resourceId, @ApiParam(value = "Resource attribute to be created", required = true) String data,
90                         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
91
92                 ServletContext context = request.getSession().getServletContext();
93
94                 String url = request.getMethod() + " " + request.getRequestURI();
95                 log.debug("Start handle request of {}", url);
96                 log.debug("modifier id is {}", userId);
97                 log.debug("data is {}", data);
98
99                 try {
100                         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
101                         Wrapper<AttributeDefinition> attributesWrapper = new Wrapper<>();
102                         // convert json to AttributeDefinition
103
104                         buildAttributeFromString(data, attributesWrapper, errorWrapper);
105                         if (errorWrapper.isEmpty()) {
106                                 AttributeBusinessLogic businessLogic = getBusinessLogic(context, () -> AttributeBusinessLogic.class);
107                                 Either<AttributeDefinition, ResponseFormat> createAttribute = businessLogic.createAttribute(resourceId, attributesWrapper.getInnerElement(), userId);
108                                 if (createAttribute.isRight()) {
109                                         errorWrapper.setInnerElement(createAttribute.right().value());
110                                 } else {
111                                         attributesWrapper.setInnerElement(createAttribute.left().value());
112                                 }
113                         }
114
115                         Response response;
116                         if (!errorWrapper.isEmpty()) {
117                                 log.info("Failed to create Attribute. Reason - ", errorWrapper.getInnerElement());
118                                 response = buildErrorResponse(errorWrapper.getInnerElement());
119                         } else {
120                                 AttributeDefinition createdAttDef = attributesWrapper.getInnerElement();
121                                 log.debug("Attribute {} created successfully with id {}", createdAttDef.getName(), createdAttDef.getUniqueId());
122                                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED);
123                                 response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(createdAttDef));
124                         }
125
126                         return response;
127
128                 } catch (Exception e) {
129                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Attribute");
130                         log.debug("create property failed with exception", e);
131                         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
132                         return buildErrorResponse(responseFormat);
133
134                 }
135         }
136
137         /**
138          * Updates existing Attribute with given attributeID on a resource with given resourceID
139          * 
140          * @param resourceId
141          * @param attributeId
142          * @param data
143          * @param request
144          * @param userId
145          * @return
146          */
147         @PUT
148         @Path("resources/{resourceId}/attributes/{attributeId}")
149         @Consumes(MediaType.APPLICATION_JSON)
150         @Produces(MediaType.APPLICATION_JSON)
151         @ApiOperation(value = "Update Resource Attribute", httpMethod = "PUT", notes = "Returns updated attribute", response = Response.class)
152         @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource attribute updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
153         public Response updateAttribute(@ApiParam(value = "resource id to update with new attribute", required = true) @PathParam("resourceId") final String resourceId,
154                         @ApiParam(value = "attribute id to update", required = true) @PathParam("attributeId") final String attributeId, @ApiParam(value = "Resource attribute to update", required = true) String data, @Context final HttpServletRequest request,
155                         @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
156
157                 ServletContext context = request.getSession().getServletContext();
158
159                 String url = request.getMethod() + " " + request.getRequestURI();
160                 log.debug("Start handle request of {}", url);
161
162                 // get modifier id
163                 User modifier = new User();
164                 modifier.setUserId(userId);
165                 log.debug("modifier id is {}", userId);
166
167                 try {
168                         // convert json to PropertyDefinition
169                         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
170                         Wrapper<AttributeDefinition> attributesWrapper = new Wrapper<>();
171                         // convert json to AttributeDefinition
172
173                         buildAttributeFromString(data, attributesWrapper, errorWrapper);
174
175                         if (errorWrapper.isEmpty()) {
176                                 AttributeBusinessLogic businessLogic = getBusinessLogic(context, () -> AttributeBusinessLogic.class);
177                                 Either<AttributeDefinition, ResponseFormat> eitherUpdateAttribute = businessLogic.updateAttribute(resourceId, attributeId, attributesWrapper.getInnerElement(), userId);
178                                 // update property
179                                 if (eitherUpdateAttribute.isRight()) {
180                                         errorWrapper.setInnerElement(eitherUpdateAttribute.right().value());
181                                 } else {
182                                         attributesWrapper.setInnerElement(eitherUpdateAttribute.left().value());
183                                 }
184                         }
185
186                         Response response;
187                         if (!errorWrapper.isEmpty()) {
188                                 log.info("Failed to update Attribute. Reason - ", errorWrapper.getInnerElement());
189                                 response = buildErrorResponse(errorWrapper.getInnerElement());
190                         } else {
191                                 AttributeDefinition updatedAttribute = attributesWrapper.getInnerElement();
192                                 log.debug("Attribute id {} updated successfully ", updatedAttribute.getUniqueId());
193                                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
194                                 response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(updatedAttribute));
195                         }
196
197                         return response;
198
199                 } catch (Exception e) {
200                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Attribute");
201                         log.debug("update attribute failed with exception", e);
202                         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
203                         return buildErrorResponse(responseFormat);
204
205                 }
206         }
207
208         /**
209          * Deletes existing Attribute with given attributeID on a resource with given resourceID
210          * 
211          * @param resourceId
212          * @param attributeId
213          * @param request
214          * @param userId
215          * @return
216          */
217         @DELETE
218         @Path("resources/{resourceId}/attributes/{attributeId}")
219         @Consumes(MediaType.APPLICATION_JSON)
220         @Produces(MediaType.APPLICATION_JSON)
221         @ApiOperation(value = "Create Resource Attribute", httpMethod = "DELETE", notes = "Returns deleted attribute", response = Response.class)
222         @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted attribute"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
223                         @ApiResponse(code = 404, message = "Resource property not found") })
224         public Response deleteAttribute(@ApiParam(value = "resource id of attribute", required = true) @PathParam("resourceId") final String resourceId,
225                         @ApiParam(value = "Attribute id to delete", required = true) @PathParam("attributeId") final String attributeId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
226
227                 ServletContext context = request.getSession().getServletContext();
228
229                 String url = request.getMethod() + " " + request.getRequestURI();
230                 log.debug("Start handle request of {}", url);
231                 log.debug("modifier id is {}", userId);
232
233                 try {
234
235                         // delete the property
236                         AttributeBusinessLogic businessLogic = getBusinessLogic(context, () -> AttributeBusinessLogic.class);
237                         Either<AttributeDefinition, ResponseFormat> eitherAttribute = businessLogic.deleteAttribute(resourceId, attributeId, userId);
238                         if (eitherAttribute.isRight()) {
239                                 log.debug("Failed to delete Attribute. Reason - ", eitherAttribute.right().value());
240                                 return buildErrorResponse(eitherAttribute.right().value());
241                         }
242                         AttributeDefinition attributeDefinition = eitherAttribute.left().value();
243                         String name = attributeDefinition.getName();
244
245                         log.debug("Attribute {} deleted successfully with id {}", name, attributeDefinition.getUniqueId());
246                         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT);
247                         return buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(attributeDefinition));
248
249                 } catch (Exception e) {
250                         BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Attribute");
251                         log.debug("delete attribute failed with exception", e);
252                         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
253                         return buildErrorResponse(responseFormat);
254
255                 }
256         }
257
258         private void buildAttributeFromString(String data, Wrapper<AttributeDefinition> attributesWrapper, Wrapper<ResponseFormat> errorWrapper) {
259
260                 try {
261                         Gson gson = new GsonBuilder().setPrettyPrinting().create();
262                         final AttributeDefinition attribute = gson.fromJson(data, AttributeDefinition.class);
263                         if (attribute == null) {
264                                 log.info("Attribute content is invalid - {}", data);
265                                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
266                                 errorWrapper.setInnerElement(responseFormat);
267                         } else {
268                                 attributesWrapper.setInnerElement(attribute);
269                         }
270
271                 } catch (Exception e) {
272                         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
273                         errorWrapper.setInnerElement(responseFormat);
274                         log.debug("Attribute content is invalid - {}", data, e);
275                         log.info("Attribute content is invalid - {}", data);
276                 }
277         }
278 }