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";
125 private Response response;
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");
149 void resetMock() throws Exception {
155 void after() throws Exception {
159 private void initTestData() {
161 user.setUserId(USER_ID);
162 user.setRole(Role.ADMIN.name());
163 when(userBusinessLogic.getUser(USER_ID)).thenReturn(user);
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() {
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);
186 .register(new OperationExceptionMapper(new ServletResponseBuilder(), responseFormatManager))
187 .register(MultiPartFeature.class)
188 .property("contextConfig", context);
192 protected void configureClient(final ClientConfig config) {
193 config.register(MultiPartFeature.class);
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);
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);
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);
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);
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);
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();
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);
278 return new File(resource.toURI());
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;