Merge "VID S1 Instantiation failing when include supplementary file"
authorEylon Malin <eylon.malin@intl.att.com>
Tue, 11 Feb 2020 08:50:35 +0000 (08:50 +0000)
committerGerrit Code Review <gerrit@onap.org>
Tue, 11 Feb 2020 08:50:35 +0000 (08:50 +0000)
27 files changed:
.readthedocs.yaml [new file with mode: 0644]
docs/.gitignore [new file with mode: 0644]
docs/_static/css/ribbon.css [new file with mode: 0644]
docs/_static/favicon.ico [new file with mode: 0755]
docs/_static/logo_onap_2017.png [new file with mode: 0644]
docs/conf.py [new file with mode: 0644]
docs/conf.yaml [new file with mode: 0644]
docs/requirements-docs.txt [new file with mode: 0644]
docs/tox.ini [new file with mode: 0644]
vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt
vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt
vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java
vid-app-common/src/main/java/org/onap/vid/utils/KotlinUtils.kt
vid-app-common/src/test/java/org/onap/vid/controller/AsyncInstantiationControllerTest.java [new file with mode: 0644]
vid-app-common/src/test/java/org/onap/vid/job/command/VnfCommandTest.kt [new file with mode: 0644]
vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java
vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/VfModuleTest.java [new file with mode: 0644]
vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java
vid-app-common/src/test/resources/payload_jsons/vfModuleDelete1Create1None1Request.json
vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-lcp-tenant.json [new file with mode: 0644]
vid-automation/src/test/resources/asyncInstantiation/templates__instance_from_template__set_without_modify1.json
vid-automation/src/test/resources/asyncInstantiation/templates__instance_template.json
vid-webpack-master/cypress/integration/iFrames/ala-carte.e2e.ts
vid-webpack-master/cypress/integration/iFrames/instantiation-templates.e2e.ts
vid-webpack-master/cypress/support/steps/fill.vfModule.step.ts
vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vfModuleGenerator/vfModule.control.generator.spec.ts
vid-webpack-master/src/app/shared/components/genericForm/formControlsServices/vfModuleGenerator/vfModule.control.generator.ts

diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644 (file)
index 0000000..3797dc8
--- /dev/null
@@ -0,0 +1,20 @@
+---
+# .readthedocs.yml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+# Required
+version: 2
+
+formats:
+  - htmlzip
+
+build:
+  image: latest
+
+python:
+  version: 3.7
+  install:
+    - requirements: docs/requirements-docs.txt
+
+sphinx:
+  configuration: docs/conf.py
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644 (file)
index 0000000..43ca5b6
--- /dev/null
@@ -0,0 +1,3 @@
+/.tox
+/_build/*
+/__pycache__/*
diff --git a/docs/_static/css/ribbon.css b/docs/_static/css/ribbon.css
new file mode 100644 (file)
index 0000000..6008cb1
--- /dev/null
@@ -0,0 +1,63 @@
+.ribbon {
+  z-index: 1000;
+  background-color: #a00;
+  overflow: hidden;
+  white-space: nowrap;
+  position: fixed;
+  top: 25px;
+  right: -50px;
+  -webkit-transform: rotate(45deg);
+     -moz-transform: rotate(45deg);
+      -ms-transform: rotate(45deg);
+       -o-transform: rotate(45deg);
+          transform: rotate(45deg);
+  -webkit-box-shadow: 0 0 10px #888;
+     -moz-box-shadow: 0 0 10px #888;
+          box-shadow: 0 0 10px #888;
+
+}
+
+.ribbon a {
+  border: 1px solid #faa;
+  color: #fff;
+  display: block;
+  font: bold 81.25% 'Helvetica Neue', Helvetica, Arial, sans-serif;
+  margin: 1px 0;
+  padding: 10px 50px;
+  text-align: center;
+  text-decoration: none;
+  text-shadow: 0 0 5px #444;
+  transition: 0.5s;
+}
+
+.ribbon a:hover {
+  background: #c11;
+  color: #fff;
+}
+
+
+/* override table width restrictions */
+@media screen and (min-width: 767px) {
+
+   .wy-table-responsive table td, .wy-table-responsive table th {
+      /* !important prevents the common CSS stylesheets from overriding
+         this as on RTD they are loaded after this stylesheet */
+      white-space: normal !important;
+   }
+
+   .wy-table-responsive {
+      overflow: visible !important;
+   }
+}
+
+@media screen and (max-width: 767px) {
+    .wy-table-responsive table td {
+        white-space: nowrap;
+    }
+}
+
+/* fix width of the screen */
+
+.wy-nav-content {
+    max-width: none;
+}
diff --git a/docs/_static/favicon.ico b/docs/_static/favicon.ico
new file mode 100755 (executable)
index 0000000..cb712eb
Binary files /dev/null and b/docs/_static/favicon.ico differ
diff --git a/docs/_static/logo_onap_2017.png b/docs/_static/logo_onap_2017.png
new file mode 100644 (file)
index 0000000..5d064f4
Binary files /dev/null and b/docs/_static/logo_onap_2017.png differ
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644 (file)
index 0000000..8f40e8b
--- /dev/null
@@ -0,0 +1,15 @@
+from docs_conf.conf import *
+
+branch = 'latest'
+master_doc = 'index'
+
+linkcheck_ignore = [
+    'http://localhost',
+]
+
+intersphinx_mapping = {}
+
+html_last_updated_fmt = '%d-%b-%y %H:%M'
+
+def setup(app):
+    app.add_stylesheet("css/ribbon_onap.css")
diff --git a/docs/conf.yaml b/docs/conf.yaml
new file mode 100644 (file)
index 0000000..ab59281
--- /dev/null
@@ -0,0 +1,7 @@
+---
+project_cfg: onap
+project: onap
+
+# Change this to ReleaseBranchName to modify the header
+default-version: latest
+#
diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt
new file mode 100644 (file)
index 0000000..b3188dd
--- /dev/null
@@ -0,0 +1,15 @@
+tox
+Sphinx
+doc8
+docutils
+setuptools
+six
+sphinx_rtd_theme>=0.4.3
+sphinxcontrib-blockdiag
+sphinxcontrib-needs>=0.2.3
+sphinxcontrib-nwdiag
+sphinxcontrib-seqdiag
+sphinxcontrib-swaggerdoc
+sphinxcontrib-plantuml
+sphinx_bootstrap_theme
+lfdocs-conf
diff --git a/docs/tox.ini b/docs/tox.ini
new file mode 100644 (file)
index 0000000..edac8c3
--- /dev/null
@@ -0,0 +1,22 @@
+[tox]
+minversion = 1.6
+envlist = docs,
+skipsdist = true
+
+[testenv:docs]
+basepython = python3
+deps = -r{toxinidir}/requirements-docs.txt
+commands =
+    sphinx-build -b html -n -d {envtmpdir}/doctrees ./ {toxinidir}/_build/html
+    echo "Generated docs available in {toxinidir}/_build/html"
+whitelist_externals =
+    echo
+    git
+    sh
+
+[testenv:docs-linkcheck]
+basepython = python3
+#deps = -r{toxinidir}/requirements-docs.txt
+commands = echo "Link Checking not enforced"
+#commands = sphinx-build -b linkcheck -d {envtmpdir}/doctrees ./ {toxinidir}/_build/linkcheck
+whitelist_externals = echo
index 731625c..68c9f53 100644 (file)
@@ -207,9 +207,6 @@ class VfmoduleCommand @Autowired constructor(
         val serviceModelInfo = serviceModelInfoFromRequest()
         val modelNewestUuid = commandUtils.getNewestModelUuid(serviceModelInfo.modelInvariantId);
 
-        check(!modelNewestUuid.equals(serviceModelInfo.modelVersionId, true)) {
-            "Model version id ${serviceModelInfo.modelVersionId} is already the latest version of model's invariant id ${serviceModelInfo.modelInvariantId}" }
-
         val serviceNewestModel = commandUtils.getServiceModel(modelNewestUuid);
 
         return serviceNewestModel;
index 48ff7b7..b008c13 100644 (file)
@@ -12,6 +12,7 @@ import org.onap.vid.model.serviceInstantiation.Vnf
 import org.onap.vid.mso.RestMsoImplementation
 import org.onap.vid.properties.Features
 import org.onap.vid.services.AsyncInstantiationBusinessLogic
+import org.onap.vid.utils.isNotActive
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.beans.factory.config.ConfigurableBeanFactory
 import org.springframework.context.annotation.Scope
@@ -59,9 +60,9 @@ class VnfCommand @Autowired constructor(
             val vfModules:List<VfModule> = request.vfModules.values.stream().flatMap { vfKey -> vfKey.values.stream() }.collect(Collectors.toList<VfModule>())
 
             try {
-                childJobs = pushChildrenJobsToBroker(vfModules.filter { filterModuleByNeedToCreateBase(it) }, dataForChild, JobType.VolumeGroupInstantiation)
+                childJobs = pushChildrenJobsToBroker(vfModulesForChildrenJobs(vfModules), dataForChild, JobType.VolumeGroupInstantiation)
             } catch (e: AsdcCatalogException) {
-                LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message , e)
+                LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message, e)
                 //return Job.JobStatus.FAILED
                 throw e;
             }
