1 package org.onap.vid.api;
3 import com.google.common.collect.ImmutableList;
4 import com.google.common.collect.ImmutableMap;
5 import org.apache.commons.text.StringEscapeUtils;
6 import org.springframework.http.HttpEntity;
7 import org.springframework.http.HttpMethod;
8 import org.springframework.http.HttpStatus;
9 import org.springframework.http.ResponseEntity;
10 import org.springframework.web.client.HttpClientErrorException;
11 import org.testng.annotations.BeforeClass;
12 import org.testng.annotations.DataProvider;
13 import org.testng.annotations.Test;
14 import vid.automation.test.services.SimulatorApi;
15 import vid.automation.test.services.SimulatorApi.RegistrationStrategy;
17 import java.io.IOException;
18 import java.lang.reflect.Method;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.LinkedList;
22 import java.util.stream.Collectors;
24 import static org.hamcrest.CoreMatchers.containsString;
25 import static org.hamcrest.core.Is.is;
26 import static org.junit.Assert.assertThat;
27 import static org.springframework.http.HttpStatus.BAD_REQUEST;
28 import static org.springframework.http.HttpStatus.METHOD_NOT_ALLOWED;
30 public class OperationalEnvironmentControllerApiTest extends BaseMsoApiTest {
31 private static final String UUID = "927befca-e32c-4f7d-be8d-b4107e0ac31e";
32 public static final String GET_STATUS_REQUEST_UUID = "3212b08c-0dcd-4d20-8c84-51e4f325c14a";
33 private static final String BASIC_DEACTIVATE_REQUEST_BODY = "{}";
34 private static final String BASIC_ACTIVATE_REQUEST_BODY = getResourceAsString("operationalEnvironmentController/activateOperationalEnvironment.json");
35 private static final String BASIC_CREATE_REQUEST_BODY = getResourceAsString("operationalEnvironmentController/createOperationalEnvironment.json");
36 private final String MSO_OK_RESPONSE_FOR_DEACTIVATE = "mso_ok_response_for_deactivate.json";
37 public static final String GET_CLOUD_RESOURCES_REQUEST_STATUS = "get_cloud_resources_request_status.json";
38 private final String MSO_ERROR_RESPONSE_FOR_DEACTIVATE = "mso_error_response_for_deactivate.json";
39 private final String MSO_ERROR_RESPONSE_FOR_STATUS = "mso_error_response_for_status.json";
40 private final String MSO_OK_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT = "mso_ok_response_for_post_operational_environmnet.json";
41 private final String MSO_ERROR_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT = "mso_error_response_for_post_operational_environmnet.json";
42 private final String missingParamErrorText = "Required String parameter 'operationalEnvironment' is not present";
48 [x] - Try all methods: only POST is working
49 [x] - Send wrong requests; all are responded with 400 and nice description
52 [x] - operationalEnvironment value is empty
53 - Simulate MSO responses (status and body); verify all are propagated inside a VID's 200 OK
54 [x] - [ 200, 202, 400, 404, 500 ]
57 [x] - Request body is just '{}'
58 [x] - Request body is with some fields
59 [x] - URI with more query params
62 [x] - Payload to MSO is the valid schema and values
63 [ ] - RequestorId is ok
74 @Test(dataProvider = "wrongHttpMethodsForAllUris")
75 public void tryAllWrongMethods(HttpMethod httpMethod, String uri) throws IOException {
77 ResponseEntity<String> responseEntity = restTemplate.exchange(uri, httpMethod, new HttpEntity<ImmutableMap>(ImmutableMap.of()), String.class);
78 assertThat("Response should be method not allowed => " + responseEntity, responseEntity.getBody(), containsString("Request method '" + httpMethod + "' not supported"));
79 } catch (HttpClientErrorException e) {
80 assertThat("Response should be method not allowed (by error code)", e.getStatusCode(), is(METHOD_NOT_ALLOWED));
87 public void activateWithAdditionalQueryParam() throws IOException {
88 doWithFineRequest(BASIC_ACTIVATE_REQUEST_BODY, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.EXTENDED), "/activate\"");
91 @Test(expectedExceptions = { HttpClientErrorException.class })
92 public void activateWithMissingOperationalEnvironmentParam() throws IOException {
93 doWithBadRequest(BASIC_ACTIVATE_REQUEST_BODY, missingParamErrorText, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.MISSING));
96 @Test(expectedExceptions = { HttpClientErrorException.class })
97 public void activateWithNoValueForOperationalEnvironmentParam() throws IOException {
98 doWithBadRequest(BASIC_ACTIVATE_REQUEST_BODY, missingParamErrorText, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.NO_VALUE));
102 public void deactivateWithAdditionalQueryParam() throws IOException {
103 doWithFineRequest(BASIC_DEACTIVATE_REQUEST_BODY, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.EXTENDED), "/deactivate\"");
106 @Test(expectedExceptions = { HttpClientErrorException.class })
107 public void deactivateWithMissingOperationalEnvironmentParam() throws IOException {
108 doWithBadRequest(BASIC_DEACTIVATE_REQUEST_BODY, missingParamErrorText, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.MISSING));
111 @Test(expectedExceptions = { HttpClientErrorException.class })
112 public void deactivateWithNoValueForOperationalEnvironmentParam() throws IOException {
113 doWithBadRequest(BASIC_DEACTIVATE_REQUEST_BODY, missingParamErrorText, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.NO_VALUE));
116 @Test(dataProvider = "requestPayloads")
117 public void activateWithBody(String requestBody) throws IOException {
118 doWithFineRequest(requestBody, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), "/activate\"");
121 @Test(dataProvider = "requestPayloads")
122 public void deactivateWithBody(String requestBody) throws IOException {
123 doWithFineRequest(requestBody, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), "/deactivate\"");
127 private void doWithFineRequest(String requestBody, String targetUri, String v1) throws IOException {
128 final String expectedResult = "" +
130 " \"requestReferences\": {" +
131 " \"requestId\": \"dbe54591-c8ed-46d3-abc7-d3a24873dfbd\"," +
132 " \"instanceId\": \"" + UUID + "\"" +
135 callMsoWithFineRequest(MSO_OK_RESPONSE_FOR_DEACTIVATE, ImmutableMap.of(
138 ,targetUri,requestBody,HttpStatus.ACCEPTED.value(),expectedResult, HttpMethod.POST);
141 @Test(dataProvider = "errorCodes")
142 public void deactivateWithErrorResponse(int errorCode) throws IOException {
143 doWithSimulatedErrorResponse(errorCode, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), BASIC_DEACTIVATE_REQUEST_BODY, "/deactivate\"", MSO_ERROR_RESPONSE_FOR_DEACTIVATE, HttpMethod.POST);
146 @Test(dataProvider = "errorCodes")
147 public void activateWithErrorResponse(int errorCode) throws IOException {
148 doWithSimulatedErrorResponse(errorCode, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), BASIC_ACTIVATE_REQUEST_BODY, "/activate\"", MSO_ERROR_RESPONSE_FOR_DEACTIVATE, HttpMethod.POST);
151 @Test(dataProvider = "errorCodes")
152 public void testStatusWithErrorResponse(int errorCode) throws IOException {
153 doWithSimulatedErrorResponse(errorCode, getStatusTargetUri(STATUS_URI_UUID_MODE.OK), "", "", MSO_ERROR_RESPONSE_FOR_STATUS, HttpMethod.GET);
156 private void doWithSimulatedErrorResponse(int errorCode, String targetUri, String basicRequestBody, String msoPathSuffix, String expectationTemplateFilename, HttpMethod method) throws IOException {
157 final String expectedResult = "" +
158 "<head>Huston, you have a problem<head>";
159 callMsoWithSimulatedErrorResponse(expectationTemplateFilename, ImmutableMap.of(
160 "/deactivate\"", msoPathSuffix,
163 "ERROR_PAYLOAD", StringEscapeUtils.escapeJson(expectedResult)
164 ),targetUri,basicRequestBody,errorCode, expectedResult, method);
168 dataProvider = "requestPayloads",
169 expectedExceptions = { HttpClientErrorException.class }
171 public void activateWithBadRequest(String requestBody) throws IOException {
172 doWithBadRequest(requestBody, "HttpMessageNotReadableException", getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK));
176 dataProvider = "activateBadHalfBakedPayloads",
177 expectedExceptions = { HttpClientErrorException.class }
179 public void activateWithBadHalfBakedPayload(String requestBody) throws IOException {
180 doWithBadRequest(requestBody, "HttpMessageNotReadableException", getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK));
184 dataProvider = "requestPayloads",
185 expectedExceptions = { HttpClientErrorException.class }
187 public void deactivateWithBadRequest(String requestBody) throws IOException {
188 doWithBadRequest(requestBody, "HttpMessageNotReadableException", getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK));
191 private void doWithBadRequest(String requestBody, String httpMessageNotReadableException, String targetUri) throws IOException {
192 SimulatorApi.registerExpectation(MSO_OK_RESPONSE_FOR_DEACTIVATE, ImmutableMap.of("UUID", UUID), RegistrationStrategy.CLEAR_THEN_SET);
195 ResponseEntity<String> responseEntity = restTemplate.postForEntity(targetUri, requestBody, String.class);
196 } catch (HttpClientErrorException e) {
197 assertThat("Response should be Bad Request (by error code)", e.getStatusCode(), is(BAD_REQUEST));
198 assertThat("Response should be Bad Request (by body)", e.getResponseBodyAsString(), containsString(httpMessageNotReadableException));
206 public Object[][] wrongHttpMethodsForAllUris() {
207 ImmutableList<String> uris = ImmutableList.of(
208 getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK),
209 getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK)
212 return Arrays.stream(HttpMethod.values())
213 .filter(Streams.not(ImmutableList.of(
214 HttpMethod.POST, // because POST *should* work
215 HttpMethod.PATCH, // because PATCH is invalid method for Java.net
216 HttpMethod.OPTIONS, // because OPTIONS is somehow valid... :-( => Allow=[GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH]
217 HttpMethod.HEAD // because HEAD is like POST/GET but without body, so error is hidden
219 .flatMap(httpMethod -> uris.stream()
220 .map(uri -> new Object[]{ httpMethod, uri}) // pair given method for each of the URIs
222 .collect(Collectors.toList())
223 .toArray(new Object[][] {});
227 public static Object[][] requestPayloads(Method test) {
228 switch (test.getName()) {
229 case "deactivateWithBody":
230 return new Object[][]{
231 {BASIC_DEACTIVATE_REQUEST_BODY}
232 , {"{ \"a\": \"b\" }"}
233 , {"{ \"a\": [ 55 ] }"}
235 case "activateWithBody":
236 return new Object[][]{
237 {BASIC_ACTIVATE_REQUEST_BODY}
239 default: // bad payloads
240 return new Object[][]{
250 public static Object[][] activateBadHalfBakedPayloads(Method test) {
251 final ImmutableList<String> strings = ImmutableList.of(
252 "\"relatedInstanceId\": \"1117887f-068f-46d7-9e43-9b73bef17af8\"",
253 "\"relatedInstanceName\": \"managing ECOMP Operational Environment\"",
254 "\"workloadContext\": \"VNF_E2E-IST\"",
256 " \"serviceModelList\": [" +
258 " \"serviceModelVersionId\": \"uuid2\"," +
259 " \"recoveryAction\": \"retry\"" +
265 final LinkedList<String> tests = new LinkedList<>();
266 for (int i = 0; i < strings.size(); i++) {
267 final ArrayList<String> aCase = new ArrayList<>(strings);
269 tests.add("{" + String.join(", ", aCase) + "}");
272 return tests.stream().map(o -> new Object[] { o }).collect(Collectors.toList()).toArray(new Object[][]{});
276 public static Object[][] errorCodes(Method test) {
277 return new Object[][]{
278 {500}, {505}, {400}, {401}, {405}
283 public static Object[][] statusLegitUri(Method test) {
284 return new Object[][]{
285 {STATUS_URI_UUID_MODE.OK}, {STATUS_URI_UUID_MODE.EXTENDED}
290 public static Object[][] statusNotLegitUri(Method test) {
291 return new Object[][]{
292 {STATUS_URI_UUID_MODE.MISSING}, {STATUS_URI_UUID_MODE.NO_VALUE}
296 private enum ACTIVATION_URI_UUID_MODE {
298 NO_VALUE("?operationalEnvironment="),
299 OK(NO_VALUE.val + UUID),
300 EXTENDED(OK.val + "&anotherParam=6");
304 ACTIVATION_URI_UUID_MODE(String val) {
309 private enum STATUS_URI_UUID_MODE {
311 NO_VALUE("?requestId="),
312 OK(NO_VALUE.val + GET_STATUS_REQUEST_UUID),
313 EXTENDED(OK.val + "&anotherParam=6");
317 STATUS_URI_UUID_MODE(String val) {
322 private String getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE uriUuidMode) {
323 return uri.toASCIIString() + "/operationalEnvironment/deactivate" + uriUuidMode.val;
326 private String getActivationTargetUri(ACTIVATION_URI_UUID_MODE uriUuidMode) {
327 return uri.toASCIIString() + "/operationalEnvironment/activate" + uriUuidMode.val;
330 private String getStatusTargetUri(STATUS_URI_UUID_MODE uriUuidMode) {
331 return uri.toASCIIString() + "/operationalEnvironment/requestStatus" + uriUuidMode.val;
334 private String getCreateOperationEnvironmentUri() {
335 return uri.toASCIIString() + "/operationalEnvironment/create";
339 public void createWithSimplestBody()throws IOException {
341 final String expectedResult = "" +
343 " \"requestReferences\": {" +
344 " \"requestId\": \"dbe54591-c8ed-46d3-abc7-d3a24873dfbd\","+
345 " \"instanceId\": \"" + UUID + "\"" +
348 callMsoWithFineRequest(MSO_OK_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT, ImmutableMap.of(
349 "UUID", UUID), getCreateOperationEnvironmentUri(), BASIC_CREATE_REQUEST_BODY, HttpStatus.ACCEPTED.value(), expectedResult, HttpMethod.POST);
352 @Test(dataProvider = "errorCodes")
353 public void createWithErrorResponse(int errorCode) throws IOException {
354 final String expectedResult = "" +
355 "<head>Huston, you have a problem<head>";
356 callMsoWithSimulatedErrorResponse(MSO_ERROR_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT,ImmutableMap.of(
358 "ERROR_PAYLOAD", StringEscapeUtils.escapeJson(expectedResult)
359 ), getCreateOperationEnvironmentUri(), BASIC_CREATE_REQUEST_BODY, errorCode,expectedResult, HttpMethod.POST);
365 @Test(dataProvider = "statusLegitUri")
366 public void testStatusWithLegitUri(STATUS_URI_UUID_MODE statusUriMode) throws IOException {
368 String uri = getStatusTargetUri(statusUriMode);
370 final String expectedResult = "" +
373 " \"requestId\": \"3212b08c-0dcd-4d20-8c84-51e4f325c14a\"," +
374 " \"startTime\": \"Thu, 02 Jun 2017 02:51:59 GMT\"," +
375 " \"instanceReferences\": {" +
376 " \"operationalEnvironmentInstanceId\": \"bc305d54-75b4-431b-adb2-eb6b9e546014\"" +
378 " \"requestScope\": \"operationalEnvironment\"," +
379 " \"requestType\": \"deactivate\"," +
380 " \"requestDetails\": {" +
381 " \"requestInfo\": {" +
382 " \"resourceType\": \"operationalEnvironment\"," +
383 " \"source\": \"VID\"," +
384 " \"requestorId\": \"az2017\"" +
386 " \"requestParameters\": {" +
387 " \"operationalEnvironmentType\": \"VNF\"" +
390 " \"requestStatus\": {" +
391 " \"timestamp\": \"Thu, 02 Jun 2017 02:53:39 GMT\"," +
392 " \"requestState\": \"COMPLETE\"," +
393 " \"statusMessage\": \"Operational Environment successfully deactivated\"," +
394 " \"percentProgress\": \"100\"" +
399 callMsoWithFineRequest(GET_CLOUD_RESOURCES_REQUEST_STATUS, ImmutableMap.of()
400 ,uri,"",HttpStatus.OK.value(),expectedResult, HttpMethod.GET);
405 expectedExceptions = {HttpClientErrorException.class},
406 dataProvider = "statusNotLegitUri"
408 public void testStatusWithBadRequest(STATUS_URI_UUID_MODE statusUriMode) throws IOException {
409 SimulatorApi.registerExpectation(GET_CLOUD_RESOURCES_REQUEST_STATUS, RegistrationStrategy.CLEAR_THEN_SET);
411 String uri = getStatusTargetUri(statusUriMode);
414 ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri, String.class);
415 } catch (HttpClientErrorException e) {
416 assertThat("Response should be Bad Request (by error code)", e.getStatusCode(), is(BAD_REQUEST));
417 assertThat("Response should be Bad Request (by body)", e.getResponseBodyAsString(), containsString("'requestId' is not present"));
423 public void testStatusWithWrongMethodPost() throws IOException {
424 SimulatorApi.registerExpectation(GET_CLOUD_RESOURCES_REQUEST_STATUS, RegistrationStrategy.CLEAR_THEN_SET);
426 String myUri = getStatusTargetUri(STATUS_URI_UUID_MODE.OK);
428 String response = restTemplate.postForObject(myUri, "", String.class);
429 assertThat("Response should be method not allowed => " + response, response, containsString("Request method '" + HttpMethod.POST + "' not supported"));