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.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;
27 import com.fasterxml.jackson.core.JsonProcessingException;
28 import com.fasterxml.jackson.databind.ObjectMapper;
29 import java.io.InputStream;
30 import java.nio.file.Path;
31 import javax.servlet.ServletContext;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpSession;
34 import javax.ws.rs.client.Entity;
35 import javax.ws.rs.core.MediaType;
36 import javax.ws.rs.core.Response.Status;
37 import org.apache.commons.lang3.StringUtils;
38 import org.eclipse.jetty.http.HttpStatus;
39 import org.glassfish.hk2.utilities.binding.AbstractBinder;
40 import org.glassfish.jersey.client.ClientConfig;
41 import org.glassfish.jersey.media.multipart.FormDataMultiPart;
42 import org.glassfish.jersey.media.multipart.MultiPartFeature;
43 import org.glassfish.jersey.server.ResourceConfig;
44 import org.glassfish.jersey.test.JerseyTest;
45 import org.glassfish.jersey.test.TestProperties;
46 import org.junit.jupiter.api.AfterEach;
47 import org.junit.jupiter.api.BeforeAll;
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50 import org.junit.jupiter.api.TestInstance;
51 import org.junit.jupiter.api.TestInstance.Lifecycle;
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;
82 @TestInstance(Lifecycle.PER_CLASS)
83 class ModelServletTest extends JerseyTest {
85 private static final String USER_ID = "cs0008";
88 private HttpServletRequest request;
90 private HttpSession session;
92 private ServletContext servletContext;
94 private WebAppContextWrapper webAppContextWrapper;
96 private WebApplicationContext webApplicationContext;
98 private UserBusinessLogic userBusinessLogic;
100 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
102 private ComponentsUtils componentsUtils;
104 private ServletUtils servletUtils;
106 private ResourceImportManager resourceImportManager;
108 private ModelBusinessLogic modelBusinessLogic;
110 private ModelServlet modelServlet;
112 private ResponseFormat responseFormat;
114 private UserValidations userValidations;
117 private ResponseFormatManager responseFormatManager;
120 private ModelCreateRequest modelCreateRequest;
121 private final Path rootPath = Path.of("/v1/catalog/model");
122 private final Path importsPath = rootPath.resolve("imports");
125 public void initClass() {
126 when(request.getSession()).thenReturn(session);
127 when(session.getServletContext()).thenReturn(servletContext);
128 when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR))
129 .thenReturn(webAppContextWrapper);
130 when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
131 when(webApplicationContext.getBean(ModelBusinessLogic.class)).thenReturn(modelBusinessLogic);
132 when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(USER_ID);
133 when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
134 when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils);
135 final String appConfigDir = "src/test/resources/config/catalog-be";
136 final ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
137 final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
138 final org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration();
139 configuration.setJanusGraphInMemoryGraph(true);
140 configurationManager.setConfiguration(configuration);
141 ExternalConfiguration.setAppName("catalog-be");
145 void resetMock() throws Exception {
151 void after() throws Exception {
155 private void initTestData() {
156 final String modelName = "MY-INTEGRATION-TEST-MODEL";
157 model = new Model(modelName);
158 modelCreateRequest = new ModelCreateRequest();
159 modelCreateRequest.setName(modelName);
163 protected ResourceConfig configure() {
164 MockitoAnnotations.openMocks(this);
165 forceSet(TestProperties.CONTAINER_PORT, "0");
166 final ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
167 return new ResourceConfig(ModelServlet.class)
168 .register(new AbstractBinder() {
170 protected void configure() {
171 bind(request).to(HttpServletRequest.class);
172 bind(userBusinessLogic).to(UserBusinessLogic.class);
173 bind(componentInstanceBusinessLogic).to(ComponentInstanceBusinessLogic.class);
174 bind(componentsUtils).to(ComponentsUtils.class);
175 bind(servletUtils).to(ServletUtils.class);
176 bind(resourceImportManager).to(ResourceImportManager.class);
177 bind(modelBusinessLogic).to(ModelBusinessLogic.class);
178 bind(userValidations).to(UserValidations.class);
181 .register(new OperationExceptionMapper(new ServletResponseBuilder(), responseFormatManager))
182 .register(MultiPartFeature.class)
183 .property("contextConfig", context);
187 protected void configureClient(final ClientConfig config) {
188 config.register(MultiPartFeature.class);
192 void createModelSuccessTest() throws JsonProcessingException {
193 when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
194 when(componentsUtils.getResponseFormat(ActionStatus.CREATED)).thenReturn(responseFormat);
195 when(modelBusinessLogic.createModel(any(Model.class))).thenReturn(model);
196 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
197 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
198 .header(Constants.USER_ID_HEADER, USER_ID)
199 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
200 assertEquals(Status.OK.getStatusCode(), response.getStatus());
204 void createModelFailTest() throws JsonProcessingException {
205 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
206 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
207 when(modelBusinessLogic.createModel(any(Model.class))).thenReturn(model);
208 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
209 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
210 .header(Constants.USER_ID_HEADER, USER_ID)
211 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
212 assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
216 void createModelFailWithModelNameEmptyTest() throws JsonProcessingException {
217 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
218 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
219 modelCreateRequest.setName(StringUtils.EMPTY);
220 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
221 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
222 .header(Constants.USER_ID_HEADER, USER_ID)
223 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
224 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
228 void createModelFailWithModelNameNullTest() throws JsonProcessingException {
229 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
230 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
231 modelCreateRequest.setName(null);
232 final var modelFile = new byte[0];
233 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(modelFile, parseToJsonString(modelCreateRequest));
234 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
235 .header(Constants.USER_ID_HEADER, USER_ID)
236 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
237 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
241 void createModelThrowsBusinessExceptionTest() throws JsonProcessingException {
242 final var modelFile = new byte[0];
243 final String modelCreateAsJson = parseToJsonString(modelCreateRequest);
244 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(modelFile, modelCreateAsJson);
245 when(modelBusinessLogic.createModel(model)).thenThrow(new BusinessException() {});
247 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
248 .header(Constants.USER_ID_HEADER, USER_ID)
249 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
250 assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
254 void updateModelImportsSuccessTest() {
255 final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart("model1", new byte[0]);
257 final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
258 .header(Constants.USER_ID_HEADER, USER_ID)
259 .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
260 assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
264 void updateModelImports_businessException() {
265 final var modelId = "model1";
266 final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart(modelId, new byte[0]);
267 final OperationException operationException = new OperationException(ActionStatus.INVALID_MODEL, modelId);
268 doThrow(operationException).when(modelBusinessLogic).createModelImports(eq(modelId), any(InputStream.class));
269 when(responseFormatManager.getResponseFormat(ActionStatus.INVALID_MODEL, modelId))
270 .thenReturn(new ResponseFormat(Status.BAD_REQUEST.getStatusCode()));
271 final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
272 .header(Constants.USER_ID_HEADER, USER_ID)
273 .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
274 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
278 void updateModelImports_unknownException() {
279 final var modelName = "model1";
280 final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart(modelName, new byte[0]);
281 doThrow(new RuntimeException()).when(modelBusinessLogic).createModelImports(eq(modelName), any(InputStream.class));
282 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
283 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
284 final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
285 .header(Constants.USER_ID_HEADER, USER_ID)
286 .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
287 assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
290 private FormDataMultiPart buildUpdateFormDataMultiPart(final String modelName, final byte[] importFilesZip) {
291 return new FormDataMultiPart()
292 .field("modelName", modelName)
293 .field("modelImportsZip", importFilesZip, MediaType.MULTIPART_FORM_DATA_TYPE);
296 private FormDataMultiPart buildCreateFormDataMultiPart(final byte[] modelFile, final String modelCreateAsJson) {
297 return new FormDataMultiPart()
298 .field("model", modelCreateAsJson, MediaType.APPLICATION_JSON_TYPE)
299 .field("modelImportsZip", modelFile, MediaType.MULTIPART_FORM_DATA_TYPE);
302 private String parseToJsonString(final Object object) throws JsonProcessingException {
303 return new ObjectMapper().writeValueAsString(object);