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
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.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
19 package org.openecomp.sdc.be.servlets;
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;
28 import java.io.FileReader;
29 import java.io.IOException;
30 import java.net.URISyntaxException;
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;
88 @TestInstance(Lifecycle.PER_CLASS)
89 class ResourceUploadServletTest extends JerseyTest {
90 private static final String USER_ID = "cs0008";
93 private HttpServletRequest request;
95 private HttpSession session;
97 private ServletContext servletContext;
99 private WebAppContextWrapper webAppContextWrapper;
101 private WebApplicationContext webApplicationContext;
103 private UserBusinessLogic userBusinessLogic;
105 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
107 private ComponentsUtils componentsUtils;
109 private ServletUtils servletUtils;
111 private ResourceImportManager resourceImportManager;
113 private ResourceBusinessLogic resourceBusinessLogic;
115 private ResponseFormat responseFormat;
117 private UserValidations userValidations;
119 private ModelBusinessLogic modelBusinessLogic;
121 private ResponseFormatManager responseFormatManager;
122 private final String modelName = "ETSI-SOL001-331";
124 private final String rootPath = "/v1/catalog/upload/multipart";
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");
148 void resetMock() throws Exception {
154 void after() throws Exception {
158 private void initTestData() {
160 user.setUserId(USER_ID);
161 user.setRole(Role.ADMIN.name());
162 when(userBusinessLogic.getUser(USER_ID)).thenReturn(user);
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() {
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);
185 .register(new OperationExceptionMapper(new ServletResponseBuilder(), responseFormatManager))
186 .register(MultiPartFeature.class)
187 .property("contextConfig", context);
191 protected void configureClient(final ClientConfig config) {
192 config.register(MultiPartFeature.class);
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);
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);
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);
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);
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);
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();
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);
281 return new File(resource.toURI());
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;