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