31152c63e752324664351a0ddfeb4741d44170dc
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / servlets / ResourceUploadServletTest.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.assertj.core.api.Assertions.assertThat;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.anyBoolean;
24 import static org.mockito.ArgumentMatchers.anyString;
25 import static org.mockito.Mockito.when;
26
27 import java.io.File;
28 import java.io.FileReader;
29 import java.io.IOException;
30 import java.net.URISyntaxException;
31 import java.net.URL;
32 import java.util.Optional;
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.MediaType;
38 import javax.ws.rs.core.Response;
39 import org.apache.commons.lang3.tuple.ImmutablePair;
40 import org.eclipse.jetty.http.HttpStatus;
41 import org.glassfish.hk2.utilities.binding.AbstractBinder;
42 import org.glassfish.jersey.client.ClientConfig;
43 import org.glassfish.jersey.media.multipart.FormDataMultiPart;
44 import org.glassfish.jersey.media.multipart.MultiPartFeature;
45 import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
46 import org.glassfish.jersey.server.ResourceConfig;
47 import org.glassfish.jersey.test.JerseyTest;
48 import org.glassfish.jersey.test.TestProperties;
49 import org.json.simple.JSONObject;
50 import org.json.simple.parser.JSONParser;
51 import org.json.simple.parser.ParseException;
52 import org.junit.jupiter.api.AfterEach;
53 import org.junit.jupiter.api.BeforeAll;
54 import org.junit.jupiter.api.BeforeEach;
55 import org.junit.jupiter.api.Test;
56 import org.junit.jupiter.api.TestInstance;
57 import org.junit.jupiter.api.TestInstance.Lifecycle;
58 import org.mockito.Mock;
59 import org.mockito.MockitoAnnotations;
60 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
61 import org.openecomp.sdc.be.components.impl.ModelBusinessLogic;
62 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
63 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
64 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
65 import org.openecomp.sdc.be.components.validation.UserValidations;
66 import org.openecomp.sdc.be.config.ConfigurationManager;
67 import org.openecomp.sdc.be.config.SpringConfig;
68 import org.openecomp.sdc.be.dao.api.ActionStatus;
69 import org.openecomp.sdc.be.impl.ComponentsUtils;
70 import org.openecomp.sdc.be.impl.ServletUtils;
71 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
72 import org.openecomp.sdc.be.model.Model;
73 import org.openecomp.sdc.be.model.Resource;
74 import org.openecomp.sdc.be.model.User;
75 import org.openecomp.sdc.be.servlets.builder.ServletResponseBuilder;
76 import org.openecomp.sdc.be.servlets.exception.OperationExceptionMapper;
77 import org.openecomp.sdc.be.user.Role;
78 import org.openecomp.sdc.be.user.UserBusinessLogic;
79 import org.openecomp.sdc.common.api.ConfigurationSource;
80 import org.openecomp.sdc.common.api.Constants;
81 import org.openecomp.sdc.common.impl.ExternalConfiguration;
82 import org.openecomp.sdc.common.impl.FSConfigurationSource;
83 import org.openecomp.sdc.exception.ResponseFormat;
84 import org.springframework.context.ApplicationContext;
85 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
86 import org.springframework.web.context.WebApplicationContext;
87
88 @TestInstance(Lifecycle.PER_CLASS)
89 class ResourceUploadServletTest extends JerseyTest {
90     private static final String USER_ID = "cs0008";
91
92     @Mock
93     private HttpServletRequest request;
94     @Mock
95     private HttpSession session;
96     @Mock
97     private ServletContext servletContext;
98     @Mock
99     private WebAppContextWrapper webAppContextWrapper;
100     @Mock
101     private WebApplicationContext webApplicationContext;
102     @Mock
103     private UserBusinessLogic userBusinessLogic;
104     @Mock
105     private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
106     @Mock
107     private ComponentsUtils componentsUtils;
108     @Mock
109     private ServletUtils servletUtils;
110     @Mock
111     private ResourceImportManager resourceImportManager;
112     @Mock
113     private ResourceBusinessLogic resourceBusinessLogic;
114     @Mock
115     private ResponseFormat responseFormat;
116     @Mock
117     private UserValidations userValidations;
118     @Mock
119     private ModelBusinessLogic modelBusinessLogic;
120     @Mock
121     private ResponseFormatManager responseFormatManager;
122     private final String modelName = "ETSI-SOL001-331";
123
124     private final String rootPath = "/v1/catalog/upload/multipart";
125     private Response response;
126     private User user;
127
128     @BeforeAll
129     public void initClass() {
130         when(request.getSession()).thenReturn(session);
131         when(session.getServletContext()).thenReturn(servletContext);
132         when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR))
133             .thenReturn(webAppContextWrapper);
134         when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
135         when(webApplicationContext.getBean(ModelBusinessLogic.class)).thenReturn(modelBusinessLogic);
136         when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(USER_ID);
137         when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
138         when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils);
139         final String appConfigDir = "src/test/resources/config/catalog-be";
140         final ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
141         final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
142         final org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration();
143         configuration.setJanusGraphInMemoryGraph(true);
144         configurationManager.setConfiguration(configuration);
145         ExternalConfiguration.setAppName("catalog-be");
146     }
147
148     @BeforeEach
149     void resetMock() throws Exception {
150         super.setUp();
151         initTestData();
152     }
153
154     @AfterEach
155     void after() throws Exception {
156         super.tearDown();
157     }
158
159     private void initTestData() {
160         user = new User();
161         user.setUserId(USER_ID);
162         user.setRole(Role.ADMIN.name());
163         when(userBusinessLogic.getUser(USER_ID)).thenReturn(user);
164     }
165
166     @Override
167     protected ResourceConfig configure() {
168         MockitoAnnotations.openMocks(this);
169         forceSet(TestProperties.CONTAINER_PORT, "0");
170         final ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
171         return new ResourceConfig(ResourceUploadServlet.class)
172             .register(new AbstractBinder() {
173                 @Override
174                 protected void configure() {
175                     bind(request).to(HttpServletRequest.class);
176                     bind(userBusinessLogic).to(UserBusinessLogic.class);
177                     bind(componentInstanceBusinessLogic).to(ComponentInstanceBusinessLogic.class);
178                     bind(componentsUtils).to(ComponentsUtils.class);
179                     bind(servletUtils).to(ServletUtils.class);
180                     bind(resourceImportManager).to(ResourceImportManager.class);
181                     bind(resourceBusinessLogic).to(ResourceBusinessLogic.class);
182                     bind(modelBusinessLogic).to(ModelBusinessLogic.class);
183                     bind(userValidations).to(UserValidations.class);
184                 }
185             })
186             .register(new OperationExceptionMapper(new ServletResponseBuilder(), responseFormatManager))
187             .register(MultiPartFeature.class)
188             .property("contextConfig", context);
189     }
190
191     @Override
192     protected void configureClient(final ClientConfig config) {
193         config.register(MultiPartFeature.class);
194     }
195
196     @Test
197     void uploadMultipartWithModelSuccessTest() throws IOException, ParseException, URISyntaxException {
198         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
199         when(componentsUtils.getResponseFormat(ActionStatus.CREATED)).thenReturn(responseFormat);
200         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
201         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
202         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
203         when(resourceImportManager.importNormativeResource(anyString(), any(), any(), anyBoolean(), anyBoolean()))
204             .thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.CREATED));
205         when(modelBusinessLogic.findModel(modelName)).thenReturn(Optional.of(new Model(modelName)));
206         response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
207             .header(Constants.USER_ID_HEADER, USER_ID)
208             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
209                 "src/test/resources/node-types/nodeTypeWithModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
210         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
211     }
212
213     @Test
214     void uploadMultipartWithoutModelsFieldSuccessTest() throws IOException, ParseException, URISyntaxException {
215         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
216         when(componentsUtils.getResponseFormat(ActionStatus.CREATED)).thenReturn(responseFormat);
217         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
218         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
219         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
220         when(resourceImportManager.importNormativeResource(anyString(), any(), any(), anyBoolean(), anyBoolean()))
221             .thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.CREATED));
222         response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
223             .header(Constants.USER_ID_HEADER, USER_ID)
224             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType002.zip",
225                 "src/test/resources/node-types/nodeTypeWithoutModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
226         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
227     }
228
229     @Test
230     void uploadMultipartFailWithEmptyModelsTest() throws IOException, ParseException, URISyntaxException {
231         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
232         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
233         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
234         when(modelBusinessLogic.findModel("")).thenReturn(Optional.empty());
235         response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
236             .header(Constants.USER_ID_HEADER, USER_ID)
237             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType002.zip",
238                 "src/test/resources/node-types/nodeTypeWithEmptyModels.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
239         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
240     }
241
242     @Test
243     void uploadMultipartFailWithModelNotFoundTest() throws IOException, ParseException, URISyntaxException {
244         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
245         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
246         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
247         when(modelBusinessLogic.findModel(modelName)).thenReturn(Optional.empty());
248         response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
249             .header(Constants.USER_ID_HEADER, USER_ID)
250             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
251                 "src/test/resources/node-types/nodeTypeWithModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
252         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
253     }
254
255     @Test
256     void uploadMultipartThrowsBusinessExceptionTest() throws IOException, ParseException, URISyntaxException {
257         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
258         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
259         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
260         response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
261             .header(Constants.USER_ID_HEADER, USER_ID)
262             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
263                 "src/test/resources/node-types/invalid.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
264         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
265     }
266
267     private String getInputData(final String jsonFilename) throws IOException, ParseException {
268         final JSONObject inputData = (JSONObject) new JSONParser().parse(
269             new FileReader(jsonFilename));
270         return inputData.toJSONString();
271     }
272
273     private File getFile(final String fileName) throws URISyntaxException {
274         final URL resource = this.getClass().getClassLoader().getResource(fileName);
275         if (resource == null) {
276             throw new IllegalArgumentException("file not found! " + fileName);
277         }
278         return new File(resource.toURI());
279     }
280
281     private FormDataMultiPart buildFormDataMultiPart(final String zipFilePath, final String inputJsonData)
282         throws IOException, ParseException, URISyntaxException {
283         final FileDataBodyPart filePart = new FileDataBodyPart("resourceZip", getFile(zipFilePath));
284         final FormDataMultiPart multipartEntity = new FormDataMultiPart();
285         multipartEntity.bodyPart(filePart);
286         multipartEntity.field("resourceMetadata", getInputData(inputJsonData));
287         return  multipartEntity;
288     }
289 }