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