@@ -70,11 +71,26 @@ class VnfCommand @Autowired constructor(
         return Job.JobStatus.COMPLETED_WITH_NO_ACTION
     }
 
-    private fun filterModuleByNeedToCreateBase(it: VfModule):Boolean {
+    private fun vfModulesForChildrenJobs(vfModules: List<VfModule>): List<VfModule> =
+            vfModules
+                    .filter { filterModuleByNeedToCreateBase(it) }
+                    .map { childVfModuleWithVnfRegionAndTenant(it) }
+
+    internal fun childVfModuleWithVnfRegionAndTenant(vfModule: VfModule): VfModule {
+        if (featureManager.isNotActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)) {
+            return vfModule
+        }
+
+        val vnfLcpCloudRegionId = getRequest().lcpCloudRegionId
+        val vnfTenantId = getRequest().tenantId
+        return vfModule.cloneWith(vnfLcpCloudRegionId, vnfTenantId)
+    }
+
+    private fun filterModuleByNeedToCreateBase(vfModule: VfModule): Boolean {
         return needToCreateBaseModule ==
-            commandUtils.isVfModuleBaseModule(
-                    serviceModelInfoFromRequest().modelVersionId,
-                    it.modelInfo.modelVersionId)
+                commandUtils.isVfModuleBaseModule(
+                        serviceModelInfoFromRequest().modelVersionId,
+                        vfModule.modelInfo.modelVersionId)
     }
 
     override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan {
index 0b9a2a7..79ea7f1 100644 (file)
@@ -140,4 +140,28 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest
                            this.getOriginalName()
                );
        }
+
+       public VfModule cloneWith(String lcpCloudRegionId, String tenantId) {
+               return new VfModule(
+                       this.getModelInfo(),
+                       this.getInstanceName(),
+                       this.getVolumeGroupInstanceName(),
+                       this.getAction().toString(),
+                       lcpCloudRegionId,
+                       lcpCloudRegionId,
+                       tenantId,
+                       this.getInstanceParams(),
+                       this.getSupplementaryParams(),
+                       this.isRollbackOnFailure(),
+                       this.isUsePreload(),
+                       this.getInstanceId(),
+                       this.getTrackById(),
+                       this.getIsFailed(),
+                       this.getStatusMessage(),
+                       this.isRetainAssignments(),
+                       this.isRetainVolumeGroups(),
+                       this.getPosition(),
+                       this.getOriginalName()
+               );
+       }
 }
\ No newline at end of file
index 81afe29..83077f2 100644 (file)
@@ -23,11 +23,15 @@ package org.onap.vid.utils
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
 import org.apache.commons.lang3.StringUtils.isEmpty
+import org.togglz.core.Feature
+import org.togglz.core.manager.FeatureManager
 
 inline fun <reified E: Enum<E>> getEnumFromMapOfStrings(map: Map<String, Any>, key:String, defaultValue:E): E {
     return java.lang.Enum.valueOf(E::class.java, (map.getOrDefault(key, defaultValue.name) as String))
 }
 
