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.IOException;
30 import java.io.InputStream;
31 import java.nio.file.Path;
32 import java.util.List;
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.HttpHeaders;
38 import javax.ws.rs.core.MediaType;
39 import javax.ws.rs.core.Response.Status;
40 import org.apache.commons.lang3.StringUtils;
41 import org.eclipse.jetty.http.HttpStatus;
42 import org.glassfish.hk2.utilities.binding.AbstractBinder;
43 import org.glassfish.jersey.client.ClientConfig;
44 import org.glassfish.jersey.media.multipart.FormDataMultiPart;
45 import org.glassfish.jersey.media.multipart.MultiPartFeature;
46 import org.glassfish.jersey.server.ResourceConfig;
47 import org.glassfish.jersey.test.JerseyTest;
48 import org.glassfish.jersey.test.TestProperties;
49 import org.junit.jupiter.api.AfterEach;
50 import org.junit.jupiter.api.BeforeEach;
51 import org.junit.jupiter.api.Test;
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 class ModelServletTest extends JerseyTest {
84 private static final String USER_ID = "cs0008";
87 private HttpServletRequest request;
89 private HttpSession session;
91 private ServletContext servletContext;
93 private WebAppContextWrapper webAppContextWrapper;
95 private WebApplicationContext webApplicationContext;
97 private UserBusinessLogic userBusinessLogic;
99 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
101 private ComponentsUtils componentsUtils;
103 private ServletUtils servletUtils;
105 private ResourceImportManager resourceImportManager;
107 private ModelBusinessLogic modelBusinessLogic;
109 private ModelServlet modelServlet;
111 private ResponseFormat responseFormat;
113 private UserValidations userValidations;
116 private ResponseFormatManager responseFormatManager;
119 private ModelCreateRequest modelCreateRequest;
120 private final Path rootPath = Path.of("/v1/catalog/model");
121 private final Path importsPath = rootPath.resolve("imports");
124 void resetMock() throws Exception {
132 void after() throws Exception {
136 private void initMocks() {
137 when(request.getSession()).thenReturn(session);
138 when(session.getServletContext()).thenReturn(servletContext);
139 when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR))
140 .thenReturn(webAppContextWrapper);
141 when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
142 when(webApplicationContext.getBean(ModelBusinessLogic.class)).thenReturn(modelBusinessLogic);
143 when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(USER_ID);
144 when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
145 when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils);
148 private void initConfig() {
149 final String appConfigDir = "src/test/resources/config/catalog-be";
150 final ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
151 final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
152 final org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration();
153 configuration.setJanusGraphInMemoryGraph(true);
154 configurationManager.setConfiguration(configuration);
155 ExternalConfiguration.setAppName("catalog-be");
158 private void initTestData() {
159 final String modelName = "MY-INTEGRATION-TEST-MODEL";
160 model = new Model(modelName);
161 modelCreateRequest = new ModelCreateRequest();
162 modelCreateRequest.setName(modelName);
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(ModelServlet.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(modelBusinessLogic).to(ModelBusinessLogic.class);
181 bind(userValidations).to(UserValidations.class);
184 .register(new OperationExceptionMapper(new ServletResponseBuilder(), responseFormatManager))
185 .register(MultiPartFeature.class)
186 .property("contextConfig", context);
190 protected void configureClient(final ClientConfig config) {
191 config.register(MultiPartFeature.class);
195 void createModelSuccessTest() throws JsonProcessingException {
196 when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
197 when(componentsUtils.getResponseFormat(ActionStatus.CREATED)).thenReturn(responseFormat);
198 when(modelBusinessLogic.createModel(any(Model.class))).thenReturn(model);
199 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
200 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
201 .header(Constants.USER_ID_HEADER, USER_ID)
202 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
203 assertEquals(Status.OK.getStatusCode(), response.getStatus());
207 void createModelFailTest() throws JsonProcessingException {
208 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
209 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
210 when(modelBusinessLogic.createModel(any(Model.class))).thenReturn(model);
211 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
212 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
213 .header(Constants.USER_ID_HEADER, USER_ID)
214 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
215 assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
219 void createModelFailWithModelNameEmptyTest() throws JsonProcessingException {
220 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
221 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
222 modelCreateRequest.setName(StringUtils.EMPTY);
223 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(new byte[0], parseToJsonString(modelCreateRequest));
224 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
225 .header(Constants.USER_ID_HEADER, USER_ID)
226 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
227 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
231 void createModelFailWithModelNameNullTest() throws JsonProcessingException {
232 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
233 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
234 modelCreateRequest.setName(null);
235 final var modelFile = new byte[0];
236 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(modelFile, parseToJsonString(modelCreateRequest));
237 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
238 .header(Constants.USER_ID_HEADER, USER_ID)
239 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
240 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
244 void createModelThrowsBusinessExceptionTest() throws JsonProcessingException {
245 final var modelFile = new byte[0];
246 final String modelCreateAsJson = parseToJsonString(modelCreateRequest);
247 final FormDataMultiPart formDataMultiPart = buildCreateFormDataMultiPart(modelFile, modelCreateAsJson);
248 when(modelBusinessLogic.createModel(model)).thenThrow(new BusinessException() {});
250 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
251 .header(Constants.USER_ID_HEADER, USER_ID)
252 .post(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
253 assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
257 void updateModelImportsSuccessTest() {
258 final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart("model1", new byte[0]);
260 final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
261 .header(Constants.USER_ID_HEADER, USER_ID)
262 .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
263 assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
267 void updateModelImports_businessException() {
268 final var modelId = "model1";
269 final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart(modelId, new byte[0]);
270 final OperationException operationException = new OperationException(ActionStatus.INVALID_MODEL, modelId);
271 doThrow(operationException).when(modelBusinessLogic).createModelImports(eq(modelId), any(InputStream.class));
272 when(responseFormatManager.getResponseFormat(ActionStatus.INVALID_MODEL, modelId))
273 .thenReturn(new ResponseFormat(Status.BAD_REQUEST.getStatusCode()));
274 final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
275 .header(Constants.USER_ID_HEADER, USER_ID)
276 .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
277 assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
281 void updateModelImports_unknownException() {
282 final var modelName = "model1";
283 final FormDataMultiPart formDataMultiPart = buildUpdateFormDataMultiPart(modelName, new byte[0]);
284 doThrow(new RuntimeException()).when(modelBusinessLogic).createModelImports(eq(modelName), any(InputStream.class));
285 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
286 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
287 final var response = target(importsPath.toString()).request(MediaType.APPLICATION_JSON)
288 .header(Constants.USER_ID_HEADER, USER_ID)
289 .put(Entity.entity(formDataMultiPart, MediaType.MULTIPART_FORM_DATA));
290 assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
294 void listModelSuccessTest() throws IOException {
295 var model1 = new Model("model1");
296 var model2 = new Model("model2");
297 var model3 = new Model("model3");
298 final List<Model> modelList = List.of(model1, model2, model3);
299 when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
300 when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
301 when(modelBusinessLogic.listModels()).thenReturn(modelList);
303 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
304 .header(Constants.USER_ID_HEADER, USER_ID)
307 assertEquals(Status.OK.getStatusCode(), response.getStatus());
308 assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
309 final String responseBody = response.readEntity(String.class);
310 final String toRepresentation = (String) RepresentationUtils.toRepresentation(modelList);
311 assertEquals(toRepresentation, responseBody);
315 void listModelErrorTest() {
316 when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
317 when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(responseFormat);
318 doThrow(new RuntimeException()).when(modelBusinessLogic).listModels();
320 final var response = target(rootPath.toString()).request(MediaType.APPLICATION_JSON)
321 .header(Constants.USER_ID_HEADER, USER_ID)
324 assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
327 private FormDataMultiPart buildUpdateFormDataMultiPart(final String modelName, final byte[] importFilesZip) {
328 return new FormDataMultiPart()
329 .field("modelName", modelName)
330 .field("modelImportsZip", importFilesZip, MediaType.MULTIPART_FORM_DATA_TYPE);
333 private FormDataMultiPart buildCreateFormDataMultiPart(final byte[] modelFile, final String modelCreateAsJson) {
334 return new FormDataMultiPart()
335 .field("model", modelCreateAsJson, MediaType.APPLICATION_JSON_TYPE)
336 .field("modelImportsZip", modelFile, MediaType.MULTIPART_FORM_DATA_TYPE);
339 private String parseToJsonString(final Object object) throws JsonProcessingException {
340 return new ObjectMapper().writeValueAsString(object);