10176b2a50b46f15e87e33c96913799e0241c382
[sdc.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.sdc.frontend.ci.tests.execute.sanity;
21
22 import static org.hamcrest.MatcherAssert.assertThat;
23 import static org.hamcrest.Matchers.anEmptyMap;
24 import static org.hamcrest.Matchers.empty;
25 import static org.hamcrest.Matchers.emptyString;
26 import static org.hamcrest.Matchers.hasSize;
27 import static org.hamcrest.Matchers.is;
28 import static org.hamcrest.Matchers.not;
29 import static org.hamcrest.Matchers.notNullValue;
30 import static org.junit.jupiter.api.Assertions.assertEquals;
31 import static org.junit.jupiter.api.Assertions.assertNotEquals;
32 import static org.junit.jupiter.api.Assertions.assertNotNull;
33 import static org.junit.jupiter.api.Assertions.assertTrue;
34 import static org.junit.jupiter.api.Assertions.fail;
35
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Map.Entry;
43 import java.util.Optional;
44 import java.util.stream.Collectors;
45
46 import org.onap.sdc.backend.ci.tests.data.providers.OnboardingDataProviders;
47 import org.onap.sdc.backend.ci.tests.datatypes.enums.ComponentType;
48 import org.onap.sdc.backend.ci.tests.datatypes.enums.ResourceCategoryEnum;
49 import org.onap.sdc.backend.ci.tests.utils.general.ElementFactory;
50 import org.onap.sdc.frontend.ci.tests.datatypes.ComponentData;
51 import org.onap.sdc.frontend.ci.tests.datatypes.DirectiveType;
52 import org.onap.sdc.frontend.ci.tests.datatypes.LogicalOperator;
53 import org.onap.sdc.frontend.ci.tests.datatypes.ResourceCreateData;
54 import org.onap.sdc.frontend.ci.tests.datatypes.ServiceDependencyProperty;
55 import org.onap.sdc.frontend.ci.tests.datatypes.composition.RelationshipInformation;
56 import org.onap.sdc.frontend.ci.tests.exception.UnzipException;
57 import org.onap.sdc.frontend.ci.tests.execute.setup.DriverFactory;
58 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
59 import org.onap.sdc.frontend.ci.tests.execute.setup.SetupCDTest;
60 import org.onap.sdc.frontend.ci.tests.flow.AddComponentPropertyFlow;
61 import org.onap.sdc.frontend.ci.tests.flow.AddNodeToCompositionFlow;
62 import org.onap.sdc.frontend.ci.tests.flow.CreateDirectiveNodeFilterFlow;
63 import org.onap.sdc.frontend.ci.tests.flow.CreateSubstitutionFilterFlow;
64 import org.onap.sdc.frontend.ci.tests.flow.CreateVfFlow;
65 import org.onap.sdc.frontend.ci.tests.flow.CreateVfcFlow;
66 import org.onap.sdc.frontend.ci.tests.flow.DownloadCsarArtifactFlow;
67 import org.onap.sdc.frontend.ci.tests.flow.DownloadToscaTemplateFlow;
68 import org.onap.sdc.frontend.ci.tests.flow.EditComponentPropertiesFlow;
69 import org.onap.sdc.frontend.ci.tests.flow.composition.CreateRelationshipFlow;
70 import org.onap.sdc.frontend.ci.tests.flow.exception.UiTestFlowRuntimeException;
71 import org.onap.sdc.frontend.ci.tests.pages.AttributesOutputsPage;
72 import org.onap.sdc.frontend.ci.tests.pages.ComponentPage;
73 import org.onap.sdc.frontend.ci.tests.pages.ResourceCreatePage;
74 import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesAssignmentPage;
75 import org.onap.sdc.frontend.ci.tests.pages.ResourcePropertiesPage;
76 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.CompositionPage;
77 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.RelationshipWizardInterfaceOperation.InterfaceOperationsData;
78 import org.onap.sdc.frontend.ci.tests.pages.component.workspace.ToscaArtifactsPage;
79 import org.onap.sdc.frontend.ci.tests.pages.home.HomePage;
80 import org.onap.sdc.frontend.ci.tests.utilities.FileHandling;
81 import org.openecomp.sdc.be.model.ComponentInstance;
82 import org.openqa.selenium.WebDriver;
83 import org.slf4j.Logger;
84 import org.slf4j.LoggerFactory;
85 import org.testng.annotations.BeforeMethod;
86 import org.testng.annotations.Test;
87 import org.yaml.snakeyaml.Yaml;
88
89 import com.aventstack.extentreports.Status;
90
91 public class ServiceTemplateDesignUiTests extends SetupCDTest {
92
93     private static final Logger LOGGER = LoggerFactory.getLogger(ServiceTemplateDesignUiTests.class);
94
95     private WebDriver webDriver;
96     private HomePage homePage;
97     private List<ResourceCreateData> vfcs = new ArrayList<>();
98     private ResourceCreateData vfResourceCreateData;
99     private ComponentInstance networkFunctionInstance;
100     private ComponentInstance networkServiceInstance;
101     private AddNodeToCompositionFlow addNodeToCompositionFlow;
102     private ComponentPage componentPage;
103     private Map<String, String> propertiesToBeAddedMap;
104     private ResourceCreatePage resourceCreatePage;
105     private final List<ServiceDependencyProperty> substitutionFilterProperties = new ArrayList<>();
106     private final String interfaceName = "Standard";
107     private final String interfaceOperationName = "create";
108     private final String implementationName = "IntegrationTest";
109     private final String inputName = "InputName1";
110     private final String inputValue = "InputValue1";
111
112     @BeforeMethod
113     public void init() {
114         webDriver = DriverFactory.getDriver();
115         homePage = new HomePage(webDriver);
116     }
117
118     @Test(dataProviderClass = OnboardingDataProviders.class, dataProvider = "vfcList")
119     public void importAndCertifyVfc(final String rootFolder, final String vfcFilename) {
120         setLog(vfcFilename);
121         final String resourceName = ElementFactory.addRandomSuffixToName(ElementFactory.getResourcePrefix());
122         final CreateVfcFlow createVfcFlow = createVFC(rootFolder + vfcFilename, resourceName);
123         vfcs.stream().filter(vfc -> vfc.getName().startsWith(resourceName)).findFirst().orElseThrow(
124             () -> new UiTestFlowRuntimeException(String.format("VFCs List should contain a VFC with the expected name %s", resourceName)));
125         final ResourceCreatePage vfcResourceCreatePage = createVfcFlow.getLandedPage()
126             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ResourceCreatePage"));
127         vfcResourceCreatePage.isLoaded();
128         vfcResourceCreatePage.certifyComponent();
129         ExtentTestActions.takeScreenshot(Status.INFO, "vfc-certified",
130             String.format("VFC '%s' was certified", resourceName));
131     }
132
133     @Test(dependsOnMethods = "importAndCertifyVfc")
134     public void createBaseService() {
135         final CreateVfFlow createVfFlow = createVF();
136        resourceCreatePage = createVfFlow.getLandedPage()
137             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ResourceCreatePage"));
138         resourceCreatePage.isLoaded();
139     }
140
141     @Test(dependsOnMethods = "createBaseService")
142     public void addComponentProperty() throws UnzipException {
143         propertiesToBeAddedMap = loadPropertiesToAdd();
144         addProperty(propertiesToBeAddedMap);
145         componentPage = addValueToProperty(loadPropertiesToEdit());
146         componentPage.isLoaded();
147         downloadAndVerifyCsarPackageAfterAddProperty(componentPage);
148     }
149
150     @Test(dependsOnMethods = "createBaseService")
151     public void addRelationshipTemplate() throws UnzipException {
152         homePage.isLoaded();
153         resourceCreatePage = (ResourceCreatePage) homePage.clickOnComponent(vfResourceCreateData.getName());
154         resourceCreatePage.isLoaded();
155         addNodeToCompositionFlow = addNodeToCompositionAndCreateRelationship();
156         final CompositionPage compositionPage = addNodeToCompositionFlow.getLandedPage()
157             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return CompositionPage"));
158         compositionPage.isLoaded();
159         componentPage = compositionPage.goToGeneral();
160         componentPage.isLoaded();
161         downloadAndVerifyCsarPackage(componentPage);
162     }
163
164     @Test(dependsOnMethods = "addRelationshipTemplate")
165     public void addOutputsToVF_test() throws UnzipException, IOException {
166         homePage.isLoaded();
167         final ComponentPage resourceCreatePage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
168         resourceCreatePage.isLoaded();
169
170         final AttributesOutputsPage attributesOutputsPage = resourceCreatePage.goToAttributesOutputs();
171         attributesOutputsPage.isLoaded();
172
173         final ComponentInstance createdComponentInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
174             .orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a ComponentInstance"));
175
176         attributesOutputsPage.clickOnAttributeNavigation(createdComponentInstance.getName());
177         assertTrue(attributesOutputsPage.isAttributePresent("attr_1"));
178         attributesOutputsPage.declareOutput("attr_1");
179         attributesOutputsPage.clickOnOutputsTab();
180         assertTrue(attributesOutputsPage.isOutputPresent("attr_1"));
181
182         attributesOutputsPage.clickOnAttributesTab();
183         assertTrue(attributesOutputsPage.isAttributePresent("attr_2"));
184         attributesOutputsPage.declareOutput("attr_2");
185         attributesOutputsPage.clickOnOutputsTab();
186         assertTrue(attributesOutputsPage.isOutputPresent("attr_2"));
187
188         attributesOutputsPage.clickOnAttributesTab();
189         assertTrue(attributesOutputsPage.isAttributePresent("attr_3"));
190         attributesOutputsPage.declareOutput("attr_3");
191         attributesOutputsPage.clickOnOutputsTab();
192         assertTrue(attributesOutputsPage.isOutputPresent("attr_3"));
193
194         attributesOutputsPage.deleteOutput(createdComponentInstance.getName() + "_attr_2");
195         attributesOutputsPage.clickOnAttributesTab();
196         assertTrue(attributesOutputsPage.isAttributePresent("attr_2"));
197         attributesOutputsPage.clickOnOutputsTab();
198         assertTrue(attributesOutputsPage.isOutputDeleted("attr_2"));
199
200         attributesOutputsPage.clickOnAttributesTab();
201         ExtentTestActions.addScreenshot(Status.INFO, "AttributesTab", "The Attribute's list : ");
202
203         attributesOutputsPage.clickOnOutputsTab();
204         ExtentTestActions.addScreenshot(Status.INFO, "OutputsTab", "The Output's list : ");
205
206         Map<String, Object> yamlObject = downloadToscaArtifact(attributesOutputsPage);
207         checkMetadata(yamlObject, vfResourceCreateData);
208         checkTopologyTemplate(yamlObject);
209     }
210
211     @Test(dependsOnMethods = "addComponentProperty")
212     public void createSubstitutionFilter() throws Exception {
213         componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
214         componentPage.isLoaded();
215         loadSubstitutionFilterProperties();
216         final CompositionPage compositionPage = componentPage.goToComposition();
217         compositionPage.isLoaded();
218         substitutionFilterProperties.forEach(substitutionFilterProperty -> {
219             final CreateSubstitutionFilterFlow createSubstitutionFilterFlow = new CreateSubstitutionFilterFlow(webDriver, substitutionFilterProperty);
220             createSubstitutionFilterFlow.run(compositionPage);
221         });
222         componentPage = compositionPage.goToGeneral();
223         componentPage.isLoaded();
224         verifyToscaTemplateHasSubstitutionFilter(downloadToscaTemplate());
225     }
226
227     @Test(dependsOnMethods = "createBaseService")
228     public void createDirectiveNodeFilterTest() throws Exception {
229         final ResourceCreateData vfcResourceCreateData = vfcs.get(1);
230         final String vfcNameInComposition = vfcResourceCreateData.getName().concat(" 0");
231         final String value = "Test";
232         final LogicalOperator operator = LogicalOperator.EQUALS;
233         homePage.isLoaded();
234         componentPage = (ComponentPage) homePage.clickOnComponent(vfcResourceCreateData.getName());
235
236         componentPage.isLoaded();
237         final ResourcePropertiesPage vfcPropertiesPage = componentPage.goToProperties();
238         vfcPropertiesPage.isLoaded();
239         final List<String> propertyNames = vfcPropertiesPage.getPropertyNames();
240         final ServiceDependencyProperty serviceDependencyProperty = new ServiceDependencyProperty(propertyNames.get(0), value, operator);
241
242         homePage.getTopNavComponent().clickOnHome();
243         homePage.isLoaded();
244         homePage.clickOnComponent(vfResourceCreateData.getName());
245
246         componentPage.isLoaded();
247         final CompositionPage compositionPage = componentPage.goToComposition();
248         compositionPage.isLoaded();
249         compositionPage.selectNode(vfcNameInComposition);
250
251         final CreateDirectiveNodeFilterFlow createDirectiveNodeFilterFlow =
252                 new CreateDirectiveNodeFilterFlow(webDriver, 2, DirectiveType.SELECT, serviceDependencyProperty);
253         createDirectiveNodeFilterFlow.run(componentPage);
254
255         verifyAvailableDirectiveTypes(createDirectiveNodeFilterFlow.getDirectiveOptions());
256
257         verifyAvailablePropertyNames(propertyNames, createDirectiveNodeFilterFlow.getPropertyOptions());
258
259         componentPage = compositionPage.goToGeneral();
260         componentPage.isLoaded();
261         final Map<?, ?> yaml = downloadToscaTemplate();
262         verifyToscaTemplateHasDirectiveNodeFilter(yaml, serviceDependencyProperty, vfcNameInComposition);
263     }
264
265     private void checkMetadata(final Map<String, Object> map, final ResourceCreateData createdData) {
266         final Map<String, Object> metadata = getMapEntry(map, "metadata");
267
268         assertEquals(createdData.getName(), metadata.get("name"));
269         assertEquals(createdData.getDescription(), metadata.get("description"));
270         assertEquals("Generic", metadata.get("category"));
271         assertThat((String) metadata.get("type"), not(emptyString()));
272         assertEquals(createdData.getCategory(), metadata.get("subcategory"));
273         assertEquals(createdData.getVendorName(), metadata.get("resourceVendor"));
274         assertEquals(createdData.getVendorRelease(), metadata.get("resourceVendorRelease"));
275         assertEquals(createdData.getVendorModelNumber(), metadata.get("reourceVendorModelNumber"));
276     }
277
278     private void checkTopologyTemplate(final Map<String, Object> map) {
279         final Map<String, Object> mapEntry = getMapEntry(map, "topology_template");
280         assertNotNull(mapEntry);
281
282         final Map<String, Object> inputs = getMapEntry(mapEntry, "inputs");
283         assertThat(inputs, not(anEmptyMap()));
284
285         final Map<String, Object> outputs = getMapEntry(mapEntry, "outputs");
286         assertThat(outputs, not(anEmptyMap()));
287         assertEquals(2, outputs.keySet().stream().filter(s -> (s.contains("_attr_1") || s.contains("_attr_3")) && !s.contains("_attr_2")).count());
288
289         final Map<String, Object> nodeTemplates = getMapEntry(mapEntry, "node_templates");
290         assertThat(nodeTemplates, not(anEmptyMap()));
291
292         final Map<String, Object> substitutionMappings = getMapEntry(mapEntry, "substitution_mappings");
293         assertThat(substitutionMappings, not(anEmptyMap()));
294
295         final Map<String, Object> attributes = getMapEntry(substitutionMappings, "attributes");
296         assertThat(attributes, not(anEmptyMap()));
297         assertEquals(2, attributes.keySet().stream().filter(s -> (s.contains("_attr_1") || s.contains("_attr_3")) && !s.contains("_attr_2")).count());
298     }
299
300     private Map<String, Object> downloadToscaArtifact(final ComponentPage resourceCreatePage) throws UnzipException {
301         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = downloadToscaCsar(resourceCreatePage);
302         final ToscaArtifactsPage toscaArtifactsPage = downloadCsarArtifactFlow.getLandedPage()
303             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
304
305         assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
306         final String downloadedCsarName = toscaArtifactsPage.getDownloadedArtifactList().get(0);
307         final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
308         final Map<String, byte[]> filesFromZip = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
309         final Optional<String> resourceEntryOpt = filesFromZip.keySet().stream()
310             .filter(s -> s.equals("Definitions/" + downloadedCsarName.replace("-csar.csar", "-template.yml")))
311             .findFirst();
312         if (resourceEntryOpt.isEmpty()) {
313             fail("Could not find the resource package in Definitions");
314         }
315         return loadYamlObject(filesFromZip.get(resourceEntryOpt.get()));
316     }
317
318     private CreateVfFlow createVF() {
319         final ResourceCreateData vfCreateData = createVfFormData();
320         final CreateVfFlow createVfFlow = new CreateVfFlow(webDriver, vfCreateData);
321         createVfFlow.run(homePage);
322         return createVfFlow;
323     }
324
325     private ResourceCreateData createVfFormData() {
326         vfResourceCreateData = new ResourceCreateData();
327         vfResourceCreateData.setRandomName(ElementFactory.getResourcePrefix() + "-VF");
328         vfResourceCreateData.setCategory(ResourceCategoryEnum.GENERIC_ABSTRACT.getSubCategory());
329         vfResourceCreateData.setTagList(Arrays.asList(vfResourceCreateData.getName(), "createVF"));
330         vfResourceCreateData.setDescription("aDescription");
331         vfResourceCreateData.setVendorName("EST");
332         vfResourceCreateData.setVendorRelease("4.1.1");
333         vfResourceCreateData.setVendorModelNumber("0001");
334         return vfResourceCreateData;
335     }
336
337     private CreateVfcFlow createVFC(final String vfcFullFilename, final String resourceName) {
338         final ResourceCreateData vfcCreateData = createVfcFormData(resourceName);
339         final CreateVfcFlow createVfcFlow = new CreateVfcFlow(webDriver, vfcCreateData, vfcFullFilename);
340         createVfcFlow.run(homePage);
341         ExtentTestActions.takeScreenshot(Status.INFO, "vfc-created", String.format("VFC '%s' was created", resourceName));
342         assertThat(vfcs, notNullValue());
343         vfcs.add(vfcCreateData);
344         return createVfcFlow;
345     }
346
347     private ResourceCreateData createVfcFormData(final String resourceName) {
348         final ResourceCreateData vfcCreateData = new ResourceCreateData();
349         vfcCreateData.setRandomName(resourceName);
350         vfcCreateData.setCategory(ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS.getSubCategory());
351         vfcCreateData.setTagList(Arrays.asList(vfcCreateData.getName(), "importVFC"));
352         vfcCreateData.setDescription("aDescription");
353         vfcCreateData.setVendorName("EST");
354         vfcCreateData.setVendorRelease("4.1.1");
355         vfcCreateData.setVendorModelNumber("0001");
356         return vfcCreateData;
357     }
358
359     private AddNodeToCompositionFlow addNodeToCompositionAndCreateRelationship() {
360         assertThat(vfcs, hasSize(2));
361         final ComponentData parentComponent = new ComponentData();
362         parentComponent.setName(vfResourceCreateData.getName());
363         parentComponent.setVersion("0.1");
364         parentComponent.setComponentType(ComponentType.RESOURCE);
365
366         // Adds networkFunction to VF composition
367         final ComponentData networkFunction = new ComponentData();
368         networkFunction.setName(vfcs.get(0).getName());
369         networkFunction.setVersion("1.0");
370         networkFunction.setComponentType(ComponentType.RESOURCE);
371         final CompositionPage compositionPage = resourceCreatePage.goToComposition();
372         compositionPage.isLoaded();
373         AddNodeToCompositionFlow addNodeToCompositionFlow = addNodeToComposition(parentComponent, networkFunction, compositionPage);
374         networkFunctionInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
375             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
376
377         // Adds networkService to VF composition
378         final ComponentData networkService = new ComponentData();
379         networkService.setName(vfcs.get(1).getName());
380         networkService.setVersion("1.0");
381         networkService.setComponentType(ComponentType.RESOURCE);
382         addNodeToCompositionFlow = addNodeToComposition(parentComponent, networkService, compositionPage);
383         networkServiceInstance = addNodeToCompositionFlow.getCreatedComponentInstance()
384             .orElseThrow(() -> new UiTestFlowRuntimeException("Could not get the created component instance"));
385
386         // Creates a dependsOn relationship from networkServiceInstance to networkFunctionInstance
387         createRelationship(compositionPage, networkFunctionInstance.getName(), "tosca.capabilities.Node",
388             networkServiceInstance.getName(), "tosca.capabilities.Node");
389
390         return addNodeToCompositionFlow;
391     }
392
393     public AddNodeToCompositionFlow addNodeToComposition(final ComponentData parentComponent,
394                                                          final ComponentData resourceToAdd,
395                                                          CompositionPage compositionPage) {
396         final AddNodeToCompositionFlow addNodeToCompositionFlow = new AddNodeToCompositionFlow(webDriver, parentComponent, resourceToAdd);
397         compositionPage = (CompositionPage) addNodeToCompositionFlow.run(compositionPage)
398             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected CompositionPage"));
399         compositionPage.isLoaded();
400         ExtentTestActions.takeScreenshot(Status.INFO, "node-added-to-composition",
401             String.format("Resource '%s' was added to composition", resourceToAdd.getName()));
402         return addNodeToCompositionFlow;
403     }
404
405     /**
406      * Creates a DependsOn relationship between the imported VFCs
407      * @param compositionPage Composition Page
408      * @param fromComponentInstanceName VFC - Network Function
409      * @param fromCapability Node Capability
410      * @param toComponentInstanceName  VFC - Network Service
411      * @param toRequirement Node Requirement
412      */
413     private void createRelationship(final CompositionPage compositionPage, final String fromComponentInstanceName,
414                                     final String fromCapability, final String toComponentInstanceName, final String toRequirement) {
415         final RelationshipInformation relationshipInformation =
416             new RelationshipInformation(fromComponentInstanceName, fromCapability, toComponentInstanceName, toRequirement);
417         final CreateRelationshipFlow createRelationshipFlow = new CreateRelationshipFlow(webDriver, relationshipInformation,
418             new InterfaceOperationsData(interfaceName, interfaceOperationName, implementationName, inputName, inputValue));
419         createRelationshipFlow.run(compositionPage).orElseThrow(() -> new UiTestFlowRuntimeException("Expecting a CompositionPage instance"));
420         ExtentTestActions.takeScreenshot(Status.INFO, "relationship",
421             String.format("Relationship from networkFunctionInstance '%s' to networkServiceInstanceResource '%s' was created",
422                 fromComponentInstanceName, toComponentInstanceName));
423     }
424
425     /**
426      * Adds a property to the base service
427      * @param propertyMap map of properties to be added
428      */
429     private void addProperty(final Map<String, String> propertyMap) {
430         componentPage = (ComponentPage) homePage.clickOnComponent(vfResourceCreateData.getName());
431         componentPage.isLoaded();
432         final AddComponentPropertyFlow addComponentPropertyFlow = new AddComponentPropertyFlow(webDriver, propertyMap);
433         addComponentPropertyFlow.run(componentPage.goToPropertiesAssignment());
434     }
435
436     /**
437      * Edits a property to add a value
438      * @param propertyMap map of properties to be edited
439      */
440     private ComponentPage addValueToProperty(final Map<String, Object> propertyMap) {
441         final EditComponentPropertiesFlow editComponentPropertiesFlow = new EditComponentPropertiesFlow(webDriver, propertyMap);
442         return editComponentPropertiesFlow.run().orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected return ComponentPage"));
443     }
444
445     /**
446      * Downloads and verifies the generated tosca templates.
447      * @param componentPage the component page
448      * @throws UnzipException
449      */
450     private void downloadAndVerifyCsarPackage(final ComponentPage componentPage) throws UnzipException {
451         checkCsarPackage(downloadCsarPackage(componentPage));
452     }
453
454     /**
455      * Downloads and verifies if the generated Tosca template contains the expected properties.
456      * @throws UnzipException
457      * @param componentPage
458      */
459     private void downloadAndVerifyCsarPackageAfterAddProperty(final ComponentPage componentPage) throws UnzipException {
460         verifyPropertiesOnGeneratedTemplate(downloadCsarPackage(componentPage));
461     }
462
463     private String downloadCsarPackage(final ComponentPage componentPage) {
464         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = downloadToscaCsar(componentPage);
465         final ToscaArtifactsPage toscaArtifactsPage = downloadCsarArtifactFlow.getLandedPage()
466             .orElseThrow(() -> new UiTestFlowRuntimeException("Missing expected ToscaArtifactsPage"));
467         assertThat("No artifact download was found", toscaArtifactsPage.getDownloadedArtifactList(), not(empty()));
468         return toscaArtifactsPage.getDownloadedArtifactList().get(0);
469     }
470
471     /**
472      * Downloads the generated CSAR package.
473      * @param componentPage the component page
474      * @return the Downloaded Tosca CSAR file
475      */
476     private DownloadCsarArtifactFlow downloadToscaCsar(final ComponentPage componentPage) {
477         final DownloadCsarArtifactFlow downloadCsarArtifactFlow = new DownloadCsarArtifactFlow(webDriver);
478         downloadCsarArtifactFlow.setWaitBeforeGetTheFile(5L);
479         downloadCsarArtifactFlow.run(componentPage);
480         return downloadCsarArtifactFlow;
481     }
482
483     /**
484      * Verifies if the generated Tosca template contains the expected properties.
485      * @param downloadedCsarName the downloaded csar file name
486      * @throws UnzipException
487      */
488     private void verifyPropertiesOnGeneratedTemplate(final String downloadedCsarName) throws UnzipException {
489         final Map<String, byte[]> filesFromZip = extractFilesFromCsar(downloadedCsarName);
490         final String virtualFunctionName = vfResourceCreateData.getName().replace("-", "").toLowerCase();
491         final String vfResourceTemplateFile = "Definitions/resource-" + virtualFunctionName + "-template-interface.yml";
492         final String interfaceTemplateFile = filesFromZip.keySet().stream()
493             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
494             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
495         final byte[] toscaInterfaceTemplateGenerated = filesFromZip.get(interfaceTemplateFile);
496         assertThat("The Generated Tosca template should not be null", toscaInterfaceTemplateGenerated, is(notNullValue()));
497         final Map<String, Object> interfaceTemplateYamlMap = loadYamlObject(toscaInterfaceTemplateGenerated);
498         final Map<String, Object> nodeTypesYamlMap = getMapEntry(interfaceTemplateYamlMap, "node_types");
499         assertThat(String.format("'%s' should contain a node_types entry", interfaceTemplateYamlMap), nodeTypesYamlMap, is(notNullValue()));
500         final Map<String, Object> properties = (Map) nodeTypesYamlMap.values().stream().filter(stringObjectEntry -> stringObjectEntry != null)
501             .collect(Collectors.toList()).get(0);
502         final Map<String, Object> propertiesFoundMap = (Map<String, Object>) properties.get("properties");
503         assertThat(String.format("The generated template file %s should contain all added properties", vfResourceTemplateFile),
504             propertiesFoundMap.keySet().containsAll(propertiesToBeAddedMap.keySet()), is(true));
505     }
506
507     /**
508      * Checks if the downloaded Tosca csar includes the node templates for the added VFCs,
509      * the generated service template declared “tosca_simple_yaml_1_3” as its Tosca version,
510      * the generated csar contains the node type definitions for the added VFCs in the Definitions directory,
511      * the interface template contains the relationship declaration
512      * @param downloadedCsarName download Tosca CSAR filename
513      * @throws UnzipException
514      */
515     private void checkCsarPackage(final String downloadedCsarName) throws UnzipException {
516         final Map<String, byte[]> filesFromZip = extractFilesFromCsar(downloadedCsarName);
517         final String virtualFunctionName = vfResourceCreateData.getName().replace("-", "").toLowerCase();
518         final List<String> expectedDefinitionFolderFileList = getExpectedDefinitionFolderFileList(virtualFunctionName);
519         final Map<String, byte[]> expectedFilesFromZipMap = filesFromZip.entrySet().parallelStream()
520             .filter(key -> expectedDefinitionFolderFileList.stream()
521                 .anyMatch(filename -> filename.equalsIgnoreCase(key.getKey()))).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
522         final String vfResourceTemplateFile = "Definitions/resource-" + virtualFunctionName + "-template.yml";
523         final String generatedTemplateFile = expectedFilesFromZipMap.keySet().stream()
524             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
525             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
526         final byte[] toscaTemplateGenerated = filesFromZip.get(generatedTemplateFile);
527         assertThat(toscaTemplateGenerated, is(notNullValue()));
528         verifyGeneratedTemplate(toscaTemplateGenerated, generatedTemplateFile);
529         verifyNodesRelationship(expectedFilesFromZipMap, virtualFunctionName, filesFromZip);
530     }
531
532     private Map<String, byte[]> extractFilesFromCsar(final String downloadedCsarName) throws UnzipException {
533         final String downloadFolderPath = getConfig().getDownloadAutomationFolder();
534         final Map<String, byte[]> filesFromCsar = FileHandling.getFilesFromZip(downloadFolderPath, downloadedCsarName);
535         return filesFromCsar;
536     }
537
538     private void verifyGeneratedTemplate(final byte[] generatedTemplateData, final String generatedTemplateFile) {
539         final Map<String, Object> templateYamlMap = loadYamlObject(generatedTemplateData);
540         final boolean hasToscaDefinitionVersionEntry = templateYamlMap.containsKey("tosca_definitions_version");
541         assertThat(String.format("'%s' should contain tosca_definitions_version entry", generatedTemplateFile), hasToscaDefinitionVersionEntry,
542             is(true));
543         final String toscaVersion = (String) templateYamlMap.get("tosca_definitions_version");
544         assertThat(String.format("'%s' tosca_definitions_version entry should have tosca_simple_yaml_1_3 value", generatedTemplateFile),
545             toscaVersion.equalsIgnoreCase("tosca_simple_yaml_1_3"));
546         final Map<String, Object> topologyTemplateTosca = getMapEntry(templateYamlMap, "topology_template");
547         assertThat(String.format("'%s' should contain a topology_template entry", generatedTemplateFile), topologyTemplateTosca, is(notNullValue()));
548         final Map<String, Object> nodeTemplatesTosca = getMapEntry(topologyTemplateTosca, "node_templates");
549         assertThat(String.format("'%s' should contain a node_templates entry", generatedTemplateFile), nodeTemplatesTosca, is(notNullValue()));
550         final List<String> nodeTemplateFound = nodeTemplatesTosca.keySet().parallelStream().filter(s -> vfcs.stream()
551             .anyMatch(vfc -> s.startsWith(vfc.getName()))).collect(Collectors.toList());
552         assertThat(String.format("'%s' should contain the node type definitions for the added VFCs '%s'", nodeTemplatesTosca, vfcs),
553             nodeTemplateFound, hasSize(vfcs.size()));
554         verifyRelationshipTemplate(topologyTemplateTosca, generatedTemplateFile);
555     }
556
557     private void verifyRelationshipTemplate(final Map<String, Object> topologyTemplateToscaMap, final String generatedTemplateFile) {
558         final Map<String, Object> relationshipTemplateMap = getMapEntry(topologyTemplateToscaMap, "relationship_templates");
559         assertThat(String.format("'%s' should contain a topology_template entry", generatedTemplateFile), relationshipTemplateMap,
560             is(notNullValue()));
561         final String result = Arrays.asList(relationshipTemplateMap.values()).toString();
562         assertThat(String.format("'%s' should contain a DependsOn relationship", relationshipTemplateMap),
563             result.contains("tosca.relationships.DependsOn"), is(true));
564         assertThat(String.format("'%s' should contain interfaces entry", relationshipTemplateMap), result.contains("interfaces"), is(true));
565         assertThat(String.format("'%s' should contain a Interface Name entry '%s'", relationshipTemplateMap, interfaceName),
566             result.contains(interfaceName), is(true));
567         assertThat(String.format("'%s' should contain a Interface Operation Name '%s'", relationshipTemplateMap, interfaceOperationName),
568             result.contains(interfaceOperationName), is(true));
569         assertThat(String.format("'%s' should contain Implementation Name '%s'", relationshipTemplateMap, implementationName),
570             result.contains(interfaceOperationName), is(true));
571         assertThat(String.format("'%s' should contain inputs entry", relationshipTemplateMap), result.contains("inputs"), is(true));
572         assertThat(String.format("'%s' should contain Input Name '%s'", relationshipTemplateMap, inputName), result.contains(inputName),
573             is(true));
574         assertThat(String.format("'%s' should contain Input Value '%s'", relationshipTemplateMap, inputValue), result.contains(inputValue),
575             is(true));
576     }
577
578     private void verifyNodesRelationship(final Map<String, byte[]> expectedFilesFromZipMap, final String virtualFunctionName,
579                                          final Map<String, byte[]> filesFromZip) {
580         final String vfResourceTemplateFile = "Definitions/resource-" + virtualFunctionName + "-template-interface.yml";
581         final String interfaceTemplateFile = expectedFilesFromZipMap.keySet().stream()
582             .filter(filename -> filename.equalsIgnoreCase(vfResourceTemplateFile)).findFirst()
583             .orElseThrow(() -> new UiTestFlowRuntimeException(String.format("Resource template file not found %s", vfResourceTemplateFile)));
584         final byte[] toscaInterfaceTemplateGenerated = filesFromZip.get(interfaceTemplateFile);
585         assertThat(toscaInterfaceTemplateGenerated, is(notNullValue()));
586         final Map<String, Object> interfaceTemplateYamlMap = loadYamlObject(toscaInterfaceTemplateGenerated);
587         final Map<String, Object> nodeTypesYamlMap = getMapEntry(interfaceTemplateYamlMap, "node_types");
588         assertThat(String.format("'%s' should contain a node_types entry", interfaceTemplateYamlMap), nodeTypesYamlMap, is(notNullValue()));
589         final String result = Arrays.asList(nodeTypesYamlMap.values()).toString();
590         assertThat(String.format("'%s' should contain a capabilities entry", nodeTypesYamlMap), result.contains("capabilities"), is(true));
591         assertThat(String.format("'%s' should contain a requirements entry", nodeTypesYamlMap), result.contains("requirements"), is(true));
592         assertThat(String.format("'%s' should contain a relationship entry", nodeTypesYamlMap), result.contains("relationship"), is(true));
593         assertThat(String.format("'%s' should contain a DependsOn relationship value", nodeTypesYamlMap),
594             result.contains("tosca.relationships.DependsOn"), is(true));
595     }
596
597     private List<String> getExpectedDefinitionFolderFileList(final String vfResourceName) {
598         final List<String> expectedDefinitionFolderFileList = new ArrayList<>();
599         vfcs.forEach(vfc -> expectedDefinitionFolderFileList.add("Definitions/resource-" + vfc.getName() + "-template.yml"));
600         expectedDefinitionFolderFileList.add("Definitions/resource-" + vfResourceName + "-template.yml");
601         expectedDefinitionFolderFileList.add("Definitions/resource-" + vfResourceName + "-template-interface.yml");
602         return expectedDefinitionFolderFileList;
603     }
604
605     private Map<String, Object> getMapEntry(final Map<String, Object> yamlObj, final String entryName) {
606         try {
607             return (Map<String, Object>) yamlObj.get(entryName);
608         } catch (final Exception e) {
609             final String errorMsg = String.format("Could not get the '%s' entry.", entryName);
610             LOGGER.error(errorMsg, e);
611             fail(errorMsg + "Error message: " + e.getMessage());
612         }
613         return null;
614     }
615
616     private Map<String, Object> loadYamlObject(final byte[] definitionYamlFile) {
617         return new Yaml().load(new String(definitionYamlFile));
618     }
619
620     private Map<String, String> loadPropertiesToAdd() {
621         final Map<String, String> propertyMap = new HashMap<>();
622         propertyMap.put("property1", "string");
623         propertyMap.put("property2", "integer");
624         propertyMap.put("property3", "boolean");
625         propertyMap.put("property4", "list");
626         propertyMap.put("property5", "map");
627         propertyMap.put("property6", "scalar-unit.size");
628         return propertyMap;
629     }
630
631     private Map<String, Object> loadPropertiesToEdit() {
632         final Map<String, Object> propertyMap = new HashMap<>();
633         propertyMap.put("property1", "Integration Test");
634         propertyMap.put("property2", 100);
635         propertyMap.put("property3", Boolean.TRUE);
636         propertyMap.put("property4", Arrays.asList("PropListV1", "PropListV2", "PropListV3"));
637         final Map<String, String> stringMap = new HashMap<>();
638         stringMap.put("PropMapKey1", "PropMapValue1");
639         stringMap.put("PropMapKey2", "PropMapValue2");
640         stringMap.put("PropMapKey3", "PropMapValue3");
641         propertyMap.put("property5", stringMap);
642         propertyMap.put("property6", 500);
643         return propertyMap;
644     }
645
646     private void loadSubstitutionFilterProperties() {
647         final ResourcePropertiesAssignmentPage propertiesPage = componentPage.goToPropertiesAssignment();
648         propertiesPage.isLoaded();
649         ExtentTestActions.takeScreenshot(Status.INFO, "propertiesAssigment",
650             String.format("The %s Properties Assignment Page is loaded", vfResourceCreateData.getName()));
651         Map<String, String> propertyNamesAndTypes = propertiesPage.getPropertyNamesAndTypes();
652         assertThat(String.format("The Component '%s' should have properties", vfResourceCreateData.getName()), propertyNamesAndTypes,
653             not(anEmptyMap()));
654         propertyNamesAndTypes.forEach((name, type)
655             -> substitutionFilterProperties.add(new ServiceDependencyProperty(name, getPropertyValueByType(type), LogicalOperator.EQUALS)));
656     }
657
658     private String getPropertyValueByType(final String type) {
659         switch (type) {
660             case "string":
661                 return "IntegrationTest";
662             case "integer":
663                 return "202";
664             case "size":
665                 return "500";
666             case "boolean":
667                 return "TRUE";
668             case "list":
669                 return "[value1, value2]";
670             case "map":
671                 return "MyKey: MyValue";
672             default:
673                 throw new UnsupportedOperationException("Not yet implemented for " + type);
674         }
675     }
676
677     /**
678      * Downloads Tosca Template file
679      * @return the tosca template yaml file
680      * @throws Exception
681      */
682     private Map<?, ?> downloadToscaTemplate() throws Exception {
683         final DownloadToscaTemplateFlow downloadToscaTemplateFlow = new DownloadToscaTemplateFlow(webDriver);
684         final ToscaArtifactsPage toscaArtifactsPage = (ToscaArtifactsPage) downloadToscaTemplateFlow.run(componentPage).get();
685         return FileHandling.parseYamlFile(getConfig().getDownloadAutomationFolder()
686             .concat(java.io.File.separator).concat(toscaArtifactsPage.getDownloadedArtifactList().get(0)));
687     }
688
689     private void verifyToscaTemplateHasSubstitutionFilter(final Map<?, ?> yaml) {
690         assertNotNull(yaml, "No contents in TOSCA Template");
691         final List<?> substitutionFilters = (List<?>) getSubstitutionFilterFromYaml(yaml).get("properties");
692         substitutionFilterProperties.forEach(substitutionFilterProperty -> {
693             final Map<?, ?> substitutionFilterMap = (Map<?, ?>) substitutionFilters.stream()
694                 .filter(subFilter -> ((Map<?, ?>) subFilter).containsKey(substitutionFilterProperty.getName())).findAny().get();
695             assertThat("Added substitution filter not found in TOSCA Template",
696                 substitutionFilterMap.containsKey(substitutionFilterProperty.getName()));
697             final Map<?, ?> substitutionFilterValue = (Map<?, ?>) ((List<?>) substitutionFilterMap.get(substitutionFilterProperty.getName())).get(0);
698             assertThat("Substitution Filter Value should not be empty", substitutionFilterMap, not(anEmptyMap()));
699             final String expectedSubstitutionPropertyValue = substitutionFilterProperty.getValue();
700             final String actualSubstitutionPropertyValue = substitutionFilterValue.values().stream().findFirst().get() instanceof Map
701                 ? substitutionFilterValue.values().stream().findFirst().get().toString().replace("=", ": ")
702                 .replaceAll("\\{(.*?)\\}", "$1").trim()
703                 : substitutionFilterValue.values().stream().findFirst().get().toString();
704             assertThat("Invalid value for added substitution filters found in TOSCA Template",
705                 expectedSubstitutionPropertyValue.equalsIgnoreCase(actualSubstitutionPropertyValue));
706             assertThat("Invalid logical operator for added substitution filters found in TOSCA Template",
707                 substitutionFilterValue.containsKey(substitutionFilterProperty.getLogicalOperator().getName()));
708         });
709     }
710
711     private Map<?, ?> getSubstitutionFilterFromYaml(final Map<?, ?> yaml) {
712         final Map<?, ?> topology = (Map<?, ?>) yaml.get("topology_template");
713         final Map<?, ?> substitutionMappings = (Map<?, ?>) topology.get("substitution_mappings");
714         return (Map<?, ?>) substitutionMappings.get("substitution_filter");
715     }
716
717     private void verifyAvailableDirectiveTypes(final List<String> availableDirectiveTypes) {
718         assertNotNull(availableDirectiveTypes, "Expected list of available Directive Types, but recieved null");
719         Arrays.asList(DirectiveType.values()).forEach(directiveType -> {
720             assertTrue(availableDirectiveTypes.contains(directiveType.getName())
721                     , String.format("Expected directive %s to be availabe in UI options %s"
722                             , directiveType.getName(), availableDirectiveTypes.toString()));
723         });
724         ExtentTestActions.log(Status.PASS, "All expected directive types are available for selection");
725     }
726
727     private void verifyAvailablePropertyNames(List<String> propertyNames, List<String> propertyNameOptions) {
728         assertEquals(propertyNameOptions.size(), propertyNames.size(), "Mismatch in the number of properties available for selection");
729         propertyNames.forEach(name -> {
730             assertNotEquals(false, propertyNameOptions.remove(name)
731                     , String.format("Expected property %s not found in UI Select element", name));
732         });
733         ExtentTestActions.log(Status.PASS, "All expected properties are available for selection");
734     }
735
736     private void verifyToscaTemplateHasDirectiveNodeFilter(final Map<?, ?> yaml, ServiceDependencyProperty nodeFilterProperty, String nodeTemplateName) {
737         assertNotNull(yaml, "Tosca Template Yaml is not expected to be empty");
738         final List<?> nodeFilters = (List<?>) getDirectiveNodeFilterFromYaml(yaml, nodeTemplateName).get("properties");
739         final Map<?, ?> nodeFilter = (Map<?, ?>) nodeFilters.stream()
740                     .filter(yamlNodeFilter -> ((Map<?, ?>) yamlNodeFilter).containsKey(nodeFilterProperty.getName())).findAny().get();
741         assertNotNull(nodeFilter, "Added directive node filter not found in TOSCA Template");
742
743         final Map<?, ?> nodeFilterValue = (Map<?, ?>) ((List<?>) nodeFilter.get(nodeFilterProperty.getName())).get(0);
744         assertTrue(nodeFilterValue.containsValue(nodeFilterProperty.getValue())
745                 , "Invalid value for added directive node filter found in TOSCA Template");
746         assertTrue(nodeFilterValue.containsKey(nodeFilterProperty.getLogicalOperator().getName())
747                 , "Invalid logical operator for added directive node filter found in TOSCA Template");
748     }
749
750     private Map<?,?> getDirectiveNodeFilterFromYaml(final Map<?,?> yaml, String nodeTemplateName) {
751         final Map<?, ?> topology = (Map<?, ?>) yaml.get("topology_template");
752         final Map<?, ?> nodeTemplates = (Map<?, ?>) topology.get("node_templates");
753         final Map<?, ?> resourceNode = (Map<?, ?>) nodeTemplates.get(nodeTemplateName);
754         return (Map<?, ?>) resourceNode.get("node_filter");
755     }
756 }