351e5b03f6a45cf990573bb14d3f4cac0a982f15
[vid.git] / vid-automation / src / main / java / vid / automation / test / test / ChangeManagementTest.java
1 package vid.automation.test.test;
2
3
4 import static java.util.Collections.emptyMap;
5 import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
6 import static org.apache.commons.lang3.exception.ExceptionUtils.rethrow;
7 import static org.hamcrest.CoreMatchers.containsString;
8 import static org.hamcrest.CoreMatchers.everyItem;
9 import static org.hamcrest.CoreMatchers.hasItem;
10 import static org.hamcrest.CoreMatchers.is;
11 import static org.hamcrest.CoreMatchers.notNullValue;
12 import static org.hamcrest.CoreMatchers.startsWith;
13 import static org.hamcrest.MatcherAssert.assertThat;
14 import static org.hamcrest.Matchers.greaterThan;
15 import static org.hamcrest.collection.IsEmptyCollection.empty;
16 import static org.hamcrest.core.IsNot.not;
17 import static org.onap.simulator.presetGenerator.presets.aai.PresetBaseAAICustomQuery.FORMAT.SIMPLE;
18 import static org.onap.vid.api.BaseApiTest.getResourceAsString;
19 import static vid.automation.test.infra.Features.FLAG_FLASH_REDUCED_RESPONSE_CHANGEMG;
20 import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
21
22 import com.aventstack.extentreports.Status;
23 import com.google.common.collect.ImmutableList;
24 import com.google.common.collect.ImmutableMap;
25 import com.google.common.primitives.Ints;
26 import java.io.IOException;
27 import java.sql.Connection;
28 import java.sql.DriverManager;
29 import java.sql.SQLException;
30 import java.sql.Statement;
31 import java.util.Arrays;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.stream.Collectors;
35 import java.util.stream.Stream;
36 import net.javacrumbs.jsonunit.core.Option;
37 import org.json.JSONException;
38 import org.junit.Assert;
39 import org.onap.sdc.ci.tests.datatypes.UserCredentials;
40 import org.onap.sdc.ci.tests.execute.setup.ExtentTestActions;
41 import org.onap.sdc.ci.tests.utilities.GeneralUIUtils;
42 import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
43 import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetTenants;
44 import org.onap.simulator.presetGenerator.presets.aai.PresetBaseAAICustomQuery;
45 import org.onap.simulator.presetGenerator.presets.scheduler.PresetDeleteSchedulerChangeManagement;
46 import org.openqa.selenium.JavascriptExecutor;
47 import org.openqa.selenium.WebElement;
48 import org.openqa.selenium.remote.RemoteWebElement;
49 import org.openqa.selenium.support.ui.Select;
50 import org.skyscreamer.jsonassert.JSONAssert;
51 import org.skyscreamer.jsonassert.JSONCompareMode;
52 import org.testng.ITestResult;
53 import org.testng.annotations.AfterClass;
54 import org.testng.annotations.AfterMethod;
55 import org.testng.annotations.BeforeClass;
56 import org.testng.annotations.DataProvider;
57 import org.testng.annotations.Test;
58 import vid.automation.test.Constants;
59 import vid.automation.test.infra.Click;
60 import vid.automation.test.infra.Exists;
61 import vid.automation.test.infra.FeatureTogglingTest;
62 import vid.automation.test.infra.Features;
63 import vid.automation.test.infra.Get;
64 import vid.automation.test.infra.Input;
65 import vid.automation.test.infra.SelectOption;
66 import vid.automation.test.infra.Wait;
67 import vid.automation.test.model.User;
68 import vid.automation.test.sections.ChangeManagementPage;
69 import vid.automation.test.services.SimulatorApi;
70 import vid.automation.test.utils.DB_CONFIG;
71
72 public class ChangeManagementTest extends VidBaseTestCase {
73
74     public static final String SCHEDULED_ID = "0b87fe60-50b0-4bac-a0a7-49e951b0ba9e";
75     private final String SCHEDULE_ERROR_PREFIX = "Portal not found. Cannot send: ";
76
77     @Test
78     public void testLeftPanelChangeManagementButton() {
79         Assert.assertTrue(Wait.byText(Constants.SideMenu.VNF_CHANGES));
80     }
81
82     @Test
83     public void testChangeManagementHeaderLine() {
84         ChangeManagementPage.openChangeManagementPage();
85         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.pageHeadlineId));
86         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.headlineNewButtonId));
87         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.headlineSearchInputId));
88     }
89
90     @Test
91     public void testOpenNewChangeManagementModal() {
92         ChangeManagementPage.openNewChangeManagementModal();
93         Assert.assertTrue(Exists.modal());
94         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalSubscriberInputId));
95         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalServiceTypeInputId));
96         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalVNFNameInputId));
97
98         if (Features.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH.isActive()) {
99             Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalVNFTypeInputId1));
100             Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalVNFCloudRegion));
101             Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalVNFSearchVNF));
102         } else {
103             Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalVNFTypeInputId));
104         }
105
106         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalFromVNFVersionInputId));
107         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.newModalWorkFlowInputId));
108         Assert.assertTrue(Exists.byId(Constants.generalSubmitButtonId));
109         Assert.assertTrue(Exists.byId(Constants.generalCancelButtonId));
110     }
111
112     private void openAndFill1stScreen(String vnfName, String vnfTargetVersion, String workflow) {
113         String subscriberId = VNF_DATA_WITH_IN_PLACE.subscriberId;
114         String subscriberName = VNF_DATA_WITH_IN_PLACE.subscriberName;
115         String serviceType = VNF_DATA_WITH_IN_PLACE.serviceType;
116         String vnfType = VNF_DATA_WITH_IN_PLACE.vnfType;
117         String cloudRegion = VNF_DATA_WITH_IN_PLACE.cloudRegion;
118         String vnfSourceVersion = VNF_DATA_WITH_IN_PLACE.vnfSourceVersion;
119         ChangeManagementPage.openNewChangeManagementModal();
120         Wait.angularHttpRequestsLoaded();
121         SelectOption.waitForOptionInSelect(subscriberName, "subscriberName");
122         ChangeManagementPage.selectSubscriberById(subscriberId);
123         Wait.angularHttpRequestsLoaded();
124
125         SelectOption.byIdAndVisibleText(Constants.ChangeManagement.newModalServiceTypeInputId, serviceType);
126         Wait.angularHttpRequestsLoaded();
127
128         if (Features.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH.isActive()) {
129             Input.text(vnfType, Constants.ChangeManagement.newModalVNFTypeInputId);
130             SelectOption.byIdAndVisibleText(Constants.ChangeManagement.newModalVNFCloudRegion, cloudRegion);
131             Click.byId(Constants.ChangeManagement.newModalVNFSearchVNF);
132         } else {
133             SelectOption.byIdAndVisibleText(Constants.ChangeManagement.newModalVNFTypeInputId, vnfType);
134         }
135         Wait.angularHttpRequestsLoaded();
136
137         SelectOption.byIdAndVisibleText(Constants.ChangeManagement.newModalFromVNFVersionInputId, vnfSourceVersion);
138         Wait.angularHttpRequestsLoaded();
139         Click.byId(Constants.ChangeManagement.newModalVNFNameInputId);
140         Click.byText(vnfName);
141         // close the multi-select
142         Click.byId(Constants.ChangeManagement.newModalVNFNameInputId);
143         Wait.angularHttpRequestsLoaded();
144         GeneralUIUtils.ultimateWait();
145
146         if (vnfTargetVersion != null) {
147             SelectOption.byClassAndVisibleText(Constants.ChangeManagement.newModalTargetVersionInputsClass, vnfTargetVersion);
148             Wait.angularHttpRequestsLoaded();
149         }
150         SelectOption.byIdAndVisibleText(Constants.ChangeManagement.newModalWorkFlowInputId, workflow);
151
152     }
153
154     public void scheduleChange2ndScreen(String duration, String fallback, String concurrencyLimit, String policy) {
155
156         Wait.byText(Constants.ChangeManagement.schedulerModalNowLabel);
157         Click.byText(Constants.ChangeManagement.schedulerModalNowLabel);
158
159
160         SelectOption.byValue(Constants.ChangeManagement.schedulerModalHoursOption, Constants.ChangeManagement.schedulerModalTimeUnitSelectId);
161
162         Input.text(duration, Constants.ChangeManagement.schedulerModalDurationInputTestId);
163         Input.text(fallback, Constants.ChangeManagement.schedulerModalFallbackInputTestId);
164         Input.text(concurrencyLimit, Constants.ChangeManagement.schedulerModalConcurrencyLimitInputTestId);
165         Wait.angularHttpRequestsLoaded();
166         SelectOption.byIdAndVisibleText(Constants.ChangeManagement.schedulerModalPolicySelectId, policy);
167
168         Click.byText(Constants.ChangeManagement.schedulerModalScheduleButtonText);
169
170     }
171
172     static class VNF_DATA_WITH_IN_PLACE {
173         static final int vnfZrdm3amdns02test2Id = 11822;
174         static final int vnfHarrisonKrisId = 12822;
175         static String subscriberId = "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb";
176         static String subscriberName = "Emanuel";
177         static String serviceType = "vRichardson";
178         static String vnfType = "vMobileDNS";
179         static String cloudRegion = "AAIAIC25 (AIC)";
180         static String vnfSourceVersion = "1.0";
181         static String vnfName = "zolson3amdns02test2";
182         static String vnfTargetVersion = "5.0";
183         static String workflowName = "VNF In Place Software Update";
184     }
185
186     @AfterClass
187     protected void dropSpecialVNFs() {
188
189         resetGetServicesCache();
190
191         System.out.println("Connecting database...");
192
193         try (Connection connection = DriverManager.getConnection(DB_CONFIG.url, DB_CONFIG.username, DB_CONFIG.password)) {
194             System.out.println("Database connected!");
195
196             Statement stmt = connection.createStatement();
197             stmt.addBatch("DELETE FROM `vid_vnf_workflow` WHERE `VNF_DB_ID` = " + VNF_DATA_WITH_IN_PLACE.vnfZrdm3amdns02test2Id);
198             stmt.addBatch("DELETE FROM `vid_vnf` WHERE `VNF_DB_ID` = " + VNF_DATA_WITH_IN_PLACE.vnfZrdm3amdns02test2Id);
199             int[] executeBatch = stmt.executeBatch();
200
201             stmt = connection.createStatement();
202             stmt.addBatch("DELETE FROM `vid_vnf_workflow` WHERE `VNF_DB_ID` = " + VNF_DATA_WITH_IN_PLACE.vnfHarrisonKrisId);
203             stmt.addBatch("DELETE FROM `vid_vnf` WHERE `VNF_DB_ID` = " + VNF_DATA_WITH_IN_PLACE.vnfHarrisonKrisId);
204             executeBatch = stmt.executeBatch();
205
206         } catch (SQLException e) {
207             throw new IllegalStateException("Cannot connect the database!", e);
208         }
209     }
210
211     @BeforeClass
212     protected void registerToSimulator() {
213         SimulatorApi.clearAll();
214         SimulatorApi.registerExpectation(APPEND,
215                 "changeManagement/ecompportal_getSessionSlotCheckInterval.json"
216                 , "changeManagement/get_aai_sub_details.json"
217                 , "changeManagement/get_sdc_catalog_services_2f80c596.json"
218                 , "changeManagement/get_service-design-and-creation.json"
219                 , "changeManagement/get_vnf_data_by_globalid_and_service_type.json"
220                 , "changeManagement/service-design-and-creation.json"
221                 , "changeManagement/mso_get_manual_task.json"
222                 , "changeManagement/mso_post_manual_task.json"
223                 , "changeManagement/mso_get_change_managements_scaleout.json"
224         );
225         SimulatorApi.registerExpectationFromPreset(new PresetAAIGetSubscribersGet(), APPEND);
226         if (FLAG_FLASH_REDUCED_RESPONSE_CHANGEMG.isActive()) {
227             String AAI_VNFS_FOR_CHANGE_MANAGEMENT_JSON_BY_PARAMS = "registration_to_simulator/changeManagement/get_vnf_data_by_globalid_and_service_type_with_modelVer.json";
228             String globalCustomerId = "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb";
229             String serviceType = "vRichardson";
230             SimulatorApi.registerExpectationFromPreset(new PresetBaseAAICustomQuery(
231                     SIMPLE,
232                     "/business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/"
233                             + serviceType + "/service-instances",
234                     "query/vnfs-fromServiceInstance-filterByCloudRegion?nfRole=vMobileDNS&cloudRegionID=AAIAIC25"
235             ) {
236                 @Override
237                 public Object getResponseBody() {
238                     return getResourceAsString(
239                             AAI_VNFS_FOR_CHANGE_MANAGEMENT_JSON_BY_PARAMS);
240                 }
241             }, APPEND);
242         }
243
244
245         SimulatorApi.registerExpectationFromPreset(new PresetAAIGetSubscribersGet(), SimulatorApi.RegistrationStrategy.APPEND);
246
247         if (Features.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH.isActive()) {
248             SimulatorApi.registerExpectationFromPreset(new PresetAAIGetTenants(
249                             VNF_DATA_WITH_IN_PLACE.subscriberId,
250                             VNF_DATA_WITH_IN_PLACE.serviceType),
251                     SimulatorApi.RegistrationStrategy.APPEND);
252
253         }
254
255         registerDefaultTablesData();
256         resetGetServicesCache();
257     }
258
259     private void registerDefaultTablesData() {
260         SimulatorApi.registerExpectation(
261                 new String[]{"changeManagement/get_scheduler_details_short.json",
262                         "changeManagement/mso_get_change_managements.json"
263                         , "changeManagement/delete_scheduled_task.json"},
264                 ImmutableMap.of(
265                         "<SCHEDULE_ID>", SCHEDULED_ID,
266                         "<IN_PROGRESS_DATE>", "Fri, 08 Sep 2017 19:34:32 GMT"), APPEND
267         );
268     }
269
270     @BeforeClass
271     protected void prepareSpecialVNFs() {
272
273         dropSpecialVNFs();
274
275         System.out.println("Connecting database...");
276
277         try (Connection connection = DriverManager.getConnection(DB_CONFIG.url, DB_CONFIG.username, DB_CONFIG.password)) {
278
279             System.out.println("Database connected!");
280
281             ///////////////////////////////
282             // Add 2 vnfs with some workflows
283             Statement stmt = connection.createStatement();
284             stmt.addBatch("INSERT INTO `vid_vnf` (`VNF_DB_ID`, `VNF_APP_UUID`, `VNF_APP_INVARIANT_UUID`) " +
285                     "VALUES (" + VNF_DATA_WITH_IN_PLACE.vnfZrdm3amdns02test2Id + ", '76e908e0-5201-44d2-a3e2-9e6128d05820', '72e465fe-71b1-4e7b-b5ed-9496118ff7a8')");
286             stmt.addBatch("INSERT INTO `vid_vnf_workflow` (`VNF_DB_ID`, `WORKFLOW_DB_ID`) VALUES (" + VNF_DATA_WITH_IN_PLACE.vnfZrdm3amdns02test2Id + ", 2)");
287             stmt.addBatch("INSERT INTO `vid_vnf_workflow` (`VNF_DB_ID`, `WORKFLOW_DB_ID`) VALUES (" + VNF_DATA_WITH_IN_PLACE.vnfZrdm3amdns02test2Id + ", 3)");
288             stmt.addBatch("INSERT INTO `vid_vnf_workflow` (`VNF_DB_ID`, `WORKFLOW_DB_ID`) VALUES (" + VNF_DATA_WITH_IN_PLACE.vnfZrdm3amdns02test2Id + ", 4)");
289             int[] executeBatch = stmt.executeBatch();
290             assertThat(Ints.asList(executeBatch), everyItem(greaterThan(0)));
291
292             stmt = connection.createStatement();
293             stmt.addBatch("INSERT INTO `vid_vnf` (`VNF_DB_ID`, `VNF_APP_UUID`, `VNF_APP_INVARIANT_UUID`) " +
294                     "VALUES (" + VNF_DATA_WITH_IN_PLACE.vnfHarrisonKrisId + ", '0903e1c0-8e03-4936-b5c2-260653b96413', '00beb8f9-6d39-452f-816d-c709b9cbb87d')");
295             stmt.addBatch("INSERT INTO `vid_vnf_workflow` (`VNF_DB_ID`, `WORKFLOW_DB_ID`) VALUES (" + VNF_DATA_WITH_IN_PLACE.vnfHarrisonKrisId + ", 1)");
296             stmt.addBatch("INSERT INTO `vid_vnf_workflow` (`VNF_DB_ID`, `WORKFLOW_DB_ID`) VALUES (" + VNF_DATA_WITH_IN_PLACE.vnfHarrisonKrisId + ", 2)");
297             executeBatch = stmt.executeBatch();
298             assertThat(Ints.asList(executeBatch), everyItem(greaterThan(0)));
299
300         } catch (SQLException e) {
301             throw new IllegalStateException("Cannot connect the database!", e);
302         }
303
304     }
305
306     @Override
307     protected UserCredentials getUserCredentials() {
308
309         String userName = Constants.Users.EMANUEL_vWINIFRED;
310         User user = usersService.getUser(userName);
311         return new UserCredentials(user.credentials.userId, user.credentials.password, userName, "", "");
312     }
313
314     private void updateConfigFile(String fileName) {
315         Assert.assertFalse(Exists.byId(Constants.ChangeManagement.newModalConfigUpdateInputId));
316         openAndFill1stScreen(VNF_DATA_WITH_IN_PLACE.vnfName, VNF_DATA_WITH_IN_PLACE.vnfTargetVersion, "VNF Config Update");
317         Assert.assertFalse(Get.byId(Constants.generalSubmitButtonId).isEnabled());
318         Input.file("changeManagement/" + fileName, Constants.ChangeManagement.newModalConfigUpdateInputId);
319         GeneralUIUtils.ultimateWait();
320     }
321
322     @Test
323     public void regretToCancelWorkflowOnPendingPopUp() {
324         updateSimulatorWithParametersOfScheduledJod("get_scheduler_details_short.json");
325         ChangeManagementPage.openChangeManagementPage();
326
327         Wait.angularHttpRequestsLoaded();
328         ChangeManagementPage.clickOnRefreshButton();
329
330         GeneralUIUtils.ultimateWait();
331         clickAndAssertOnCancelButton(SCHEDULED_ID);
332         Click.byClass("pull-right modal-close");
333         //TODO: if refresh button functional will be change to refactor next line.
334         ChangeManagementPage.clickOnRefreshButton();
335
336         assertAndCheckStatusCellOnDeletedSheduledJob(SCHEDULED_ID, "cancel-action icon-pending");
337     }
338
339     @Test
340     public void clickOnScheduledJob_SuccessfulMessageAppear() {
341
342         SimulatorApi.registerExpectationFromPreset(new PresetDeleteSchedulerChangeManagement(), APPEND);
343
344         ChangeManagementPage.openChangeManagementPage();
345         GeneralUIUtils.ultimateWait();
346         clickAndAssertOnCancelButton(SCHEDULED_ID);
347         updateSimulatorWithParametersOfScheduledJod("get_scheduler_details_short_with_after_cancel" +
348                 ".json");
349
350         clickAndAssertClickOnCancelWorkflowButtonOnPendingPopUp();
351
352         GeneralUIUtils.ultimateWait();
353         //TODO: To develop automatic table refresh to avoid click on refresh button.
354         ChangeManagementPage.clickOnRefreshButton();
355         assertCorrectJobDeleted("ctsf0002v");
356
357         assertAndCheckStatusCellOnDeletedSheduledJob(SCHEDULED_ID, "ng-hide");
358
359
360     }
361
362     private void clickAndAssertOnCancelButton(String scheduledID) {
363         Wait.waitByTestId("icon-status-" + scheduledID, 5);
364         Click.byTestId("icon-status-" + scheduledID);
365         GeneralUIUtils.ultimateWait();
366         WebElement cancelPendingConfirmationMessage = Get.byTestId("btn-cancel-workflow");
367         assertThat(cancelPendingConfirmationMessage.getText(), containsString("Are you sure you want to delete workflow"));
368         screenshot("delete workflow");
369     }
370
371     private void clickAndAssertClickOnCancelWorkflowButtonOnPendingPopUp() {
372
373         try {
374             Click.byClass(Constants.ChangeManagement.pendingModalCancelWorkflowButtonClass);
375             GeneralUIUtils.ultimateWait();
376             Assert.assertTrue(Exists.byClassAndText(Constants.generalModalTitleClass, "Success"));
377         } finally {
378             if (Exists.byClassAndText("modal-title", "Pending")) {
379                 Click.byClass("pull-right modal-close");
380             }
381         }
382         screenshot("cancel workflow");
383         Click.byClassAndVisibleText("btn", "OK");
384     }
385
386     private void assertCorrectJobDeleted(String vnfName) {
387         WebElement canceledScheduledJobRow = GeneralUIUtils.getWebElementByTestID("pending-table-cm-row");
388         String scheduledVnfName = ((RemoteWebElement) canceledScheduledJobRow).findElementsByTagName("td").get(1).getText();
389         String scheduledState = ((RemoteWebElement) canceledScheduledJobRow).findElementsByTagName("td").get(5).getText();
390         Assert.assertEquals(vnfName, scheduledVnfName);
391         Assert.assertEquals("Deleted", scheduledState);
392     }
393
394     private void assertAndCheckStatusCellOnDeletedSheduledJob(String scheduledId, String classString) {
395         boolean isNotDisplayed = GeneralUIUtils.waitForElementInVisibilityByTestId("icon-status-" + scheduledId, 5);
396         Assert.assertTrue(isNotDisplayed);
397     }
398
399     public void updateSimulatorWithParametersOfScheduledJod(String jasonFile) {
400         SimulatorApi.registerExpectation(
401                 new String[]{"changeManagement/" + jasonFile},
402                 ImmutableMap.of("<SCHEDULE_ID>", SCHEDULED_ID), APPEND
403         );
404     }
405
406     @FeatureTogglingTest(value = Features.FLAG_HANDLE_SO_WORKFLOWS, flagActive = false)
407     @Test
408     public void testWorkflowVNFInPlaceSoftwareUpdateNotInWorkflowsListWhenNotExpected() {
409
410         List<String> workflows = getListOfWorkflowsFor("Harrison Kris");
411         assertThat(workflows, not(hasItem(VNF_DATA_WITH_IN_PLACE.workflowName)));
412     }
413
414     @FeatureTogglingTest(value = Features.FLAG_HANDLE_SO_WORKFLOWS, flagActive = false)
415     @Test
416     public void testWorkflowVNFInPlaceSoftwareUpdateInWorkflowsListWhenExpected() {
417         List<String> workflows = getListOfWorkflowsFor(VNF_DATA_WITH_IN_PLACE.vnfName);
418         assertThat(workflows, hasItem(VNF_DATA_WITH_IN_PLACE.workflowName));
419     }
420
421     public void openAndFill1stScreenWithWorkflowVNFInPlaceSoftwareUpdate() {
422         openAndFill1stScreen(VNF_DATA_WITH_IN_PLACE.vnfName, VNF_DATA_WITH_IN_PLACE.vnfTargetVersion, VNF_DATA_WITH_IN_PLACE.workflowName);
423     }
424
425     @AfterMethod(alwaysRun = true)
426     public void screenshotAndCloseForm(ITestResult testResult) {
427
428         screenshot(testResult.getName() + (testResult.isSuccess() ? "" : " FAIL"));
429
430         // Tries closing left-out popups, if any
431         // If none -- catch clause will swallow the exception
432         try {
433             Click.byId(Constants.generalCancelButtonId);
434             Click.byId(Constants.generalCancelButtonId);
435             Click.byId(Constants.generalCancelButtonId);
436         } catch (Exception | Error e) {
437             // ok, stop
438         }
439         Wait.modalToDisappear();
440     }
441
442     protected void screenshot(String testName) {
443         try {
444             ExtentTestActions.addScreenshot(Status.INFO, "ChangeManagementTest." + testName, testName);
445         } catch (IOException e) {
446             rethrow(e);
447         }
448     }
449
450     @Test
451     public void testWorkflowVNFInPlaceSoftwareUpdateShows3Fields() {
452
453         openAndFill1stScreenWithWorkflowVNFInPlaceSoftwareUpdate();
454
455         List<String> idsWithoutMatchingElement =
456                 Stream.of(
457                         "internal-workflow-parameter-text-2-operations-timeout",
458                         "internal-workflow-parameter-text-3-existing-software-version",
459                         "internal-workflow-parameter-text-4-new-software-version")
460                         .filter(id -> Get.byId(id) == null)
461                         .collect(Collectors.toList());
462         assertThat("all three special VNFInPlace fields should appear", idsWithoutMatchingElement, is(empty()));
463
464         assertThat(Get.byId(Constants.generalSubmitButtonId).isEnabled(), is(false));
465     }
466
467     @Test
468     public void testWorkflowVNFInPlaceSoftwareUpdate3ValidValues() {
469         openAndFill1stScreenWithWorkflowVNFInPlaceSoftwareUpdate();
470
471         final String[][] options = {
472                 {"true", "111", "222", "333"}
473                 , {"true", "14710454", "Cz-Ou0EK5eH9.gAK1", "G9bUiFX3QM8xpxF8TlZ7b5T0"}
474                 , {"true", "25316893", "fMx9V5kp.5.JGtYRhNGVTPoJ", "Jv5IieY0kTNjkfZ64bHXngR6"}
475                 , {"true", "8", "3t3MhTRqkyjB85o5NC9OacAw", "B.bJ6f7KYI6WzDMR0fyNM9r4"}
476                 , {"true", "3176", "ZlRS7tczf0cbMxQbBfyc6AP5", "1G1"}
477                 , {"true", "78058488", "n", "WkH"}
478                 , {"true", "501778", "1.d74LrJbBmcR.7bfvH.UZMX", "tFTAel7PS4RKEJeJ0b6mTeVT"}
479                 , {"true", "76639623", "m2.EhbBxRE.rJj3j6qDtMxGR", "Rgkm-EPM1K0KAWm43Ex1wwjj"}
480                 , {"true", "91244280", "zPDHRrXW65xR6GV.gVZND8C0", "mkrqFG26m7Vmv-28etQVyp04"}
481                 , {"true", "8966", "7k2sRK2qSFRVCFpEvrlbmxAL", "IlvfmWTqzpF0Jo3elpZPHXx"}
482                 , {"true", "01303495", "G26yl8B0NbLIKxu23h86QbZz", "vSou1seqCrcv9KoVbhlj4Wa4"}
483                 , {"true", "787", "ce7joKCHYowpM2PtCb53Zs2v", ".qw1oY9HKjfAF2Yt05JNgib9"}
484                 , {"true", "40116583", "-3bDEzEn.RbNnT2hWKQqf2HL", "QzlKlKZiIpc7sQ.EzO"}
485                 , {"false", "", "222", "333"}
486                 , {"false", "111", "", "333"}
487                 , {"false", "111", "222", ""}
488                 , {"false", "111a", "222", "333"}
489                 , {"false", "aaa", "222", "333"}
490                 , {"false", "111-", "222", "333"}
491 //                , {"false", " 111", "222", "333"}
492 //                , {"false", "111", "222 ", "333"}
493 //                , {"false", "111", "222", " 333"}
494                 , {"false", "111", "222", "3 33"}
495                 , {"false", "111", "22,2", "333"}
496                 , {"false", "111", "222~", "333"}
497                 , {"false", "111", "222", "333&"}
498                 , {"false", "$", "222", "333"}
499                 , {"false", "111", "@", "333"}
500                 , {"false", "111", "222", "^^^^^^"}
501         };
502
503         for (String[] option : options) {
504             fillVNFInPlace3Fields(option[1], option[2], option[3]);
505             assertThat("failed for set: " + Arrays.toString(option),
506                     Get.byId(Constants.generalSubmitButtonId).isEnabled(), is(Boolean.parseBoolean(option[0])));
507         }
508
509     }
510
511     private void fillVNFInPlace3Fields(String operationsTimeout, String existingSwVersion, String newSwVersion) {
512         Get.byId("internal-workflow-parameter-text-2-operations-timeout").clear();
513         Get.byId("internal-workflow-parameter-text-3-existing-software-version").clear();
514         Get.byId("internal-workflow-parameter-text-4-new-software-version").clear();
515
516         Get.byId("internal-workflow-parameter-text-2-operations-timeout").sendKeys(operationsTimeout);
517         Get.byId("internal-workflow-parameter-text-3-existing-software-version").sendKeys(existingSwVersion);
518         Get.byId("internal-workflow-parameter-text-4-new-software-version").sendKeys(newSwVersion);
519     }
520
521     private List<String> getListOfWorkflowsFor(String vnfName) {
522
523         openAndFill1stScreen(vnfName, null /*no matter*/, "Replace");
524
525         Select selectlist = new Select(Get.byId("workflow"));
526         List<String> workflows = selectlist.getOptions().stream().map(we -> we.getText()).collect(Collectors.toList());
527
528         Click.byId(Constants.generalCancelButtonId);
529
530         return workflows;
531     }
532
533     @DataProvider
534     public static Object[][] dataForUpdateWorkflowPartialWithInPlace() {
535         return new Object[][]{
536                 {"1111", "22222", "33333"}
537                 , {"8", "3t3MhTRqkyjB85o5NC9OacAw", "B.bJ6f7KYI6Wz-----DMR0.fyNM9r4"}
538                 , {"78058488", "n", "WkH"}
539         };
540     }
541
542     @Test(dataProvider = "dataForUpdateWorkflowPartialWithInPlace")
543     public void testVidToMsoCallbackDataWithInPlaceSWUpdate(String operationsTimeout, String existingSwVersion, String newSwVersion) {
544
545         openAndFill1stScreenWithWorkflowVNFInPlaceSoftwareUpdate();
546         fillVNFInPlace3Fields(operationsTimeout, existingSwVersion, newSwVersion);
547
548         assertThatVidToPortalCallbackDataIsOk(VNF_DATA_WITH_IN_PLACE.workflowName, ImmutableMap.of(
549                 "existingSoftwareVersion", existingSwVersion,
550                 "newSoftwareVersion", newSwVersion,
551                 "operationTimeout", operationsTimeout
552         ));
553     }
554
555     @Test
556     public void testUploadConfigUpdateFile() {
557         String fileName = "configuration_file.csv";
558         updateConfigFile(fileName);
559         Assert.assertEquals(Get.byId(Constants.ChangeManagement.newModalConfigUpdateInputId + "-label").getText(), fileName);
560         Assert.assertTrue(Get.byId(Constants.generalSubmitButtonId).isEnabled());
561         assertThatVidToPortalCallbackDataIsOk("VNF Config Update", ImmutableMap.of(
562                 "configUpdateFile",
563                 "{\"request-parameters\":{\"vm\":[{\"vnfc\":["
564                         + "{\"vnfc-name\":\"ibcx0001vm001dbg001\",\"vnfc-function-code\":\"dbg\"}],\"vm-name\":\"ibcx0001vm001\"},"
565                         + "{\"vnfc\":[{\"vnfc-name\":\"ibcx0001vm002dbg001\"}],\"vm-name\":\"ibcx0001vm002\"}]},\"configuration-parameters\":{\"node0_hostname\":\"dbtx0001vm001\"}}"
566         ));
567     }
568
569     @FeatureTogglingTest(value = Features.FLAG_FLASH_CLOUD_REGION_AND_NF_ROLE_OPTIONAL_SEARCH, flagActive = false)
570     @Test
571     public void testUploadConfigUpdateNonCsvFile() {
572         String fileName = "non-valid.json";
573         updateConfigFile(fileName);
574         WebElement errorLabel = Get.byId("errorLabel");
575         Assert.assertEquals("wrong error message for non csv file", "Invalid file type. Please select a file with a CSV extension.", errorLabel.getText());
576         Assert.assertFalse(Get.byId(Constants.generalSubmitButtonId).isEnabled());
577     }
578
579     @Test(dataProvider = "invalidCsvFiles")
580     public void testUploadInvalidConfigUpdateFile(String fileName) {
581         updateConfigFile(fileName);
582         WebElement errorLabel = Get.byId("errorContentLabel");
583         Assert.assertEquals("wrong error message for non csv file", "Invalid file structure.", errorLabel.getText());
584         Assert.assertFalse(Get.byId(Constants.generalSubmitButtonId).isEnabled());
585     }
586
587     @DataProvider
588     public static Object[][] invalidCsvFiles() {
589         return new Object[][]{
590                 {"emptyFile.csv"},
591                 {"withoutPayload.csv"},
592                 {"withoutConfigurationParameters.csv"},
593                 {"withoutRequestParameters.csv"}
594         };
595     }
596
597     @Test
598     public void testVidToMsoCallbackData() {
599         String workflow = "Replace";
600
601         openAndFill1stScreen(VNF_DATA_WITH_IN_PLACE.vnfName, VNF_DATA_WITH_IN_PLACE.vnfTargetVersion, workflow);
602
603         assertThatVidToPortalCallbackDataIsOk(workflow, emptyMap());
604     }
605
606     private void assertThatVidToMsoCallbackDataIsOk(String workflow, String payload) {
607         Assert.assertTrue(Get.byId(Constants.generalSubmitButtonId).isEnabled());
608         Click.byId(Constants.generalSubmitButtonId);
609
610         String vidToMsoCallbackData = Input.getValueByTestId("vidToMsoCallbackData");
611
612         String modelInvariantId = "72e465fe-71b1-4e7b-b5ed-9496118ff7a8";
613         String vnfInstanceId = "8e5e3ba1-3fe6-4d86-966e-f9f03dab4855";
614         String expected = getExpectedVidToMsoCallbackData(modelInvariantId, vnfInstanceId, VNF_DATA_WITH_IN_PLACE.vnfName, VNF_DATA_WITH_IN_PLACE.vnfTargetVersion, workflow, payload);
615
616         try {
617             JSONAssert.assertEquals("built mso request is not ok", expected, vidToMsoCallbackData, JSONCompareMode.STRICT);
618         } catch (JSONException e) {
619             throw new RuntimeException(e);
620         }
621
622         Click.byId(Constants.generalCancelButtonId);
623     }
624
625     private void assertThatVidToPortalCallbackDataIsOk(String workflowName, Map<String, String> workflowParams) {
626         screenshot("submit to scheduler");
627         Assert.assertTrue(Get.byId(Constants.generalSubmitButtonId).isEnabled());
628         Click.byId(Constants.generalSubmitButtonId);
629
630         String errorMessage = GeneralUIUtils.getWebElementByTestID("error-message", 2).getText();
631
632         String modelInvariantId = "72e465fe-71b1-4e7b-b5ed-9496118ff7a8";
633         String vnfInstanceId = "8e5e3ba1-3fe6-4d86-966e-f9f03dab4855";
634
635         assertThat(errorMessage, startsWith(SCHEDULE_ERROR_PREFIX));
636         assertThat(errorMessage.replace(SCHEDULE_ERROR_PREFIX, ""), jsonEquals(
637                 ImmutableMap.of(
638                         "widgetName", "Portal-Common-Scheduler",
639                         "widgetParameter", "",
640                         "widgetData", ImmutableMap.builder()
641                                 .put("vnfNames", ImmutableList.of(ImmutableMap.of(
642                                         "id", vnfInstanceId,
643                                         "invariant-id", modelInvariantId,
644                                         "version", "5.0"
645                                 )))
646                                 .put("workflowParameters", emptyMap())
647                                 .put("subscriberId", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb")
648                                 .put("fromVNFVersion", "" + "76e908e0-5201-44d2-a3e2-9e6128d05820" + "")
649                                 .put("workflow", "" + workflowName + "")
650                                 .put("policyYN", "Y")
651                                 .put("sniroYN", "Y")
652                                 .put("testApi", "VNF_API")
653                                 .put("vnfType", "vMobileDNS")
654                                 .putAll(workflowParams)
655                                 .build()
656                 )
657         ).when(Option.IGNORING_EXTRA_FIELDS));
658
659
660         Click.byId(Constants.generalCancelButtonId);
661     }
662
663     @Test(enabled = false)
664     public void testUpdateWorkflowNow() {
665
666         String workflow = "Update";
667
668         String duration = "1";
669         String fallback = "1";
670         String concurrencyLimit = "1";
671         String policy = "SNIRO_1710.Config_MS_PlacementOptimizationPolicy_dhv_v1.1.xml";
672
673         openAndFill1stScreen(VNF_DATA_WITH_IN_PLACE.vnfName, VNF_DATA_WITH_IN_PLACE.vnfTargetVersion, workflow);
674         Assert.assertTrue(Get.byId(Constants.generalSubmitButtonId).isEnabled());
675         Click.byId(Constants.generalSubmitButtonId);
676
677         scheduleChange2ndScreen(duration, fallback, concurrencyLimit, policy);
678     }
679
680     @Test
681     public void testNewChangeManagementCreation() {
682         ChangeManagementPage.openChangeManagementPage();
683
684         //TODO: After scheduler will be ready than we will examine if the creation working fine.
685     }
686
687     @Test
688     public void testMainDashboardTable() {
689         ChangeManagementPage.openChangeManagementPage();
690         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.dashboardActiveTabId));
691         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.dashboardFinishedTabId));
692
693         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.dashboardActiveTableId));
694         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.dashboardInProgressTheadId));
695         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.dashboardPendingTheadId));
696
697         Click.byId(Constants.ChangeManagement.dashboardFinishedTabId);
698         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.dashboardFinishedTableId));
699         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.dashboardFinishedTheadId));
700
701         Click.byId(Constants.ChangeManagement.dashboardActiveTabId);
702     }
703
704     @Test
705     public void testFinishedSectionIncludeUnlockedItem() {
706         ChangeManagementPage.openChangeManagementPage();
707         Click.byId(Constants.ChangeManagement.dashboardFinishedTabId);
708         Assert.assertThat(Get.byClassAndText("vnf-name", "Unlocked instance"), is(notNullValue()));
709     }
710
711     @Test
712     public void testMainDashboardTableContent() {
713         ChangeManagementPage.openChangeManagementPage();
714         GeneralUIUtils.ultimateWait();
715         List<WebElement> webElements = Get.multipleElementsByTestId(Constants.ChangeManagement.activeTableRowId);
716         assertThat("List of pending workflows is empty", webElements, is(not(empty())));
717         //TODO: After scheduler will be ready than we will examine if the content is valid.
718     }
719
720     @Test
721     public void testOnlyOneModalIsOpen() throws Exception {
722
723         updateSimulatorWithParametersOfScheduledJod("mso_get_change_managements.json");
724
725         ChangeManagementPage.openChangeManagementPage();
726
727         Wait.byText("ReplaceVnfInfra");
728         GeneralUIUtils.ultimateWait();
729
730
731         List<WebElement> elements = Get.byClass(Constants.ChangeManagement.pendingIconClass);
732         Assert.assertTrue(elements != null && elements.size() > 0);
733
734         ((JavascriptExecutor) getDriver()).executeScript("arguments[0].scrollIntoView();", elements.get(0));
735
736
737         elements.get(0).click();
738
739         GeneralUIUtils.ultimateWait();
740
741         elements = Get.byClass(Constants.ChangeManagement.pendingIconClass);
742         Assert.assertTrue(elements != null && elements.size() > 0);
743         elements.get(2).click();
744
745         GeneralUIUtils.ultimateWait();
746         List<WebElement> webElements = Get.byClass("modal-dialog");
747         Assert.assertTrue(webElements.size() == 1);
748
749     }
750
751     @Test(enabled = false)
752     public void testOpenFailedStatusModal() {
753         ChangeManagementPage.openChangeManagementPage();
754
755         if (!Exists.byClass(Constants.ChangeManagement.failedIconClass)) {
756             //TODO: Create a job which will shown with status fail.
757         }
758
759         Click.byClass(Constants.ChangeManagement.failedIconClass);
760         Wait.modalToBeDisplayed();
761         Assert.assertTrue(Exists.modal());
762         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.failedModalHeaderId));
763         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.failedModalContentId));
764         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.failedModalRetryButtonId));
765         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.failedModalRollbackButtonId));
766
767         Click.byClass(Constants.generalCloseModalButtonClass);
768         Wait.modalToDisappear();
769     }
770
771     @Test(enabled = false)
772     public void testOpenInProgressStatusModal() {
773         ChangeManagementPage.openChangeManagementPage();
774
775         if (!Exists.byClass(Constants.ChangeManagement.processIconClass)) {
776             //TODO: Create a job which will shown with status in-progress.
777         }
778
779         Click.byClass(Constants.ChangeManagement.processIconClass);
780         Wait.modalToBeDisplayed();
781         Assert.assertTrue(Exists.modal());
782         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.inProgressModalHeaderId));
783         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.inProgressModalContentId));
784         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.inProgressModalStopButtonId));
785         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.inProgressModalRollbackButtonId));
786
787         Click.byClass(Constants.generalCloseModalButtonClass);
788         Wait.modalToDisappear();
789     }
790
791     @Test(enabled = false)
792     public void testOpenAlertStatusModal() {
793         ChangeManagementPage.openChangeManagementPage();
794
795         if (!Exists.byClass(Constants.ChangeManagement.alertIconClass)) {
796             //TODO: Create a job which will shown with status alert.
797         }
798
799         Click.byClass(Constants.ChangeManagement.alertIconClass);
800         Wait.modalToBeDisplayed();
801         Assert.assertTrue(Exists.modal());
802         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.alertModalHeaderId));
803         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.alertModalContentId));
804         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.alertModalContinueButtonId));
805         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.alertModalRollbackButtonId));
806
807         Click.byClass(Constants.generalCloseModalButtonClass);
808         Wait.modalToDisappear();
809     }
810
811     @Test(enabled = false)
812     public void testOpenPendingStatusModal() {
813         ChangeManagementPage.openChangeManagementPage();
814
815         if (!Exists.byClass(Constants.ChangeManagement.pendingIconClass)) {
816             //TODO: Create a job which will shown with status pending.
817         }
818
819         Click.byClass(Constants.ChangeManagement.pendingIconClass);
820         Wait.modalToBeDisplayed();
821         Assert.assertTrue(Exists.modal());
822         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.pendingModalHeaderId));
823         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.pendingModalContentId));
824         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.pendingModalRescheduleButtonId));
825         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.pendingModalRollbackButtonId));
826
827         Click.byClass(Constants.generalCloseModalButtonClass);
828         Wait.modalToDisappear();
829     }
830
831     @Test
832     public void testSuccessCancelPendingWorkflow() {
833         ChangeManagementPage.openChangeManagementPage();
834         Wait.angularHttpRequestsLoaded();
835
836         Click.byClass(Constants.ChangeManagement.cancelPendingButtonClass); //cancel pending workflow modal
837         Wait.modalToBeDisplayed();
838         Assert.assertTrue(Exists.modal());
839         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.pendingModalHeaderId));
840         Assert.assertTrue(Exists.byClass(Constants.ChangeManagement.pendingModalCancelWorkflowButtonClass));
841         screenshot("pendingModalCancelWorkflow");
842         Click.byClass(Constants.ChangeManagement.pendingModalCancelWorkflowButtonClass);
843         Wait.angularHttpRequestsLoaded();
844
845         Wait.modalToBeDisplayed(); //success alert modal should appear
846         Assert.assertTrue(Exists.modal());
847         Assert.assertTrue(Exists.byId(Constants.ChangeManagement.alertModalHeaderId));
848         Assert.assertTrue(Exists.byClassAndText(Constants.generalModalTitleClass, "Success"));
849         screenshot("successCancelWorkflow");
850         Click.byClass(Constants.generalCloseModalButtonClass);
851         Wait.modalToDisappear();
852         //TODO check the workflow deleted from table/changed to deleted action
853     }
854
855     @Test
856     public void testRefreshPageButton() {
857         ChangeManagementPage.openChangeManagementPage();
858         GeneralUIUtils.ultimateWait();
859         List<WebElement> pendingRows = Get.multipleElementsByTestId(Constants.ChangeManagement.pendingTableRowId);
860         List<WebElement> activeRows = Get.multipleElementsByTestId(Constants.ChangeManagement.activeTableRowId);
861         assertThat("The pending table has no content", pendingRows, is(not(empty())));
862         assertThat("The active table has no content", activeRows, is(not(empty())));
863         Click.byTestId(Constants.ChangeManagement.refreshBtnTestId);
864         GeneralUIUtils.ultimateWait();
865         pendingRows = Get.multipleElementsByTestId(Constants.ChangeManagement.pendingTableRowId);
866         assertThat("The pending table has no content", pendingRows, is(not(empty())));
867         assertThat("The active table has no content", activeRows, is(not(empty())));
868         //return the register requests to the default state
869         registerDefaultTablesData();
870     }
871
872     private String getExpectedVidToMsoCallbackData(String modelInvariantId, String vnfInstanceId, String vnfName, String vnfTargetVersion, String workflow, String payload) {
873         return "" +
874                 "{" +
875                 "  \"requestType\": \"" + workflow + "\"," +
876                 "  \"requestDetails\": [" +
877                 "    {" +
878                 "      \"vnfName\": \"" + vnfName + "\"," +
879                 "      \"vnfInstanceId\": \"" + vnfInstanceId + "\"," +
880                 "      \"modelInfo\": {" +
881                 "        \"modelType\": \"vnf\"," +
882                 "        \"modelInvariantId\": \"" + modelInvariantId + "\"," +
883                 "        \"modelVersionId\": \"76e908e0-5201-44d2-a3e2-9e6128d05820\"," +
884                 "        \"modelName\": \"" + vnfName + "\"," +
885                 "        \"modelVersion\": \"" + vnfTargetVersion + "\"," +
886                 "        \"modelCustomizationId\": \"c00e8fc8-af39-4da8-8c78-a7efc2fe5994\"" +
887                 "      }," +
888                 "      \"cloudConfiguration\": {" +
889                 "        \"lcpCloudRegionId\": \"mdt1\"," +
890                 "        \"tenantId\": \"88a6ca3ee0394ade9403f075db23167e\"" +
891                 "      }," +
892                 "      \"requestInfo\": {" +
893                 "        \"source\": \"VID\"," +
894                 "        \"suppressRollback\": false," +
895                 "        \"requestorId\": \"az2016\"" +
896                 "      }," +
897                 "      \"relatedInstanceList\": [" +
898                 "        {" +
899                 "          \"relatedInstance\": {" +
900                 "            \"instanceId\": \"97315a05-e6f3-4c47-ae7e-d850c327aa08\"," +
901                 "            \"modelInfo\": {" +
902                 "              \"modelType\": \"service\"," +
903                 "              \"modelInvariantId\": \"e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0\"," +
904                 "              \"modelVersionId\": \"76e908e0-5201-44d2-a3e2-9e6128d05820\"," +
905                 "              \"modelName\": \"action-data\"," +
906                 "              \"modelVersion\": \"1.0\"" +
907                 "            }" +
908                 "          }" +
909                 "        }" +
910                 "      ]," +
911                 "      \"requestParameters\": {" +
912                 payload +
913                 "        \"usePreload\": true" +
914                 "      }" +
915                 "    }" +
916                 "  ]" +
917                 "}";
918     }
919
920 }