12f803fd1942c6571e6d480632cd3a57ede000c7
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / servlets / ModelServletTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19 package org.openecomp.sdc.be.servlets;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.eq;
24 import static org.mockito.Mockito.doThrow;
25 import static org.mockito.Mockito.when;
26
27 import com.fasterxml.jackson.core.JsonProcessingException;
28 import com.fasterxml.jackson.databind.ObjectMapper;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.nio.file.Path;
32 import java.util.List;
33 import javax.servlet.ServletContext;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpSession;
36 import javax.ws.rs.client.Entity;
37 import javax.ws.rs.core.HttpHeaders;
38 import javax.ws.rs.core.MediaType;
39 import javax.ws.rs.core.Response.Status;
40 import org.apache.commons.lang3.StringUtils;
41 import org.eclipse.jetty.http.HttpStatus;
42 import org.glassfish.hk2.utilities.binding.AbstractBinder;
43 import org.glassfish.jersey.client.ClientConfig;
44 import org.glassfish.jersey.media.multipart.FormDataMultiPart;
45 import org.glassfish.jersey.media.multipart.MultiPartFeature;
46 import org.glassfish.jersey.server.ResourceConfig;
47 import org.glassfish.jersey.test.JerseyTest;
48 import org.glassfish.jersey.test.TestProperties;
49 import org.junit.jupiter.api.AfterEach;
50 import org.junit.jupiter.api.BeforeEach;
51 import org.junit.jupiter.api.Test;
52 import org.mockito.InjectMocks;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
56 import org.openecomp.sdc.be.components.impl.ModelBusinessLogic;
57 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
58 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
59 import org.openecomp.sdc.be.components.validation.UserValidations;
60 import org.openecomp.sdc.be.config.ConfigurationManager;
61 import org.openecomp.sdc.be.config.SpringConfig;
62 import org.openecomp.sdc.be.dao.api.ActionStatus;
63 import org.openecomp.sdc.be.exception.BusinessException;
64 import org.openecomp.sdc.be.impl.ComponentsUtils;
65 import org.openecomp.sdc.be.impl.ServletUtils;
66 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
67 import org.openecomp.sdc.be.model.Model;
68 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
69 import org.openecomp.sdc.be.servlets.builder.ServletResponseBuilder;
70 import org.openecomp.sdc.be.servlets.exception.OperationExceptionMapper;
71 import org.openecomp.sdc.be.ui.model.ModelCreateRequest;
72 import org.openecomp.sdc.be.user.UserBusinessLogic;
73 import org.openecomp.sdc.common.api.ConfigurationSource;
74 import org.openecomp.sdc.common.api.Constants;
75 import org.openecomp.sdc.common.impl.ExternalConfiguration;
76 import org.openecomp.sdc.common.impl.FSConfigurationSource;
77 import org.openecomp.sdc.exception.ResponseFormat;
78 import org.springframework.context.ApplicationContext;
79 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
80 import org.springframework.web.context.WebApplicationContext;
81
82 class ModelServletTest extends JerseyTest {
83
84     private static final String USER_ID = "cs0008";
85
86     @Mock
87     private HttpServletRequest request;
88     @Mock
89     private HttpSession session;
90     @Mock
91     private ServletContext servletContext;
92     @Mock
93     private WebAppContextWrapper webAppContextWrapper;
94     @Mock
95     private WebApplicationContext webApplicationContext;
96     @Mock
97     private UserBusinessLogic userBusinessLogic;
98     @Mock
99     private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
100     @Mock
101     private ComponentsUtils componentsUtils;
102     @Mock
103     private ServletUtils servletUtils;
104     @Mock
105     private ResourceImportManager resourceImportManager;
106     @Mock
107     private ModelBusinessLogic modelBusinessLogic;
108     @InjectMocks
109     private ModelServlet modelServlet;
110     @Mock
111     private ResponseFormat responseFormat;
112     @Mock
113     private UserValidations userValidations;
114
115     @Mock
116     private ResponseFormatManager responseFormatManager;
117
118     private Model model;
119     private ModelCreateRequest modelCreateRequest;
120     private final Path rootPath = Path.of("/v1/catalog/model");
121     private final Path importsPath = rootPath.resolve("imports");
122
123     @BeforeEach
124     void resetMock() throws Exception {
125         super.setUp();
126         initMocks();
127         initConfig();
128         initTestData();
129     }
130
131     @AfterEach
132     void after() throws Exception {
133         super.tearDown();
134     }
135
136     private void initMocks() {
137         when(request.getSession()).thenReturn(session);
138         when(session.getServletContext()).thenReturn(servletContext);
139         when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR))
140             .thenReturn(webAppContextWrapper);
141         when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
142         when(webApplicationContext.getBean(ModelBusinessLogic.class)).thenReturn(modelBusinessLogic);
143         when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(USER_ID);
144         when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
145         when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils);
146     }
147
148     private void initConfig() {
149         final String appConfigDir = "src/test/resources/config/catalog-be";
150         final ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
151         final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
152         final org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration();
153         configuration.setJanusGraphInMemoryGraph(true);
154         configurationManager.setConfiguration(configuration);
155         ExternalConfiguration.setAppName("catalog-be");
156     }
157
158     private void initTestData() {
159         final String modelName = "MY-INTEGRATION-TEST-MODEL";
160         model = new Model(modelName);
161         modelCreateRequest = new ModelCreateRequest();
162         modelCreateRequest.setName(modelName);
163     }
164
165     @Override
166     protected ResourceConfig configure() {
167         MockitoAnnotations.openMocks(this);
168         forceSet(TestProperties.CONTAINER_PORT, "0");
169         final ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
170         return new ResourceConfig(ModelServlet.class)
171             .register(new AbstractBinder() {
172                 @Override
173                 protected void configure() {
174                     bind(request).to(HttpServletRequest.class);
175                     bind(userBusinessLogic).to(UserBusinessLogic.class);
176                     bind(componentInstanceBusinessLogic).to(ComponentInstanceBusinessLogic.class);
177                     bind(componentsUtils).to(ComponentsUtils.class);
178                     bind(servletUtils).to(ServletUtils.class);
179                     bind(resourceImportManager).to(ResourceImportManager.class);
180                     bind(modelBusinessLogic).to(ModelBusinessLogic.class);
181                     bind(userValidations).to(UserValidations.class);
182                 }
183             })
184             .register(new OperationExceptionMapper(new ServletResponseBuilder(), responseFormatManager))
185             .register(MultiPartFeature.class)
186             .property("contextConfig", context);
187     }
188
189     @Override
190     protected void configureClient(final ClientConfig config) {
191         config.register(MultiPartFeature.class);
192     }
193
194     @Test
195     void createModelSuccessTest() throws JsonProcessingException {
196         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
197         when(componentsUtils.getResponseFormat(ActionStatus.CREATED)).thenReturn(responseFormat);
198         when(modelBusinessLogic.createModel(any(Model.class))).thenReturn(model);
199         final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
200         final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
201             .header(Constants.USER_ID_HEADER, USER_ID)
202             .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
203         assertEquals(Status.OK.getStatusCode(), response.getStatus());
204     }
205
206     @Test
207     void createModelFailTest() throws JsonProcessingException {
208         when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
209         when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
210         when(modelBusinessLogic.createModel(any(Model.class))).thenReturn(model);
211         final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
212         final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
213             .header(Constants.USER_ID_HEADER, USER_ID)
214             .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
215         assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
216     }
217
218     @Test
219     void createModelFailWithModelNameEmptyTest() throws JsonProcessingException {
220         when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
221         when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
222         modelCreateRequest.setName(StringUtils.EMPTY);
223         final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
224         final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
225             .header(Constants.USER_ID_HEADER, USER_ID)
226             .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
227         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
228     }
229
230     @Test
231     void createModelFailWithModelNameNullTest() throws JsonProcessingException {
232         when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
233         when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
234         modelCreateRequest.setName(null);
235         final var modelFile = new byte[0];
236         final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(modelFile, parseToJsonString(modelCreateRequest));
237         final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
238             .header(Constants.USER_ID_HEADER, USER_ID)
239             .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
240         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
241     }
242
243     @Test
244     void createModelThrowsBusinessExceptionTest() throws JsonProcessingException {
245         final var modelFile = new byte[0];
246         final String modelCreateAsJson = parseToJsonString(modelCreateRequest);
247         final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(modelFile, modelCreateAsJson);
248         when(modelBusinessLogic.createModel(model)).thenThrow(new BusinessException() {});
249
250         final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
251             .header(Constants.USER_ID_HEADER, USER_ID)
252             .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
253         assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
254     }
255
256     @Test
257     void updateModelImportsSuccessTest() {
258         final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart("model1", new byte[0]);
259
260         final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
261             .header(Constants.USER_ID_HEADER, USER_ID)
262             .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
263         assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
264     }
265
266     @Test
267     void updateModelImports_businessException() {
268         final var modelId = "model1";
269         final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart(modelId, new byte[0]);
270         final OperationException operationException = new OperationException(ActionStatus.INVALID_MODEL, modelId);
271         doThrow(operationException).when(modelBusinessLogic).createModelImports(eq(modelId), any(InputStream.class));
272         when(responseFormatManager.getResponseFormat(ActionStatus.INVALID_MODEL, modelId))
273             .thenReturn(new ResponseFormat(Status.BAD_REQUEST.getStatusCode()));
274         final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
275             .header(Constants.USER_ID_HEADER, USER_ID)
276             .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
277         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
278     }
279
280     @Test
281     void updateModelImports_unknownException() {
282         final var modelName = "model1";
283         final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart(modelName, new byte[0]);
284         doThrow(new RuntimeException()).when(modelBusinessLogic).createModelImports(eq(modelName), any(InputStream.class));
285         when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
286         when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
287         final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
288             .header(Constants.USER_ID_HEADER, USER_ID)
289             .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
290         assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
291     }
292
293     @Test
294     void listModelSuccessTest() throws IOException {
295         var model1 = new Model("model1");
296         var model2 = new Model("model2");
297         var model3 = new Model("model3");
298         final List<Model> modelList = List.of(model1, model2, model3);
299         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
300         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
301         when(modelBusinessLogic.listModels()).thenReturn(modelList);
302
303         final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
304             .header(Constants.USER_ID_HEADER, USER_ID)
305             .get();
306
307         assertEquals(Status.OK.getStatusCode(), response.getStatus());
308         assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
309         final String responseBody = response.readEntity(String.class);
310         final String toRepresentation = (String) RepresentationUtils.toRepresentation(modelList);
311         assertEquals(toRepresentation, responseBody);
312     }
313
314     @Test
315     void listModelErrorTest() {
316         when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
317         when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
318         doThrow(new RuntimeException()).when(modelBusinessLogic).listModels();
319
320         final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
321             .header(Constants.USER_ID_HEADER, USER_ID)
322             .get();
323
324         assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
325     }
326
327     private FormDataMultiPart buildUpdateFormDataMultiPart(final String modelName, final byte[] importFilesZip) {
328         return new FormDataMultiPart()
329             .field("modelName", modelName)
330             .field("modelImportsZip", importFilesZip, MediaType.MULTIPART_FORM_DATA_TYPE);
331     }
332
333     private FormDataMultiPart buildCreateFormDataMultiPart(final byte[] modelFile, final String modelCreateAsJson) {
334         return new FormDataMultiPart()
335             .field("model", modelCreateAsJson, MediaType.APPLICATION_JSON_TYPE)
336             .field("modelImportsZip", modelFile, MediaType.MULTIPART_FORM_DATA_TYPE);
337     }
338
339     private String parseToJsonString(final Object object) throws JsonProcessingException {
340         return new ObjectMapper().writeValueAsString(object);
341     }
342
343 }