+fun FeatureManager.isNotActive(feature: Feature) = this.isActive(feature).not()
+
 @JvmField val JACKSON_OBJECT_MAPPER: ObjectMapper = jacksonObjectMapper()
 
 class JoshworksJacksonObjectMapper: io.joshworks.restclient.http.mapper.ObjectMapper {
diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/AsyncInstantiationControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/AsyncInstantiationControllerTest.java
new file mode 100644 (file)
index 0000000..9dcd1ec
--- /dev/null
@@ -0,0 +1,178 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2019 Nokia Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.vid.controller;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.onap.vid.controller.AsyncInstantiationController.ASYNC_INSTANTIATION;
+import static org.springframework.http.MediaType.APPLICATION_JSON;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import org.checkerframework.checker.units.qual.A;
+import org.jeasy.random.EasyRandom;
+import org.jeasy.random.EasyRandomParameters;
+import org.jeasy.random.FieldPredicates;
+import org.jeasy.random.randomizers.misc.BooleanRandomizer;
+import org.jeasy.random.randomizers.text.StringRandomizer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.dal.AsyncInstantiationRepository;
+import org.onap.vid.model.ServiceInfo;
+import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
+import org.onap.vid.mso.MsoResponseWrapper2;
+import org.onap.vid.roles.RoleProvider;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.onap.vid.services.AuditService;
+import org.onap.vid.utils.SystemPropertiesWrapper;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.togglz.core.manager.FeatureManager;
+
+public class AsyncInstantiationControllerTest {
+
+    private static final long STATIC_SEED = 5336L;
+    private final EasyRandomParameters parameters = new EasyRandomParameters()
+        .randomize(Boolean.class, new BooleanRandomizer(STATIC_SEED))
+        .randomize(String.class, new StringRandomizer(4, 4, STATIC_SEED))
+        .excludeField(FieldPredicates.ofType(Serializable.class))
+        .collectionSizeRange(1, 1);
+    private final EasyRandom modelGenerator = new EasyRandom(parameters);
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    private MockMvc mockMvc;
+    private AsyncInstantiationBusinessLogic instantiationBusinessLogic;
+    private AsyncInstantiationRepository asyncInstantiationRepository;
+    private SystemPropertiesWrapper propertiesWrapper;
+    private AuditService auditService;
+
+    @Before
+    public void setUp() {
+        instantiationBusinessLogic = mock(AsyncInstantiationBusinessLogic.class);
+        RoleProvider roleProvider = mock(RoleProvider.class);
+        FeatureManager featureManager = mock(FeatureManager.class);
+        propertiesWrapper = mock(SystemPropertiesWrapper.class);
+        auditService = mock(AuditService.class);
+        asyncInstantiationRepository = mock(AsyncInstantiationRepository.class);
+        AsyncInstantiationController asyncInstantiationController = new AsyncInstantiationController(
+            instantiationBusinessLogic, asyncInstantiationRepository, roleProvider, featureManager, propertiesWrapper, auditService
+        );
+
+        mockMvc = MockMvcBuilders.standaloneSetup(asyncInstantiationController).build();
+    }
+
+    @Test
+    public void shouldReturnAllServiceInfos() throws Exception {
+        List<ServiceInfo> serviceInfos = modelGenerator.objects(ServiceInfo.class, 3).collect(Collectors.toList());
+        when(instantiationBusinessLogic.getAllServicesInfo()).thenReturn(serviceInfos);
+
+        mockMvc.perform(get("/" + ASYNC_INSTANTIATION))
+            .andExpect(content().json(asJson(serviceInfos)));
+
+        verify(instantiationBusinessLogic).getAllServicesInfo();
+        verifyNoMoreInteractions(instantiationBusinessLogic);
+    }
+
+    @Test
+    public void shouldRetryJobsWithGivenUuid() throws Exception {
+        when(propertiesWrapper.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)).thenReturn("some user");
+
+        List<UUID> expectedUuids = new ArrayList<>();
+        expectedUuids.add(UUID.fromString("c195c600-a162-4655-9d88-d1a44518c4b5"));
+        expectedUuids.add(UUID.fromString("1a7ee2b5-ac2b-4dc7-a2a6-22e5d3b33d79"));
+        MsoResponseWrapper2<List<UUID>> expectedResponse = new MsoResponseWrapper2<>(200, expectedUuids);
+
+        ServiceInstantiation serviceInstantiation = modelGenerator.nextObject(ServiceInstantiation.class);
+
+        ArgumentCaptor<ServiceInstantiation> svcInstCaptor = ArgumentCaptor.forClass(ServiceInstantiation.class);
+        ArgumentCaptor<UUID> uuidCaptor = ArgumentCaptor.forClass(UUID.class);
+
+        when(instantiationBusinessLogic.retryJob(
+            svcInstCaptor.capture(),
+            uuidCaptor.capture(),
+            any()
+        )).thenReturn(expectedUuids);
+
+        mockMvc.perform(
+            post("/" + ASYNC_INSTANTIATION + "/retryJobWithChangedData/{jobId}",
+                "804d26c3-fbe9-426c-8eff-25c6ab18fdcf")
+                .content(asJson(serviceInstantiation))
+                .contentType(APPLICATION_JSON))
+            .andExpect(content().json(asJson(expectedResponse)));
+
+        assertThat(svcInstCaptor.getValue().getInstanceId()).isEqualTo(serviceInstantiation.getInstanceId());
+        assertThat(uuidCaptor.getValue()).isEqualTo(UUID.fromString("804d26c3-fbe9-426c-8eff-25c6ab18fdcf"));
+    }
+
+    @Test
+    public void shouldDeleteJob() throws Exception {
+        mockMvc.perform(
+            delete("/" + ASYNC_INSTANTIATION + "/job/{jobId}", "804d26c3-fbe9-426c-8eff-25c6ab18fdcf"));
+
+        verify(instantiationBusinessLogic).deleteJob(eq(UUID.fromString("804d26c3-fbe9-426c-8eff-25c6ab18fdcf")));
+    }
+
+    @Test
+    public void shouldHideServiceJob() throws Exception {
+        mockMvc.perform(
+            post("/" + ASYNC_INSTANTIATION + "/hide/{jobId}", "804d26c3-fbe9-426c-8eff-25c6ab18fdcf"));
+
+        verify(instantiationBusinessLogic).hideServiceInfo(eq(UUID.fromString("804d26c3-fbe9-426c-8eff-25c6ab18fdcf")));
+    }
+
+    @Test
+    public void shouldRetryJob() throws Exception {
+        when(propertiesWrapper.getProperty(SystemProperties.USER_ATTRIBUTE_NAME)).thenReturn("some user");
+
+        List<UUID> expectedUuids = new ArrayList<>();
+        expectedUuids.add(UUID.fromString("c195c600-a162-4655-9d88-d1a44518c4b5"));
+        expectedUuids.add(UUID.fromString("1a7ee2b5-ac2b-4dc7-a2a6-22e5d3b33d79"));
+        MsoResponseWrapper2<List<UUID>> expectedResponse = new MsoResponseWrapper2<>(200, expectedUuids);
+
+        when(instantiationBusinessLogic.retryJob(eq(UUID.fromString("804d26c3-fbe9-426c-8eff-25c6ab18fdcf")), any()))
+            .thenReturn(expectedUuids);
+
+        mockMvc.perform(
+            post("/" + ASYNC_INSTANTIATION + "/retry/{jobId}", "804d26c3-fbe9-426c-8eff-25c6ab18fdcf"))
+            .andExpect(content().json(asJson(expectedResponse)));
+    }
+
+    private <T> String asJson(T object) throws JsonProcessingException {
+        return objectMapper.writeValueAsString(object);
+    }
+}
\ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/VnfCommandTest.kt b/vid-app-common/src/test/java/org/onap/vid/job/command/VnfCommandTest.kt
new file mode 100644 (file)
index 0000000..660abe4
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.job.command
+
+import net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.core.AllOf.allOf
+import org.mockito.Answers
+import org.mockito.InjectMocks
+import org.mockito.Mock
+import org.onap.vid.job.JobAdapter
+import org.onap.vid.job.JobsBrokerService
+import org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator
+import org.onap.vid.job.impl.JobSharedData
+import org.onap.vid.model.Action
+import org.onap.vid.mso.RestMsoImplementation
+import org.onap.vid.properties.Features
+import org.onap.vid.services.AsyncInstantiationBusinessLogic
+import org.onap.vid.testUtils.TestUtils
+import org.onap.vid.testUtils.TestUtils.initMockitoMocks
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+import org.togglz.core.manager.FeatureManager
+import org.mockito.Mockito.`when` as _when
+
+class VnfCommandTest {
+
+    @Mock lateinit var asyncInstantiationBL: AsyncInstantiationBusinessLogic
+    @Mock lateinit var restMso: RestMsoImplementation
+    @Mock lateinit var msoRequestBuilder: MsoRequestBuilder
+    @Mock lateinit var msoResultHandlerService: MsoResultHandlerService
+    @Mock lateinit var inProgressStatusService:InProgressStatusService
+    @Mock lateinit var watchChildrenJobsBL: WatchChildrenJobsBL
+    @Mock lateinit var jobsBrokerService: JobsBrokerService
+    @Mock lateinit var jobAdapter: JobAdapter
+    @Mock lateinit var featureManager: FeatureManager
+
+    @Mock lateinit var jobSharedData: JobSharedData
+    @Mock(answer = Answers.RETURNS_MOCKS) lateinit var vnfJobRequest: org.onap.vid.model.serviceInstantiation.Vnf
+
+    @InjectMocks lateinit var vnfCommand: VnfCommand;
+
+    @BeforeMethod
+    fun initMocks() {
+        initMockitoMocks(this)
+    }
+
+    @Test(dataProvider = "trueAndFalse", dataProviderClass = TestUtils::class)
+    fun `childVfModuleWithVnfRegionAndTenant -- given vfmodule -- tenant and region are copied from vnf`(featureToggleOn: Boolean) {
+
+        val vfModule = FakeResourceCreator.createVfModule(Action.Create)
+                        .cloneWith("vfmodule-lcp-cloud-region-id", "vfmodule-tenant-id")
+
+        _when(featureManager.isActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(featureToggleOn)
+
+        _when(vnfJobRequest.lcpCloudRegionId).thenReturn("vnf-lcp-cloud-region-id")
+        _when(vnfJobRequest.tenantId).thenReturn("vnf-tenant-id")
+        _when(jobSharedData.request).thenReturn(vnfJobRequest)
+
+        vnfCommand.init(jobSharedData, mapOf())
+
+        val expectedSource = if (featureToggleOn) "vnf" else "vfmodule"
+
+        assertThat(vnfCommand.childVfModuleWithVnfRegionAndTenant(vfModule),
+                allOf(
+                        jsonPartEquals("lcpCloudRegionId", "${expectedSource}-lcp-cloud-region-id"),
+                        jsonPartEquals("tenantId", "${expectedSource}-tenant-id")
+                )
+        )
+    }
+
+}
index fe6cfaf..642adb3 100644 (file)
@@ -194,7 +194,12 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
     void defineMocks() {
         Mockito.reset(restMso);
         Mockito.reset(aaiClient);
+        Mockito.reset(commandUtils);
         mockAaiClientAnyNameFree();
+
+        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
+        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
+        when(featureManager.isActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(true);
     }
 
     @Test
@@ -376,9 +381,7 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
 
            * not looking on audit (yet)
         */
-        reset(restMso);
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(false);
+        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(false); // this makes the test pass without mocking the vfModules
         final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
         final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
         final String VNF_REQUEST_ID = UUID.randomUUID().toString();
@@ -421,8 +424,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
 
 
         String msoVnfStatus = COMPLETE_STR;
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
         final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
         final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
         final String VNF_REQUEST_ID = UUID.randomUUID().toString();
@@ -436,7 +437,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
         //push alacarte with 1 vnf, verify STATUS pending
         UUID uuid = pushALaCarteWithVnf();
         singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
-        reset(restMso);
 
         /*---------- service -----------*/
 
@@ -519,8 +519,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
         NetworkDetails networkDetails1 = new NetworkDetails("LukaDoncic", "1");
         NetworkDetails networkDetails2 = new NetworkDetails("KevinDurant", "2");
 
-        reset(restMso);
-
         /*---------- service -----------*/
 
         //mock mso to answer 200 of create service instance request, verify STATUS in progress
@@ -1019,8 +1017,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
         JobStatus expectedJobStatus,
         int getStatusCounter) throws IOException, AsdcCatalogException {
 
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
-        reset(commandUtils);
         when(commandUtils.isVfModuleBaseModule("6b528779-44a3-4472-bdff-9cd15ec93450", "f8360508-3f17-4414-a2ed-6bc71161e8db")).thenReturn(true);
         when(commandUtils.isVfModuleBaseModule("6b528779-44a3-4472-bdff-9cd15ec93450", "25284168-24bb-4698-8cb4-3f509146eca5")).thenReturn(false);
 
@@ -1271,7 +1267,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
                 asyncRequestStatusResponseAsRestObject(IN_PROGRESS_STR),
                 asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
 
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
         enableAddCloudOwnerOnMsoRequest();
 
 
@@ -1318,14 +1313,11 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
     public void deployService_failIt_retryDeploy_getRetryAsTemplate_makeSureFalsyIsFailedInTemplate() {
 
         final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
-        when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
 
         //push alacarte with 1 vnf, verify STATUS pending
         UUID uuid = pushALaCarteWithVnf();
         singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
 
-        reset(restMso);
         //mock mso to answer 200 of create service instance request, verify STATUS in progress
         when(restMso.restCall(eq(HttpMethod.POST), eq(RequestReferencesContainer.class), any(), endsWith("serviceInstances"), any())).thenReturn(
             createResponse(200, SERVICE_INSTANCE_ID, SERVICE_REQUEST_ID));
diff --git a/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/VfModuleTest.java b/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/VfModuleTest.java
new file mode 100644 (file)
index 0000000..a1c78c4
--- /dev/null
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.model.serviceInstantiation;
+
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
+import static org.hamcrest.core.AllOf.allOf;
+import static org.onap.vid.testUtils.TestUtils.setStringsInStringProperties;
+
+import org.onap.vid.mso.model.ModelInfo;
+import org.testng.annotations.Test;
+
+public class VfModuleTest {
+
+    @Test
+    public void cloneWithLcpCloudRegionIdAndTenantId() {
+        String targetLcpCloudRegionId = "dictated lcpCloudRegionId";
+        String targetTenantId = "dictated tenantId";
+
+        VfModule originVfModule = createVfModule();
+
+        assertThat(originVfModule.cloneWith(targetLcpCloudRegionId, targetTenantId), allOf(
+            hasProperty("lcpCloudRegionId", equalTo(targetLcpCloudRegionId)),
+            hasProperty("tenantId", equalTo(targetTenantId)),
+            jsonEquals(originVfModule).whenIgnoringPaths("lcpCloudRegionId", "tenantId")
+        ));
+
+        // verify vfModule did not mutate
+        assertThat(originVfModule, jsonEquals(createVfModule()));
+    }
+
+    private VfModule createVfModule() {
+        VfModule vfModule = new VfModule(
+            setStringsInStringProperties(new ModelInfo()),
+            null, null, null, null, null,
+            null, null, null, true, true,
+            null, null, true, null, true,
+            true, null, null);
+
+        return setStringsInStringProperties(vfModule);
+    }
+}
\ No newline at end of file
index 862b8db..71f7ee0 100644 (file)
@@ -21,9 +21,7 @@
 package org.onap.vid.testUtils;
 
 import static com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper;
-import static java.util.function.Function.identity;
 import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
 import static org.apache.commons.beanutils.PropertyUtils.getPropertyDescriptors;
 import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
 import static org.apache.commons.text.CharacterPredicates.DIGITS;
@@ -52,7 +50,9 @@ import java.lang.reflect.Field;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.function.Predicate;
 import javax.ws.rs.client.Client;
@@ -61,7 +61,6 @@ import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import org.apache.commons.beanutils.BeanUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
@@ -174,15 +173,27 @@ public class TestUtils {
     }
 
     public static String[] allPropertiesOf(Class<?> aClass) {
-        return Arrays.stream(getPropertyDescriptors(aClass))
+        return getPropertyDescriptorsRecursively(aClass).stream()
             .map(PropertyDescriptor::getDisplayName)
+            .distinct()
             .toArray(String[]::new);
     }
 
+    private static List<PropertyDescriptor> getPropertyDescriptorsRecursively(Class<?> aClass) {
+        List<PropertyDescriptor> result = new LinkedList<>();
+
+        for (Class<?> i = aClass; i != null && i != Object.class; i = i.getSuperclass()) {
+            Collections.addAll(result, getPropertyDescriptors(i));
+        }
+
+        return result;
+    }
+
     private static <T> List<String> allStringPropertiesOf(T object) {
-        return Arrays.stream(getPropertyDescriptors(object.getClass()))
+        return getPropertyDescriptorsRecursively(object.getClass()).stream()
             .filter(descriptor -> descriptor.getPropertyType().isAssignableFrom(String.class))
             .map(PropertyDescriptor::getDisplayName)
+            .distinct()
             .collect(toList());
     }
 
@@ -221,16 +232,15 @@ public class TestUtils {
      * @return The modified object
      */
     public static <T> T setStringsInStringProperties(T object) {
-        try {
-            final List<String> stringFields = allStringPropertiesOf(object);
-
-            BeanUtils.populate(object, stringFields.stream()
-                .collect(toMap(identity(), identity())));
+        allStringPropertiesOf(object).forEach(it -> {
+            try {
+                FieldUtils.writeField(object, it, it, true);
+            } catch (IllegalAccessException e) {
+                // YOLO
+            }
+        });
 
-            return object;
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
+        return object;
     }
 
     public static void registerCloudConfigurationValueGenerator() {
index 642c2aa..a4f609a 100644 (file)
@@ -10,6 +10,7 @@
             "instanceId": "VF_MODULE_INSTANCE_ID",
             "action": "Create",
             "lcpCloudRegionId": "AAIAIC25",
+            "legacyRegion": "some legacy region",
             "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
             "modelInfo": {
               "modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091",
@@ -36,6 +37,7 @@
             "provStatus": "Prov Status",
             "inMaint": false,
             "lcpCloudRegionId": "AAIAIC25",
+            "legacyRegion": "some legacy region",
             "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
             "modelInfo": {
               "modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
@@ -59,6 +61,7 @@
             "provStatus": "Prov Status",
             "inMaint": false,
             "lcpCloudRegionId": "AAIAIC25",
+            "legacyRegion": "some legacy region",
             "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
             "modelInfo": {
               "modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
diff --git a/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-lcp-tenant.json b/vid-automation/src/test/resources/a-la-carte/redux-a-la-carte-no-lcp-tenant.json
new file mode 100644 (file)
index 0000000..a38469e
--- /dev/null
@@ -0,0 +1,84 @@
+{
+  "vnfs": {
+    "2017-488_PASQUALE-vPE 0": {
+      "action": "Create",
+      "rollbackOnFailure": "true",
+      "vfModules": {
+        "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
+          "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
+            "instanceName": "mimazepubi",
+            "rollbackOnFailure": "false",
+            "sdncPreLoad": false,
+            "instanceParams": [
+              {}
+            ],
+            "modelInfo": {
+              "modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091",
+              "modelVersionId": "f8360508-3f17-4414-a2ed-6bc71161e8db",
+              "modelName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
+              "modelVersion": "5",
+              "modelCustomizationId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
+              "modelUniqueId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
+              "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
+              "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db"
+            },
+            "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
+            "isMissingData": false
+          }
+        },
+        "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
+          "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
+            "instanceName": "puwesovabe",
+            "volumeGroupName": "puwesovabe_vol",
+            "rollbackOnFailure": "true",
+            "sdncPreLoad": true,
+            "instanceParams": [
+              {
+                "pasqualevpe0_bandwidth": "10",
+                "2017488_pasqualevpe0_vnf_instance_name": "mtnj309me6",
+                "2017488_pasqualevpe0_vnf_config_template_version": "17.2",
+                "2017488_pasqualevpe0_AIC_CLLI": "ATLMY8GA",
+                "pasqualevpe0_bandwidth_units": "Gbps"
+              }
+            ],
+            "modelInfo": {
+              "modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
+              "modelVersionId": "25284168-24bb-4698-8cb4-3f509146eca5",
+              "modelName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
+              "modelVersion": "6",
+              "modelCustomizationId": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
+              "modelUniqueId": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
+              "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
+              "uuid": "25284168-24bb-4698-8cb4-3f509146eca5"
+            },
+            "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
+            "isMissingData": false
+          }
+        },
+        "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
+          "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
+            "instanceName": "bnmgtrx",
+            "volumeGroupName": "",
+            "rollbackOnFailure": "false",
+            "sdncPreLoad": false,
+            "instanceParams": [
+              {}
+            ],
+            "modelInfo": {
+              "modelInvariantId": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
+              "modelVersionId": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
+              "modelName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
+              "modelVersion": "6",
+              "modelCustomizationId": "3cd946bb-50e0-40d8-96d3-c9023520b557",
+              "modelUniqueId": "3cd946bb-50e0-40d8-96d3-c9023520b557",
+              "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
+              "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a"
+            },
+            "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
+            "isMissingData": false
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
index bb3fb15..a62360c 100644 (file)
               }
             ],
             "isMissingData": false,
-            "lcpCloudRegionId": "hvf6",
             "modelInfo": {
               "modelCustomizationId": "4d0818cf-eaa9-4a3f-89c2-639953089e14",
               "modelCustomizationName": "VprobeNcVnf..FE_base_module..module-0",
             },
             "rollbackOnFailure": true,
             "sdncPreLoad": null,
-            "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
             "uuid": "c5b26cc1-a66f-4b69-aa23-6abc7c647c88"
           }
         }
index f186f90..56ba46b 100644 (file)
@@ -68,8 +68,6 @@
             },
             "instanceName": "hvf6arlba007_lba_Base_01",
             "action": "Create",
-            "lcpCloudRegionId": "hvf6",
-            "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
             "instanceParams": [
               {}
             ],
index fa628d4..3b42a1c 100644 (file)
@@ -215,15 +215,20 @@ describe('A la carte', function () {
       });
     });
 
-    it(`VFModule a-la-carte`, () => {
-      var timeBomb = new Date('12/09/2018');
-      if (new Date() < timeBomb) {
-        return;
-      }
+    it(`Add ALaCarte VfModule Without LcpRegion Tenant Id And Legacy`, () => {
+      addAlacarteVfmoduleByFlag(true, 'redux-a-la-carte-no-lcp-tenant.json');
+    });
+
+    it(`Add ALaCarte VfModule With LcpRegion Tenant Id And Legacy`, () => {
+      addAlacarteVfmoduleByFlag(false, 'redux-a-la-carte.json');
+    });
+
+    function addAlacarteVfmoduleByFlag  (flag: boolean, expectedJsonFile: string) {
       cy.readFile('cypress/support/jsonBuilders/mocks/jsons/emptyServiceRedux.json').then((res) => {
         cy.setTestApiParamToGR();
         res.service.serviceHierarchy['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].service.vidNotions.instantiationType = 'ALaCarte';
         res.service.serviceHierarchy['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].service.inputs = null;
+        res.global['flags'] = { 'FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF' : flag };
         cy.setReduxState(<any>res);
         cy.openIframe('app/ui/#/servicePlanning?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd');
 
@@ -241,31 +246,30 @@ describe('A la carte', function () {
               '2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2',
             ];
 
-            cy.addALaCarteVfModule(vnfName, vfModulesNames[0], 'mimazepubi', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, false)
+            cy.addALaCarteVfModule(vnfName, vfModulesNames[0], 'mimazepubi', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, false, flag)
+            .then(() => {
+              cy.addALaCarteVfModule(vnfName, vfModulesNames[1], 'puwesovabe', 'AAIAIC25', 'my region', 'USP-SIP-IC-24335-T-01', true, true, false, flag)
               .then(() => {
-                cy.addALaCarteVfModule(vnfName, vfModulesNames[1], 'puwesovabe', 'AAIAIC25', 'my region', 'USP-SIP-IC-24335-T-01', true, true, false)
-                  .then(() => {
-                    cy.addALaCarteVfModule(vnfName, vfModulesNames[2], 'bnmgtrx', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, true)
-                      .then(() => {
-                        cy.getReduxState().then((state) => {
-                          const vfModules = state.service.serviceInstance['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].vnfs[vnfName].vfModules;
-                          cy.readFile('../vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json').then((file) => {
-                            for (let vfModulesName of vfModulesNames) {
-                              const vfModule = vfModules[vfModulesName];
-                              let vfModuleObject = vfModule[Object.keys(vfModule)[0]];
-                              file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName].action = "Create";
-                              cy.deepCompare(vfModuleObject, file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName]);
-                            }
-                          });
-                        });
-                      });
+                cy.addALaCarteVfModule(vnfName, vfModulesNames[2], 'bnmgtrx', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, true, flag)
+                .then(() => {
+                  cy.getReduxState().then((state) => {
+                    const vfModules = state.service.serviceInstance['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].vnfs[vnfName].vfModules;
+                    cy.readFile('../vid-automation/src/test/resources/a-la-carte/' + expectedJsonFile).then((file) => {
+                      for (let vfModulesName of vfModulesNames) {
+                        const vfModule = vfModules[vfModulesName];
+                        let vfModuleObject = vfModule[Object.keys(vfModule)[0]];
+                        file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName].action = "Create";
+                        cy.deepCompare(vfModuleObject, file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName]);
+                      }
+                    });
                   });
+                });
               });
+            });
           });
         });
       });
-    });
-
+    };
 
     function changeServiceEcompNamingToTrue(obj: ServiceModel) {
       obj.service.serviceEcompNaming = "true";
@@ -283,8 +287,5 @@ describe('A la carte', function () {
         .get('.error').contains(INSTANCE_NAME_NOT_MANDATORY_MESSAGE);
     }
 
-
-
-
   });
 });
