Specify model at service creation
[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 User user;
126
127     @BeforeAll
128     public void initClass() {
129         when(request.getSession()).thenReturn(session);
130         when(session.getServletContext()).thenReturn(servletContext);
131         when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR))
132             .thenReturn(webAppContextWrapper);
133         when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
134         when(webApplicationContext.getBean(ModelBusinessLogic.class)).thenReturn(modelBusinessLogic);
135         when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(USER_ID);
136         when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
137         when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils);
138         final String appConfigDir = "src/test/resources/config/catalog-be";
139         final ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
140         final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
141         final org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration();
142         configuration.setJanusGraphInMemoryGraph(true);
143         configurationManager.setConfiguration(configuration);
144         ExternalConfiguration.setAppName("catalog-be");
145     }
146
147     @BeforeEach
148     void resetMock() throws Exception {
149         super.setUp();
150         initTestData();
151     }
152
153     @AfterEach
154     void after() throws Exception {
155         super.tearDown();
156     }
157
158     private void initTestData() {
159         user = new User();
160         user.setUserId(USER_ID);
161         user.setRole(Role.ADMIN.name());
162         when(userBusinessLogic.getUser(USER_ID)).thenReturn(user);
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(ResourceUploadServlet.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(resourceBusinessLogic).to(ResourceBusinessLogic.class);
181                     bind(modelBusinessLogic).to(ModelBusinessLogic.class);
182                     bind(userValidations).to(UserValidations.class);
183                 }
184             })
185             .register(new OperationExceptionMapper(new ServletResponseBuilder(), responseFormatManager))
186             .register(MultiPartFeature.class)
187             .property("contextConfig", context);
188     }
189
190     @Override
191     protected void configureClient(final ClientConfig config) {
192         config.register(MultiPartFeature.class);
193     }
194
195     @Test
196     void uploadMultipartWithModelSuccessTest() throws IOException, ParseException, URISyntaxException {
197         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
198         when(componentsUtils.getResponseFormat(ActionStatus.CREATED)).thenReturn(responseFormat);
199         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
200         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
201         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
202         when(resourceImportManager.importNormativeResource(anyString(), any(), any(), anyBoolean(), anyBoolean()))
203             .thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.CREATED));
204         when(modelBusinessLogic.findModel(modelName)).thenReturn(Optional.of(new Model(modelName)));
205         final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
206             .header(Constants.USER_ID_HEADER, USER_ID)
207             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
208                 "src/test/resources/node-types/nodeTypeWithModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
209         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
210     }
211
212     @Test
213     void uploadMultipartWithoutModelsFieldSuccessTest() throws IOException, ParseException, URISyntaxException {
214         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
215         when(componentsUtils.getResponseFormat(ActionStatus.CREATED)).thenReturn(responseFormat);
216         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
217         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
218         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
219         when(resourceImportManager.importNormativeResource(anyString(), any(), any(), anyBoolean(), anyBoolean()))
220             .thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.CREATED));
221         final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
222             .header(Constants.USER_ID_HEADER, USER_ID)
223             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType002.zip",
224                 "src/test/resources/node-types/nodeTypeWithoutModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
225         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
226     }
227
228     @Test
229     void uploadMultipartFailWithEmptyModelsTest() throws IOException, ParseException, URISyntaxException {
230         when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
231         when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
232         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
233         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
234         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
235         when(modelBusinessLogic.findModel("")).thenReturn(Optional.empty());
236         final Response response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
237             .header(Constants.USER_ID_HEADER, USER_ID)
238             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType002.zip",
239                 "src/test/resources/node-types/nodeTypeWithEmptyModels.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
240         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
241     }
242
243     @Test
244     void uploadMultipartFailWithModelNotFoundTest() throws IOException, ParseException, URISyntaxException {
245         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
246         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
247         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
248         when(modelBusinessLogic.findModel(modelName)).thenReturn(Optional.empty());
249         final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
250             .header(Constants.USER_ID_HEADER, USER_ID)
251             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
252                 "src/test/resources/node-types/nodeTypeWithModelsField.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
253         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
254     }
255
256     @Test
257     void uploadMultipartThrowsBusinessExceptionTest() throws IOException, ParseException, URISyntaxException {
258         when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
259         when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
260         when(servletUtils.getUserAdmin()).thenReturn(userBusinessLogic);
261         when(userBusinessLogic.getUser(anyString())).thenReturn(user);
262         when(resourceBusinessLogic.validatePropertiesDefaultValues(any())).thenReturn(true);
263         final var response = target().path(rootPath).request(MediaType.APPLICATION_JSON)
264             .header(Constants.USER_ID_HEADER, USER_ID)
265             .post(Entity.entity(buildFormDataMultiPart("node-types/TestNodeType001.zip",
266                 "src/test/resources/node-types/invalid.json"), MediaType.MULTIPART_FORM_DATA), Response.class);
267         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
268     }
269
270     private String getInputData(final String jsonFilename) throws IOException, ParseException {
271         final JSONObject inputData = (JSONObject) new JSONParser().parse(
272             new FileReader(jsonFilename));
273         return inputData.toJSONString();
274     }
275
276     private File getFile(final String fileName) throws URISyntaxException {
277         final URL resource = this.getClass().getClassLoader().getResource(fileName);
278         if (resource == null) {
279             throw new IllegalArgumentException("file not found! " + fileName);
280         }
281         return new File(resource.toURI());
282     }
283
284     private FormDataMultiPart buildFormDataMultiPart(final String zipFilePath, final String inputJsonData)
285         throws IOException, ParseException, URISyntaxException {
286         final FileDataBodyPart filePart = new FileDataBodyPart("resourceZip", getFile(zipFilePath));
287         final FormDataMultiPart multipartEntity = new FormDataMultiPart();
288         multipartEntity.bodyPart(filePart);
289         multipartEntity.field("resourceMetadata", getInputData(inputJsonData));
290         return  multipartEntity;
291     }
292 }