Support TOSCA functions in Node Filters
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / servlets / ComponentSubstitutionFilterServletTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 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
20 package org.openecomp.sdc.be.servlets;
21
22 import static org.assertj.core.api.Assertions.assertThat;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyBoolean;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.ArgumentMatchers.anyList;
28 import static org.mockito.ArgumentMatchers.anyString;
29 import static org.mockito.ArgumentMatchers.nullable;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.reset;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 import static org.openecomp.sdc.common.api.Constants.USER_ID_HEADER;
36
37 import com.fasterxml.jackson.core.JsonProcessingException;
38 import com.fasterxml.jackson.databind.ObjectMapper;
39 import java.util.Collections;
40 import java.util.List;
41 import java.util.Optional;
42 import javax.servlet.ServletContext;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpSession;
45 import javax.ws.rs.client.Entity;
46 import javax.ws.rs.core.MediaType;
47 import javax.ws.rs.core.Response;
48 import org.eclipse.jetty.http.HttpStatus;
49 import org.glassfish.hk2.utilities.binding.AbstractBinder;
50 import org.glassfish.jersey.server.ResourceConfig;
51 import org.glassfish.jersey.test.JerseyTest;
52 import org.glassfish.jersey.test.TestProperties;
53 import org.junit.jupiter.api.AfterEach;
54 import org.junit.jupiter.api.BeforeAll;
55 import org.junit.jupiter.api.BeforeEach;
56 import org.junit.jupiter.api.Test;
57 import org.mockito.ArgumentMatchers;
58 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
59 import org.openecomp.sdc.be.components.impl.ComponentSubstitutionFilterBusinessLogic;
60 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
61 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
62 import org.openecomp.sdc.be.components.validation.UserValidations;
63 import org.openecomp.sdc.be.config.ConfigurationManager;
64 import org.openecomp.sdc.be.config.SpringConfig;
65 import org.openecomp.sdc.be.dao.api.ActionStatus;
66 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
67 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition;
68 import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDefinition;
69 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
70 import org.openecomp.sdc.be.impl.ComponentsUtils;
71 import org.openecomp.sdc.be.impl.ServletUtils;
72 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
73 import org.openecomp.sdc.be.model.User;
74 import org.openecomp.sdc.be.model.dto.FilterConstraintDto;
75 import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper;
76 import org.openecomp.sdc.be.ui.model.UIConstraint;
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 public class ComponentSubstitutionFilterServletTest extends JerseyTest {
89
90     private static final String USER_ID = "jh0003";
91     private static final String servicePropertyName = "controller_actor";
92     private static final String constraintOperator = "equal";
93     private static final String sourceType = "static";
94     private static final String sourceName = sourceType;
95     private static final String propertyValue = "constraintValue";
96     private static final String componentId = "dac65869-dfb4-40d2-aa20-084324659ec1";
97     private static final String constraintType = "properties";
98     private static final String componentType = "services";
99
100     private static HttpServletRequest request;
101     private static HttpSession session;
102     private static ServletContext servletContext;
103     private static WebAppContextWrapper webAppContextWrapper;
104     private static WebApplicationContext webApplicationContext;
105     private static UserBusinessLogic userBusinessLogic;
106     private static ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
107     private static ComponentsUtils componentsUtils;
108     private static ServletUtils servletUtils;
109     private static ResourceImportManager resourceImportManager;
110     private static ComponentSubstitutionFilterBusinessLogic componentSubstitutionFilterBusinessLogic;
111     private static ResponseFormat responseFormat;
112     private static UserValidations userValidations;
113     private SubstitutionFilterDataDefinition substitutionFilterDataDefinition;
114     private UIConstraint uiConstraint;
115     private String inputJson;
116     private User user;
117     private FilterConstraintDto filterConstraintDto;
118
119     @BeforeAll
120     public static void initClass() {
121         createMocks();
122         when(request.getSession()).thenReturn(session);
123         when(session.getServletContext()).thenReturn(servletContext);
124         when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR))
125             .thenReturn(webAppContextWrapper);
126         when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
127         when(webApplicationContext.getBean(ComponentSubstitutionFilterBusinessLogic.class))
128             .thenReturn(componentSubstitutionFilterBusinessLogic);
129         when(request.getHeader("USER_ID")).thenReturn(USER_ID);
130         when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
131         when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils);
132         String appConfigDir = "src/test/resources/config/catalog-be";
133         ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
134         ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
135         org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration();
136         configuration.setJanusGraphInMemoryGraph(true);
137         configurationManager.setConfiguration(configuration);
138         ExternalConfiguration.setAppName("catalog-be");
139     }
140
141     @BeforeEach
142     public void resetMock() throws Exception {
143         super.setUp();
144         reset(componentSubstitutionFilterBusinessLogic);
145         initComponentData();
146     }
147
148     @AfterEach
149     void after() throws Exception {
150         super.tearDown();
151     }
152
153     @Test
154     void addSubstitutionFilterTest() throws Exception {
155         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
156         final String path = String.format(pathFormat, componentType, componentId, constraintType);
157
158         when(userValidations.validateUserExists(user)).thenReturn(user);
159         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
160         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
161         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
162
163         assertNotNull(uiConstraint);
164         assertThat(uiConstraint.getServicePropertyName()).isEqualToIgnoringCase(servicePropertyName);
165         assertThat(uiConstraint.getConstraintOperator()).isEqualToIgnoringCase(constraintOperator);
166         assertThat(uiConstraint.getSourceType()).isEqualToIgnoringCase(sourceType);
167         assertThat(uiConstraint.getSourceName()).isEqualToIgnoringCase(sourceName);
168         assertThat(uiConstraint.getValue().toString()).isEqualToIgnoringCase(propertyValue);
169
170         when(componentsUtils.parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class)))
171             .thenReturn(Optional.of(uiConstraint));
172
173         assertNotNull(substitutionFilterDataDefinition);
174         assertThat(substitutionFilterDataDefinition.getProperties().getListToscaDataDefinition()).hasSize(1);
175         when(componentSubstitutionFilterBusinessLogic.addSubstitutionFilter(componentId, filterConstraintDto, true, ComponentTypeEnum.SERVICE))
176             .thenReturn(Optional.of(substitutionFilterDataDefinition));
177
178         final Response response = target()
179             .path(path)
180             .request(MediaType.APPLICATION_JSON)
181             .header(USER_ID_HEADER, USER_ID)
182             .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
183
184         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
185
186         verify(componentSubstitutionFilterBusinessLogic, times(1))
187                 .addSubstitutionFilter(componentId, filterConstraintDto, true, ComponentTypeEnum.SERVICE);
188     }
189
190     @Test
191     void addSubstitutionFilterFailConstraintParseTest() {
192         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
193         final String path = String.format(pathFormat, componentType, componentId, constraintType);
194
195         when(userValidations.validateUserExists(user)).thenReturn(user);
196         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
197         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
198
199         when(componentsUtils.parseToConstraint(anyString(), any(User.class), nullable(ComponentTypeEnum.class)))
200             .thenReturn(Optional.empty());
201
202         final Response response = target()
203             .path(path)
204             .request(MediaType.APPLICATION_JSON)
205             .header(USER_ID_HEADER, USER_ID)
206             .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
207
208         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
209     }
210
211     @Test
212     void addSubstitutionFilterFailTest() {
213         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
214         final String path = String.format(pathFormat, componentType, componentId, constraintType);
215
216         when(userValidations.validateUserExists(user)).thenReturn(user);
217         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
218         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
219
220         when(componentsUtils.parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class)))
221             .thenReturn(Optional.of(uiConstraint));
222
223         final Response response = target()
224             .path(path)
225             .request(MediaType.APPLICATION_JSON)
226             .header(USER_ID_HEADER, USER_ID)
227             .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
228
229         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
230     }
231
232     @Test
233     void updateSubstitutionFilterTest() throws BusinessLogicException {
234         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
235         final String path = String.format(pathFormat, componentType, componentId, constraintType);
236
237         when(userValidations.validateUserExists(user)).thenReturn(user);
238         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
239         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
240         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
241
242         when(componentsUtils.validateAndParseConstraint(ArgumentMatchers.any(ComponentTypeEnum.class), anyString(),
243             any(User.class))).thenReturn(Collections.singletonList(uiConstraint));
244
245         when(componentSubstitutionFilterBusinessLogic.updateSubstitutionFilter(componentId.toLowerCase(),
246             List.of(filterConstraintDto), true, ComponentTypeEnum.SERVICE))
247             .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition));
248
249         final Response response = target()
250             .path(path)
251             .request(MediaType.APPLICATION_JSON)
252             .header(USER_ID_HEADER, USER_ID)
253             .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
254
255         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
256
257         verify(componentSubstitutionFilterBusinessLogic, times(1))
258                 .updateSubstitutionFilter(anyString(), anyList(), anyBoolean(), any(ComponentTypeEnum.class));
259     }
260
261     @Test
262     void updateSubstitutionFilterFailConstraintParseTest() {
263         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
264         final String path = String.format(pathFormat, componentType, componentId, constraintType);
265
266         when(userValidations.validateUserExists(user)).thenReturn(user);
267         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
268         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
269
270         when(componentsUtils.validateAndParseConstraint(ArgumentMatchers.any(ComponentTypeEnum.class), anyString(),
271             any(User.class))).thenReturn(Collections.emptyList());
272
273         final Response response = target()
274             .path(path)
275             .request(MediaType.APPLICATION_JSON)
276             .header(USER_ID_HEADER, USER_ID)
277             .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
278
279         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
280     }
281
282     @Test
283     void updateSubstitutionFilterFailTest()  {
284         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s";
285         final String path = String.format(pathFormat, componentType, componentId, constraintType);
286
287         when(userValidations.validateUserExists(user)).thenReturn(user);
288         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
289         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
290
291         when(componentsUtils.validateAndParseConstraint(ArgumentMatchers.any(ComponentTypeEnum.class), anyString(),
292             any(User.class))).thenReturn(Collections.singletonList(uiConstraint));
293
294         final Response response = target()
295             .path(path)
296             .request(MediaType.APPLICATION_JSON)
297             .header(USER_ID_HEADER, USER_ID)
298             .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON));
299
300         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
301     }
302
303     @Test
304     void deleteSubstitutionFilterConstraintTest() throws BusinessLogicException {
305         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0";
306         final String path = String.format(pathFormat, componentType, componentId, constraintType);
307
308         when(userValidations.validateUserExists(user)).thenReturn(user);
309         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
310         when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
311         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
312
313         when(componentSubstitutionFilterBusinessLogic.deleteSubstitutionFilter(componentId, 0,
314                 true, ComponentTypeEnum.SERVICE))
315             .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition));
316
317         final Response response = target()
318             .path(path)
319             .request(MediaType.APPLICATION_JSON)
320             .header(USER_ID_HEADER, USER_ID)
321             .delete(Response.class);
322
323         assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
324
325         verify(componentSubstitutionFilterBusinessLogic, times(1))
326                 .deleteSubstitutionFilter(anyString(), anyInt(), anyBoolean(), any(ComponentTypeEnum.class));
327     }
328
329     @Test
330     void deleteSubstitutionFilterConstraintFailTest() {
331         final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0";
332         final String path = String.format(pathFormat, componentType, componentId, constraintType);
333
334         when(userValidations.validateUserExists(user)).thenReturn(user);
335         when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user);
336         when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
337
338         final Response response = target()
339             .path(path)
340             .request(MediaType.APPLICATION_JSON)
341             .header(USER_ID_HEADER, USER_ID)
342             .delete(Response.class);
343
344         assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500);
345     }
346
347     private static void createMocks() {
348         request = mock(HttpServletRequest.class);
349         userBusinessLogic = mock(UserBusinessLogic.class);
350         componentInstanceBusinessLogic = mock(ComponentInstanceBusinessLogic.class);
351         componentsUtils = mock(ComponentsUtils.class);
352         servletUtils = mock(ServletUtils.class);
353         resourceImportManager = mock(ResourceImportManager.class);
354         componentSubstitutionFilterBusinessLogic = mock(ComponentSubstitutionFilterBusinessLogic.class);
355
356         session = mock(HttpSession.class);
357         servletContext = mock(ServletContext.class);
358         webAppContextWrapper = mock(WebAppContextWrapper.class);
359         webApplicationContext = mock(WebApplicationContext.class);
360         responseFormat = mock(ResponseFormat.class);
361         userValidations = mock(UserValidations.class);
362     }
363
364     @Override
365     protected ResourceConfig configure() {
366         forceSet(TestProperties.CONTAINER_PORT, "0");
367         final ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
368         return new ResourceConfig(ComponentSubstitutionFilterServlet.class)
369             .register(new AbstractBinder() {
370                 @Override
371                 protected void configure() {
372                     bind(request).to(HttpServletRequest.class);
373                     bind(userBusinessLogic).to(UserBusinessLogic.class);
374                     bind(componentInstanceBusinessLogic).to(ComponentInstanceBusinessLogic.class);
375                     bind(componentsUtils).to(ComponentsUtils.class);
376                     bind(servletUtils).to(ServletUtils.class);
377                     bind(resourceImportManager).to(ResourceImportManager.class);
378                     bind(componentSubstitutionFilterBusinessLogic).to(ComponentSubstitutionFilterBusinessLogic.class);
379                 }
380             })
381             .property("contextConfig", context);
382     }
383
384     private void initComponentData() throws JsonProcessingException {
385         uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue);
386         final FilterConstraintMapper filterConstraintMapper = new FilterConstraintMapper();
387         filterConstraintDto = filterConstraintMapper.mapFrom(uiConstraint);
388         inputJson = buildConstraintDataJson(uiConstraint);
389
390         SubstitutionFilterPropertyDataDefinition substitutionFilterPropertyDataDefinition = new SubstitutionFilterPropertyDataDefinition();
391         substitutionFilterPropertyDataDefinition.setName(uiConstraint.getServicePropertyName());
392         substitutionFilterPropertyDataDefinition.setConstraints(List.of(filterConstraintMapper.mapTo(filterConstraintDto)));
393
394         final ListDataDefinition<SubstitutionFilterPropertyDataDefinition> listDataDefinition =
395             new ListDataDefinition<>(List.of(substitutionFilterPropertyDataDefinition));
396
397         substitutionFilterDataDefinition = new SubstitutionFilterDataDefinition();
398         substitutionFilterDataDefinition.setProperties(listDataDefinition);
399         substitutionFilterDataDefinition.setID("SUBSTITUTION_FILTER_UID");
400
401         user = new User();
402         user.setUserId(USER_ID);
403         user.setRole(Role.ADMIN.name());
404     }
405
406     private String buildConstraintDataJson(final UIConstraint uiConstraint) throws JsonProcessingException {
407         final ObjectMapper mapper = new ObjectMapper();
408         return mapper.writeValueAsString(uiConstraint);
409     }
410
411 }
412