index f7419ef..bb2c01a 100644 (file)
@@ -104,16 +104,12 @@ describe('Drawing Board: Instantiation Templates', function () {
 
         cy.editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
           .getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007_lba_Base_01')
-          .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
-          .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
           .getElementByDataTestsId("cancelButton").click();
 
         cy.editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
           .getElementByDataTestsId("instanceName").should('have.value', 'my_hvf6arlba007_lba_dj_01')
           .getElementByDataTestsId("volumeGroupName").should('have.value', 'my_special_hvf6arlba007_lba_dj_01_vol')
-          .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
-          .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
           .getElementByDataTestsId("rollback").should('contain', 'Rollback')
           .getElementByDataTestsId("sdncPreLoad").should('have.value', 'on')
           .getElementByDataTestsId("cancelButton").click();
@@ -156,8 +152,6 @@ describe('Drawing Board: Instantiation Templates', function () {
         cy.editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
         cy.clearInput("instanceName");
         cy.typeToInput("instanceName", newVfModuleName);
-        cy.selectDropdownOptionByText('lcpRegion', 'hvf6');
-        cy.selectDropdownOptionByText('tenant', 'DN5242-Nov21-T1');
         cy.getElementByDataTestsId('form-set').click();
 
         // Then...
@@ -177,8 +171,6 @@ describe('Drawing Board: Instantiation Templates', function () {
             {
               instanceName: newVfModuleName,
               volumeGroupName: `${newVfModuleName}_vol`,
-              lcpCloudRegionId: "hvf6",
-              tenantId: "4914ab0ab3a743e58f0eefdacc1dde77",
             }
           );
 
index b87e773..cfb8a05 100644 (file)
@@ -34,7 +34,7 @@ function addMacroVfModule(vnfName: string, vfModuleName: string, instanceName: s
 }
 
 function addALaCarteVfModule(vnfName: string, vfModuleName: string, instanceName: string, lcpRegion: string, legacyRegion: string,
-                     tenant: string, rollback: boolean, sdncPreLoad: boolean, deleteVgName: boolean): Chainable<any> {
+                     tenant: string, rollback: boolean, sdncPreLoad: boolean, deleteVgName: boolean, flag: boolean): Chainable<any> {
   return cy.getElementByDataTestsId('node-' + vnfName).click({force: true}).then(() => {
     cy.getElementByDataTestsId('node-' + vfModuleName + '-add-btn').click({force: true}).then(() => {
       cy.getElementByDataTestsId('instanceName').clear().type(instanceName, {force: true}).then(() => {
@@ -42,11 +42,13 @@ function addALaCarteVfModule(vnfName: string, vfModuleName: string, instanceName
           cy.getElementByDataTestsId('volumeGroupName').clear();
         }
       }).then(() => {
-        cy.selectDropdownOptionByText('lcpRegion', lcpRegion);
-        if (legacyRegion) {
-          cy.typeToInput("lcpRegionText", legacyRegion);
+        if(!flag) {
+          cy.selectDropdownOptionByText('lcpRegion', lcpRegion);
+          if (legacyRegion) {
+            cy.typeToInput("lcpRegionText", legacyRegion);
+          }
+          cy.selectDropdownOptionByText('tenant', tenant);
         }
-        cy.selectDropdownOptionByText('tenant', tenant);
         cy.selectDropdownOptionByText('rollback', String(rollback));
         if (sdncPreLoad) {
           cy.getElementByDataTestsId('sdncPreLoad').check();
index 49deb3a..154c60f 100644 (file)
@@ -4,7 +4,7 @@ import {NgRedux} from '@angular-redux/store';
 import {ControlGeneratorUtil, SDN_C_PRE_LOAD} from "../control.generator.util.service";
 import {AaiService} from "../../../../services/aaiService/aai.service";
 import {GenericFormService} from "../../generic-form.service";
-import {FormBuilder, FormControl, FormGroup} from "@angular/forms";
+import {FormBuilder} from "@angular/forms";
 import {LogService} from "../../../../utils/log/log.service";
 import {
   FormControlModel,
@@ -12,12 +12,14 @@ import {
   ValidatorOptions
 } from "../../../../models/formControlModels/formControl.model";
 import {FormControlNames, VfModuleControlGenerator} from "./vfModule.control.generator";
-import {FeatureFlagsService} from "../../../../services/featureFlag/feature-flags.service";
+import {FeatureFlagsService, Features} from "../../../../services/featureFlag/feature-flags.service";
 import {VfModuleInstance} from "../../../../models/vfModuleInstance";
 import {VfModule} from "../../../../models/vfModule";
 import {SharedControllersService} from "../sharedControlles/shared.controllers.service";
 import {AppState} from "../../../../store/reducers";
 import {SharedTreeService} from "../../../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
+import {instance, mock, when} from "ts-mockito";
+import each from "jest-each";
 
 class MockAppStore<T> {
   getState() {
@@ -921,6 +923,8 @@ describe('VFModule Control Generator', () => {
   let service: VfModuleControlGenerator;
   let httpMock: HttpTestingController;
   let store : NgRedux<AppState>;
+  let mockFeatureFlagsService: FeatureFlagsService = mock(FeatureFlagsService);
+
 
   beforeAll(done => (async () => {
     TestBed.configureTestingModule({
@@ -933,7 +937,7 @@ describe('VFModule Control Generator', () => {
         FormBuilder,
         LogService,
         SharedTreeService,
-        {provide:FeatureFlagsService, useClass: MockFeatureFlagsService},
+        {provide: FeatureFlagsService, useValue: instance(mockFeatureFlagsService)},
         {provide: NgRedux, useClass: MockAppStore}]
     });
     await TestBed.compileComponents();
@@ -946,6 +950,23 @@ describe('VFModule Control Generator', () => {
 
   })().then(done).catch(done.fail));
 
+  let formControlsWithoutLcpRegionTenantLegacy : string[] =
+    [FormControlNames.INSTANCE_NAME,
+      FormControlNames.VOLUME_GROUP_NAME,
+      FormControlNames.ROLLBACK_ON_FAILURE,
+      SDN_C_PRE_LOAD,];
+
+  let formControlsWithLcpRegionTenantLegacy : string[] =
+        [FormControlNames.INSTANCE_NAME,
+        FormControlNames.VOLUME_GROUP_NAME,
+        FormControlNames.LCPCLOUD_REGION_ID,
+        FormControlNames.LEGACY_REGION,
+        FormControlNames.TENANT_ID,
+        FormControlNames.ROLLBACK_ON_FAILURE,
+        SDN_C_PRE_LOAD,];
+
+
+
   test(' getMacroFormControls gets vnfStoreKey === null', () => {
     const serviceId: string = "6e59c5de-f052-46fa-aa7e-2fca9d674c44";
     const vnfStoreKey: string = null;
@@ -1058,20 +1079,15 @@ describe('VFModule Control Generator', () => {
     expect(console.error).toHaveBeenCalled();
   });
 
-  test('getAlaCarteFormControls should return the correct order of controls', () => {
+  each([
+    [true, 4, formControlsWithoutLcpRegionTenantLegacy],
+    [false, 7,formControlsWithLcpRegionTenantLegacy]
+  ]).
+  test('getAlaCarteFormControls should return the correct order of controls', (flag: boolean, controlAmount: number, orderedControls: string[]) => {
+    when(mockFeatureFlagsService.getFlagState(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(flag);
     const controls:FormControlModel[] = getAlaCarteFormControls();
 
-    const orderedControls : string[] = [
-      FormControlNames.INSTANCE_NAME,
-      FormControlNames.VOLUME_GROUP_NAME,
-      FormControlNames.LCPCLOUD_REGION_ID,
-      FormControlNames.LEGACY_REGION,
-      FormControlNames.TENANT_ID,
-      FormControlNames.ROLLBACK_ON_FAILURE,
-      SDN_C_PRE_LOAD,
-    ];
-
-    expect(controls.length).toEqual(7);
+    expect(controls.length).toEqual(controlAmount);
     for(let i = 0 ; i < orderedControls.length ; i++) {
      expect(controls[i].controlName).toEqual(orderedControls[i]);
     }
@@ -1093,26 +1109,6 @@ describe('VFModule Control Generator', () => {
     return controls;
   }
 
-  test('getAlaCarteFormControls responce with wrong order of controls', () => {
-    const controls:FormControlModel[] = getAlaCarteFormControls();
-
-    const orderedControls : string[] = [
-      FormControlNames.INSTANCE_NAME,
-      FormControlNames.VOLUME_GROUP_NAME,
-      FormControlNames.LCPCLOUD_REGION_ID,
-      FormControlNames.TENANT_ID, // TENANT_ID must be after LEGACY_REGION
-      FormControlNames.LEGACY_REGION,
-      FormControlNames.ROLLBACK_ON_FAILURE,
-      SDN_C_PRE_LOAD,
-    ];
-
-    for(let i = 0 ; i < orderedControls.length ; i++) {
-      if (controls[i].controlName === 'legacyRegion') {
-        expect(orderedControls[i]).toEqual('tenantId');
-      }
-    }
-  });
-
   test('getMacroFormControls should return the correct order of controls', () => {
     const serviceId: string = "6e59c5de-f052-46fa-aa7e-2fca9d674c44";
     const vnfStoreKey: string = 'VF_vGeraldine 0';
@@ -1149,25 +1145,6 @@ describe('VFModule Control Generator', () => {
     expect(instanceNameValidator.validatorArg).toEqual(/^[a-zA-Z0-9._-]*$/);
   });
 
-  test(' getAlaCarteFormControls gets null service', () => {
-    const controls:FormControlModel[] = getAlaCarteFormControls();
-    expect(controls.length).toEqual(7);
-
-    const orderedControls : string[] = [
-      FormControlNames.INSTANCE_NAME,
-      FormControlNames.VOLUME_GROUP_NAME,
-      FormControlNames.LCPCLOUD_REGION_ID,
-      FormControlNames.LEGACY_REGION,
-      FormControlNames.TENANT_ID,
-      FormControlNames.ROLLBACK_ON_FAILURE,
-      SDN_C_PRE_LOAD,
-    ];
-
-    for(let i = 0 ; i < orderedControls.length ; i++) {
-      expect(controls[i].controlName).toEqual(orderedControls[i]);
-    }
-  });
-
 
   test('when flag is active - response should contains upload file', ()=>{
     spyOn(store, 'getState').and.returnValue( {
index 7021815..b614ecf 100644 (file)
@@ -23,6 +23,7 @@ import {SharedControllersService} from "../sharedControlles/shared.controllers.s
 import {MessageModal} from "../../../messageModal/message-modal.service";
 import {ButtonType} from "../../../customModal/models/button.type";
 import {SharedTreeService} from "../../../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
+import {FeatureFlagsService, Features} from "../../../../services/featureFlag/feature-flags.service";
 
 export enum FormControlNames {
   INSTANCE_NAME = 'instanceName',
@@ -47,7 +48,8 @@ export class VfModuleControlGenerator {
               private store: NgRedux<AppState>,
               private http: HttpClient,
               private _aaiService: AaiService,
-              private _logService: LogService) {
+              private _logService: LogService,
+              private _featureFlagsService:FeatureFlagsService) {
     this.aaiService = _aaiService;
   }
 
@@ -124,9 +126,11 @@ export class VfModuleControlGenerator {
     const vfModuleInstance = this._basicControlGenerator.retrieveInstanceIfUpdateMode(this.store, this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode));
     let result: FormControlModel[] = [];
     this.pushInstanceAndVGToForm(result, vfModuleInstance, serviceId, vnfModel, true);
-    result.push(this._sharedControllersService.getLcpRegionControl(serviceId, vfModuleInstance, result));
-    result.push(this._sharedControllersService.getLegacyRegion(vfModuleInstance));
-    result.push(this._sharedControllersService.getTenantControl(serviceId, vfModuleInstance));
+    if( !this._featureFlagsService.getFlagState(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)) {
+      result.push(this._sharedControllersService.getLcpRegionControl(serviceId, vfModuleInstance, result));
+      result.push(this._sharedControllersService.getLegacyRegion(vfModuleInstance));
+      result.push(this._sharedControllersService.getTenantControl(serviceId, vfModuleInstance));
+    }
     result.push(this._sharedControllersService.getRollbackOnFailureControl(vfModuleInstance));
     result.push(this._sharedControllersService.getSDNCControl(vfModuleInstance, this.getSdncExtraContents()));
     if (this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {