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