catalog-be servlets refactoring
[sdc.git] / catalog-be / src / test / java / org / openecomp / sdc / be / servlets / ResourceServletTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.servlets;
22
23 import com.google.gson.Gson;
24 import com.google.gson.GsonBuilder;
25 import fj.data.Either;
26 import org.apache.commons.codec.binary.Base64;
27 import org.apache.commons.lang3.tuple.ImmutablePair;
28 import org.glassfish.hk2.utilities.binding.AbstractBinder;
29 import org.glassfish.jersey.server.ResourceConfig;
30 import org.glassfish.jersey.test.JerseyTest;
31 import org.glassfish.jersey.test.TestProperties;
32 import org.junit.Before;
33 import org.junit.BeforeClass;
34 import org.junit.Test;
35 import org.mockito.Mockito;
36 import org.mockito.invocation.InvocationOnMock;
37 import org.mockito.stubbing.Answer;
38 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
39 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
40 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
41 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
42 import org.openecomp.sdc.be.config.SpringConfig;
43 import org.openecomp.sdc.be.dao.api.ActionStatus;
44 import org.openecomp.sdc.be.impl.ComponentsUtils;
45 import org.openecomp.sdc.be.impl.ServletUtils;
46 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
47 import org.openecomp.sdc.be.model.Resource;
48 import org.openecomp.sdc.be.model.UploadResourceInfo;
49 import org.openecomp.sdc.be.model.User;
50 import org.openecomp.sdc.be.user.Role;
51 import org.openecomp.sdc.be.user.UserBusinessLogic;
52 import org.openecomp.sdc.common.api.Constants;
53 import org.openecomp.sdc.common.impl.ExternalConfiguration;
54 import org.openecomp.sdc.common.util.GeneralUtility;
55 import org.openecomp.sdc.exception.ResponseFormat;
56 import org.springframework.context.ApplicationContext;
57 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
58 import org.springframework.http.HttpStatus;
59 import org.springframework.web.context.WebApplicationContext;
60
61 import javax.servlet.ServletContext;
62 import javax.servlet.http.HttpServletRequest;
63 import javax.servlet.http.HttpSession;
64 import javax.ws.rs.client.Entity;
65 import javax.ws.rs.core.Application;
66 import javax.ws.rs.core.MediaType;
67 import javax.ws.rs.core.Response;
68 import java.util.Arrays;
69
70 import static org.junit.Assert.assertEquals;
71 import static org.junit.Assert.assertTrue;
72 import static org.mockito.Mockito.when;
73
74 public class ResourceServletTest extends JerseyTest {
75     public static final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
76     public static final ResourceImportManager resourceImportManager = Mockito.mock(ResourceImportManager.class);
77     final static HttpSession session = Mockito.mock(HttpSession.class);
78     final static ServletContext servletContext = Mockito.mock(ServletContext.class);
79     final static WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class);
80     final static WebApplicationContext webApplicationContext = Mockito.mock(WebApplicationContext.class);
81     public static final ServletUtils servletUtils = Mockito.mock(ServletUtils.class);
82     public static final ComponentsUtils componentUtils = Mockito.mock(ComponentsUtils.class);
83     public static final UserBusinessLogic userAdmin = Mockito.mock(UserBusinessLogic.class);
84     Gson gson = new GsonBuilder().setPrettyPrinting().create();
85
86     @BeforeClass
87     public static void setup() {
88         ExternalConfiguration.setAppName("catalog-be");
89         when(request.getSession()).thenReturn(session);
90         when(session.getServletContext()).thenReturn(servletContext);
91         when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR)).thenReturn(webAppContextWrapper);
92         when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webApplicationContext);
93         when(webApplicationContext.getBean(ResourceImportManager.class)).thenReturn(resourceImportManager);
94         when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
95         when(servletUtils.getComponentsUtils()).thenReturn(componentUtils);
96         when(servletUtils.getUserAdmin()).thenReturn(userAdmin);
97         String userId = "jh0003";
98         User user = new User();
99         user.setUserId(userId);
100         user.setRole(Role.ADMIN.name());
101         Either<User, ActionStatus> eitherUser = Either.left(user);
102         when(userAdmin.getUser(userId, false)).thenReturn(eitherUser);
103         when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(userId);
104
105         ImmutablePair<Resource, ActionStatus> pair = new ImmutablePair<>(new Resource(), ActionStatus.OK);
106         Either<ImmutablePair<Resource, ActionStatus>, ResponseFormat> ret = Either.left(pair);
107         when(resourceImportManager.importUserDefinedResource(Mockito.anyString(), Mockito.any(UploadResourceInfo.class), Mockito.any(User.class), Mockito.anyBoolean())).thenReturn(ret);
108
109     }
110
111     @Before
112     public void beforeTest() {
113         Mockito.reset(componentUtils);
114
115         Mockito.doAnswer(new Answer<ResponseFormat>() {
116             public ResponseFormat answer(InvocationOnMock invocation) {
117                 Object[] args = invocation.getArguments();
118                 ActionStatus action = (ActionStatus) args[0];
119                 return (action == ActionStatus.OK) ? new ResponseFormat(HttpStatus.CREATED.value()) : new ResponseFormat(HttpStatus.INTERNAL_SERVER_ERROR.value());
120             }
121         }).when(componentUtils).getResponseFormat(Mockito.any(ActionStatus.class));
122
123     }
124
125     @Test
126     public void testHappyScenarioTest() {
127         UploadResourceInfo validJson = buildValidJson();
128         setMD5OnRequest(true, validJson);
129         Response response = target().path("/v1/catalog/resources").request(MediaType.APPLICATION_JSON).post(Entity.json(gson.toJson(validJson)), Response.class);
130         Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(Mockito.any(ActionStatus.class));
131         Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(ActionStatus.OK);
132         assertEquals(response.getStatus(), HttpStatus.CREATED.value());
133
134     }
135
136     @Test
137     public void testNonValidMd5Fail() {
138         UploadResourceInfo validJson = buildValidJson();
139
140         setMD5OnRequest(false, validJson);
141
142         Response response = target().path("/v1/catalog/resources").request(MediaType.APPLICATION_JSON).post(Entity.json(gson.toJson(validJson)), Response.class);
143         Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(Mockito.any(ActionStatus.class));
144         Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM);
145         assertEquals(response.getStatus(), HttpStatus.INTERNAL_SERVER_ERROR.value());
146
147     }
148
149     @Test
150     public void testNonValidPayloadNameFail() {
151         UploadResourceInfo mdJson = buildValidJson();
152         mdJson.setPayloadName("myCompute.xml");
153
154         runAndVerifyActionStatusError(mdJson, ActionStatus.INVALID_TOSCA_FILE_EXTENSION);
155
156     }
157
158     @Test
159     public void testNullPayloadFail() {
160         UploadResourceInfo mdJson = buildValidJson();
161         mdJson.setPayloadData(null);
162         runAndVerifyActionStatusError(mdJson, ActionStatus.INVALID_RESOURCE_PAYLOAD);
163
164     }
165
166     @Test
167     public void testNonYmlPayloadFail() {
168         UploadResourceInfo mdJson = buildValidJson();
169         String payload = "{ json : { isNot : yaml } ";
170         encodeAndSetPayload(mdJson, payload);
171         runAndVerifyActionStatusError(mdJson, ActionStatus.INVALID_YAML_FILE);
172
173     }
174
175     @Test
176     public void testNonToscaPayloadFail() {
177         UploadResourceInfo mdJson = buildValidJson();
178
179         String payload = "node_types: \r\n" + "  org.openecomp.resource.importResource4test:\r\n" + "    derived_from: tosca.nodes.Root\r\n" + "    description: update update";
180         encodeAndSetPayload(mdJson, payload);
181         runAndVerifyActionStatusError(mdJson, ActionStatus.INVALID_TOSCA_TEMPLATE);
182
183     }
184
185     @Test
186     public void testServiceToscaPayloadFail() {
187         UploadResourceInfo mdJson = buildValidJson();
188
189         String payload = "tosca_definitions_version: tosca_simple_yaml_1_0_0\r\n" + "node_types: \r\n" + "  org.openecomp.resource.importResource4test:\r\n" + "    derived_from: tosca.nodes.Root\r\n" + "    topology_template: thisIsService\r\n"
190                 + "    description: update update";
191
192         encodeAndSetPayload(mdJson, payload);
193         runAndVerifyActionStatusError(mdJson, ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE);
194
195     }
196
197     @Test
198     public void testMultipleResourcesInPayloadFail() {
199         UploadResourceInfo mdJson = buildValidJson();
200
201         String payload = "tosca_definitions_version: tosca_simple_yaml_1_0_0\r\n" + "node_types: \r\n" + "  org.openecomp.resource.importResource4test2:\r\n" + "    derived_from: tosca.nodes.Root\r\n" + "  org.openecomp.resource.importResource4test:\r\n"
202                 + "    derived_from: tosca.nodes.Root\r\n" + "    description: update update";
203
204         encodeAndSetPayload(mdJson, payload);
205         runAndVerifyActionStatusError(mdJson, ActionStatus.NOT_SINGLE_RESOURCE);
206
207     }
208
209     @Test
210     public void testNonValidNameSpaceInPayloadFail() {
211         UploadResourceInfo mdJson = buildValidJson();
212
213         String payload = "tosca_definitions_version: tosca_simple_yaml_1_0_0\r\n" + "node_types: \r\n" + "  org.openecomp.resourceX.importResource4test:\r\n" + "    derived_from: tosca.nodes.Root\r\n" + "    description: update update";
214
215         encodeAndSetPayload(mdJson, payload);
216         runAndVerifyActionStatusError(mdJson, ActionStatus.INVALID_RESOURCE_NAMESPACE);
217
218     }
219
220     private void encodeAndSetPayload(UploadResourceInfo mdJson, String payload) {
221         byte[] encodedBase64Payload = Base64.encodeBase64(payload.getBytes());
222         mdJson.setPayloadData(new String(encodedBase64Payload));
223     }
224
225     private void runAndVerifyActionStatusError(UploadResourceInfo mdJson, ActionStatus invalidResourcePayload) {
226         setMD5OnRequest(true, mdJson);
227         Response response = target().path("/v1/catalog/resources").request(MediaType.APPLICATION_JSON).post(Entity.json(gson.toJson(mdJson)), Response.class);
228         Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(Mockito.any(ActionStatus.class));
229         Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(invalidResourcePayload);
230         assertEquals(response.getStatus(), HttpStatus.INTERNAL_SERVER_ERROR.value());
231     }
232
233     private void setMD5OnRequest(boolean isValid, UploadResourceInfo json) {
234         String md5 = (isValid) ? GeneralUtility.calculateMD5Base64EncodedByString(gson.toJson(json)) : "stam=";
235         when(request.getHeader(Constants.MD5_HEADER)).thenReturn(md5);
236
237     }
238
239     private UploadResourceInfo buildValidJson() {
240         UploadResourceInfo ret = new UploadResourceInfo();
241         ret.setName("ciMyCompute");
242         ret.setPayloadName("ciMyCompute.yml");
243         ret.addSubCategory("Application Layer 4+", "Application Servers");
244         ret.setDescription("ResourceDescription");
245         ret.setVendorName("VendorName");
246         ret.setVendorRelease("VendorRelease");
247         ret.setContactId("AT1234");
248         ret.setIcon("router");
249         ret.setTags(Arrays.asList(new String[] { "ciMyCompute" }));
250         ret.setPayloadData(
251                 "dG9zY2FfZGVmaW5pdGlvbnNfdmVyc2lvbjogdG9zY2Ffc2ltcGxlX3lhbWxfMV8wXzANCm5vZGVfdHlwZXM6IA0KICBvcmcub3BlbmVjb21wLnJlc291cmNlLk15Q29tcHV0ZToNCiAgICBkZXJpdmVkX2Zyb206IHRvc2NhLm5vZGVzLlJvb3QNCiAgICBhdHRyaWJ1dGVzOg0KICAgICAgcHJpdmF0ZV9hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIHB1YmxpY19hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIG5ldHdvcmtzOg0KICAgICAgICB0eXBlOiBtYXANCiAgICAgICAgZW50cnlfc2NoZW1hOg0KICAgICAgICAgIHR5cGU6IHRvc2NhLmRhdGF0eXBlcy5uZXR3b3JrLk5ldHdvcmtJbmZvDQogICAgICBwb3J0czoNCiAgICAgICAgdHlwZTogbWFwDQogICAgICAgIGVudHJ5X3NjaGVtYToNCiAgICAgICAgICB0eXBlOiB0b3NjYS5kYXRhdHlwZXMubmV0d29yay5Qb3J0SW5mbw0KICAgIHJlcXVpcmVtZW50czoNCiAgICAgIC0gbG9jYWxfc3RvcmFnZTogDQogICAgICAgICAgY2FwYWJpbGl0eTogdG9zY2EuY2FwYWJpbGl0aWVzLkF0dGFjaG1lbnQNCiAgICAgICAgICBub2RlOiB0b3NjYS5ub2Rlcy5CbG9ja1N0b3JhZ2UNCiAgICAgICAgICByZWxhdGlvbnNoaXA6IHRvc2NhLnJlbGF0aW9uc2hpcHMuQXR0YWNoZXNUbw0KICAgICAgICAgIG9jY3VycmVuY2VzOiBbMCwgVU5CT1VOREVEXSAgDQogICAgY2FwYWJpbGl0aWVzOg0KICAgICAgaG9zdDogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5Db250YWluZXINCiAgICAgICAgdmFsaWRfc291cmNlX3R5cGVzOiBbdG9zY2Eubm9kZXMuU29mdHdhcmVDb21wb25lbnRdIA0KICAgICAgZW5kcG9pbnQgOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuRW5kcG9pbnQuQWRtaW4gDQogICAgICBvczogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5PcGVyYXRpbmdTeXN0ZW0NCiAgICAgIHNjYWxhYmxlOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuU2NhbGFibGUNCiAgICAgIGJpbmRpbmc6DQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5uZXR3b3JrLkJpbmRhYmxl");
252         return ret;
253     }
254
255     @Override
256     protected Application configure() {
257         UserBusinessLogic userBusinessLogic = Mockito.mock(UserBusinessLogic.class);
258         GroupBusinessLogic groupBL = Mockito.mock(GroupBusinessLogic.class);
259         ComponentInstanceBusinessLogic componentInstanceBL = Mockito.mock(ComponentInstanceBusinessLogic.class);
260         ResourceBusinessLogic resourceBusinessLogic = Mockito.mock(ResourceBusinessLogic.class);
261
262         ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
263         forceSet(TestProperties.CONTAINER_PORT, "0");
264         return new ResourceConfig(ResourcesServlet.class)
265             .register(new AbstractBinder() {
266                 @Override
267                 protected void configure() {
268                     bind(request).to(HttpServletRequest.class);
269                     bind(servletUtils).to(ServletUtils.class);
270                     bind(componentUtils).to(ComponentsUtils.class);
271                     bind(userBusinessLogic).to(UserBusinessLogic.class);
272                     bind(resourceBusinessLogic).to(ResourceBusinessLogic.class);
273                     bind(groupBL).to(GroupBusinessLogic.class);
274                     bind(componentInstanceBL).to(ComponentInstanceBusinessLogic.class);
275                     bind(resourceImportManager).to(ResourceImportManager.class);
276                 }
277             })
278             .property("contextConfig", context);
279     }
280 }