summaryrefslogtreecommitdiffstats
path: root/vid-automation/src/test/java/org/onap
diff options
context:
space:
mode:
authorkurczews <krzysztof.kurczewski@nokia.com>2018-08-13 13:40:47 +0200
committerkurczews <krzysztof.kurczewski@nokia.com>2018-08-13 13:43:12 +0200
commit2513c3cae11dbc717d2c22ffdd8266aa2e61a800 (patch)
tree7c1a9c1630be657506995f4a291504562bf712b1 /vid-automation/src/test/java/org/onap
parent9b45c01d9bb3a4565ed64c20e72511edc0854636 (diff)
Renaming vid-automation #4
Change-Id: I907b9a6c199302d748918e236ee2945d56f4dd26 Issue-ID: VID-205 Signed-off-by: kurczews <krzysztof.kurczewski@nokia.com>
Diffstat (limited to 'vid-automation/src/test/java/org/onap')
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/AaiApiTest.java558
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/AsyncInfraApiTest.java233
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationApiTest.java524
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/BaseApiAaiTest.java70
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/BaseApiTest.java206
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/BaseMsoApiTest.java80
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/CategoryParametersApiTest.java119
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/ChangeManagementApiTest.java750
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/OperationalEnvironmentControllerApiTest.java431
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java109
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/SampleApiTest.java67
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/SdcApiTest.java162
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/ServiceInstanceMsoApiTest.java121
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/Streams.java47
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/TestUtils.java81
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/VidConfigurationApiTest.java24
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/pProbeAaiApiTest.java146
-rw-r--r--vid-automation/src/test/java/org/onap/vid/api/pProbeMsoApiTest.java107
18 files changed, 3835 insertions, 0 deletions
diff --git a/vid-automation/src/test/java/org/onap/vid/api/AaiApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/AaiApiTest.java
new file mode 100644
index 000000000..7d558940d
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/AaiApiTest.java
@@ -0,0 +1,558 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import net.javacrumbs.jsonunit.JsonAssert;
+import org.apache.commons.text.StringEscapeUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIBadBodyForGetServicesGet;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAICloudRegionAndSourceFromConfigurationPut;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetInstanceGroupsByCloudRegion;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetInstanceGroupsByCloudRegionInvalidRequest;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetInstanceGroupsByCloudRegionRequiredMissing;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetNetworkCollectionDetails;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetNetworkCollectionDetailsInvalidRequest;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetNetworkCollectionDetailsRequiredMissing;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetPortMirroringSourcePorts;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetPortMirroringSourcePortsError;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetRelatedInstanceGroupsByVnfId;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
+import org.onap.vid.model.aai.AaiResponse;
+import org.onap.vid.model.mso.OperationalEnvironmentList;
+import org.onap.vid.more.LoggerFormatTest;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.util.UriComponentsBuilder;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import vid.automation.test.services.SimulatorApi;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URISyntaxException;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.*;
+import static org.onap.simulator.presetGenerator.presets.ecompportal_att.EcompPortalPresetsUtils.getEcompPortalPresets;
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET;
+
+public class AaiApiTest extends BaseApiAaiTest {
+
+
+ public static final String GET_OPERATIONAL_ENVIRONMENTS_JSON = "get_operational_environments_aai.json";
+ public static final String GET_OPERATIONAL_ENVIRONMENTS_JSON_ERROR = "get_operational_environments_aai_error.json";
+ public static final String[] AAI_GET_SERVICES_ERROR_SIMULATOR_RESPONSES = {"getServicesAaiErrorResp.json", "aai_get_full_subscribers.json"};
+ public static final String[] AAI_GET_SERVICES_FINE_SIMULATOR_RESPONSES = {"getServicesAaiFineResp.json", "aai_get_full_subscribers.json"};
+
+ public static final String OPERATIONAL_ENVIRONMENT_TYPE = "VNF";
+ public static final String OPERATIONAL_ENVIRONMENT_STATUS = "Activate";
+ public static final String BASE_GET_SERVICES_AAI_REQUEST_BODY = "{\"start\" : \"service-design-and-creation/models\", \"query\" : \"query/serviceModels-byDistributionStatus?distributionStatus=DISTRIBUTION_COMPLETE_OK\";}";
+ public static final String GET_INSTANCE_GROUPS_BY_CLOUDREGION_EXPECTED_RESPONSE = "{\"results\":[{\"instance-group\":{\"id\":\"AAI-12002-test3-vm230w\",\"description\":\"a9DEa0kpY\",\"instance-group-role\":\"JZmha7QSS4tJ\",\"model-invariant-id\":\"model-id3\",\"model-version-id\":\"a0efd5fc-f7be-4502-936a-a6c6392b958f\",\"instance-group-type\":\"type\",\"resource-version\":\"1520888659539\",\"instance-group-name\":\"wKmBXiO1xm8bK\",\"instance-group-function\":\"testfunction2\",\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"cloud-region.cloud-owner\",\"relationship-value\":\"AAI-12002-vm230w\"},{\"relationship-key\":\"cloud-region.cloud-region-id\",\"relationship-value\":\"AAI-region-vm230w\"}],\"relatedToPropertyList\":[{\"property-key\":\"cloud-region.owner-defined-type\",\"property-value\":null}],\"related-to\":\"cloud-region\",\"related-link\":\"/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/AAI-12002-vm230w/AAI-region-vm230w\",\"relationship-label\":\"org.onap.relationships.inventory.Uses\",\"relationship-data\":[{\"relationship-key\":\"cloud-region.cloud-owner\",\"relationship-value\":\"AAI-12002-vm230w\"},{\"relationship-key\":\"cloud-region.cloud-region-id\",\"relationship-value\":\"AAI-region-vm230w\"}],\"related-to-property\":[{\"property-key\":\"cloud-region.owner-defined-type\",\"property-value\":null}]}]}}},{\"instance-group\":{\"id\":\"AAI-12002-test1-vm230w\",\"description\":\"a9DEa0kpY\",\"instance-group-role\":\"JZmha7QSS4tJ\",\"model-invariant-id\":\"model-id1\",\"model-version-id\":\"a0efd5fc-f7be-4502-936a-a6c6392b958f\",\"instance-group-type\":\"type\",\"resource-version\":\"1520886467989\",\"instance-group-name\":\"wKmBXiO1xm8bK\",\"instance-group-function\":\"testfunction2\",\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"cloud-region.cloud-owner\",\"relationship-value\":\"AAI-12002-vm230w\"},{\"relationship-key\":\"cloud-region.cloud-region-id\",\"relationship-value\":\"AAI-region-vm230w\"}],\"relatedToPropertyList\":[{\"property-key\":\"cloud-region.owner-defined-type\",\"property-value\":null}],\"related-to\":\"cloud-region\",\"related-link\":\"/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/AAI-12002-vm230w/AAI-region-vm230w\",\"relationship-label\":\"org.onap.relationships.inventory.Uses\",\"relationship-data\":[{\"relationship-key\":\"cloud-region.cloud-owner\",\"relationship-value\":\"AAI-12002-vm230w\"},{\"relationship-key\":\"cloud-region.cloud-region-id\",\"relationship-value\":\"AAI-region-vm230w\"}],\"related-to-property\":[{\"property-key\":\"cloud-region.owner-defined-type\",\"property-value\":null}]}]}}},{\"instance-group\":{\"id\":\"AAI-12002-test2-vm230w\",\"description\":\"a9DEa0kpY\",\"instance-group-role\":\"JZmha7QSS4tJ\",\"model-invariant-id\":\"model-id2\",\"model-version-id\":\"version2\",\"instance-group-type\":\"type\",\"resource-version\":\"1520888629970\",\"instance-group-name\":\"wKmBXiO1xm8bK\",\"instance-group-function\":\"testfunction2\",\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"cloud-region.cloud-owner\",\"relationship-value\":\"AAI-12002-vm230w\"},{\"relationship-key\":\"cloud-region.cloud-region-id\",\"relationship-value\":\"AAI-region-vm230w\"}],\"relatedToPropertyList\":[{\"property-key\":\"cloud-region.owner-defined-type\",\"property-value\":null}],\"related-to\":\"cloud-region\",\"related-link\":\"/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/AAI-12002-vm230w/AAI-region-vm230w\",\"relationship-label\":\"org.onap.relationships.inventory.Uses\",\"relationship-data\":[{\"relationship-key\":\"cloud-region.cloud-owner\",\"relationship-value\":\"AAI-12002-vm230w\"},{\"relationship-key\":\"cloud-region.cloud-region-id\",\"relationship-value\":\"AAI-region-vm230w\"}],\"related-to-property\":[{\"property-key\":\"cloud-region.owner-defined-type\",\"property-value\":null}]}]}}}]}\n";
+ public static final String GET_NETWORK_COLLECTION_EXPECTED_RESPONSE = "{\"results\":{\"collection\":{\"collection-id\":\"collection-1-2018-rs804s\",\"model-invariant-id\":\"5761e0a7-defj777\",\"model-version-id\":\"5761e0a7-defj232\",\"collection-name\":\"collection-name\",\"collection-type\":\"L3-NETWORK\",\"collection-role\":\"SUB-INTERFACE\",\"collection-function\":\"collection-function\",\"collection-customization-id\":\"custom-unique-data-id\",\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"customer.global-customer-id\",\"relationship-value\":\"customer-1-2017-rs804s\"},{\"relationship-key\":\"service-subscription.service-type\",\"relationship-value\":\"service-value7-rs804s\"},{\"relationship-key\":\"service-instance.service-instance-id\",\"relationship-value\":\"2UJZZ01777-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"service-instance.service-instance-name\",\"property-value\":null}],\"related-to\":\"service-instance\",\"related-link\":\"/aai/v13/business/customers/customer/customer-1-2017-rs804s/service-subscriptions/service-subscription/service-value7-rs804s/service-instances/service-instance/2UJZZ01777-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"customer.global-customer-id\",\"relationship-value\":\"customer-1-2017-rs804s\"},{\"relationship-key\":\"service-subscription.service-type\",\"relationship-value\":\"service-value7-rs804s\"},{\"relationship-key\":\"service-instance.service-instance-id\",\"relationship-value\":\"2UJZZ01777-rs804s\"}],\"related-to-property\":[{\"property-key\":\"service-instance.service-instance-name\",\"property-value\":null}]},{\"relationDataList\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}],\"related-to\":\"instance-group\",\"related-link\":\"/aai/v13/network/instance-groups/instance-group/instanceGroup-2018-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"related-to-property\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}]}]},\"resource-version\":\"1521662811309\"},\"networks\":[{\"network-id\":\"l3network-id-rs804s\",\"network-name\":\"oam-net\",\"network-type\":\"Tenant_Layer_3\",\"network-role\":\"HngwProtectedOam.OAM\",\"network-technology\":\"Contrail\",\"is-bound-to-vpn\":false,\"resource-version\":\"1521662814627\",\"is-provider-network\":false,\"is-shared-network\":false,\"is-external-network\":false,\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}],\"related-to\":\"instance-group\",\"related-link\":\"/aai/v13/network/instance-groups/instance-group/instanceGroup-2018-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"related-to-property\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}]}]}},{\"network-id\":\"l3network-id-3-rs804s\",\"network-name\":\"oam-net\",\"network-type\":\"Tenant_Layer_3\",\"network-role\":\"HngwProtectedOam.OAM\",\"network-technology\":\"Contrail\",\"is-bound-to-vpn\":false,\"resource-version\":\"1521662816043\",\"is-provider-network\":false,\"is-shared-network\":false,\"is-external-network\":false,\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}],\"related-to\":\"instance-group\",\"related-link\":\"/aai/v13/network/instance-groups/instance-group/instanceGroup-2018-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"related-to-property\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}]}]}},{\"network-id\":\"l3network-id-2-rs804s\",\"network-name\":\"oam-net\",\"network-type\":\"Tenant_Layer_3\",\"network-role\":\"HngwProtectedOam.OAM\",\"network-technology\":\"Contrail\",\"is-bound-to-vpn\":false,\"resource-version\":\"1521662815304\",\"is-provider-network\":false,\"is-shared-network\":false,\"is-external-network\":false,\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}],\"related-to\":\"instance-group\",\"related-link\":\"/aai/v13/network/instance-groups/instance-group/instanceGroup-2018-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"instance-group.id\",\"relationship-value\":\"instanceGroup-2018-rs804s\"}],\"related-to-property\":[{\"property-key\":\"instance-group.description\",\"property-value\":\"zr6h\"},{\"property-key\":\"instance-group.instance-group-name\",\"property-value\":\"wKmBXiO1xm8bK\"}]}]}}],\"service-instance\":{\"service-instance-id\":\"2UJZZ01777-rs804s\",\"resource-version\":\"1521662813382\",\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"collection.collection-id\",\"relationship-value\":\"collection-1-2018-rs804s\"}],\"relatedToPropertyList\":null,\"related-to\":\"collection\",\"related-link\":\"/aai/v13/network/collections/collection/collection-1-2018-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"collection.collection-id\",\"relationship-value\":\"collection-1-2018-rs804s\"}],\"related-to-property\":null}]}},\"instance-group\":{\"id\":\"instanceGroup-2018-rs804s\",\"description\":\"zr6h\",\"instance-group-role\":\"JZmha7QSS4tJ\",\"model-invariant-id\":\"5761e0a7-defj777\",\"model-version-id\":\"5761e0a7-defj22\",\"instance-group-type\":\"7DDjOdNL\",\"resource-version\":\"1521662814023\",\"instance-group-name\":\"wKmBXiO1xm8bK\",\"instance-group-function\":\"testfunction2\",\"relationship-list\":{\"relationship\":[{\"relationDataList\":[{\"relationship-key\":\"l3-network.network-id\",\"relationship-value\":\"l3network-id-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"l3-network.network-name\",\"property-value\":\"oam-net\"}],\"related-to\":\"l3-network\",\"related-link\":\"/aai/v13/network/l3-networks/l3-network/l3network-id-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"l3-network.network-id\",\"relationship-value\":\"l3network-id-rs804s\"}],\"related-to-property\":[{\"property-key\":\"l3-network.network-name\",\"property-value\":\"oam-net\"}]},{\"relationDataList\":[{\"relationship-key\":\"collection.collection-id\",\"relationship-value\":\"collection-1-2018-rs804s\"}],\"relatedToPropertyList\":null,\"related-to\":\"collection\",\"related-link\":\"/aai/v13/network/collections/collection/collection-1-2018-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"collection.collection-id\",\"relationship-value\":\"collection-1-2018-rs804s\"}],\"related-to-property\":null},{\"relationDataList\":[{\"relationship-key\":\"l3-network.network-id\",\"relationship-value\":\"l3network-id-3-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"l3-network.network-name\",\"property-value\":\"oam-net\"}],\"related-to\":\"l3-network\",\"related-link\":\"/aai/v13/network/l3-networks/l3-network/l3network-id-3-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"l3-network.network-id\",\"relationship-value\":\"l3network-id-3-rs804s\"}],\"related-to-property\":[{\"property-key\":\"l3-network.network-name\",\"property-value\":\"oam-net\"}]},{\"relationDataList\":[{\"relationship-key\":\"l3-network.network-id\",\"relationship-value\":\"l3network-id-2-rs804s\"}],\"relatedToPropertyList\":[{\"property-key\":\"l3-network.network-name\",\"property-value\":\"oam-net\"}],\"related-to\":\"l3-network\",\"related-link\":\"/aai/v13/network/l3-networks/l3-network/l3network-id-2-rs804s\",\"relationship-label\":\"org.onap.relationships.inventory.MemberOf\",\"relationship-data\":[{\"relationship-key\":\"l3-network.network-id\",\"relationship-value\":\"l3network-id-2-rs804s\"}],\"related-to-property\":[{\"property-key\":\"l3-network.network-name\",\"property-value\":\"oam-net\"}]}]}}}}\n";
+ public static final String GET_AAI_SERVIES_EXPECTED_RESULT = "{\n" +
+ " \"services\": [{\n" +
+ " \"uuid\": \"20c4431c-246d-11e7-93ae-92361f002671\",\n" +
+ " \"invariantUUID\": \"78ca26d0-246d-11e7-93ae-92361f002671\",\n" +
+ " \"name\": \"vSAMP10aDEV::base::module-0\",\n" +
+ " \"version\": \"2\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"resource\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"797a6c41-0f80-4d35-a288-3920c4e06baa\",\n" +
+ " \"invariantUUID\": \"5b607929-6088-4614-97ef-cac817508e0e\",\n" +
+ " \"name\": \"CONTRAIL30_L2NODHCP\",\n" +
+ " \"version\": \"1.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"resource\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_ERROR\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"f1bde010-cc5f-4765-941f-75f15b24f9fc\",\n" +
+ " \"invariantUUID\": \"0143d57b-a517-4de9-a0a1-eb76db51f402\",\n" +
+ " \"name\": \"BkVmxAv061917..base_vPE_AV..module-0\",\n" +
+ " \"version\": \"2\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"resource\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"ipe-resource-id-ps-02\",\n" +
+ " \"invariantUUID\": \"ipe-resource-id-ps-02\",\n" +
+ " \"name\": \"abc\",\n" +
+ " \"version\": \"v1.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"resource\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"lmoser410-connector-model-version-id\",\n" +
+ " \"invariantUUID\": \"lmoser410-connector-model-id\",\n" +
+ " \"name\": \"connector\",\n" +
+ " \"version\": \"v1.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"widget\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"ff2ae348-214a-11e7-93ae-92361f002673\",\n" +
+ " \"invariantUUID\": \"3a97db99-c4bb-498a-a13a-38f65f1ced3d\",\n" +
+ " \"name\": \"vSAMP10aDEV::base::module-0\",\n" +
+ " \"version\": \"1.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"resource\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"204c641a-3494-48c8-979a-86856f5fd32a\",\n" +
+ " \"invariantUUID\": \"3c504d40-b847-424c-9d25-4fb7e0a3e994\",\n" +
+ " \"name\": \"named-query-element\",\n" +
+ " \"version\": \"1.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"widget\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"acba1f72-c6e0-477f-9426-ad190151e100\",\n" +
+ " \"invariantUUID\": \"93e56950-cb19-44e6-ace4-8b50f2d02e45\",\n" +
+ " \"name\": \"RG_6-19_Test\",\n" +
+ " \"version\": \"1.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"resource\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"fc65e5e7-45c7-488a-b36d-f453ab3057fe\",\n" +
+ " \"invariantUUID\": \"ee448504-ceee-47db-8e1b-742115f219db\",\n" +
+ " \"name\": \"ciServicea268facd387e\",\n" +
+ " \"version\": \"1.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"service\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"027948b6-25e2-4e39-b87d-d9f5797941de\",\n" +
+ " \"invariantUUID\": \"56f2d0d3-7943-4159-bf01-b82692ec035e\",\n" +
+ " \"name\": \"service_sanity_amir\",\n" +
+ " \"version\": \"2.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"service\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }, {\n" +
+ " \"uuid\": \"fbf96e3b-1804-4c89-bf5b-53acb7f2edc0\",\n" +
+ " \"invariantUUID\": \"56f2d0d3-7943-4159-bf01-b82692ec035e\",\n" +
+ " \"name\": \"service_sanity_amir\",\n" +
+ " \"version\": \"3.0\",\n" +
+ " \"toscaModelURL\": null,\n" +
+ " \"category\": \"service\",\n" +
+ " \"lifecycleState\": null,\n" +
+ " \"lastUpdaterUserId\": null,\n" +
+ " \"lastUpdaterFullName\": null,\n" +
+ " \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
+ " \"artifacts\": null,\n" +
+ " \"resources\": null\n" +
+ " }],\n" +
+ " \"readOnly\": false\n" +
+ "}";
+
+ static final ObjectMapper om = new ObjectMapper();
+
+ private String getGetOperationEnvironmentsUri() {
+ return uri.toASCIIString() + "/get_operational_environments";
+ }
+
+ private String getAaiServicesUri() {
+ return uri.toASCIIString() + "/rest/models/services";
+ }
+
+ private String getGetOperationEnvironmentUriWithParameters() {
+ String url = getGetOperationEnvironmentsUri();
+ UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
+ // Add query parameter
+ .queryParam("operationalEnvironmentStatus", OPERATIONAL_ENVIRONMENT_STATUS)
+ .queryParam("operationalEnvironmentType", OPERATIONAL_ENVIRONMENT_TYPE);
+
+ String urlWithParameters = builder.toUriString();
+ return urlWithParameters;
+
+ }
+
+ private AaiResponse<OperationalEnvironmentList> loginAndDoGetWithUrl(String url) {
+ ResponseEntity<AaiResponse<OperationalEnvironmentList>> responseEntity = restTemplate.exchange(
+ url,
+ HttpMethod.GET,
+ null,
+ new ParameterizedTypeReference<AaiResponse<OperationalEnvironmentList>>() {});
+ AaiResponse<OperationalEnvironmentList> response = responseEntity.getBody();
+ return response;
+ }
+
+ @Test
+ public void testErrorGetOperationalEnvironments() {
+ //Register required response
+ SimulatorApi.registerExpectation(GET_OPERATIONAL_ENVIRONMENTS_JSON_ERROR, APPEND);
+ String url = getGetOperationEnvironmentsUri();
+ AaiResponse<OperationalEnvironmentList> response = loginAndDoGetWithUrl(url);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR.value(), response.getHttpCode());
+ assertEquals("simulated error text", response.getErrorMessage());
+
+
+ }
+
+ //This test requires a simulator which runs on VID
+ @Test
+ public void testSuccessGetOperationalEnvironments() {
+ //Register required response
+ String uuidOfOperationalEnvironment = "f07ca256-96dd-40ad-b4d2-7a77e2a974ed";
+ SimulatorApi.registerExpectation(GET_OPERATIONAL_ENVIRONMENTS_JSON, ImmutableMap.of("UUID_of_Operational_Environment", uuidOfOperationalEnvironment), APPEND);
+ String url = getGetOperationEnvironmentUriWithParameters();
+ AaiResponse<OperationalEnvironmentList> response = loginAndDoGetWithUrl(url);
+ assertEquals(HttpStatus.OK.value(), response.getHttpCode());
+ OperationalEnvironmentList list = response.getT();
+ assertNotEquals(null, list.getOperationalEnvironment());
+ assertEquals(2, list.getOperationalEnvironment().size());
+ assertEquals(uuidOfOperationalEnvironment, list.getOperationalEnvironment().get(0).getOperationalEnvironmentId());
+ assertEquals(1, list.getOperationalEnvironment().get(0).getRelationshipList().getRelationship().size());
+ }
+
+
+ @Test
+ public void testVoid(){
+ SimulatorApi.registerExpectation(SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET,
+ "add_subinterface/aai_get_tenants.json"
+ , "add_subinterface/aai_get_services.json"
+ );
+ }
+
+
+ @Test(dataProvider = "errorCodes")
+ public void getServicesWitErrorResponse(int errorCode) throws IOException, URISyntaxException {
+ final String expectedResult = "{\"services\":[],\"readOnly\":false}";
+
+ callAaiWithSimulatedErrorResponse(AAI_GET_SERVICES_ERROR_SIMULATOR_RESPONSES,
+ ImmutableMap.of("500", Integer.toString(errorCode), "ERROR_PAYLOAD", StringEscapeUtils.escapeJson(expectedResult)),
+ getAaiServicesUri(), "", 200, expectedResult, HttpMethod.GET);
+
+ }
+
+ @Test
+ public void getServicesFineRequest() throws IOException, URISyntaxException {
+
+ callAaiWithSimulatedErrorResponse(AAI_GET_SERVICES_FINE_SIMULATOR_RESPONSES,
+ ImmutableMap.of(),
+ getAaiServicesUri(), "", 200, GET_AAI_SERVIES_EXPECTED_RESULT, HttpMethod.GET);
+
+ }
+
+ @DataProvider
+ public static Object[][] errorCodes(Method test) {
+ return new Object[][]{
+ {500},{505}, {400}, {401}, {405}
+ };
+ }
+
+ @Test
+ public void whenThrowExceptionInsAaiResponseErrorAreLogged() {
+ String notAJson = "not a json";
+ SimulatorApi.registerExpectationFromPreset(new PresetAAIBadBodyForGetServicesGet(notAJson), CLEAR_THEN_SET);
+ SimulatorApi.registerExpectationFromPresets(getEcompPortalPresets(), APPEND);
+ SimulatorApi.registerExpectationFromPreset(new PresetAAIGetSubscribersGet(), APPEND);
+
+ restTemplateErrorAgnostic.getForEntity(uri + "/aai_get_services",String.class);
+ String logLines = LoggerFormatTest.getLogLines("error", 15, 0, restTemplate, uri);
+
+ assertThat("not found in error log", logLines, containsString("Failed to parse aai response"));
+ assertThat("not found in error log", logLines, containsString(notAJson));
+ assertThat("not found in error log", logLines, containsString("GetServicesAAIRespone"));
+
+ }
+
+ @Test
+ public void portMirroringConfigData_givenValidAaiResponse_yieldCloudRegionId() {
+ SimulatorApi.registerExpectationFromPreset(new PresetAAICloudRegionAndSourceFromConfigurationPut("SOME-RANDOM-UUID", "THE-EXPECTED-REGION-ID"), CLEAR_THEN_SET);
+
+ final String response = restTemplate.getForObject(uri + "/aai_getPortMirroringConfigsData?configurationIds=" + "SOME-RANDOM-UUID", String.class);
+
+ final ImmutableMap<String, ImmutableMap<String, String>> expected = ImmutableMap.of(
+ "SOME-RANDOM-UUID", ImmutableMap.of(
+ "cloudRegionId", "THE-EXPECTED-REGION-ID"
+ ));
+
+ assertResponse(expected, response);
+
+ /*
+ More tests:
+ [ ] Error responses from AAI (404 etc): descriptive error response, including what tried and what happened
+ [ ] malformed response from AAI: descriptive error response, including the payload
+ [ ] empty/missing value for configurationId: client-error http code
+ */
+ }
+
+
+ @Test
+ public void portMirroringSourcePorts_validAAIResponseWithSinglePort_yieldCorrectPortData() {
+ SimulatorApi.registerExpectationFromPreset(
+ new PresetAAIGetPortMirroringSourcePorts("CONFIGURATION-ID", "INTERFACE-ID", "INTERFACE-NAME", true),
+ CLEAR_THEN_SET
+ );
+
+ final String response = restTemplate.getForObject(uri + "/aai_getPortMirroringSourcePorts?configurationIds=" + "CONFIGURATION-ID", String.class);
+
+ final ImmutableMap<String, ImmutableList> expected = ImmutableMap.of(
+ "CONFIGURATION-ID", ImmutableList.of(ImmutableMap.of(
+ "interfaceId", "INTERFACE-ID", "interfaceName", "INTERFACE-NAME", "isPortMirrored", true
+ )));
+
+ assertResponse(expected, response);
+ }
+
+ @Test
+ public void portMirroringSourcePorts_nullValueForInterfaceId_yield200OkWithFineDescription() {
+ final PresetAAIGetPortMirroringSourcePorts preset = new PresetAAIGetPortMirroringSourcePorts("CONFIGURATION-ID", null, "INTERFACE-NAME", true);
+ SimulatorApi.registerExpectationFromPreset(
+ preset,
+ CLEAR_THEN_SET
+ );
+
+ final String response = restTemplate.getForObject(uri + "/aai_getPortMirroringSourcePorts?configurationIds=" + "CONFIGURATION-ID", String.class);
+
+ final ImmutableMap<String, ImmutableList<ImmutableMap>> expected = ImmutableMap.of(
+ "CONFIGURATION-ID", ImmutableList.of(ImmutableMap.of(
+ "errorDescription", "Value of 'interface-id' is missing.",
+ "rawAaiResponse", preset.getResponseBody().toString()
+ )));
+
+ assertResponse(expected, response);
+ }
+
+ @Test
+ public void portMirroringSourcePorts_given503ErrorAaiResponse_yield200OkWithErrorMsg() {
+ final PresetAAIGetPortMirroringSourcePortsError preset = new PresetAAIGetPortMirroringSourcePortsError("CONFIGURATION-ID", "INTERFACE-ID", "INTERFACE-NAME", true);
+ SimulatorApi.registerExpectationFromPreset(
+ preset,
+ CLEAR_THEN_SET
+ );
+
+ final String response = restTemplate.getForObject(uri + "/aai_getPortMirroringSourcePorts?configurationIds=" + "CONFIGURATION-ID", String.class);
+
+ final ImmutableMap<String, ImmutableList<ImmutableMap>> expected = ImmutableMap.of(
+ "CONFIGURATION-ID", ImmutableList.of(ImmutableMap.of(
+ "errorDescription", "Got 503 from aai",
+ "rawAaiResponse", preset.getResponseBody()
+ )));
+
+ assertResponse(expected, response);
+ }
+
+ @Test
+ public void portMirroringConfigData_given404ErrorAaiResponse_yield200OkWithErrorMsg() {
+ SimulatorApi.clearAll();
+
+ final String response = restTemplate.getForObject(uri + "/aai_getPortMirroringConfigsData?configurationIds=" + "SOME-RANDOM-UUID", String.class);
+
+ final ImmutableMap<String, ImmutableMap<String, String>> expected = ImmutableMap.of(
+ "SOME-RANDOM-UUID", ImmutableMap.of(
+ "errorDescription", "Got 404 from aai",
+ "rawAaiResponse", ""
+ ));
+
+ assertResponse(expected, response);
+ }
+
+ @Test
+ public void getNetworkCollectionDetailsByServiceInstanceId_yieldValidResponse() {
+ SimulatorApi.clearAll();
+ final PresetAAIGetNetworkCollectionDetails presetAAIGetNetworkCollectionDetails = new PresetAAIGetNetworkCollectionDetails("SOME-RANDOM-UUID");
+ SimulatorApi.registerExpectationFromPreset(presetAAIGetNetworkCollectionDetails, CLEAR_THEN_SET);
+ final String response = restTemplate.getForObject(uri + "/aai_get_network_collection_details/" + "SOME-RANDOM-UUID", String.class);
+
+ assertResponse(GET_NETWORK_COLLECTION_EXPECTED_RESPONSE, response);
+ }
+
+ @Test
+ public void getNetworkCollectionDetailsByServiceInstanceId_responseWithExtraFields_yieldValidResponse() {
+ SimulatorApi.clearAll();
+ final PresetAAIGetNetworkCollectionDetailsInvalidRequest presetAAIGetNetworkCollectionDetails = new PresetAAIGetNetworkCollectionDetailsInvalidRequest("SOME-RANDOM-UUID");
+ SimulatorApi.registerExpectationFromPreset(presetAAIGetNetworkCollectionDetails, CLEAR_THEN_SET);
+ final String response = restTemplate.getForObject(uri + "/aai_get_network_collection_details/" + "SOME-RANDOM-UUID", String.class);
+
+ assertResponse(GET_NETWORK_COLLECTION_EXPECTED_RESPONSE, response);
+ }
+ @Test
+ public void getNetworkCollectionDetailsByServiceInstanceId_given404ErrorAaiResponse_yield200OkWithErrorMsg() {
+ SimulatorApi.clearAll();
+ try {
+ restTemplate.getForObject(uri + "/aai_get_network_collection_details/" + "SOME-RANDOM-UUID", String.class);
+ }catch (HttpClientErrorException e){
+ assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());
+ }
+ }
+
+ @Test
+ public void getNetworkCollectionDetailsByServiceInstanceId_responseWithRequiredMissing() {
+ SimulatorApi.clearAll();
+ final PresetAAIGetNetworkCollectionDetailsRequiredMissing presetAAIGetNetworkCollectionDetails = new PresetAAIGetNetworkCollectionDetailsRequiredMissing("SOME-RANDOM-UUID");
+ SimulatorApi.registerExpectationFromPreset(presetAAIGetNetworkCollectionDetails, CLEAR_THEN_SET);
+ try {
+ restTemplate.getForObject(uri + "/aai_get_network_collection_details/" + "SOME-RANDOM-UUID", String.class);
+ }catch (HttpServerErrorException e){
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, e.getStatusCode());
+ }
+ }
+
+ @Test
+ public void getGetInstanceGroupsByCloudRegion_yieldValidResponse() {
+ SimulatorApi.clearAll();
+ final PresetAAIGetInstanceGroupsByCloudRegion presetAAIGetInstanceGroupsByCloudRegion = new PresetAAIGetInstanceGroupsByCloudRegion("CLOUD-OWNER", "CLOUD-REGION-ID", "NETWORK-FUNCTION");
+ SimulatorApi.registerExpectationFromPreset(presetAAIGetInstanceGroupsByCloudRegion, CLEAR_THEN_SET);
+ final String response = restTemplate.getForObject(uri + "/aai_get_instance_groups_by_cloudregion/" + "CLOUD-OWNER" + "/" + "CLOUD-REGION-ID" + "/" +"NETWORK-FUNCTION", String.class);
+
+ assertResponse(GET_INSTANCE_GROUPS_BY_CLOUDREGION_EXPECTED_RESPONSE, response);
+ }
+
+ @Test
+ public void getGetInstanceGroupsByCloudRegion_responseWithExtraFields_yieldValidResponse() {
+ SimulatorApi.clearAll();
+ final PresetAAIGetInstanceGroupsByCloudRegionInvalidRequest presetAAIGetInstanceGroupsByCloudRegion = new PresetAAIGetInstanceGroupsByCloudRegionInvalidRequest("CLOUD-OWNER", "CLOUD-REGION-ID", "NETWORK-FUNCTION");
+ SimulatorApi.registerExpectationFromPreset(presetAAIGetInstanceGroupsByCloudRegion, CLEAR_THEN_SET);
+ final String response = restTemplate.getForObject(uri + "/aai_get_instance_groups_by_cloudregion/" + "CLOUD-OWNER" + "/" + "CLOUD-REGION-ID" + "/" +"NETWORK-FUNCTION", String.class);
+
+ assertResponse(GET_INSTANCE_GROUPS_BY_CLOUDREGION_EXPECTED_RESPONSE, response);
+ }
+ @Test
+ public void getGetInstanceGroupsByCloudRegion_given404ErrorAaiResponse_yield200OkWithErrorMsg() {
+ SimulatorApi.clearAll();
+ try {
+ restTemplate.getForObject(uri + "/aai_get_instance_groups_by_cloudregion/" + "CLOUD-OWNER" + "/" + "CLOUD-REGION-ID" + "/" +"NETWORK-FUNCTION", String.class);
+ }catch (HttpClientErrorException e){
+ assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());
+ }
+ }
+
+ @Test
+ public void getGetInstanceGroupsByCloudRegion_responseWithRequiredMissing() {
+ SimulatorApi.clearAll();
+ final PresetAAIGetInstanceGroupsByCloudRegionRequiredMissing presetAAIGetInstanceGroupsByCloudRegion = new PresetAAIGetInstanceGroupsByCloudRegionRequiredMissing("CLOUD-OWNER", "CLOUD-REGION-ID", "NETWORK-FUNCTION");
+ SimulatorApi.registerExpectationFromPreset(presetAAIGetInstanceGroupsByCloudRegion, CLEAR_THEN_SET);
+ try {
+ restTemplate.getForObject(uri + "/aai_get_instance_groups_by_cloudregion/" + "CLOUD-OWNER" + "/" + "CLOUD-REGION-ID" + "/" +"NETWORK-FUNCTION", String.class);
+ }catch (HttpServerErrorException e){
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, e.getStatusCode());
+ }
+ }
+
+ @Test
+ public void portMirroringConfigData_emptyIdOnAaiResponse_yieldError() {
+ final PresetAAICloudRegionAndSourceFromConfigurationPut presetAAIResponseWitnProblem = new PresetAAICloudRegionAndSourceFromConfigurationPut("SOME-RANDOM-UUID", "");
+ SimulatorApi.registerExpectationFromPreset(presetAAIResponseWitnProblem, CLEAR_THEN_SET);
+
+ final String response = restTemplate.getForObject(uri + "/aai_getPortMirroringConfigsData?configurationIds=" + "SOME-RANDOM-UUID", String.class);
+
+ final ImmutableMap<String, ImmutableMap<String, String>> expected = ImmutableMap.of(
+ "SOME-RANDOM-UUID", ImmutableMap.of(
+ "errorDescription", "Node 'properties.cloud-region-id' of node-type 'cloud-region' is blank",
+ "rawAaiResponse", presetAAIResponseWitnProblem.getResponseBody().toString().replace(" ", "")
+ ));
+
+ assertResponse(expected, response);
+ }
+
+ @Test
+ public void getGetRelatedInstanceGroupsByVnfId__yieldValidResponse() {
+ String vnfId = "some_vnf_id";
+ final PresetAAIGetRelatedInstanceGroupsByVnfId getRelatedInstanceGroupsByVnfId = new PresetAAIGetRelatedInstanceGroupsByVnfId(vnfId);
+ SimulatorApi.registerExpectationFromPreset(getRelatedInstanceGroupsByVnfId, CLEAR_THEN_SET);
+
+ final String response = restTemplate.getForObject(uri + "/aai_get_instance_groups_by_vnf_instance_id/" + vnfId, String.class);
+
+ assertResponse("[{\"type\":\"instance-group\",\"name\":\"instance group name\"},{\"type\":\"instance-group\",\"name\":\"instance group name\"}]", response);
+ }
+
+ @Test
+ public void getGetRelatedInstanceGroupsByVnfId__yield404NotFound() {
+ final PresetAAIGetRelatedInstanceGroupsByVnfId getRelatedInstanceGroupsByVnfId = new PresetAAIGetRelatedInstanceGroupsByVnfId("abcd");
+ SimulatorApi.registerExpectationFromPreset(getRelatedInstanceGroupsByVnfId, CLEAR_THEN_SET);
+ try {
+ restTemplate.getForObject(uri + "/aai_get_instance_groups_by_vnf_instance_id/" + "dcba", String.class);
+ } catch (HttpClientErrorException e){
+ assertEquals(HttpStatus.NOT_FOUND, e.getStatusCode());
+ }
+
+ }
+
+ @Test
+ public void portMirroringConfigData_twoResponsesOneValidAndOneInvalid_yieldBothErrorAndOk() {
+ final PresetAAICloudRegionAndSourceFromConfigurationPut presetAAIResponseWitnProblem = new PresetAAICloudRegionAndSourceFromConfigurationPut("ANOTHER-RANDOM-UUID", "");
+ SimulatorApi.registerExpectationFromPreset(presetAAIResponseWitnProblem, CLEAR_THEN_SET);
+ SimulatorApi.registerExpectationFromPreset(new PresetAAICloudRegionAndSourceFromConfigurationPut("SOME-RANDOM-UUID", "THE-EXPECTED-REGION-ID"), APPEND);
+
+ final String response = restTemplate.getForObject(uri + "/aai_getPortMirroringConfigsData?configurationIds=" + "SOME-RANDOM-UUID,ANOTHER-RANDOM-UUID", String.class);
+
+ final ImmutableMap<String, ImmutableMap<String, Object>> expected = ImmutableMap.of(
+ "SOME-RANDOM-UUID", ImmutableMap.of(
+ "cloudRegionId", "THE-EXPECTED-REGION-ID"
+ ),
+ "ANOTHER-RANDOM-UUID", ImmutableMap.of(
+ "errorDescription", "Node 'properties.cloud-region-id' of node-type 'cloud-region' is blank",
+ "rawAaiResponse", presetAAIResponseWitnProblem.getResponseBody().toString().replace(" ", "")
+ ));
+
+ assertResponse(expected, response);
+ }
+
+ private void assertResponse(Object expected, String response) {
+ try {
+ JsonAssert.assertJsonEquals(expected, response);
+ } catch (Exception | AssertionError e) {
+ System.err.println("response was: " + response);
+ throw e;
+ }
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/AsyncInfraApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/AsyncInfraApiTest.java
new file mode 100644
index 000000000..5f83f36dc
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/AsyncInfraApiTest.java
@@ -0,0 +1,233 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableList;
+import com.google.gson.JsonObject;
+import net.codestory.http.WebServer;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
+import org.onap.simulator.presetGenerator.presets.ecompportal_att.PresetGetSessionSlotCheckIntervalGet;
+import org.onap.vid.more.LoggerFormatTest;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import vid.automation.test.infra.Features;
+import vid.automation.test.infra.Wait;
+import vid.automation.test.model.JobBulk;
+import vid.automation.test.model.JobModel;
+import vid.automation.test.services.SimulatorApi;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.testng.AssertJUnit.assertEquals;
+
+public class AsyncInfraApiTest extends BaseApiTest {
+
+ private static final String PENDING = "PENDING";
+ public static final String API_URL = "asyncForTests";
+
+ private boolean asyncJobsIsOn() {
+ return Features.FLAG_ASYNC_JOBS.isActive()
+ && Features.FLAG_ASYNC_INSTANTIATION.isActive();
+ }
+
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+ @BeforeMethod
+ protected void deleteAllPendingJobs() {
+ System.out.println("Connecting database...");
+
+ try (Connection connection = DriverManager.getConnection(DB_CONFIG.url, DB_CONFIG.username, DB_CONFIG.password)) {
+ System.out.println("Database connected!");
+ try (Statement stmt = connection.createStatement()) {
+ stmt.addBatch("DELETE from `vid_service_info`");
+ stmt.addBatch("DELETE FROM `vid_job`");
+
+ int[] executeBatch = stmt.executeBatch();
+ }
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("Cannot connect the database!", e);
+ }
+ }
+
+
+ @Test
+ public void createBulkOfJobsViaApi_thenGetEachOneOfThem() {
+ int jobCount = 10;
+ final String url = "http://localhost:1234/testMe";
+ ResponseEntity<JobBulk> result = postJobBulk(jobCount, url, "NoOp");
+ assertEquals(HttpStatus.OK, result.getStatusCode());
+ Assert.assertNotNull(result.getBody());
+ assertEquals(jobCount, getJobChildren(result).size());
+
+
+ result.getBody().getJobs().forEach(job -> {
+ assertThat(job.getUuid(), not(isEmptyOrNullString()));
+ assertEquals(PENDING, job.getStatus());
+ });
+
+ result.getBody().getJobs().forEach(job -> {
+ ResponseEntity<JobModel> jobResult = restTemplate.getForEntity(buildUri(API_URL+"/job/{uuid}"), JobModel.class, job.getUuid());
+ assertEquals(job.getUuid(), jobResult.getBody().getUuid());
+ //assertEquals(PENDING, jobResult.getBody().getStatus());
+ });
+ }
+
+ private List<JobModel> getJobChildren(ResponseEntity<JobBulk> result) {
+ return result.getBody().getJobs().stream().filter(job -> job.getTemplateId() != null).collect(Collectors.toList());
+ }
+
+ private ResponseEntity<JobBulk> postJobBulk(int jobCount, String url, String type) {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("name", "service-"+random.nextInt());
+ jsonObject.addProperty("count", jobCount);
+ jsonObject.addProperty("url", url);
+ jsonObject.addProperty("type", type);
+ ResponseEntity<JobBulk> result = restTemplate.postForEntity(buildUri(API_URL), jsonObject.toString(), JobBulk.class);
+ return result;
+ }
+
+ @Test
+ public void addFewJobs_verifyCallbacksAreAllAndNoDuplicates() throws InterruptedException {
+ final Collection<String> expected = new ConcurrentSkipListSet<>();
+ final Collection<String> results = new ConcurrentSkipListSet<>();
+ final Collection<String> duplicates = new ConcurrentSkipListSet<>();
+ final String targetPath = "/my-mso";
+
+ // https://github.com/CodeStory/fluent-http
+ final WebServer server = new WebServer().configure(routes -> routes
+ .post(targetPath, (context) -> {
+ final String body = context.extract(String.class);
+ if (!results.add(body)) {
+ duplicates.add(body);
+ }
+ return body;
+ })
+ ).startOnRandomPort();
+
+ final int jobCount = 10;
+ final int childCount = 2;
+
+ InetAddress inetAddress = getExternalInetAddress();
+
+ final String returnUrl = "http://" + inetAddress.getHostAddress() + ":" + server.port() + targetPath;
+ System.out.println(returnUrl);
+
+ // POST jobs
+ IntStream.range(0, jobCount).parallel().forEach(i -> {
+ ResponseEntity<JobBulk> result = postJobBulk(childCount, returnUrl, "HttpCall");
+ getJobChildren(result).forEach(child -> {
+ expected.add(child.getUuid());
+ });
+ });
+ Wait.waitFor((actual -> actual.size() == expected.size()), results, 75, 200, TimeUnit.MILLISECONDS);
+ // wait some another time give change for duplications
+ TimeUnit.SECONDS.sleep(5);
+
+ if (asyncJobsIsOn()) {
+ assertThat("async jobs is on: should callback for all jobs - no more, no less", results, equalTo(expected));
+ assertThat("async jobs is on: should callback for exactly number of jobs", results, hasSize(jobCount * childCount));
+ assertThat("async jobs is on: should have no duplicate jobs callback", duplicates, empty());
+ } else {
+ assertThat("async jobs is off: should not callback for any job", results, empty());
+ assertThat("async jobs is off: should have no duplicate jobs callback", duplicates, empty());
+ }
+
+ server.stop();
+
+ }
+
+ private InetAddress getExternalInetAddress() {
+ // https://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java
+ InetAddress candidateAddress = null;
+ try {
+ for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
+ NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
+
+ if (iface.getName().contains("docker")) {
+ // ignore local docker virtual gateway IPs
+ continue;
+ }
+
+ // Iterate all IP addresses assigned to each card...
+ for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
+ InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
+
+ // take only non-loopback, ipv4 addresses
+ if (!inetAddr.isLoopbackAddress() && inetAddr instanceof Inet4Address) {
+
+ System.out.println("inetAddr (" + iface.getName() + "): " + inetAddr);
+ if (inetAddr.isSiteLocalAddress()) {
+ // Found non-loopback site-local address. Return it immediately...
+ System.out.println("inetAddr, site-local (" + iface.getName() + "): " + inetAddr);
+ candidateAddress = inetAddr;
+ }
+ else if (candidateAddress == null) {
+ // Found non-loopback address, but not necessarily site-local.
+ // Store it as a candidate to be returned if site-local address is not subsequently found...
+ candidateAddress = inetAddr;
+ // Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
+ // only the first. For subsequent iterations, candidate will be non-null.
+ }
+ }
+ }
+
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return candidateAddress;
+ }
+
+ @Test
+ public void testGetStatusBadRequest() {
+ ResponseEntity<String> jobResult = getJob("1234");
+ assertEquals(HttpStatus.BAD_REQUEST, jobResult.getStatusCode());
+ }
+
+ @Test
+ public void testGetStatusNotFound() {
+ ResponseEntity<String> jobResult = getJob(UUID.randomUUID().toString());
+ assertEquals(HttpStatus.NOT_FOUND, jobResult.getStatusCode());
+ }
+
+ private ResponseEntity<String> getJob(String uuid) {
+ return restTemplateErrorAgnostic.getForEntity(buildUri(API_URL + "/job/{uuid}"), String.class , uuid);
+ }
+
+ @Test
+ public void testExceptionHandlingOfVidRestrictedBaseController() {
+ //get logs require user role that may need simulator presets
+ SimulatorApi.registerExpectationFromPresets(ImmutableList.of(
+ new PresetGetSessionSlotCheckIntervalGet(),
+ new PresetAAIGetSubscribersGet()), SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+ ResponseEntity<String> jobResult = restTemplateErrorAgnostic.getForEntity(buildUri(API_URL + "/error"), String.class);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, jobResult.getStatusCode());
+ assertThat(jobResult.getBody(), containsString("GenericUncheckedException"));
+ assertThat(jobResult.getBody(), containsString("dummy error"));
+ String logLines = LoggerFormatTest.getLogLines("error", 15, 0, restTemplate, uri);
+ assertThat(logLines, containsString("GenericUncheckedException"));
+ assertThat(logLines, containsString("dummy error"));
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationApiTest.java
new file mode 100644
index 000000000..1a0e1c9b7
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/AsyncInstantiationApiTest.java
@@ -0,0 +1,524 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import net.bytebuddy.utility.RandomString;
+import net.javacrumbs.jsonunit.JsonAssert;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Description;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAISearchNodeQueryEmptyResult;
+import org.onap.simulator.presetGenerator.presets.ecompportal_att.PresetGetSessionSlotCheckIntervalGet;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOAssignServiceInstanceGen2WithNames;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOCreateServiceInstanceGen2WithNames;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGet;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGetErrorResponse;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2ErrorResponse;
+import org.onap.vid.model.asyncInstantiation.JobAuditStatus;
+import org.onap.vid.model.asyncInstantiation.ServiceInfo;
+import org.onap.vid.model.mso.MsoResponseWrapper2;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.HttpClientErrorException;
+
+import org.springframework.web.client.RestTemplate;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import vid.automation.test.infra.FeatureTogglingTest;
+import vid.automation.test.infra.Features;
+import vid.automation.test.infra.Wait;
+import vid.automation.test.model.JobStatus;
+import vid.automation.test.services.SimulatorApi;
+import java.util.*;
+
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static java.util.stream.Collectors.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasProperty;
+import static org.hamcrest.Matchers.hasSize;
+import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+@FeatureTogglingTest({Features.FLAG_ASYNC_JOBS, Features.FLAG_ASYNC_INSTANTIATION})
+public class AsyncInstantiationApiTest extends BaseMsoApiTest {
+
+ private static final String CREATE_BULK_OF_MACRO_REQUEST = "asyncInstantiation/vidRequestCreateBulkOfMacro.json";
+
+ @DataProvider
+ public static Object[][] trueAndFalse() {
+ return new Object[][]{{TRUE},{FALSE}};
+ }
+
+ private String getCreateBulkUri() {
+ return uri.toASCIIString() + "/asyncInstantiation/bulk";
+ }
+
+ private String getHideServiceUri(String jobId) {
+ return uri.toASCIIString() + "/asyncInstantiation/hide/"+jobId;
+ }
+
+ private String getServiceInfoUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation";
+ }
+
+ private String getJobAuditUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation/auditStatus/{JOB_ID}?source={SOURCE}";
+ }
+
+ private String getDeleteServiceUrl(String uuid) {
+ return uri.toASCIIString() + "/asyncInstantiation/job/" + uuid;
+ }
+
+ public static class JobIdAndStatusMatcher extends BaseMatcher<ServiceInfo> {
+ private String expectedJobId;
+
+ public JobIdAndStatusMatcher(String expectedJobId) {
+ this.expectedJobId = expectedJobId;
+ }
+
+ @Override
+ public boolean matches(Object item) {
+ if (!(item instanceof ServiceInfo)) {
+ return false;
+ }
+ ServiceInfo serviceInfo = (ServiceInfo) item;
+ return expectedJobId.equals(serviceInfo.jobId);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("failed to find job with uuid ")
+ .appendValue(expectedJobId);
+ }
+ }
+
+
+
+ @Test
+ public void createBulkOfCreateInstances(){
+ Map<Keys, String> names = generateNames();
+ final int bulkSize = 3;
+ ImmutableList<BasePreset> presets = addPresetsForCreateBulkOfCreateInstances(bulkSize, names);
+ createBulkOfInstancesAndAssert(presets, false, bulkSize, JobStatus.COMPLETED, names);
+ }
+
+ private Map<Keys,String> generateNames() {
+ return Stream.of(Keys.values()).collect(
+ Collectors.toMap(x->x, x -> UUID.randomUUID().toString().replace("-","")));
+ }
+
+ private ImmutableList<BasePreset> addPresetsForCreateBulkOfCreateInstances(int bulkSize, Map<Keys, String> names){
+ ImmutableList<BasePreset> msoBulkPresets = IntStream.rangeClosed(1,bulkSize).
+ mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i))
+ .collect(ImmutableList.toImmutableList());
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .add(new PresetAAISearchNodeQueryEmptyResult())
+ .addAll(msoBulkPresets)
+ .add(new PresetMSOOrchestrationRequestGet())
+ .build();
+ return presets;
+
+ }
+
+ private ResponseEntity<List<JobAuditStatus>> auditStatusCall(String url) {
+ return restTemplate.exchange(
+ url,
+ org.springframework.http.HttpMethod.GET,
+ null,
+ new ParameterizedTypeReference<List<JobAuditStatus>>() {});
+ }
+
+ @DataProvider
+ public static Object[][] auditSources() {
+ return new Object[][]{{JobAuditStatus.SourceStatus.VID},{JobAuditStatus.SourceStatus.MSO}};
+ }
+
+
+ @Test(dataProvider = "auditSources")
+ public void getAuditStatus_nonExistingJobId_returnsEmptyList(JobAuditStatus.SourceStatus source){
+ List<JobAuditStatus> audits = getAuditStatuses(UUID.randomUUID().toString(), source.name());
+ Assert.assertEquals(audits.size(),0);
+ }
+
+ @Test(expectedExceptions = HttpClientErrorException.class)
+ public void getAuditStatus_nonExistingSource_returnsError() {
+ try {
+ getAuditStatuses(UUID.randomUUID().toString(), new RandomString(8).nextString());
+ } catch (HttpClientErrorException e) {
+ Assert.assertEquals(e.getResponseBodyAsString(),"The parameter source must have a value among : MSO, VID");
+ assertThat(e.getStatusCode(), is(HttpStatus.BAD_REQUEST));
+ throw e;
+ }
+ }
+
+ @Test()
+ public void simulateBulkRequest_getAuditStatus_auditStatusesReturnedAccordingSource() {
+ final int bulkSize = 2;
+ final List<String> jobIds = createBulkAndWaitForBeCompleted(bulkSize);
+
+ for(String jobId: jobIds) {
+ List<JobAuditStatus> actualVidAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.VID.name());
+ List<JobAuditStatus> expectedVidAudits = Stream.of(JobStatus.PENDING, JobStatus.IN_PROGRESS, JobStatus.COMPLETED)
+ .map(status->new JobAuditStatus(UUID.fromString(jobId),
+ status.name(),
+ JobAuditStatus.SourceStatus.VID,
+ null,
+ null,
+ status.equals(JobStatus.COMPLETED))).collect(toList());
+ assertThat(actualVidAudits, is(expectedVidAudits));
+
+ List<JobAuditStatus> actualMsoAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name());
+ List<JobAuditStatus> expectedMsoAudits = Stream.of("REQUESTED", "COMPLETE")
+ .map(status-> new JobAuditStatus(UUID.fromString(jobId),
+ status,
+ JobAuditStatus.SourceStatus.MSO,
+ UUID.fromString("c0011670-0e1a-4b74-945d-8bf5aede1d9c"),
+ status.equals("COMPLETE") ? "Service Instance was created successfully." : null,
+ false)).collect(toList());
+ assertThat(actualMsoAudits, is(expectedMsoAudits));
+ }
+ }
+
+ protected List<String> createBulkAndWaitForBeCompleted(int bulkSize){
+ Map<Keys, String> names = generateNames();
+ ImmutableList<BasePreset> presets = addPresetsForCreateBulkOfCreateInstances(bulkSize, names);
+ final List<String> jobIds = createBulkOfInstances(presets, false, bulkSize, names);
+ Assert.assertEquals(jobIds.size(),bulkSize);
+
+ assertTrue(String.format("Not all services with ids: %s are in state completed after 30 sec",
+ jobIds.stream().collect(joining(","))),
+
+ Wait.waitFor(y-> serviceListCall().getBody().stream()
+ .filter(si -> jobIds.contains(si.jobId))
+ .filter(si -> si.jobStatus==JobStatus.COMPLETED)
+ .count() == bulkSize,
+ null, 30, 1 ));
+ return jobIds;
+ }
+
+ private List<JobAuditStatus> getAuditStatuses(String jobUUID, String source){
+ String url = getJobAuditUrl().replace("{JOB_ID}",jobUUID).replace("{SOURCE}", source);
+ ResponseEntity<List<JobAuditStatus>> statusesResponse = auditStatusCall(url);
+ assertThat(statusesResponse.getStatusCode(), CoreMatchers.equalTo(HttpStatus.OK));
+ return statusesResponse.getBody();
+ }
+
+ @Test(expectedExceptions = HttpClientErrorException.class)
+ public void addBulkAndDeleteInProgress_deletionIsRejected(){
+ try {
+ final Map<String, JobStatus> jobs = addBulkAllPendingButOneInProgress();
+ deleteOneJobHavingTheStatus(jobs, JobStatus.IN_PROGRESS);
+ } catch (HttpClientErrorException e) {
+ JsonAssert.assertJsonPartEquals(
+ "Service status does not allow deletion from the queue (Request id: null)",
+ e.getResponseBodyAsString(),
+ "message"
+ );
+ assertThat(e.getStatusCode(), is(HttpStatus.METHOD_NOT_ALLOWED));
+
+ throw e;
+ }
+ }
+
+ @Test
+ public void addBulkAndDeletePending_deletedIsHiddenFromServiceInfoResults(){
+ Map<String, JobStatus> statusesBefore = addBulkAllPendingButOneInProgress();
+
+ final String deletedJob = deleteOneJobHavingTheStatus(statusesBefore, JobStatus.PENDING);
+
+ final Map<String, JobStatus> statusesNow = serviceListCall().getBody().stream()
+ .filter(si -> statusesBefore.keySet().contains(si.jobId))
+ .collect(toMap(si -> si.jobId, si -> si.jobStatus));
+
+ statusesBefore.remove(deletedJob);
+ assertThat("deleted job shall not be present in StatusInfo response", statusesNow, is(statusesBefore));
+ }
+
+ private Map<String, JobStatus> addBulkAllPendingButOneInProgress(){
+ return addBulkAllPendingButOneInProgress(3);
+ }
+
+ private Map<String, JobStatus> addBulkAllPendingButOneInProgress(int bulkSize){
+ Map<Keys, String> names = generateNames();
+ ImmutableList<BasePreset> msoBulkPresets = IntStream.rangeClosed(1,bulkSize)
+ .mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i))
+ .collect(ImmutableList.toImmutableList());
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAISearchNodeQueryEmptyResult())
+ .add(new PresetAAIGetSubscribersGet())
+ .addAll(msoBulkPresets)
+ .add(new PresetMSOOrchestrationRequestGet("IN_PROGRESS"))
+ .build();
+ final List<String> jobIds = createBulkOfInstances(presets, false, bulkSize, names);
+
+ // wait for single IN_PROGRESS, so statuses will stop from changing
+ Wait.waitFor(foo -> serviceListCall().getBody().stream()
+ .filter(si -> jobIds.contains(si.jobId))
+ .anyMatch(si -> si.jobStatus.equals(JobStatus.IN_PROGRESS)),
+ null, 20, 1);
+
+ final Map<String, JobStatus> statusMapBefore = serviceListCall().getBody().stream()
+ .filter(si -> jobIds.contains(si.jobId))
+ .collect(toMap(si -> si.jobId, si -> si.jobStatus));
+
+ assertThat(jobIds, hasSize(bulkSize));
+
+
+ return statusMapBefore;
+ }
+
+ private String deleteOneJobHavingTheStatus(Map<String, JobStatus> jobIdToStatus, JobStatus jobStatus) {
+ final String jobToDelete = jobIdToStatus.entrySet().stream()
+ .filter(entry -> entry.getValue().equals(jobStatus))
+ .map(Map.Entry::getKey)
+ .findFirst().orElseThrow(() -> new AssertionError("no job in " + jobStatus + " state: " + jobIdToStatus));
+
+
+ restTemplate.delete(getDeleteServiceUrl(jobToDelete));
+
+ return jobToDelete;
+ }
+
+ @Test(invocationCount = 3)
+ public void createBulkOfCreateInstancesWithSinglePreset_firstOneInProgressOtherArePending(){
+ final int bulkSize = 3;
+ Map<String, JobStatus> statusMap = addBulkAllPendingButOneInProgress(bulkSize);
+ Set<String> jobIds = statusMap.keySet();
+
+ final Map<JobStatus, List<ServiceInfo>> statuses = serviceListCall().getBody().stream()
+ .filter(si -> jobIds.contains(si.jobId))
+ .collect(groupingBy(ServiceInfo::getJobStatus));
+
+ // Variable "statuses" contains two lists by status:
+ // IN_PROGRESS: The ultimate first job - named with _001 - is always the only one in progress
+ // PENDING: The other two jobs - named with _002 and _003 - are the still pending
+ assertThat(jobIds, hasSize(bulkSize));
+ assertThat(statuses.get(JobStatus.IN_PROGRESS), hasSize(1));
+ assertThat(statuses.get(JobStatus.IN_PROGRESS), everyItem(hasProperty("serviceInstanceName", endsWith("_001"))));
+
+ assertThat(statuses.get(JobStatus.PENDING), hasSize(bulkSize - 1));
+ }
+
+
+ @Test(dataProvider = "trueAndFalse" )
+ public void whenServiceInBulkFailed_otherServicesAreStopped(Boolean isPresetForCreate){
+ Map<Keys, String> names = generateNames();
+ final int bulkSize = 3;
+
+ //if there is a preset for create, service shall failed during in_progress (upon get status)
+ //it there is no preset for create, service shall failed during pending (upon create request)
+ List<BasePreset> msoBulkPresets = isPresetForCreate ?
+ IntStream.rangeClosed(1,bulkSize)
+ .mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i))
+ .collect(ImmutableList.toImmutableList()) :
+ new LinkedList<>();
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .add(new PresetAAISearchNodeQueryEmptyResult())
+ .addAll(msoBulkPresets)
+ .add(new PresetMSOOrchestrationRequestGet("FAILED"))
+ .build();
+ List<String> jobIds = createBulkOfInstances(presets, false, bulkSize, names);
+ Assert.assertEquals(jobIds.size(),bulkSize);
+ boolean result = Wait.waitFor(x->{
+ List<ServiceInfo> serviceInfoList = serviceListCall().getBody();
+ Map<JobStatus, Long> statusCount = serviceInfoList.stream().filter(si->jobIds.contains(si.jobId)).collect(groupingBy(ServiceInfo::getJobStatus, counting()));
+ return Objects.equals(statusCount.get(JobStatus.FAILED), 1L) && Objects.equals(statusCount.get(JobStatus.STOPPED), 2L);
+ }, null, 15, 1);
+ assertTrue(String.format("failed to get jobs [%s] to state of: 1 failed and 2 stopped ",
+ String.join(",", jobIds)),result);
+ }
+
+ @Test
+ public void createBulkOfAssignInstances(){
+ Map<Keys, String> names = generateNames();
+ final int bulkSize = 2;
+ ImmutableList<BasePreset> msoBulkPresets = IntStream.rangeClosed(1,bulkSize)
+ .mapToObj(i-> new PresetMSOAssignServiceInstanceGen2WithNames(names, i))
+ .collect(ImmutableList.toImmutableList());
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .add(new PresetAAISearchNodeQueryEmptyResult())
+ .addAll(msoBulkPresets)
+ .add(new PresetMSOOrchestrationRequestGet())
+ .build();
+ createBulkOfInstancesAndAssert(presets, true, bulkSize, JobStatus.COMPLETED, names);
+ }
+
+ @Test
+ public void tryToCreateBulkOfAssignInstancesErrorResponseFromMso(){
+ ImmutableList<BasePreset> presets = ImmutableList.of(
+ new PresetGetSessionSlotCheckIntervalGet(),
+ new PresetAAIGetSubscribersGet(),
+ new PresetAAISearchNodeQueryEmptyResult(),
+ new PresetMSOServiceInstanceGen2ErrorResponse(406));
+
+ List<String> jobIds = createBulkOfInstancesAndAssert(presets, true,1, JobStatus.FAILED, generateNames());
+ String jobId = jobIds.get(0);
+ List<JobAuditStatus> actualMsoAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name());
+ JobAuditStatus expectedMsoAudit = new JobAuditStatus(UUID.fromString(jobId),"FAILED",JobAuditStatus.SourceStatus.MSO,
+ null,
+ "Http Code:406, \"messageId\":\"SVC0002\",\"text\":\"JSON Object Mapping Request\"" ,
+ false);
+ assertThat(actualMsoAudits.get(0), is(expectedMsoAudit));
+ }
+
+ @Test
+ public void whenHideCompletedService_thenServiceNotReturnInServiceList(){
+ List<String> services = createBulkAndWaitForBeCompleted(2);
+ hideService(services.get(0));
+ List<String> serviceInfoList = serviceListCall().getBody().stream().map(ServiceInfo::getJobId).collect(toList());
+ assertThat(serviceInfoList, hasItem(services.get(1)));
+ assertThat(serviceInfoList, not(hasItem(services.get(0))));
+ }
+
+ private MsoResponseWrapper2 hideService(String jobId) {
+ MsoResponseWrapper2 responseWrapper2 = callMsoForResponseWrapper(org.springframework.http.HttpMethod.POST, getHideServiceUri(jobId), "");
+ return responseWrapper2;
+ }
+
+ private List<String> createBulkOfInstancesAndAssert(ImmutableList<BasePreset> presets, boolean isPause, int bulkSize, JobStatus finalState, Map<Keys, String> names){
+ List<String> jobIds = createBulkOfInstances(presets, isPause, bulkSize, names);
+ Assert.assertEquals(jobIds.size(),bulkSize);
+ for(String jobId: jobIds) {
+ ServiceInfo expectedServiceInfo = new ServiceInfo("ab2222", JobStatus.IN_PROGRESS, isPause, "someID",
+ "someName", "myProject", "NFT1", "NFTJSSSS-NFT1", "greatTenant", "greatTenant", "mtn3", null,
+ "mySubType", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", null, names.get(Keys.SERVICE_NAME),
+ "300adb1e-9b0c-4d52-bfb5-fa5393c4eabb", "AIM_TRANSPORT_00004", "1.0", jobId, null);
+ JobInfoChecker jobInfoChecker = new JobInfoChecker(
+ restTemplate, ImmutableSet.of(JobStatus.PENDING, JobStatus.IN_PROGRESS, finalState), jobId, expectedServiceInfo);
+ boolean result = jobInfoChecker.test(null);
+ assertTrue("service info of jobId: " + jobId + " was in status: " + jobInfoChecker.lastStatus, result);
+
+ jobInfoChecker.setExpectedJobStatus(ImmutableSet.of(finalState));
+ if (ImmutableList.of(JobStatus.COMPLETED, JobStatus.PAUSE).contains(finalState)) {
+ expectedServiceInfo.serviceInstanceId = "f8791436-8d55-4fde-b4d5-72dd2cf13cfb";
+ }
+ result = Wait.waitFor(jobInfoChecker, null, 20, 1);
+ assertTrue("service info of jobId: " + jobId + " was in status: " + jobInfoChecker.lastStatus, result);
+ }
+
+ return jobIds;
+ }
+
+ private List<String> createBulkOfInstances(ImmutableList<BasePreset> presets, boolean isPause, int bulkSize, Map<Keys, String> names){
+
+ SimulatorApi.registerExpectationFromPresets(presets, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+
+ String requestBody = TestUtils.convertRequest(objectMapper, CREATE_BULK_OF_MACRO_REQUEST);
+ requestBody = requestBody.replace("\"IS_PAUSE_VALUE\"", String.valueOf(isPause)).replace("\"BULK_SIZE\"", String.valueOf(bulkSize));
+ for (Map.Entry<Keys, String> e : names.entrySet()) {
+ requestBody = requestBody.replace(e.getKey().name(), e.getValue());
+ }
+ MsoResponseWrapper2 responseWrapper2 = callMsoForResponseWrapper(org.springframework.http.HttpMethod.POST, getCreateBulkUri(), requestBody);
+ assertNotNull(responseWrapper2);
+ return (List<String>)responseWrapper2.getEntity();
+ }
+
+ public class JobInfoChecker<Integer> implements Predicate<Integer> {
+
+ private final RestTemplate restTemplate;
+ private Set<JobStatus> expectedJobStatus;
+ private ServiceInfo expectedServiceInfo;
+ private final String jobId;
+ private JobStatus lastStatus;
+
+ public JobInfoChecker(RestTemplate restTemplate, Set<JobStatus> expectedJobStatus, String jobId, ServiceInfo expectedServiceInfo) {
+ this.restTemplate = restTemplate;
+ this.expectedJobStatus = expectedJobStatus;
+ this.jobId = jobId;
+ this.expectedServiceInfo = expectedServiceInfo;
+ }
+
+ public void setExpectedJobStatus(Set<JobStatus> expectedJobStatus) {
+ this.expectedJobStatus = expectedJobStatus;
+ }
+
+ @Override
+ public boolean test(Integer integer) {
+ ResponseEntity<List<ServiceInfo>> serviceListResponse = serviceListCall();
+ assertThat(serviceListResponse.getStatusCode(), CoreMatchers.equalTo(HttpStatus.OK));
+ assertThat(serviceListResponse.getBody(), hasItem(new JobIdAndStatusMatcher(jobId)));
+ ServiceInfo serviceInfoFromDB = serviceListResponse.getBody().stream()
+ .filter(serviceInfo -> serviceInfo.jobId.equals(jobId))
+ .findFirst().orElse(null);
+ Assert.assertNotNull(serviceInfoFromDB);
+ Assert.assertEquals(serviceInfoDataReflected(serviceInfoFromDB), serviceInfoDataReflected(expectedServiceInfo));
+ assertTrue("actual service instance doesn't contain template service name:" + expectedServiceInfo.serviceInstanceName,
+ serviceInfoFromDB.serviceInstanceName.contains(expectedServiceInfo.serviceInstanceName));
+ if (serviceInfoFromDB.jobStatus==JobStatus.IN_PROGRESS || serviceInfoFromDB.jobStatus==JobStatus.COMPLETED) {
+ assertTrue("actual service instance doesn't contain template service name and trailing numbers:" + expectedServiceInfo.serviceInstanceName,
+ serviceInfoFromDB.serviceInstanceName.contains(expectedServiceInfo.serviceInstanceName+"_00"));
+ }
+
+ if (expectedServiceInfo.serviceInstanceId != null) {
+ assertThat(serviceInfoFromDB.serviceInstanceId, is(expectedServiceInfo.serviceInstanceId));
+ }
+ lastStatus = serviceInfoFromDB.jobStatus;
+ return expectedJobStatus.contains(serviceInfoFromDB.jobStatus);
+ }
+ }
+
+ private ResponseEntity<List<ServiceInfo>> serviceListCall() {
+ return restTemplate.exchange(
+ getServiceInfoUrl(),
+ org.springframework.http.HttpMethod.GET,
+ null,
+ new ParameterizedTypeReference<List<ServiceInfo>>() {});
+ }
+
+ //serialize fields except of fields we cannot know ahead of time
+ private static String serviceInfoDataReflected(ServiceInfo service1) {
+ return new ReflectionToStringBuilder(service1, ToStringStyle.SHORT_PREFIX_STYLE)
+ .setExcludeFieldNames("jobStatus", "templateId", "statusModifiedDate", "createdBulkDate", "serviceInstanceId", "serviceInstanceName")
+ .toString();
+ }
+
+ @Test
+ public void errorResponseInGetStatusFromMso_getAuditStatusFromMso_errorMsgExistInAdditionalInfo(){
+ Map<Keys, String> names = generateNames();
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .add(new PresetAAISearchNodeQueryEmptyResult())
+ .add(new PresetMSOAssignServiceInstanceGen2WithNames(names, 1))
+ .add(new PresetMSOOrchestrationRequestGetErrorResponse(406))
+ .build();
+
+ final List<String> jobIds = createBulkOfInstancesAndAssert(presets, true,1, JobStatus.IN_PROGRESS, names);
+ String jobId = jobIds.get(0);
+ Wait.waitFor(y-> getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name()).stream()
+ .anyMatch(si -> si.getJobStatus().equals("FAILED")),
+ null, 10, 1 );
+ List<JobAuditStatus> actualMsoAudits = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name());
+ List<JobAuditStatus> expectedMsoAudits = Stream.of("REQUESTED", "FAILED")
+ .map(status -> new JobAuditStatus(UUID.fromString(jobId),
+ status,
+ JobAuditStatus.SourceStatus.MSO,
+ UUID.fromString("c0011670-0e1a-4b74-945d-8bf5aede1d9c"),
+ status.equals("FAILED") ? "Http Code:406, \"messageId\":\"SVC0002\",\"text\":\"JSON Object Mapping Request\"" : null,
+ false)).collect(toList());
+ assertThat(actualMsoAudits, is(expectedMsoAudits));
+
+ }
+
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/BaseApiAaiTest.java b/vid-automation/src/test/java/org/onap/vid/api/BaseApiAaiTest.java
new file mode 100644
index 000000000..4ac38a0e7
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/BaseApiAaiTest.java
@@ -0,0 +1,70 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.RequestEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.HttpStatusCodeException;
+import org.testng.annotations.BeforeClass;
+import vid.automation.test.services.SimulatorApi;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonStringEquals;
+import static org.hamcrest.Matchers.either;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static vid.automation.test.services.SimulatorApi.registerExpectation;
+
+/**
+ * Created by Oren on 11/1/17.
+ */
+public class BaseApiAaiTest extends BaseApiTest {
+
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+
+ protected void callAaiWithSimulatedErrorResponse(String [] expectationJsonFileNames, ImmutableMap<String, Object> replacementsForJson, String targetUri, String basicRequestBody, int expectedErrorCode, String expectedResult, HttpMethod method) throws IOException, URISyntaxException {
+
+ registerExpectation(expectationJsonFileNames, replacementsForJson, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+ RequestEntity<String> request;
+ switch (method) {
+ case POST:
+ //not supported yet
+ break;
+
+ case PUT:
+ request = RequestEntity
+ .put(new URI(targetUri))
+ .body(basicRequestBody);
+ try {
+ restTemplate.exchange(request, String.class);
+ }
+ catch(HttpStatusCodeException e) {
+ assertThat("Wrong propagated status from AAI", e.getStatusCode().value(), is(expectedErrorCode));
+ }
+
+
+ case GET:
+ try {
+ ResponseEntity<String> responseWrapper = restTemplate.getForEntity(targetUri, String.class);
+ assertThat("Wrong propagated status from AAI", responseWrapper.getStatusCode().value(), is(expectedErrorCode));
+ assertThat("The response is in the format of JSON", responseWrapper.getBody(),
+ either(is(expectedResult)).or(jsonStringEquals(expectedResult)));
+ }
+ catch(HttpClientErrorException | HttpServerErrorException e) {
+ assertThat("Wrong propagated status from AAI", e.getStatusCode().value(), is(expectedErrorCode));
+ }
+ break;
+ }
+
+
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/BaseApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/BaseApiTest.java
new file mode 100644
index 000000000..223657170
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/BaseApiTest.java
@@ -0,0 +1,206 @@
+package org.onap.vid.api;
+
+import com.att.automation.common.report_portal_integration.listeners.ReportPortalListener;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.primitives.Ints;
+import org.apache.commons.io.IOUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.uri.internal.JerseyUriBuilder;
+import org.openecomp.sdc.ci.tests.datatypes.UserCredentials;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.DefaultResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Listeners;
+import vid.automation.test.infra.FeaturesTogglingConfiguration;
+import vid.automation.test.services.UsersService;
+import vid.automation.test.utils.CookieAndJsonHttpHeadersInterceptor;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+
+import static java.util.Collections.singletonList;
+import static org.apache.commons.text.StringEscapeUtils.unescapeJson;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+
+@Listeners(ReportPortalListener.class)
+public class BaseApiTest {
+ protected static final Logger LOGGER = LogManager.getLogger(BaseApiTest.class);
+
+ @SuppressWarnings("WeakerAccess")
+ protected URI uri;
+ @SuppressWarnings("WeakerAccess")
+ protected ObjectMapper objectMapper = new ObjectMapper();
+ @SuppressWarnings("WeakerAccess")
+ protected Client client;
+ protected Random random;
+ protected final RestTemplate restTemplate = new RestTemplate();
+
+ protected final UsersService usersService = new UsersService();
+ protected final RestTemplate restTemplateErrorAgnostic = new RestTemplate();
+
+ @BeforeClass
+ public void init() {
+ uri = getUri();
+ objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
+ client = ClientBuilder.newClient();
+ client.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+ random = new Random(System.currentTimeMillis());
+ FeaturesTogglingConfiguration.initializeFeatureManager();
+ }
+
+ private URI getUri() {
+ String host = System.getProperty("VID_HOST", "127.0.0.1");
+ Integer port = Integer.valueOf(System.getProperty("VID_PORT", "8080"));
+ return new JerseyUriBuilder().host(host).port(port).scheme("http").path("vid").build();
+ }
+
+ public void login() {
+ UserCredentials userCredentials = getUserCredentials();
+ final List<ClientHttpRequestInterceptor> interceptors = singletonList(new CookieAndJsonHttpHeadersInterceptor(getUri(), userCredentials));
+ restTemplate.setInterceptors(interceptors);
+
+ restTemplateErrorAgnostic.setInterceptors(interceptors);
+ restTemplateErrorAgnostic.setErrorHandler(new DefaultResponseErrorHandler() {
+ @Override
+ public boolean hasError(ClientHttpResponse response) {
+ return false;
+ }
+ });
+ }
+
+
+ static class DB_CONFIG {
+ static String url = String.format("jdbc:mariadb://%s:%d/vid_portal",
+ System.getProperty("DB_HOST", System.getProperty("VID_HOST", "127.0.0.1")),
+ Integer.valueOf(System.getProperty("DB_PORT", "3306"))
+ );
+ static String username = "euser";
+ static String password = "euser";
+
+ static final int userId = 2222;
+ static final String loginId = "ab2222";
+ static final int roleId = 2222221;
+ static final int logRoleId = 2222222;
+ }
+
+
+ @BeforeClass
+ protected void createNewTestUser() {
+
+ deleteNewTestUser();
+
+ LOGGER.debug("Connecting database...");
+
+ try (Connection connection = DriverManager.getConnection(DB_CONFIG.url, DB_CONFIG.username, DB_CONFIG.password)) {
+
+ LOGGER.debug("Database connected!");
+ //create new user with specific role
+ Statement stmt = connection.createStatement();
+ stmt.addBatch("INSERT INTO `fn_user` (`USER_ID`, `ORG_USER_ID`, `LOGIN_ID`, `LOGIN_PWD`) VALUES (" + DB_CONFIG.userId + ", 'Porfirio Gerhardt', '" + DB_CONFIG.loginId + "', '" + DB_CONFIG.loginId + "')");
+ stmt.addBatch("INSERT INTO `fn_role` (`ROLE_ID`, `ROLE_NAME`, `ACTIVE_YN`, `PRIORITY`) VALUES (" + DB_CONFIG.roleId + ", 'PACKET CORE___vFlowLogic', 'Y', 5)");
+ stmt.addBatch("INSERT INTO `fn_role` (`ROLE_ID`, `ROLE_NAME`, `ACTIVE_YN`, `PRIORITY`) VALUES (" + DB_CONFIG.logRoleId + ", 'READ___LOGS___PERMITTED', 'Y', 5)");
+ stmt.addBatch("INSERT INTO `fn_user_role` (`USER_ID`, `ROLE_ID`, `PRIORITY`, `APP_ID`) VALUES (" + DB_CONFIG.userId + ", " + DB_CONFIG.roleId + ", NULL, 1)");
+ stmt.addBatch("INSERT INTO `fn_user_role` (`USER_ID`, `ROLE_ID`, `PRIORITY`, `APP_ID`) VALUES (" + DB_CONFIG.userId + ", " + DB_CONFIG.logRoleId + ", NULL, 1)");
+
+
+ int[] executeBatch = stmt.executeBatch();
+ assertThat(Ints.asList(executeBatch), everyItem(greaterThan(0)));
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("Cannot connect the database!", e);
+ }
+
+ }
+
+ @AfterClass
+ protected void deleteNewTestUser() {
+ LOGGER.debug("Connecting database...");
+
+ try (Connection connection = DriverManager.getConnection(DB_CONFIG.url, DB_CONFIG.username, DB_CONFIG.password)) {
+ LOGGER.debug("Database connected!");
+ Statement stmt = connection.createStatement();
+ stmt.addBatch("DELETE FROM `fn_user_role` WHERE `USER_ID` = " + DB_CONFIG.userId);
+ stmt.addBatch("DELETE FROM `fn_user` WHERE `USER_ID` = " + DB_CONFIG.userId);
+ stmt.addBatch("DELETE FROM `fn_role` WHERE `ROLE_ID` = " + DB_CONFIG.roleId);
+ stmt.addBatch("DELETE FROM `fn_role` WHERE `ROLE_ID` = " + DB_CONFIG.logRoleId);
+
+
+ int[] executeBatch = stmt.executeBatch();
+
+ } catch (SQLException e) {
+ throw new IllegalStateException("Cannot connect the database!", e);
+ }
+ }
+
+ protected UserCredentials getUserCredentials() {
+ final Properties configProp = new Properties();
+ try {
+ InputStream input = ClassLoader.getSystemResourceAsStream("test_config.properties");
+ configProp.load(input);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ HttpHeaders loginRequestHeaders = new HttpHeaders();
+ loginRequestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ String loginId = configProp.getProperty("test.loginId", "i'm illegal");
+ String loginPassword = configProp.getProperty("test.loginPassword", "i'm illegal");
+ return new UserCredentials(loginId, loginPassword, null, null, null);
+ }
+
+
+
+
+ protected String getCleanJsonString(String jsonString) {
+ // remove leading/trailing double-quotes and unescape
+ String res = unescapeJson(jsonString.replaceAll("^\"|\"$", ""));
+ LOGGER.debug("getCleanJsonString: " + jsonString + " ==> " + res);
+ return res;
+ }
+
+ protected String getCleanJsonString(Object object) throws JsonProcessingException {
+ if (object instanceof String) {
+ return getCleanJsonString((String) object);
+ } else {
+ return new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(object);
+ }
+ }
+
+ protected String buildUri(String path) {
+ return uri + "/" + path;
+ }
+
+ public static String getResourceAsString(String resourcePath) {
+ // load expected result
+ final URL resource = BaseApiTest.class.getClassLoader().getResource(resourcePath);
+ if (resource == null) throw new RuntimeException("resource file not found: " + resourcePath);
+ try {
+ return IOUtils.toString(resource, "UTF-8");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/BaseMsoApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/BaseMsoApiTest.java
new file mode 100644
index 000000000..37601a65e
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/BaseMsoApiTest.java
@@ -0,0 +1,80 @@
+package org.onap.vid.api;
+
+import com.att.automation.common.report_portal_integration.annotations.Step;
+import com.google.common.collect.ImmutableMap;
+import org.json.JSONException;
+import org.onap.vid.model.mso.MsoResponseWrapper2;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.skyscreamer.jsonassert.JSONCompareMode;
+import org.springframework.http.HttpMethod;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import vid.automation.test.services.SimulatorApi;
+import vid.automation.test.services.SimulatorApi.RegistrationStrategy;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class BaseMsoApiTest extends BaseApiTest {
+
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+ protected void callMsoWithSimulatedErrorResponse(String expectationJsonFileName, ImmutableMap<String, Object> replacementsForJson, String targetUri, String basicRequestBody, int expectedErrorCode, String expectedResult, HttpMethod method) throws IOException {
+ SimulatorApi.registerExpectation(expectationJsonFileName, replacementsForJson, RegistrationStrategy.CLEAR_THEN_SET);
+ try {
+ MsoResponseWrapper2 responseWrapper = callMsoForResponseWrapper(method, targetUri, basicRequestBody);
+
+ assertThat("Wrong propagated status from MSO", responseWrapper.getStatus(), is(expectedErrorCode));
+ assertThat("Wrong propagated body from MSO", getCleanJsonString(responseWrapper.getEntity()), is(expectedResult));
+ }catch(HttpClientErrorException | HttpServerErrorException e) {
+ assertThat("Wrong propagated status from MSO", e.getStatusCode().value(), is(expectedErrorCode));
+ }
+ }
+
+
+ protected void callMsoWithFineRequest(String expectationJsonFileName, ImmutableMap<String, Object> replacementsForJson, String targetUri, String requestBody, int expectedStatusCode, String expectedResult, HttpMethod method) throws IOException {
+ SimulatorApi.registerExpectation(expectationJsonFileName, replacementsForJson, RegistrationStrategy.CLEAR_THEN_SET);
+
+ MsoResponseWrapper2 responseWrapper = callMsoForResponseWrapper(method, targetUri, requestBody);
+
+ assertThat("Wrong propagated status from MSO", responseWrapper.getStatus(), is(expectedStatusCode));
+ try {
+ JSONAssert.assertEquals("Wrong propagated body from MSO", expectedResult, getCleanJsonString(responseWrapper.getEntity()), JSONCompareMode.NON_EXTENSIBLE);
+ } catch (JSONException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Step(description = "method: ${method}, uri: ${uri}, body: ${body}")
+ protected MsoResponseWrapper2 callMsoForResponseWrapper(HttpMethod method, String uri, String body) {
+ MsoResponseWrapper2 responseWrapper;
+ switch (method) {
+ case POST:
+ responseWrapper = restTemplate.postForObject(uri, body, MsoResponseWrapper2.class);
+ break;
+ case GET:
+ default:
+ responseWrapper = restTemplate.getForObject(uri, MsoResponseWrapper2.class);
+ break;
+ }
+
+ System.out.println("response: " + responseWrapper);
+
+ return responseWrapper;
+ }
+
+ @DataProvider
+ public static Object[][] errorCodes(Method test) {
+ return new Object[][]{
+ {500},{505}, {400}, {401}, {404}, {405}
+ };
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/CategoryParametersApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/CategoryParametersApiTest.java
new file mode 100644
index 000000000..54df0e83e
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/CategoryParametersApiTest.java
@@ -0,0 +1,119 @@
+package org.onap.vid.api;
+
+import org.onap.vid.model.category.AddCategoryOptionsRequest;
+import org.onap.vid.model.category.CategoryParameterOption;
+import org.onap.vid.model.category.CategoryParameterOptionRep;
+import org.onap.vid.model.category.CategoryParametersResponse;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.util.UriComponentsBuilder;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import vid.automation.test.services.CategoryParamsService;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+
+//This is integration test that require running tomcat
+public class CategoryParametersApiTest extends BaseApiTest {
+
+ public static final String GET_CATEGORY_PARAMETER_PROPERTIES = "maintenance/category_parameter";
+ public static final String DELETE_CATEGORY_PARAMETER_PROPERTIES = "maintenance/delete_category_parameter";
+ public static final String PROPERTY_NAME = "owningEntity";
+ public static final String PROPERTY_FAMILY = "PARAMETER_STANDARDIZATION";
+
+ public static final String NEW_PARAMETER_PROPERTY_NAME = "oren";
+ public static final String UPDATE_PARAMETER_PROPERTY_NAME = "oren2";
+
+
+ @Test(groups = { "worksOnlyWithLocalhostVID" })
+ public void addCPProperties() throws IOException {
+ AddCategoryOptionsRequest request = new AddCategoryOptionsRequest();
+ String newParameter = UUID.randomUUID().toString();
+ request.options.add(newParameter);
+ addCPPropertiesRequest(HttpMethod.POST, request, HttpStatus.OK);
+ findPropertyNameInGetResponse(newParameter);
+
+ }
+
+ @Test(groups = { "worksOnlyWithLocalhostVID" })
+ public void updateCPProperties() throws IOException {
+ List<CategoryParameterOptionRep> props = getProps();
+ CategoryParameterOptionRep updateReq = new CategoryParameterOptionRep();
+ updateReq.setName(UPDATE_PARAMETER_PROPERTY_NAME);
+ updateReq.setId(props.get(props.size()-1).getId());
+ updateCPPropertiesRequest(HttpMethod.PUT, updateReq, HttpStatus.OK);
+ findPropertyNameInGetResponse(UPDATE_PARAMETER_PROPERTY_NAME);
+ CategoryParameterOption deleteReq = new CategoryParameterOption();
+ deleteReq.setName(UPDATE_PARAMETER_PROPERTY_NAME);
+ deleteCPPropertiesRequest(HttpMethod.POST, deleteReq, HttpStatus.OK);
+ }
+
+ @Test(groups = { "worksOnlyWithLocalhostVID" })
+ //this test call to MaintenanceController which is restricted to localhost, so it can not run on jenkins pipeline
+ public void getOrderedCPProperties() throws IOException {
+ // Ensure there is some initial data when checking that the list is sorted
+ CategoryParamsService categoryParamsService = new CategoryParamsService();
+ List<CategoryParameterOptionRep> props = getProps();
+ final List<String> propsNames = props.stream().map(CategoryParameterOptionRep::getName).collect(Collectors.toList());
+ assertEquals("The list isn't sorted", propsNames, propsNames.stream().sorted(String::compareToIgnoreCase).collect(Collectors.toList()));
+ }
+
+ private List<CategoryParameterOptionRep> getProps() throws IOException {
+ Response response = getCPPropertiesRequest(HttpMethod.GET, HttpStatus.OK);
+ String expectedJsonAsString = response.readEntity(String.class);
+ CategoryParametersResponse categoryParameterResponse = objectMapper.readValue(expectedJsonAsString, CategoryParametersResponse.class);
+ List<CategoryParameterOptionRep> props = categoryParameterResponse.getCategoryParameters().get(PROPERTY_NAME);
+ return props;
+ }
+
+ private void findPropertyNameInGetResponse(String propertyName) throws IOException{
+ List<CategoryParameterOptionRep> props = getProps();
+ boolean found = false;
+ for (CategoryParameterOptionRep prop :
+ props) {
+ if(prop.getName().equals(propertyName))
+ found = true;
+ }
+ Assert.assertTrue(found);
+ }
+
+ private Response getCPPropertiesRequest(String method, HttpStatus exceptedHttpStatus) throws IOException {
+ UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromUri(uri).path("/"+GET_CATEGORY_PARAMETER_PROPERTIES)
+ .queryParam("familyName", PROPERTY_FAMILY);
+ WebTarget webTarget = client.target(urlBuilder.toUriString());
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).method(method, Entity.json(null));
+ TestUtils.assertHttpStatus(null, webTarget, response, exceptedHttpStatus);
+ return response;
+ }
+
+ private Response addCPPropertiesRequest(String method, AddCategoryOptionsRequest request, HttpStatus exceptedHttpStatus) throws IOException {
+ WebTarget webTarget = client.target(uri).path(GET_CATEGORY_PARAMETER_PROPERTIES+"/"+PROPERTY_NAME);
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).method(method, Entity.json(request));
+ TestUtils.assertHttpStatus(request, webTarget, response, exceptedHttpStatus);
+ return response;
+ }
+
+ private Response updateCPPropertiesRequest(String method, CategoryParameterOptionRep request, HttpStatus exceptedHttpStatus) throws IOException {
+ WebTarget webTarget = client.target(uri).path(GET_CATEGORY_PARAMETER_PROPERTIES+"/"+PROPERTY_NAME);
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).method(method, Entity.json(request));
+ TestUtils.assertHttpStatus(request, webTarget, response, exceptedHttpStatus);
+ return response;
+ }
+
+ private Response deleteCPPropertiesRequest(String method, CategoryParameterOption request, HttpStatus exceptedHttpStatus) throws IOException {
+ WebTarget webTarget = client.target(uri).path(DELETE_CATEGORY_PARAMETER_PROPERTIES+"/"+PROPERTY_NAME);
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).method(method, Entity.json(request));
+ TestUtils.assertHttpStatus(request, webTarget, response, exceptedHttpStatus);
+ return response;
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/ChangeManagementApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/ChangeManagementApiTest.java
new file mode 100644
index 000000000..93f721956
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/ChangeManagementApiTest.java
@@ -0,0 +1,750 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.onap.vid.model.mso.ChangeManagementRequest;
+import org.onap.vid.model.mso.ChangeManagementRequestDetails;
+import org.onap.vid.model.mso.CloudConfiguration;
+import org.onap.vid.model.mso.MsoExceptionResponse;
+import org.onap.vid.model.mso.MsoResponseWrapper2;
+import org.onap.vid.model.mso.RelatedInstance;
+import org.onap.vid.model.mso.RelatedInstanceList;
+import org.onap.vid.model.mso.RequestInfo;
+import org.onap.vid.model.mso.RequestParameters;
+import org.onap.vid.model.workflow.GetVnfWorkflowRelationRequest;
+import org.onap.vid.model.workflow.GetWorkflowsResponse;
+import org.onap.vid.model.workflow.VnfDetails;
+import org.onap.vid.model.workflow.VnfDetailsWithWorkflows;
+import org.onap.vid.model.workflow.VnfWorkflowRelationAllResponse;
+import org.onap.vid.model.workflow.VnfWorkflowRelationRequest;
+import org.onap.vid.model.workflow.VnfWorkflowRelationResponse;
+import org.onap.vid.model.workflow.WorkflowsDetail;
+import org.opencomp.vid.model.mso.*;
+import org.opencomp.vid.model.workflow.*;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.StopWatch;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import vid.automation.test.services.SimulatorApi;
+import vid.automation.test.services.SimulatorApi.RegistrationStrategy;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.client.Entity;
+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 java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.onap.vid.api.TestUtils.getNestedPropertyInMap;
+
+
+//This is integration test that require running tomcat
+public class ChangeManagementApiTest extends BaseApiTest {
+
+ public static final String WORKFLOW = "/workflow/{vnfname}";
+ public static final String APPLICATION_JSON = "application/json";
+ public static final String DELETE_SCHEDULE_OK_JSON = "delete_schedule_ok.json";
+ public static final String DELETE_SCHEDULE_NOT_AUTHORIZED_JSON = "delete_schedule_not_authorized.json";
+ private static final String UPDATE = "Update";
+ private static final String REPLACE = "Replace";
+ private static final List<String> WORKFLOWS = Arrays.asList(UPDATE, REPLACE);
+ public static final String CHANGE_MANAGEMENT = "change-management";
+ public static final String GET_VNF_WORKFLOW_RELATION = "get_vnf_workflow_relation";
+ public static final String VNF_WORKFLOW_RELATION = "vnf_workflow_relation";
+ public static final String SCHEDULER_BY_SCHEDULE_ID = "/scheduler/schedules/{scheduleId}";
+
+ @DataProvider
+ public static Object[][] requestWithoutServiceInstanceId(Method test) {
+ return new Object[][]{
+ {(Consumer<ChangeManagementRequest>) changeManagementRequest -> changeManagementRequest.getRequestDetails().get(0).setRelatedInstList(null)},
+ {(Consumer<ChangeManagementRequest>) changeManagementRequest -> changeManagementRequest.getRequestDetails().get(0).setRelatedInstList(new ArrayList<>())},
+ {(Consumer<ChangeManagementRequest>) changeManagementRequest -> changeManagementRequest.getRequestDetails().get(0).getRelatedInstList().get(0).setRelatedInstance(null)},
+ {(Consumer<ChangeManagementRequest>) changeManagementRequest -> changeManagementRequest.getRequestDetails().get(0).getRelatedInstList().get(0).getRelatedInstance().setInstanceId(null)}
+
+ };
+ }
+
+ @DataProvider
+ public static Object[][] requestWithoutPayload(Method test) {
+ return new Object[][]{
+ {(Consumer<ChangeManagementRequest>) changeManagementRequest -> changeManagementRequest.getRequestDetails().get(0).getRequestParameters().getAdditionalProperties().clear()},
+ {(Consumer<ChangeManagementRequest>) changeManagementRequest -> changeManagementRequest.getRequestDetails().get(0).setRequestParameters(null)},
+ };
+ }
+
+ @DataProvider
+ public static Object[][] wrongPayloads(Method test) {
+ return new Object[][]{
+ {"{\"existing_software_version\": \"3.1%\",\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}", "existing_software_version"},
+ {"{\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}", "existing_software_version"},
+ {"{\"existing_software_version\": 3.1,\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}", "existing_software_version"},
+ {"{\"existing_software_version\": \"\",\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}", "existing_software_version"},
+ {"{\"existing_software_version\": null,\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}", "existing_software_version"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": \"3^.2\", \"operations_timeout\": \"3600\"}", "new_software_version"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": 3.2, \"operations_timeout\": \"3600\"}", "new_software_version"},
+ {"{\"existing_software_version\": \"3.1\", \"operations_timeout\": \"3600\"}", "new_software_version"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": \"\", \"operations_timeout\": \"3600\"}", "new_software_version"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": null, \"operations_timeout\": \"3600\"}", "new_software_version"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": \"3.2\", \"operations_timeout\": \"a3600\"}", "operations_timeout"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": \"3.2\"}", "operations_timeout"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": \"3.2\", \"operations_timeout\": \"\"}", "operations_timeout"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": \"3.2\", \"operations_timeout\": null}", "operations_timeout"},
+ {"", ""},
+ };
+ }
+
+ @DataProvider
+ public static Object[][] goodPayloads(Method test) {
+ return new Object[][]{
+ {"{\"existing_software_version\": \"a3a.1\",\"new_software_version\": \"b3.2c\", \"operations_timeout\": \"3600\"}"},
+ {"{\"existing_software_version\": \"a3a.1\",\"new_software_version\": \"b3.2c\", \"operations_timeout\": 3600}"},
+ {"{\"existing_software_version\": \"a3a.1\",\"new_software_version\": \"b3.2c\", \"operations_timeout\": 3600, \"extra\": \"me\"}"},
+ {"{\"existing_software_version\": \"3.1\",\"new_software_version\": \"a.c\", \"operations_timeout\": \"0180\"}"},
+
+ };
+ }
+
+ @DataProvider
+ public static Object[][] wrongConfigPayloads(Method test) {
+ return new Object[][]{
+ {"{\"request-parameters\": \"3.1%\",\"new_software_version\": \"3.2\"}", "configuration-parameters"},
+ {"{\"configuration-parameters\": 3.1,\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}", "request-parameters"},
+ {"{\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}", "request-parameters"},
+ {"{\"payload\": {\"configuration-parameters\": 3.1,\"request-parameters\": \"3.2\" }}", "request-parameters"},
+ {"",""},
+ };
+ }
+
+ @DataProvider
+ public static Object[][] goodConfigPayloads(Method test){
+ return new Object[][]{
+ {"{\"configuration-parameters\": 3.1,\"request-parameters\": \"3.2\" }"},
+ {"{\"configuration-parameters\": 3.1,\"request-parameters\": \"3.2\", \"operations_timeout\": \"3600\"}"},
+ {"{\"configuration-parameters\": 3.1,\"new_software_version\": \"3.2\",\"request-parameters\": \"3.2\" }"}
+ };
+ }
+
+// IN_PLACE_SOFTWARE_UPDATE
+ @Test
+ public void testInPlaceSoftwareUpdateHappyPath() throws IOException {
+ testHappyPath("mso_in_place_software_update_ok.json", ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test
+ public void testInPlaceSoftwareUpdate409Error() throws IOException {
+ testChangeManagement409Error("mso_in_place_software_update_error_409.json", ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test
+ public void testInPlaceSoftwareUpdate404Error() throws IOException {
+ testChangeManagement404Error("mso_in_place_software_update_error_404.json", ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test
+ public void testInPlaceSoftwareUpdateWithoutVnfInstanceId() throws IOException {
+ testChangeManagementWithoutVnfInstanceId(ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test(dataProvider = "requestWithoutServiceInstanceId")
+ public void testInPlaceSoftwareUpdateWithoutServiceInstanceId(Consumer<ChangeManagementRequest> dropInstanceIdMethod) throws IOException {
+ testChangeManagementServiceInstanceId(dropInstanceIdMethod, ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test(dataProvider = "wrongPayloads")
+ public void testInPlaceSoftwareUpdateInvalidPayload(String payload, String propertyName) throws IOException {
+ testChangeManagementInvalidPayload(payload, propertyName, ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test(dataProvider = "requestWithoutPayload")
+ public void testInPlaceSoftwareUpdateWithoutPayload(Consumer<ChangeManagementRequest> dropPayloadMethod) throws IOException {
+ testChangeManagementWithoutPayload(dropPayloadMethod, ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test(dataProvider = "goodPayloads")
+ public void testInPlaceSoftwareUpdateGoodPayload(String payload) throws IOException {
+ testChangeManagementGoodPayload(payload, "mso_in_place_software_update_ok.json", ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE);
+ }
+
+ @Test
+ public void testInPlaceSoftwareUpdateSimultaneousCalls() throws IOException, InterruptedException {
+ SimulatorApi.clearExpectations();
+ final int SIZE = 20;
+ StopWatch stopWatch = new StopWatch("InPlaceSoftwareUpdateSimultaneousCalls");
+
+ stopWatch.start("init");
+ ExecutorService executor = Executors.newFixedThreadPool(SIZE);
+ List<VnfIds> vnfList = Stream.generate(VnfIds::new).limit(SIZE).collect(Collectors.toList());
+ stopWatch.stop();
+
+ stopWatch.start("invoke registration to simulator");
+ List<Callable<String>> siumlatorRegistrations = vnfList.stream().map(
+ vnfIds->((Callable<String>)() ->
+ {
+ SimulatorApi.registerExpectation(
+ "mso_in_place_software_update_ok.json",
+ ImmutableMap.of("SERVICE_INSTANCE_ID", vnfIds.serviceInstanceId, "VNF_INSTANCE_ID", vnfIds.vnfInstanceId),
+ RegistrationStrategy.APPEND);
+ return null;
+ }))
+ .collect(Collectors.toList());
+
+ executor.invokeAll(siumlatorRegistrations)
+ .forEach(future -> {
+ try {
+ future.get();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ stopWatch.stop();
+
+ stopWatch.start("init requests");
+ List<ChangeManagementRequest> requestsList = vnfList.stream().map(vnfIds -> this.createChangeManagementRequest(vnfIds, ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE)).collect(Collectors.toList());
+ WebTarget webTarget = client.target(uri).
+ path(CHANGE_MANAGEMENT+WORKFLOW).resolveTemplate("vnfname","VidVnf");
+ List<Callable<Response>> callables = requestsList.stream().map(request->((Callable<Response>) () -> webTarget.request(MediaType.APPLICATION_JSON_TYPE).header("Authorization", "Basic 123==").post(Entity.json(request)))).collect(Collectors.toList());
+ stopWatch.stop();
+
+ stopWatch.start("invoke calling to vid");
+ List<MsoResponseWrapper2> responseList = executor.invokeAll(callables)
+ .stream()
+ .map(future -> {
+ try {
+ return future.get().readEntity(MsoResponseWrapper2.class);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ })
+ .collect(Collectors.toList());
+ stopWatch.stop();
+
+ stopWatch.start("assertion");
+ Assert.assertEquals(responseList.size(),SIZE,"Failed to get all responses from server");
+ responseList.forEach(response->Assert.assertEquals(response.getStatus(), 202, "wrong http status for "+response.getEntity() ));
+ vnfList.forEach(vnfIds->
+ Assert.assertTrue(isTextContainsInList(responseList, vnfIds.serviceInstanceId),
+ "Failed to find response for isntanceId: "+vnfIds.serviceInstanceId));
+ stopWatch.stop();
+ System.out.print(stopWatch.prettyPrint());
+ }
+
+// CONFIG_UPDATE
+ @Test
+ public void testConfigUpdateHappyPath() throws IOException {
+ testHappyPath("mso_config_update_ok.json", ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test
+ public void testConfigUpdate409Error() throws IOException {
+ testChangeManagement409Error("mso_config_update_error_409.json", ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test
+ public void testConfigUpdate404Error() throws IOException {
+ testChangeManagement404Error("mso_config_update_error_404.json", ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test
+ public void testConfigUpdateWithoutVnfInstanceId() throws IOException {
+ testChangeManagementWithoutVnfInstanceId(ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test(dataProvider = "requestWithoutServiceInstanceId")
+ public void testConfigUpdateWithoutServiceInstanceId(Consumer<ChangeManagementRequest> dropInstanceIdMethod) throws IOException {
+ testChangeManagementServiceInstanceId(dropInstanceIdMethod, ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test(dataProvider = "wrongConfigPayloads")
+ public void testConfigUpdateInvalidPayload(String payload, String propertyName) throws IOException {
+ testChangeManagementInvalidPayload(payload, propertyName, ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test(dataProvider = "requestWithoutPayload")
+ public void testConfigUpdateWithoutPayload(Consumer<ChangeManagementRequest> dropPayloadMethod) throws IOException {
+ testChangeManagementWithoutPayload(dropPayloadMethod, ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test(dataProvider = "goodConfigPayloads")
+ public void testConfigUpdateGoodPayload(String payload) throws IOException {
+ testChangeManagementGoodPayload(payload, "mso_config_update_ok.json", ChangeManagementRequest.CONFIG_UPDATE);
+ }
+
+ @Test
+ public void testClientCredentialsFilter_expect401()
+ {
+ VnfIds vnfIds = new VnfIds();
+ ChangeManagementRequest changeManagementRequest = createBasicChangeManagementRequest(vnfIds);
+ changeManagementRequest.setRequestType(ChangeManagementRequest.REPLACE);
+ WebTarget webTarget = client.target(uri).
+ path(CHANGE_MANAGEMENT + WORKFLOW).resolveTemplate("vnfname", vnfIds.vnfName);
+ Entity entity = Entity.json(changeManagementRequest);
+ Assert.assertEquals(401, webTarget.request(MediaType.APPLICATION_JSON_TYPE).post(entity).getStatus());
+ }
+
+
+ private void testHappyPath(String expectationPath, String requestType) {
+ VnfIds vnfIds = new VnfIds();
+ MsoResponseWrapper2 body = callChangeManagementUpdate(vnfIds, expectationPath, MsoResponseWrapper2.class, requestType);
+ assertForHappyPath(vnfIds, body, requestType);
+ }
+
+ private void assertForHappyPath(VnfIds vnfIds, MsoResponseWrapper2 body, String requestType) {
+ Assert.assertEquals(body.getStatus(), 202, requestType + " failed with wrong http status");
+ Assert.assertEquals(
+ TestUtils.getNestedPropertyInMap(body.getEntity(), "requestReferences/instanceId"),
+ vnfIds.serviceInstanceId,
+ String.format("Failed to find instanceId: %s in " + requestType + " response. Actual body:%s",
+ vnfIds.serviceInstanceId, body.getEntity()));
+ }
+
+ private <T> T callChangeManagementUpdate(VnfIds vnfIds, String expectationPath, Class<T> responseClass, String requestType) {
+ SimulatorApi.registerExpectation(
+ expectationPath,
+ ImmutableMap.of("SERVICE_INSTANCE_ID", vnfIds.serviceInstanceId, "VNF_INSTANCE_ID", vnfIds.vnfInstanceId), RegistrationStrategy.CLEAR_THEN_SET);
+ ChangeManagementRequest changeManagementRequest = createChangeManagementRequest(vnfIds, requestType);
+ Response response = callChangeManagementUpdate(vnfIds, changeManagementRequest);
+ return response.readEntity(responseClass);
+ }
+
+ private Response callChangeManagementUpdate(VnfIds vnfIds, ChangeManagementRequest changeManagementRequest) {
+ WebTarget webTarget = client.target(uri).
+ path(CHANGE_MANAGEMENT + WORKFLOW).resolveTemplate("vnfname", vnfIds.vnfName);
+ Entity entity = Entity.json(changeManagementRequest);
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).header("Authorization", "Basic 123==").post(entity);
+ return response;
+ }
+
+ private void testChangeManagement409Error(String expectationPath, String requestType) throws IOException {
+ VnfIds vnfIds = new VnfIds();
+ MsoResponseWrapper2 body = callChangeManagementUpdate(vnfIds, expectationPath, MsoResponseWrapper2.class, requestType);
+ Assert.assertEquals(body.getStatus(), 409, requestType + " failed with wrong http status");
+ Assert.assertEquals(
+ TestUtils.getNestedPropertyInMap(body.getEntity(), "serviceException/messageId"),
+ "SVC2000",
+ String.format("Failed to find messageId: %s in " + requestType + " response. Actual body:%s",
+ "SVC2000", body.getEntity()));
+
+
+ assertThat(TestUtils.getNestedPropertyInMap(body.getEntity(), "serviceException/text"), containsString(vnfIds.vnfInstanceId));
+ }
+
+ private void testChangeManagement404Error(String expectationPath, String requestType) throws IOException {
+ VnfIds vnfIds = new VnfIds();
+ MsoResponseWrapper2 body = callChangeManagementUpdate(vnfIds, expectationPath, MsoResponseWrapper2.class, requestType);
+ Assert.assertEquals(body.getStatus(), 404, requestType + " failed with wrong http status");
+ assertThat(body.getEntity(), equalTo("<html><head><title>Error</title></head><body>404 - Not Found</body></html>"));
+ }
+
+ private void testChangeManagementWithoutVnfInstanceId(String requestType) throws IOException {
+ VnfIds vnfIds = new VnfIds();
+ ChangeManagementRequest changeManagementRequest = createChangeManagementRequest(vnfIds, requestType);
+ changeManagementRequest.getRequestDetails().get(0).setVnfInstanceId(null);
+ MsoExceptionResponse exceptionResponse = callChangeManagementAndExpectForException(vnfIds, changeManagementRequest, requestType);
+ assertThat(exceptionResponse.serviceException.text, containsString("No vnfInstanceId in request"));
+ }
+
+ private void testChangeManagementServiceInstanceId(Consumer<ChangeManagementRequest> dropInstanceIdMethod, String requestType) throws IOException {
+ VnfIds vnfIds = new VnfIds();
+ ChangeManagementRequest changeManagementRequest = createChangeManagementRequest(vnfIds, requestType);
+ dropInstanceIdMethod.accept(changeManagementRequest);
+ MsoExceptionResponse exceptionResponse = callChangeManagementAndExpectForException(vnfIds, changeManagementRequest, requestType);
+ assertThat(exceptionResponse.serviceException.text, containsString("No instanceId in request"));
+ }
+
+ private void testChangeManagementInvalidPayload(String payload, String propertyName, String requestType) throws IOException {
+ VnfIds vnfIds = new VnfIds();
+ ChangeManagementRequest changeManagementRequest = createChangeManagementRequest(vnfIds, requestType);
+ changeManagementRequest.getRequestDetails().get(0).getRequestParameters().getAdditionalProperties().put("payload",payload);
+ MsoExceptionResponse exceptionResponse = callChangeManagementAndExpectForException(vnfIds, changeManagementRequest, requestType);
+ assertThat(exceptionResponse.serviceException.text, containsString(propertyName));
+ assertThat(exceptionResponse.serviceException.text, containsString("No valid payload"));
+ }
+
+ private void testChangeManagementWithoutPayload(Consumer<ChangeManagementRequest> dropPayloadMethod, String requestType) throws IOException {
+ VnfIds vnfIds = new VnfIds();
+ ChangeManagementRequest changeManagementRequest = createChangeManagementRequest(vnfIds, requestType);
+ dropPayloadMethod.accept(changeManagementRequest);
+ MsoExceptionResponse exceptionResponse = callChangeManagementAndExpectForException(vnfIds, changeManagementRequest, requestType);
+ assertThat(exceptionResponse.serviceException.text, containsString("No valid payload"));
+ }
+
+ private MsoExceptionResponse callChangeManagementAndExpectForException(VnfIds vnfIds, ChangeManagementRequest changeManagementRequest, String requestType) {
+ Response response = callChangeManagementUpdate(vnfIds, changeManagementRequest);
+ Assert.assertEquals(response.getStatus(), HttpStatus.OK.value() , requestType + " wrong http status");
+ MsoResponseWrapper2<MsoExceptionResponse> msoResponseWrapper2 = response.readEntity(new GenericType<MsoResponseWrapper2<MsoExceptionResponse>>(){});
+ assertThat(msoResponseWrapper2.getStatus(), equalTo(400));
+ assertThat(msoResponseWrapper2.getEntity(), instanceOf(MsoExceptionResponse.class));
+ return (MsoExceptionResponse) msoResponseWrapper2.getEntity();
+ }
+
+ private void testChangeManagementGoodPayload(String payload, String expectationFileName, String requestType) throws IOException {
+ VnfIds vnfIds = new VnfIds();
+ SimulatorApi.registerExpectation(
+ expectationFileName,
+ ImmutableMap.of("SERVICE_INSTANCE_ID", vnfIds.serviceInstanceId, "VNF_INSTANCE_ID", vnfIds.vnfInstanceId), RegistrationStrategy.CLEAR_THEN_SET);
+ ChangeManagementRequest changeManagementRequest = createChangeManagementRequest(vnfIds, requestType);
+ changeManagementRequest.getRequestDetails().get(0).getRequestParameters().getAdditionalProperties().put("payload",payload);
+ Response response = callChangeManagementUpdate(vnfIds, changeManagementRequest);
+ MsoResponseWrapper2 body = response.readEntity(MsoResponseWrapper2.class);
+ assertForHappyPath(vnfIds, body, requestType);
+ }
+
+ private ChangeManagementRequest createChangeManagementRequest(VnfIds vnfDetails, String requestType) {
+ ChangeManagementRequest changeManagementRequest = createBasicChangeManagementRequest(vnfDetails);
+ changeManagementRequest.setRequestType(requestType);
+ if(requestType.equals(ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE)) {
+ CloudConfiguration cloudConfiguration = new CloudConfiguration();
+ cloudConfiguration.lcpCloudRegionId = "mdt1";
+ cloudConfiguration.tenantId = "88a6ca3ee0394ade9403f075db23167e";
+ changeManagementRequest.getRequestDetails().get(0).setCloudConfiguration(cloudConfiguration);
+ }
+ changeManagementRequest.getRequestDetails().get(0).getRequestParameters().setAdditionalProperty("payload", getPayload(requestType));
+ return changeManagementRequest;
+ }
+
+ private ChangeManagementRequest createBasicChangeManagementRequest(VnfIds vnfDetails)
+ {
+ ChangeManagementRequestDetails requestDetails = new ChangeManagementRequestDetails();
+
+// org.onap.vid.domain.mso.CloudConfiguration cloudConfiguration = new org.onap.vid.domain.mso.CloudConfiguration();
+// cloudConfiguration.setLcpCloudRegionId("mdt1");
+// cloudConfiguration.setTenantId("88a6ca3ee0394ade9403f075db23167e");
+// requestDetails.setCloudConfiguration(cloudConfiguration);
+
+ RequestInfo requestInfo = new RequestInfo();
+ requestInfo.setSource("VID");
+ requestInfo.setRequestorId("az2016");
+ requestDetails.setRequestInfo(requestInfo);
+
+ RequestParameters requestParameters = new RequestParameters();
+ requestDetails.setRequestParameters(requestParameters);
+
+ RelatedInstance relatedInstance = new RelatedInstance();
+ relatedInstance.instanceId = vnfDetails.serviceInstanceId;
+ RelatedInstanceList relatedInstanceList = new RelatedInstanceList();
+ relatedInstanceList.setRelatedInstance(relatedInstance);
+ requestDetails.setRelatedInstList(Collections.singletonList(relatedInstanceList));
+
+ requestDetails.setVnfName(vnfDetails.vnfName);
+ requestDetails.setVnfInstanceId(vnfDetails.vnfInstanceId);
+
+ ChangeManagementRequest changeManagementRequest = new ChangeManagementRequest();
+ changeManagementRequest.setRequestDetails(Collections.singletonList(requestDetails));
+ return changeManagementRequest;
+ }
+
+ private String getPayload(String requestType) {
+ if(requestType.equals(ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE)) {
+ return "{\"existing_software_version\": \"3.1\",\"new_software_version\": \"3.2\", \"operations_timeout\": \"3600\"}";
+ }
+ else if(requestType.equals(ChangeManagementRequest.CONFIG_UPDATE)) {
+ return "{\"request-parameters\": \"3.1\",\"configuration-parameters\": \"3.2\", \"operations_timeout\": \"3600\"}";
+ }
+ return "";
+ }
+
+ private boolean isTextContainsInList(List<MsoResponseWrapper2> responseList, String str) {
+ for (MsoResponseWrapper2 response : responseList) {
+ if (response.getEntity().toString().contains(str))
+ return true;
+ }
+ return false;
+ }
+
+// @Test
+ public void testVnfWorkflowApiCRD() throws IOException {
+ List<WorkflowsDetail> workflowsDetails = generateWorkflowsDetails(10);
+
+ //create vnf to workflows relations
+ VnfWorkflowRelationRequest vnfWorkflowRelationRequest = new VnfWorkflowRelationRequest(workflowsDetails);
+ vnfWorkFlowOperationOK(HttpMethod.POST, vnfWorkflowRelationRequest);
+
+ //ensure all relations exist using get workflows for vnf
+ ensureAllVnfToWorkflowsExist(workflowsDetails);
+
+ //ensure all relations exist using get all vnf_to_workflows relations
+ Response response = vnfWorkFlowOperationOK(HttpMethod.GET, null);
+ VnfWorkflowRelationAllResponse vnfWorkflowRelationAllResponse = response.readEntity(VnfWorkflowRelationAllResponse.class);
+ Map<VnfDetails, List<String>> vnfDetailsToWorkflowsMap = vnfWorkflowRelationAllResponse.getVnfs().stream()
+ .collect(Collectors.toMap(x -> new VnfDetails(x.getUUID(), x.getInvariantUUID()), VnfDetailsWithWorkflows::getWorkflows));
+
+ workflowsDetails.forEach(workflowsDetail ->
+ Assert.assertTrue(vnfDetailsToWorkflowsMap.get(workflowsDetail.getVnfDetails()).contains(workflowsDetail.getWorkflowName())));
+
+ //delete vnf to workflows relations
+ vnfWorkFlowOperationOK(HttpMethod.DELETE, vnfWorkflowRelationRequest);
+
+ //make sure all relations not exist any more
+ ensureAllVnfToWorkflowsRelationsNotExist(workflowsDetails);
+
+ }
+
+ private void ensureAllVnfToWorkflowsExist(List<WorkflowsDetail> workflowsDetails) throws IOException {
+ for (WorkflowsDetail workflowsDetail : workflowsDetails) {
+ GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest = new GetVnfWorkflowRelationRequest(Collections.singletonList(workflowsDetail.getVnfDetails()));
+ GetWorkflowsResponse getWorkflowsResponse = getWorkflowsResponseOK(getVnfWorkflowRelationRequest);
+ Assert.assertEquals(getWorkflowsResponse.getWorkflows().size(), 1);
+ Assert.assertEquals(getWorkflowsResponse.getWorkflows().get(0), workflowsDetail.getWorkflowName());
+ }
+ }
+
+ private void ensureAllVnfToWorkflowsRelationsNotExist(List<WorkflowsDetail> workflowsDetails) throws IOException {
+ for (WorkflowsDetail workflowsDetail : workflowsDetails) {
+ GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest = new GetVnfWorkflowRelationRequest(Collections.singletonList(workflowsDetail.getVnfDetails()));
+ GetWorkflowsResponse getWorkflowsResponse = getWorkflowsResponseOK(getVnfWorkflowRelationRequest);
+ Assert.assertEquals(getWorkflowsResponse.getWorkflows().size(), 0);
+ }
+ }
+
+// @Test
+ public void testVnfWorkflowIntersection() throws IOException {
+ List<WorkflowsDetail> workflowsDetails = new ArrayList<>();
+ List<VnfDetails> vnfDetailsList = new ArrayList<>();
+ //0 - UPDATE,REPLACE
+ VnfDetails vnfDetails = generateRandomVnfDetails(vnfDetailsList);
+ workflowsDetails.add(new WorkflowsDetail(vnfDetails, REPLACE));
+ workflowsDetails.add(new WorkflowsDetail(vnfDetails, UPDATE));
+ //1 - UPDATE,REPLACE
+ vnfDetails = generateRandomVnfDetails(vnfDetailsList);
+ workflowsDetails.add(new WorkflowsDetail(vnfDetails, REPLACE));
+ workflowsDetails.add(new WorkflowsDetail(vnfDetails, UPDATE));
+ //2 - REPLACE
+ vnfDetails = generateRandomVnfDetails(vnfDetailsList);
+ workflowsDetails.add(new WorkflowsDetail(vnfDetails, REPLACE));
+ //3 - REPLACE
+ vnfDetails = generateRandomVnfDetails(vnfDetailsList);
+ workflowsDetails.add(new WorkflowsDetail(vnfDetails, REPLACE));
+ //4 - UPDATE
+ vnfDetails = generateRandomVnfDetails(vnfDetailsList);
+ workflowsDetails.add(new WorkflowsDetail(vnfDetails, UPDATE));
+
+ VnfWorkflowRelationRequest vnfWorkflowRelationRequest = new VnfWorkflowRelationRequest(workflowsDetails);
+ vnfWorkFlowOperationOK(HttpMethod.POST, vnfWorkflowRelationRequest);
+
+ Set<String> replaceUpdateSet = ImmutableSet.of(REPLACE, UPDATE);
+ Set<String> replaceSet = ImmutableSet.of(REPLACE);
+ Set<String> emptySet = ImmutableSet.of();
+
+ assertWorkflowsListSize(vnfDetailsList, replaceUpdateSet, 0, 1);
+ assertWorkflowsListSize(vnfDetailsList, replaceSet, 0, 2);
+ assertWorkflowsListSize(vnfDetailsList, replaceSet, 2, 3);
+ assertWorkflowsListSize(vnfDetailsList, emptySet, 3, 4);
+ assertWorkflowsListSize(vnfDetailsList, replaceSet, 0, 1, 2);
+ assertWorkflowsListSize(vnfDetailsList, replaceSet, 0, 1, 2, 3);
+ assertWorkflowsListSize(vnfDetailsList, emptySet, 0, 1, 2, 3, 4);
+ assertWorkflowsListSize(vnfDetailsList, replaceUpdateSet, 0);
+
+ //delete vnf to workflows relations
+ vnfWorkFlowOperationOK(HttpMethod.DELETE, vnfWorkflowRelationRequest);
+ ensureAllVnfToWorkflowsRelationsNotExist(workflowsDetails);
+
+ //get vnf that was inserted and relation were removed return empty set
+ assertWorkflowsListSize(vnfDetailsList, emptySet, 0);
+ }
+
+ @Test
+ public void testGetVnfThatWasNeverInsertedReturn404() throws IOException {
+ //get vnf that was never inserted return 404
+ assertWorkflowsResponse(new GetVnfWorkflowRelationRequest(ImmutableList.of(generateRandomVnfDetails())), HttpStatus.NOT_FOUND);
+ }
+
+// @Test
+ void testDeleteVnfThatWasNeverInserted() throws IOException {
+ //delete vnf that was never inserted return 200 with error in body
+ WorkflowsDetail randomWorkfowDetail = generateRandomWorkflowsDetail();
+ Response response = vnfWorkFlowOperationOK(HttpMethod.DELETE, new VnfWorkflowRelationRequest(ImmutableList.of(randomWorkfowDetail)));
+ VnfWorkflowRelationResponse vnfWorkflowRelationResponse = response.readEntity(VnfWorkflowRelationResponse.class);
+ Assert.assertEquals(vnfWorkflowRelationResponse.getErrors().size(), 1);
+ Assert.assertTrue(vnfWorkflowRelationResponse.getErrors().get(0).contains(randomWorkfowDetail.getVnfDetails().getUUID()));
+ Assert.assertTrue(vnfWorkflowRelationResponse.getErrors().get(0).contains(randomWorkfowDetail.getVnfDetails().getInvariantUUID()));
+ }
+
+// @Test
+ public void testInsertSameVnfToWorkflowsTwice() throws IOException {
+ List<WorkflowsDetail> workflowsDetails = generateWorkflowsDetails(1);
+ VnfWorkflowRelationRequest vnfWorkflowRelationRequest = new VnfWorkflowRelationRequest(workflowsDetails);
+ vnfWorkFlowOperationOK(HttpMethod.POST, vnfWorkflowRelationRequest);
+ vnfWorkFlowOperationOK(HttpMethod.POST, vnfWorkflowRelationRequest);
+
+ //ensure workflow exist
+ ensureAllVnfToWorkflowsExist(workflowsDetails);
+
+ //delete vnf to workflows relations
+ vnfWorkFlowOperationOK(HttpMethod.DELETE, vnfWorkflowRelationRequest);
+
+ //make sure all relations not exist any more
+ ensureAllVnfToWorkflowsRelationsNotExist(workflowsDetails);
+ }
+
+// @Test
+ public void testMultipleVnfsWhileOneWorkflowNotExist() throws IOException {
+ List<WorkflowsDetail> workflowsDetails = generateWorkflowsDetails(3);
+
+ //relation 0 add relation to non exist workflow
+ WorkflowsDetail nonExistWorkflowsDetail = workflowsDetails.get(0);
+ nonExistWorkflowsDetail.setWorkflowName("NotExist");
+ VnfWorkflowRelationRequest vnfWorkflowRelationRequest = new VnfWorkflowRelationRequest(workflowsDetails);
+
+ Response response = vnfWorkFlowOperationOK(HttpMethod.POST, vnfWorkflowRelationRequest);
+ VnfWorkflowRelationResponse vnfWorkflowRelationResponse = response.readEntity(VnfWorkflowRelationResponse.class);
+ assertErrorResponseForWorkflowDetail(nonExistWorkflowsDetail, vnfWorkflowRelationResponse);
+
+ //ensure other vnf to workflows exist
+ ensureAllVnfToWorkflowsExist(workflowsDetails.subList(1, workflowsDetails.size()));
+
+ //ensure there is no workflow for vnf 0
+ GetWorkflowsResponse getWorkflowsResponse = getWorkflowsResponseOK(
+ new GetVnfWorkflowRelationRequest(ImmutableList.of(nonExistWorkflowsDetail.getVnfDetails())));
+ Assert.assertEquals(getWorkflowsResponse.getWorkflows().size(), 0);
+
+ //delete vnf to workflows relations
+ response = vnfWorkFlowOperationOK(HttpMethod.DELETE, vnfWorkflowRelationRequest);
+ vnfWorkflowRelationResponse = response.readEntity(VnfWorkflowRelationResponse.class);
+ assertErrorResponseForWorkflowDetail(nonExistWorkflowsDetail, vnfWorkflowRelationResponse);
+
+ //make sure all relations not exist any more
+ ensureAllVnfToWorkflowsRelationsNotExist(workflowsDetails);
+ }
+
+// @Test
+ public void testInsertVnfWithEmptyUUID() throws IOException {
+ assertAddVnfWithEmptyIdReturn404((vnfDetails -> vnfDetails.setUUID("")));
+ }
+
+// @Test
+ public void testInsertVnfWithEmptyInvariantUUID() throws IOException {
+ assertAddVnfWithEmptyIdReturn404((vnfDetails -> vnfDetails.setInvariantUUID("")));
+ }
+
+ @Test
+ //This test requires a simulator which runs on VID and is mocking Scheduler
+ public void testDeleteScheduledWorkflowOk() throws Exception {
+ //Register required response
+ SimulatorApi.registerExpectation(DELETE_SCHEDULE_OK_JSON, RegistrationStrategy.APPEND);
+ assertCancelScheduleResponse(HttpStatus.NO_CONTENT);//204
+ }
+
+ @Test
+ //This test requires a simulator which runs on VID and is mocking Scheduler
+ public void testDeleteScheduledWorkflowNotFound() throws Exception {
+ //Register required response
+ SimulatorApi.registerExpectation(DELETE_SCHEDULE_NOT_AUTHORIZED_JSON, RegistrationStrategy.APPEND);
+ assertCancelScheduleResponse(HttpStatus.UNAUTHORIZED);//401
+ }
+
+ private void assertAddVnfWithEmptyIdReturn404(Consumer<VnfDetails> emptyIdSetter) throws IOException {
+ List<WorkflowsDetail> workflowsDetails = generateWorkflowsDetails(1);
+ emptyIdSetter.accept(workflowsDetails.get(0).getVnfDetails());
+ VnfWorkflowRelationRequest vnfWorkflowRelationRequest = new VnfWorkflowRelationRequest(workflowsDetails);
+ Response response = vnfWorkFlowOperationOK(HttpMethod.POST, vnfWorkflowRelationRequest);
+ VnfWorkflowRelationResponse vnfWorkflowRelationResponse = response.readEntity(VnfWorkflowRelationResponse.class);
+ assertErrorResponseForWorkflowDetail(workflowsDetails.get(0), vnfWorkflowRelationResponse);
+ assertWorkflowsResponse(new GetVnfWorkflowRelationRequest(ImmutableList.of(generateRandomVnfDetails())), HttpStatus.NOT_FOUND);
+ }
+
+ private void assertErrorResponseForWorkflowDetail(WorkflowsDetail wrongWorkflowsDetail, VnfWorkflowRelationResponse vnfWorkflowRelationResponse) {
+ Assert.assertEquals(vnfWorkflowRelationResponse.getErrors().size(), 1);
+ Assert.assertTrue(vnfWorkflowRelationResponse.getErrors().get(0).contains(wrongWorkflowsDetail.getWorkflowName()));
+ Assert.assertTrue(vnfWorkflowRelationResponse.getErrors().get(0).contains(wrongWorkflowsDetail.getVnfDetails().getUUID()));
+ Assert.assertTrue(vnfWorkflowRelationResponse.getErrors().get(0).contains(wrongWorkflowsDetail.getVnfDetails().getInvariantUUID()));
+ }
+
+ private VnfDetails generateRandomVnfDetails(List<VnfDetails> vnfDetailsList) {
+ VnfDetails vnfDetails = generateRandomVnfDetails();
+ vnfDetailsList.add(vnfDetails);
+ return vnfDetails;
+ }
+
+ private VnfDetails generateRandomVnfDetails() {
+ return new VnfDetails(UUID.randomUUID().toString(), UUID.randomUUID().toString());
+ }
+
+ private void assertWorkflowsListSize(List<VnfDetails> inputList, Set<String> exceptedWorkflows, int... indices) throws IOException {
+ List<VnfDetails> vnfDetailsList = new ArrayList<>();
+ for (int index : indices) {
+ vnfDetailsList.add(inputList.get(index));
+ }
+ GetWorkflowsResponse getWorkflowsResponse = getWorkflowsResponseOK(new GetVnfWorkflowRelationRequest(vnfDetailsList));
+ Assert.assertEquals(getWorkflowsResponse.getWorkflows().size(), exceptedWorkflows.size());
+ Assert.assertTrue(getWorkflowsResponse.getWorkflows().containsAll(exceptedWorkflows));
+ }
+
+ private void assertCancelScheduleResponse(HttpStatus expectedStatus) {
+ WebTarget webTarget = client.target(uri).path(CHANGE_MANAGEMENT + SCHEDULER_BY_SCHEDULE_ID.replace("{scheduleId}", "1234"));
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).delete();
+ Assert.assertEquals(response.getStatus(), expectedStatus.value());
+ }
+
+ private GetWorkflowsResponse getWorkflowsResponseOK(GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest) throws IOException {
+ WebTarget webTarget = client.target(uri).path(CHANGE_MANAGEMENT + "/" + GET_VNF_WORKFLOW_RELATION);
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(getVnfWorkflowRelationRequest));
+ TestUtils.assertStatusOK(getVnfWorkflowRelationRequest, webTarget, response);
+ return response.readEntity(GetWorkflowsResponse.class);
+ }
+
+ private void assertWorkflowsResponse(GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest, HttpStatus exceptedHttpStatus) throws IOException {
+ WebTarget webTarget = client.target(uri).path(CHANGE_MANAGEMENT + "/" + GET_VNF_WORKFLOW_RELATION);
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(getVnfWorkflowRelationRequest));
+ TestUtils.assertHttpStatus(getVnfWorkflowRelationRequest, webTarget, response, exceptedHttpStatus);
+ response.readEntity(VnfWorkflowRelationResponse.class); //assert the body is of type VnfWorkflowRelationResponse
+ Assert.assertTrue(((String) response.getHeaders().get("Content-Type").get(0)).contains(APPLICATION_JSON));
+ }
+
+ private Response vnfWorkFlowOperationOK(String method, VnfWorkflowRelationRequest vnfWorkflowRelationRequest) throws IOException {
+ return vnfWorkFlowOperation(method, vnfWorkflowRelationRequest, HttpStatus.OK);
+ }
+
+ private Response vnfWorkFlowOperation(String method, VnfWorkflowRelationRequest vnfWorkflowRelationRequest, HttpStatus exceptedHttpStatus) throws IOException {
+ WebTarget webTarget = client.target(uri).path(CHANGE_MANAGEMENT + "/" + VNF_WORKFLOW_RELATION);
+ Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).method(method, Entity.json(vnfWorkflowRelationRequest));
+ TestUtils.assertHttpStatus(vnfWorkflowRelationRequest, webTarget, response, exceptedHttpStatus);
+ return response;
+ }
+
+ @SuppressWarnings("SameParameterValue")
+ private List<WorkflowsDetail> generateWorkflowsDetails(int size) {
+ List<WorkflowsDetail> workflowsDetails = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ workflowsDetails.add(i, generateRandomWorkflowsDetail());
+ }
+ return workflowsDetails;
+ }
+
+ private WorkflowsDetail generateRandomWorkflowsDetail() {
+ String workflow = WORKFLOWS.get(random.nextInt(WORKFLOWS.size()));
+ VnfDetails vnfDetails = generateRandomVnfDetails();
+ return new WorkflowsDetail(vnfDetails, workflow);
+ }
+
+ static public class VnfIds {
+ public String serviceInstanceId;
+ public String vnfInstanceId;
+ public String vnfName;
+
+ public VnfIds() {
+ this.serviceInstanceId = UUID.randomUUID().toString();
+ this.vnfInstanceId = UUID.randomUUID().toString();
+ this.vnfName = "VidVnf";
+ }
+
+
+ }
+
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/OperationalEnvironmentControllerApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/OperationalEnvironmentControllerApiTest.java
new file mode 100644
index 000000000..222b0f5fb
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/OperationalEnvironmentControllerApiTest.java
@@ -0,0 +1,431 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.text.StringEscapeUtils;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.HttpClientErrorException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import vid.automation.test.services.SimulatorApi;
+import vid.automation.test.services.SimulatorApi.RegistrationStrategy;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.METHOD_NOT_ALLOWED;
+
+public class OperationalEnvironmentControllerApiTest extends BaseMsoApiTest {
+ private static final String UUID = "927befca-e32c-4f7d-be8d-b4107e0ac31e";
+ public static final String GET_STATUS_REQUEST_UUID = "3212b08c-0dcd-4d20-8c84-51e4f325c14a";
+ private static final String BASIC_DEACTIVATE_REQUEST_BODY = "{}";
+ private static final String BASIC_ACTIVATE_REQUEST_BODY = getResourceAsString("operationalEnvironmentController/activateOperationalEnvironment.json");
+ private static final String BASIC_CREATE_REQUEST_BODY = getResourceAsString("operationalEnvironmentController/createOperationalEnvironment.json");
+ private final String MSO_OK_RESPONSE_FOR_DEACTIVATE = "mso_ok_response_for_deactivate.json";
+ public static final String GET_CLOUD_RESOURCES_REQUEST_STATUS = "get_cloud_resources_request_status.json";
+ private final String MSO_ERROR_RESPONSE_FOR_DEACTIVATE = "mso_error_response_for_deactivate.json";
+ private final String MSO_ERROR_RESPONSE_FOR_STATUS = "mso_error_response_for_status.json";
+ private final String MSO_OK_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT = "mso_ok_response_for_post_operational_environmnet.json";
+ private final String MSO_ERROR_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT = "mso_error_response_for_post_operational_environmnet.json";
+ private final String missingParamErrorText = "Required String parameter 'operationalEnvironment' is not present";
+
+ /*
+ # DEACTIVATION
+
+ ## Tests
+ [x] - Try all methods: only POST is working
+ [x] - Send wrong requests; all are responded with 400 and nice description
+ [x] - missing param
+ [x] - missing body
+ [x] - operationalEnvironment value is empty
+ - Simulate MSO responses (status and body); verify all are propagated inside a VID's 200 OK
+ [x] - [ 200, 202, 400, 404, 500 ]
+
+ - Positive cases
+ [x] - Request body is just '{}'
+ [x] - Request body is with some fields
+ [x] - URI with more query params
+
+ ### Always verify
+ [x] - Payload to MSO is the valid schema and values
+ [ ] - RequestorId is ok
+
+ */
+
+ @Override
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+
+ @Test(dataProvider = "wrongHttpMethodsForAllUris")
+ public void tryAllWrongMethods(HttpMethod httpMethod, String uri) throws IOException {
+ try {
+ ResponseEntity<String> responseEntity = restTemplate.exchange(uri, httpMethod, new HttpEntity<ImmutableMap>(ImmutableMap.of()), String.class);
+ assertThat("Response should be method not allowed => " + responseEntity, responseEntity.getBody(), containsString("Request method '" + httpMethod + "' not supported"));
+ } catch (HttpClientErrorException e) {
+ assertThat("Response should be method not allowed (by error code)", e.getStatusCode(), is(METHOD_NOT_ALLOWED));
+ }
+
+ }
+
+
+ @Test
+ public void activateWithAdditionalQueryParam() throws IOException {
+ doWithFineRequest(BASIC_ACTIVATE_REQUEST_BODY, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.EXTENDED), "/activate\"");
+ }
+
+ @Test(expectedExceptions = { HttpClientErrorException.class })
+ public void activateWithMissingOperationalEnvironmentParam() throws IOException {
+ doWithBadRequest(BASIC_ACTIVATE_REQUEST_BODY, missingParamErrorText, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.MISSING));
+ }
+
+ @Test(expectedExceptions = { HttpClientErrorException.class })
+ public void activateWithNoValueForOperationalEnvironmentParam() throws IOException {
+ doWithBadRequest(BASIC_ACTIVATE_REQUEST_BODY, missingParamErrorText, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.NO_VALUE));
+ }
+
+ @Test
+ public void deactivateWithAdditionalQueryParam() throws IOException {
+ doWithFineRequest(BASIC_DEACTIVATE_REQUEST_BODY, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.EXTENDED), "/deactivate\"");
+ }
+
+ @Test(expectedExceptions = { HttpClientErrorException.class })
+ public void deactivateWithMissingOperationalEnvironmentParam() throws IOException {
+ doWithBadRequest(BASIC_DEACTIVATE_REQUEST_BODY, missingParamErrorText, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.MISSING));
+ }
+
+ @Test(expectedExceptions = { HttpClientErrorException.class })
+ public void deactivateWithNoValueForOperationalEnvironmentParam() throws IOException {
+ doWithBadRequest(BASIC_DEACTIVATE_REQUEST_BODY, missingParamErrorText, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.NO_VALUE));
+ }
+
+ @Test(dataProvider = "requestPayloads")
+ public void activateWithBody(String requestBody) throws IOException {
+ doWithFineRequest(requestBody, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), "/activate\"");
+ }
+
+ @Test(dataProvider = "requestPayloads")
+ public void deactivateWithBody(String requestBody) throws IOException {
+ doWithFineRequest(requestBody, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), "/deactivate\"");
+ }
+
+
+ private void doWithFineRequest(String requestBody, String targetUri, String v1) throws IOException {
+ final String expectedResult = "" +
+ "{" +
+ " \"requestReferences\": {" +
+ " \"requestId\": \"dbe54591-c8ed-46d3-abc7-d3a24873dfbd\"," +
+ " \"instanceId\": \"" + UUID + "\"" +
+ " }" +
+ "}";
+ callMsoWithFineRequest(MSO_OK_RESPONSE_FOR_DEACTIVATE, ImmutableMap.of(
+ "/deactivate\"", v1,
+ "UUID", UUID)
+ ,targetUri,requestBody,HttpStatus.ACCEPTED.value(),expectedResult, HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void deactivateWithErrorResponse(int errorCode) throws IOException {
+ doWithSimulatedErrorResponse(errorCode, getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), BASIC_DEACTIVATE_REQUEST_BODY, "/deactivate\"", MSO_ERROR_RESPONSE_FOR_DEACTIVATE, HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void activateWithErrorResponse(int errorCode) throws IOException {
+ doWithSimulatedErrorResponse(errorCode, getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK), BASIC_ACTIVATE_REQUEST_BODY, "/activate\"", MSO_ERROR_RESPONSE_FOR_DEACTIVATE, HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void testStatusWithErrorResponse(int errorCode) throws IOException {
+ doWithSimulatedErrorResponse(errorCode, getStatusTargetUri(STATUS_URI_UUID_MODE.OK), "", "", MSO_ERROR_RESPONSE_FOR_STATUS, HttpMethod.GET);
+ }
+
+ private void doWithSimulatedErrorResponse(int errorCode, String targetUri, String basicRequestBody, String msoPathSuffix, String expectationTemplateFilename, HttpMethod method) throws IOException {
+ final String expectedResult = "" +
+ "<head>Huston, you have a problem<head>";
+ callMsoWithSimulatedErrorResponse(expectationTemplateFilename, ImmutableMap.of(
+ "/deactivate\"", msoPathSuffix,
+ "UUID", UUID,
+ "500", errorCode,
+ "ERROR_PAYLOAD", StringEscapeUtils.escapeJson(expectedResult)
+ ),targetUri,basicRequestBody,errorCode, expectedResult, method);
+ }
+
+ @Test(
+ dataProvider = "requestPayloads",
+ expectedExceptions = { HttpClientErrorException.class }
+ )
+ public void activateWithBadRequest(String requestBody) throws IOException {
+ doWithBadRequest(requestBody, "HttpMessageNotReadableException", getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK));
+ }
+
+ @Test(
+ dataProvider = "activateBadHalfBakedPayloads",
+ expectedExceptions = { HttpClientErrorException.class }
+ )
+ public void activateWithBadHalfBakedPayload(String requestBody) throws IOException {
+ doWithBadRequest(requestBody, "HttpMessageNotReadableException", getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK));
+ }
+
+ @Test(
+ dataProvider = "requestPayloads",
+ expectedExceptions = { HttpClientErrorException.class }
+ )
+ public void deactivateWithBadRequest(String requestBody) throws IOException {
+ doWithBadRequest(requestBody, "HttpMessageNotReadableException", getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK));
+ }
+
+ private void doWithBadRequest(String requestBody, String httpMessageNotReadableException, String targetUri) throws IOException {
+ SimulatorApi.registerExpectation(MSO_OK_RESPONSE_FOR_DEACTIVATE, ImmutableMap.of("UUID", UUID), RegistrationStrategy.CLEAR_THEN_SET);
+
+ try {
+ ResponseEntity<String> responseEntity = restTemplate.postForEntity(targetUri, requestBody, String.class);
+ } catch (HttpClientErrorException e) {
+ assertThat("Response should be Bad Request (by error code)", e.getStatusCode(), is(BAD_REQUEST));
+ assertThat("Response should be Bad Request (by body)", e.getResponseBodyAsString(), containsString(httpMessageNotReadableException));
+ throw e;
+ }
+
+ }
+
+
+ @DataProvider
+ public Object[][] wrongHttpMethodsForAllUris() {
+ ImmutableList<String> uris = ImmutableList.of(
+ getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE.OK),
+ getActivationTargetUri(ACTIVATION_URI_UUID_MODE.OK)
+ );
+
+ return Arrays.stream(HttpMethod.values())
+ .filter(Streams.not(ImmutableList.of(
+ HttpMethod.POST, // because POST *should* work
+ HttpMethod.PATCH, // because PATCH is invalid method for Java.net
+ HttpMethod.OPTIONS, // because OPTIONS is somehow valid... :-( => Allow=[GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH]
+ HttpMethod.HEAD // because HEAD is like POST/GET but without body, so error is hidden
+ )::contains))
+ .flatMap(httpMethod -> uris.stream()
+ .map(uri -> new Object[]{ httpMethod, uri}) // pair given method for each of the URIs
+ )
+ .collect(Collectors.toList())
+ .toArray(new Object[][] {});
+ }
+
+ @DataProvider
+ public static Object[][] requestPayloads(Method test) {
+ switch (test.getName()) {
+ case "deactivateWithBody":
+ return new Object[][]{
+ {BASIC_DEACTIVATE_REQUEST_BODY}
+ , {"{ \"a\": \"b\" }"}
+ , {"{ \"a\": [ 55 ] }"}
+ };
+ case "activateWithBody":
+ return new Object[][]{
+ {BASIC_ACTIVATE_REQUEST_BODY}
+ };
+ default: // bad payloads
+ return new Object[][]{
+ {null}
+ , {""}
+ , {"{"}
+ , {"foo"}
+ };
+ }
+ }
+
+ @DataProvider
+ public static Object[][] activateBadHalfBakedPayloads(Method test) {
+ final ImmutableList<String> strings = ImmutableList.of(
+ "\"relatedInstanceId\": \"1117887f-068f-46d7-9e43-9b73bef17af8\"",
+ "\"relatedInstanceName\": \"managing ECOMP Operational Environment\"",
+ "\"workloadContext\": \"VNF_E2E-IST\"",
+ "\"manifest\": {" +
+ " \"serviceModelList\": [" +
+ " {" +
+ " \"serviceModelVersionId\": \"uuid2\"," +
+ " \"recoveryAction\": \"retry\"" +
+ " }" +
+ " ]" +
+ "}"
+ );
+
+ final LinkedList<String> tests = new LinkedList<>();
+ for (int i = 0; i < strings.size(); i++) {
+ final ArrayList<String> aCase = new ArrayList<>(strings);
+ aCase.remove(i);
+ tests.add("{" + String.join(", ", aCase) + "}");
+ }
+
+ return tests.stream().map(o -> new Object[] { o }).collect(Collectors.toList()).toArray(new Object[][]{});
+ }
+
+ @DataProvider
+ public static Object[][] errorCodes(Method test) {
+ return new Object[][]{
+ {500}, {505}, {400}, {401}, {405}
+ };
+ }
+
+ @DataProvider
+ public static Object[][] statusLegitUri(Method test) {
+ return new Object[][]{
+ {STATUS_URI_UUID_MODE.OK}, {STATUS_URI_UUID_MODE.EXTENDED}
+ };
+ }
+
+ @DataProvider
+ public static Object[][] statusNotLegitUri(Method test) {
+ return new Object[][]{
+ {STATUS_URI_UUID_MODE.MISSING}, {STATUS_URI_UUID_MODE.NO_VALUE}
+ };
+ }
+
+ private enum ACTIVATION_URI_UUID_MODE {
+ MISSING(""),
+ NO_VALUE("?operationalEnvironment="),
+ OK(NO_VALUE.val + UUID),
+ EXTENDED(OK.val + "&anotherParam=6");
+
+ final String val;
+
+ ACTIVATION_URI_UUID_MODE(String val) {
+ this.val = val;
+ }
+ }
+
+ private enum STATUS_URI_UUID_MODE {
+ MISSING(""),
+ NO_VALUE("?requestId="),
+ OK(NO_VALUE.val + GET_STATUS_REQUEST_UUID),
+ EXTENDED(OK.val + "&anotherParam=6");
+
+ final String val;
+
+ STATUS_URI_UUID_MODE(String val) {
+ this.val = val;
+ }
+ }
+
+ private String getDeactivationTargetUri(ACTIVATION_URI_UUID_MODE uriUuidMode) {
+ return uri.toASCIIString() + "/operationalEnvironment/deactivate" + uriUuidMode.val;
+ }
+
+ private String getActivationTargetUri(ACTIVATION_URI_UUID_MODE uriUuidMode) {
+ return uri.toASCIIString() + "/operationalEnvironment/activate" + uriUuidMode.val;
+ }
+
+ private String getStatusTargetUri(STATUS_URI_UUID_MODE uriUuidMode) {
+ return uri.toASCIIString() + "/operationalEnvironment/requestStatus" + uriUuidMode.val;
+ }
+
+ private String getCreateOperationEnvironmentUri() {
+ return uri.toASCIIString() + "/operationalEnvironment/create";
+ }
+
+ @Test
+ public void createWithSimplestBody()throws IOException {
+
+ final String expectedResult = "" +
+ "{" +
+ " \"requestReferences\": {" +
+ " \"requestId\": \"dbe54591-c8ed-46d3-abc7-d3a24873dfbd\","+
+ " \"instanceId\": \"" + UUID + "\"" +
+ " }" +
+ "}";
+ callMsoWithFineRequest(MSO_OK_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT, ImmutableMap.of(
+ "UUID", UUID), getCreateOperationEnvironmentUri(), BASIC_CREATE_REQUEST_BODY, HttpStatus.ACCEPTED.value(), expectedResult, HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void createWithErrorResponse(int errorCode) throws IOException {
+ final String expectedResult = "" +
+ "<head>Huston, you have a problem<head>";
+ callMsoWithSimulatedErrorResponse(MSO_ERROR_RESPONSE_FOR_POST_OPERATIONAL_ENVIRONMENT,ImmutableMap.of(
+ "500", errorCode,
+ "ERROR_PAYLOAD", StringEscapeUtils.escapeJson(expectedResult)
+ ), getCreateOperationEnvironmentUri(), BASIC_CREATE_REQUEST_BODY, errorCode,expectedResult, HttpMethod.POST);
+ }
+
+
+
+
+ @Test(dataProvider = "statusLegitUri")
+ public void testStatusWithLegitUri(STATUS_URI_UUID_MODE statusUriMode) throws IOException {
+
+ String uri = getStatusTargetUri(statusUriMode);
+
+ final String expectedResult = "" +
+ "{" +
+ " \"request\": {" +
+ " \"requestId\": \"3212b08c-0dcd-4d20-8c84-51e4f325c14a\"," +
+ " \"startTime\": \"Thu, 02 Jun 2017 02:51:59 GMT\"," +
+ " \"instanceReferences\": {" +
+ " \"operationalEnvironmentInstanceId\": \"bc305d54-75b4-431b-adb2-eb6b9e546014\"" +
+ " }," +
+ " \"requestScope\": \"operationalEnvironment\"," +
+ " \"requestType\": \"deactivate\"," +
+ " \"requestDetails\": {" +
+ " \"requestInfo\": {" +
+ " \"resourceType\": \"operationalEnvironment\"," +
+ " \"source\": \"VID\"," +
+ " \"requestorId\": \"az2017\"" +
+ " }," +
+ " \"requestParameters\": {" +
+ " \"operationalEnvironmentType\": \"VNF\"" +
+ " }" +
+ " }," +
+ " \"requestStatus\": {" +
+ " \"timestamp\": \"Thu, 02 Jun 2017 02:53:39 GMT\"," +
+ " \"requestState\": \"COMPLETE\"," +
+ " \"statusMessage\": \"Operational Environment successfully deactivated\"," +
+ " \"percentProgress\": \"100\"" +
+ " }" +
+ " }" +
+ "}";
+
+ callMsoWithFineRequest(GET_CLOUD_RESOURCES_REQUEST_STATUS, ImmutableMap.of()
+ ,uri,"",HttpStatus.OK.value(),expectedResult, HttpMethod.GET);
+
+ }
+
+ @Test(
+ expectedExceptions = {HttpClientErrorException.class},
+ dataProvider = "statusNotLegitUri"
+ )
+ public void testStatusWithBadRequest(STATUS_URI_UUID_MODE statusUriMode) throws IOException {
+ SimulatorApi.registerExpectation(GET_CLOUD_RESOURCES_REQUEST_STATUS, RegistrationStrategy.CLEAR_THEN_SET);
+
+ String uri = getStatusTargetUri(statusUriMode);
+
+ try {
+ ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri, String.class);
+ } catch (HttpClientErrorException e) {
+ assertThat("Response should be Bad Request (by error code)", e.getStatusCode(), is(BAD_REQUEST));
+ assertThat("Response should be Bad Request (by body)", e.getResponseBodyAsString(), containsString("'requestId' is not present"));
+ throw e;
+ }
+ }
+
+ @Test
+ public void testStatusWithWrongMethodPost() throws IOException {
+ SimulatorApi.registerExpectation(GET_CLOUD_RESOURCES_REQUEST_STATUS, RegistrationStrategy.CLEAR_THEN_SET);
+
+ String myUri = getStatusTargetUri(STATUS_URI_UUID_MODE.OK);
+
+ String response = restTemplate.postForObject(myUri, "", String.class);
+ assertThat("Response should be method not allowed => " + response, response, containsString("Request method '" + HttpMethod.POST + "' not supported"));
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java
new file mode 100644
index 000000000..54093ec56
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java
@@ -0,0 +1,109 @@
+package org.onap.vid.api;
+
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.junit.Assert;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGetInvalidResponse;
+import org.onap.vid.model.probe.ExternalComponentStatus;
+import org.onap.vid.model.probe.HttpRequestMetadata;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import vid.automation.test.services.SimulatorApi;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.*;
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET;
+
+public class ProbeApiTest extends BaseApiTest {
+
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+ @DataProvider
+ public static Object[][] probePresetAndResponse(Method test) {
+ return new Object[][]{
+ {
+ new PresetAAIGetSubscribersGet(),
+ new ExternalComponentStatus(ExternalComponentStatus.Component.AAI,
+ true,
+ new HttpRequestMetadata(HttpMethod.GET,
+ 200,
+ "business/customers?subscriber-type=INFRA&depth=0",
+ "{\"customer\":[{\"global-customer-id\":\"MSO_1610_ST\",\"subscriber-name\":\"MSO_1610_ST\",\"subscriber-type\":\"INFRA\",\"resource-version\":\"1494001902987\"},{\"global-customer-id\":\"21014aa2-526b-11e6-beb8-9e71128cae77\",\"subscriber-name\":\"PACKET CORE\",\"subscriber-type\":\"INFRA\",\"resource-version\":\"1494001776295\"},{\"global-customer-id\":\"DHV1707-TestSubscriber-2\",\"subscriber-name\":\"ICORE CORE\",\"subscriber-type\":\"INFRA\",\"resource-version\":\"1498751754450\"},{\"global-customer-id\":\"DHV1707-TestSubscriber-1\",\"subscriber",
+ "OK"
+ )
+ )
+ },
+ {
+ new PresetAAIGetSubscribersGetInvalidResponse(200),
+ new ExternalComponentStatus(ExternalComponentStatus.Component.AAI,
+ false,
+ new HttpRequestMetadata(HttpMethod.GET,
+ 200,
+ "business/customers?subscriber-type=INFRA&depth=0",
+ "this payload is an invalid json",
+ "org.codehaus.jackson.JsonParseException"
+ )
+ )
+ },
+ {
+ new PresetAAIGetSubscribersGetInvalidResponse(500),
+ new ExternalComponentStatus(ExternalComponentStatus.Component.AAI,
+ false,
+ new HttpRequestMetadata(HttpMethod.GET,
+ 500,
+ "business/customers?subscriber-type=INFRA&depth=0",
+ "this payload is an invalid json",
+ "No subscriber received"
+ )
+ )
+ }
+
+ };
+ }
+
+ @Test(dataProvider = "probePresetAndResponse")
+ public void probeRequest_returnsResponseAsExpected(BasePreset preset, ExternalComponentStatus expectedStatus ){
+ SimulatorApi.registerExpectationFromPreset(preset, CLEAR_THEN_SET);
+ ResponseEntity<List<ExternalComponentStatus>> response = restTemplate.exchange(
+ uri + "/probe",
+ org.springframework.http.HttpMethod.GET,
+ null,
+ new ParameterizedTypeReference<List<ExternalComponentStatus>>() {});
+ List<ExternalComponentStatus> probeResults = response.getBody();
+ Assert.assertEquals(probeResults.size(),1);
+ assertAaiGetAllSubscribersAsExpected(probeResults,expectedStatus);
+
+ }
+
+ private void assertAaiGetAllSubscribersAsExpected(List<ExternalComponentStatus> probeResults,ExternalComponentStatus expectedStatus){
+ Optional<ExternalComponentStatus> aaiGetAllSubscribersResult = probeResults.stream().filter(x -> x.getComponent()== ExternalComponentStatus.Component.AAI).findFirst();
+ Assert.assertTrue(aaiGetAllSubscribersResult.isPresent());
+ ExternalComponentStatus aaiGetAllSubscribersStatus = aaiGetAllSubscribersResult.get();
+ Assert.assertEquals(aaiGetAllSubscribersStatus.isAvailable(),expectedStatus.isAvailable());
+
+ Assert.assertThat(requestMetadataReflected(aaiGetAllSubscribersStatus.getMetadata()),is(requestMetadataReflected(expectedStatus.getMetadata())));
+ Assert.assertThat(aaiGetAllSubscribersStatus.getMetadata().getUrl(), both(endsWith(expectedStatus.getMetadata().getUrl())).and(startsWith("http")));
+
+ Assert.assertThat(aaiGetAllSubscribersStatus.getMetadata().getDescription(),
+ anyOf(equalTo(expectedStatus.getMetadata().getDescription()), startsWith(expectedStatus.getMetadata().getDescription())));
+ }
+
+ //serialize fields except of fields we cannot know ahead of time
+ private static String requestMetadataReflected(HttpRequestMetadata metadata) {
+ return new ReflectionToStringBuilder(metadata, ToStringStyle.SHORT_PREFIX_STYLE)
+ .setExcludeFieldNames("duration", "url", "description")
+ .toString();
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/SampleApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/SampleApiTest.java
new file mode 100644
index 000000000..c57a90aef
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/SampleApiTest.java
@@ -0,0 +1,67 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.json.JSONException;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.skyscreamer.jsonassert.JSONCompareMode;
+import org.springframework.http.HttpStatus;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import vid.automation.test.services.SimulatorApi;
+
+import java.io.IOException;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class SampleApiTest extends BaseApiTest {
+
+ private static final String UUID = "927befca-e32c-4f7d-be8d-b4107e0ac31e";
+ private static final String FILE_NAME = "a_file_with_request_setup.json";
+ private static final String REQUEST_BODY = "{ \"foo\": \"bar\" }";
+
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+ @Test(enabled = false)
+ public void createWithSimplestBody() throws IOException, JSONException {
+ final String expectedResult = "" +
+ "{" +
+ " \"requestReferences\": {" +
+ " \"requestId\": \"rq1234d1-5a33-55df-13ab-12abad84e331\","+
+ " \"instanceId\": \"" + UUID + "\"" +
+ " }" +
+ "}";
+
+ callWithFineRequest(FILE_NAME,
+ ImmutableMap.of("UUID", UUID),
+ buildUri(), REQUEST_BODY,
+ HttpStatus.ACCEPTED.value(), expectedResult);
+ }
+
+ private String buildUri() {
+ return uri + "/foo";
+ }
+
+ private void callWithFineRequest(String expectationJsonFileName, ImmutableMap<String, Object> replacementsForJson, String targetUri, String requestBody, int expectedStatusCode, String expectedResult) throws JSONException {
+ SimulatorApi.registerExpectation(expectationJsonFileName, replacementsForJson, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+
+ MyFooResponseType response = restTemplate.postForObject(targetUri, requestBody, MyFooResponseType.class);
+
+ assertThat("Wrong propagated status from MSO", response.getStatus(), is(expectedStatusCode));
+ JSONAssert.assertEquals("Wrong propagated body from MSO", expectedResult, getCleanJsonString(response.getEntity()), JSONCompareMode.NON_EXTENSIBLE);
+ }
+
+
+ private class MyFooResponseType {
+ public int getStatus() {
+ return 202;
+ }
+
+ public String getEntity() {
+ return "baz";
+ }
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/SdcApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/SdcApiTest.java
new file mode 100644
index 000000000..0441da1d2
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/SdcApiTest.java
@@ -0,0 +1,162 @@
+package org.onap.vid.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.ImmutableList;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
+import org.onap.simulator.presetGenerator.presets.sdc.PresetSDCGetServiceMetadataGet;
+import org.onap.simulator.presetGenerator.presets.sdc.PresetSDCGetServiceToscaModelGet;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import vid.automation.test.infra.Features;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonStringEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.either;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.testng.Assert.assertFalse;
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET;
+import static vid.automation.test.services.SimulatorApi.registerExpectation;
+import static vid.automation.test.services.SimulatorApi.registerExpectationFromPresets;
+
+public class SdcApiTest extends BaseApiTest {
+
+ private static final String SDC_GET_SERVICE_MODEL = "/rest/models/services/";
+
+
+ private static final String A_LA_CARTE_INSTANTIATION_TYPE_UUID = "4d71990b-d8ad-4510-ac61-496288d9078e";
+ private static final String A_LA_CARTE_INSTANTIATION_TYPE_INVARIANT_UUID = "d27e42cf-087e-4d31-88ac-6c4b7585f800";
+ private static final String A_LA_CARTE_INSTANTIATION_TYPE_FILE_PATH = "csar15782222_instantiationTypeAlacarte_invariantUUIDMacro.zip";
+ private static final String A_LA_CARTE_INSTANTIATION_TYPE_EXPECTED_RESPONSE = "{\"service\":{\"uuid\":\"4d71990b-d8ad-4510-ac61-496288d9078e\",\"invariantUuid\":\"d27e42cf-087e-4d31-88ac-6c4b7585f800\",\"name\":\"vidmacrofalsenaming\",\"version\":\"1.0\",\"toscaModelURL\":null,\"category\":\"Network L1-3\",\"serviceType\":\"\",\"serviceRole\":\"\",\"description\":\"vidmacrofalsenaming\",\"serviceEcompNaming\":\"false\",\"instantiationType\":\"A-La-Carte\",\"inputs\":{}},\"vnfs\":{},\"networks\":{\"MULTI_PROVIDER_PORT_GROUP 0\":{\"uuid\":\"e5d235de-2188-4f9f-a28c-fe38967883f2\",\"invariantUuid\":\"b0303003-0abb-454c-9119-8cbe2e09e003\",\"description\":\"Creates a neutron multi-provider VLAN network with dummy subnet\",\"name\":\"MULTI_PROVIDER_PORT_GROUP\",\"version\":\"1.0\",\"customizationUuid\":\"0fde4286-ee4c-439d-9556-74b6be6bbc42\",\"inputs\":{},\"commands\":{},\"properties\":{\"network_assignments\":\"{is_external_network=false, ipv4_subnet_default_assignment={min_subnets_count=1}, ecomp_generated_network_assignment=false, ipv6_subnet_default_assignment={min_subnets_count=1}}\",\"network_flows\":\"{is_network_policy=false, is_bound_to_vpn=false}\",\"network_scope\":\"GLOBAL\",\"network_ecomp_naming\":\"{ecomp_generated_naming=true}\",\"network_type\":\"MULTI_PROVIDER_PORT_GROUP\",\"network_technology\":\"MULTI_GROUP\",\"network_homing\":\"{ecomp_selected_instance_node_target=false}\"},\"type\":\"VL\",\"modelCustomizationName\":\"MULTI_PROVIDER_PORT_GROUP 0\"}},\"collectionResource\":{},\"configurations\":{},\"serviceProxies\":{},\"vfModules\":{},\"volumeGroups\":{},\"pnfs\":{}}";
+
+
+ private static final String MACRO_INSTANTIATION_TYPE_FILE_PATH = "csar15782222_instantiationTypeMacro_invariantUUIDAlacarte.zip";
+ private static final String MACRO_INSTANTIATION_TYPE_UUID = "4d71990b-d8ad-4510-ac61-496288d9078e";
+ private static final String MACRO_INSTANTIATION_TYPE_INVARIANT_UUID = "a8dcd72d-d44d-44f2-aa85-53aa9ca99cba";
+ private static final String MACRO_INSTANTIATION_TYPE_EXPECTED_RESPONSE = "{\"service\":{\"uuid\":\"4d71990b-d8ad-4510-ac61-496288d9078e\",\"invariantUuid\":\"a8dcd72d-d44d-44f2-aa85-53aa9ca99cba\",\"name\":\"vidmacrofalsenaming\",\"version\":\"1.0\",\"toscaModelURL\":null,\"category\":\"Network L1-3\",\"serviceType\":\"\",\"serviceRole\":\"\",\"description\":\"vidmacrofalsenaming\",\"serviceEcompNaming\":\"false\",\"instantiationType\":\"Macro\",\"inputs\":{}},\"vnfs\":{},\"networks\":{\"MULTI_PROVIDER_PORT_GROUP 0\":{\"uuid\":\"e5d235de-2188-4f9f-a28c-fe38967883f2\",\"invariantUuid\":\"b0303003-0abb-454c-9119-8cbe2e09e003\",\"description\":\"Creates a neutron multi-provider VLAN network with dummy subnet\",\"name\":\"MULTI_PROVIDER_PORT_GROUP\",\"version\":\"1.0\",\"customizationUuid\":\"0fde4286-ee4c-439d-9556-74b6be6bbc42\",\"inputs\":{},\"commands\":{},\"properties\":{\"network_assignments\":\"{is_external_network=false, ipv4_subnet_default_assignment={min_subnets_count=1}, ecomp_generated_network_assignment=false, ipv6_subnet_default_assignment={min_subnets_count=1}}\",\"network_flows\":\"{is_network_policy=false, is_bound_to_vpn=false}\",\"network_scope\":\"GLOBAL\",\"network_ecomp_naming\":\"{ecomp_generated_naming=true}\",\"network_type\":\"MULTI_PROVIDER_PORT_GROUP\",\"network_technology\":\"MULTI_GROUP\",\"network_homing\":\"{ecomp_selected_instance_node_target=false}\"},\"type\":\"VL\",\"modelCustomizationName\":\"MULTI_PROVIDER_PORT_GROUP 0\"}},\"collectionResource\":{},\"configurations\":{},\"serviceProxies\":{},\"vfModules\":{},\"volumeGroups\":{},\"pnfs\":{}}";
+
+
+ private static final String EMPTY_INSTANTIATION_TYPE_FILE_PATH = "csar15782222_instantiationTypeEmpty_invariantUUIDAlacarte.zip";
+ private static final String EMPTY_INSTANTIATION_TYPE_EXPECTED_RESPONSE = "{\"service\":{\"uuid\":\"4d71990b-d8ad-4510-ac61-496288d9078e\",\"invariantUuid\":\"a8dcd72d-d44d-44f2-aa85-53aa9ca99cba\",\"name\":\"vidmacrofalsenaming\",\"version\":\"1.0\",\"toscaModelURL\":null,\"category\":\"Network L1-3\",\"serviceType\":\"\",\"serviceRole\":\"\",\"description\":\"vidmacrofalsenaming\",\"serviceEcompNaming\":\"false\",\"instantiationType\":\"ClientConfig\",\"inputs\":{}},\"vnfs\":{},\"networks\":{\"MULTI_PROVIDER_PORT_GROUP 0\":{\"uuid\":\"e5d235de-2188-4f9f-a28c-fe38967883f2\",\"invariantUuid\":\"b0303003-0abb-454c-9119-8cbe2e09e003\",\"description\":\"Creates a neutron multi-provider VLAN network with dummy subnet\",\"name\":\"MULTI_PROVIDER_PORT_GROUP\",\"version\":\"1.0\",\"customizationUuid\":\"0fde4286-ee4c-439d-9556-74b6be6bbc42\",\"inputs\":{},\"commands\":{},\"properties\":{\"network_assignments\":\"{is_external_network=false, ipv4_subnet_default_assignment={min_subnets_count=1}, ecomp_generated_network_assignment=false, ipv6_subnet_default_assignment={min_subnets_count=1}}\",\"network_flows\":\"{is_network_policy=false, is_bound_to_vpn=false}\",\"network_scope\":\"GLOBAL\",\"network_ecomp_naming\":\"{ecomp_generated_naming=true}\",\"network_type\":\"MULTI_PROVIDER_PORT_GROUP\",\"network_technology\":\"MULTI_GROUP\",\"network_homing\":\"{ecomp_selected_instance_node_target=false}\"},\"type\":\"VL\",\"modelCustomizationName\":\"MULTI_PROVIDER_PORT_GROUP 0\"}},\"collectionResource\":{},\"configurations\":{},\"serviceProxies\":{},\"vfModules\":{},\"volumeGroups\":{},\"pnfs\":{}}";
+
+ private static final String BOTH_INSTANTIATION_TYPE_FILE_PATH = "csar15782222_instantiationTypeBoth_invariantUUIDAlacarte.zip";
+
+
+ private static final String MIN_MAX_INITIAL_UUID = "43f13072-fe50-496b-b673-7af075d10143";
+ private static final String MIN_MAX_INITIAL_INVARIANT_UUID = "35fb95d8-d1f0-4e46-99ac-e01b423e8e3f";
+ private static final String MIN_MAX_INITIAL_FILE_PATH = "min_max_initial_vfModule_csar_v4.0.zip";
+ private static final String MIN_MAX_INITIAL_EXPECTED_RESPONSE = "{\"service\":{\"uuid\":\"43f13072-fe50-496b-b673-7af075d10143\",\"invariantUuid\":\"35fb95d8-d1f0-4e46-99ac-e01b423e8e3f\",\"name\":\"ADIOD vMX VPE BV Service 488 test\",\"version\":\"1.0\",\"toscaModelURL\":null,\"category\":\"Network L1-3\",\"serviceType\":\"\",\"serviceRole\":\"\",\"description\":\"Model Creation for PID 291247b . OAM Network Service Name : ADIOD vPE Tenant OAM Network 1 SRIOV Network Service Name : vPE ADIOD Provider Net 1\",\"serviceEcompNaming\":\"true\",\"instantiationType\":\"ClientConfig\",\"inputs\":{\"2017488adiodvpe20_ASN\":{\"type\":\"string\",\"description\":\"AV/PE\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"AV_vPE\"},\"2017488adiodvpe20_bandwidth\":{\"type\":\"string\",\"description\":\"Requested VPE bandwidth\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"10\"},\"2017488adiodvpe20_bandwidth_units\":{\"type\":\"string\",\"description\":\"Units of bandwidth\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"Gbps\"},\"2017488adiodvpe20_AIC_CLLI\":{\"type\":\"string\",\"description\":\"AIC Site CLLI\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"ATLMY8GA\"},\"2017488adiodvpe20_vnf_config_template_version\":{\"type\":\"string\",\"description\":\"VPE Software Version\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"17.2\"},\"2017488adiodvpe20_vnf_instance_name\":{\"type\":\"string\",\"description\":\"The hostname assigned to the vpe.\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"mtnj309me6\"}}},\"vnfs\":{\"2017 488 ADIOD vPE 2 0\":{\"uuid\":\"079266b1-fcf5-44ae-bc04-cc3215b28737\",\"invariantUuid\":\"e2dcd546-e647-4854-9ed9-e0a4d6880636\",\"description\":\"Name ADIOD vPE Description The Provider edge function for the ADIOD service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release code 17.2 Owners Mary Fragale Updated 9-25-17 for version 8.0 of the VLM \",\"name\":\"2017 488 ADIOD vPE 2\",\"version\":\"4.0\",\"customizationUuid\":\"2b4e9125-b607-49a3-81c7-9260f8ca32f4\",\"inputs\":{\"vnf_config_template_version\":{\"type\":\"string\",\"description\":\"VPE Software Version\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"17.2\"},\"bandwidth_units\":{\"type\":\"string\",\"description\":\"Units of bandwidth\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"Gbps\"},\"bandwidth\":{\"type\":\"string\",\"description\":\"Requested VPE bandwidth\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"10\"},\"AIC_CLLI\":{\"type\":\"string\",\"description\":\"AIC Site CLLI\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"ATLMY8GA\"},\"ASN\":{\"type\":\"string\",\"description\":\"AV/PE\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"AV_vPE\"},\"vnf_instance_name\":{\"type\":\"string\",\"description\":\"The hostname assigned to the vpe.\",\"entry_schema\":null,\"inputProperties\":null,\"constraints\":[],\"required\":true,\"default\":\"mtnj309me6\"}},\"commands\":{\"vnf_config_template_version\":{\"displayName\":\"vnf_config_template_version\",\"command\":\"get_input\",\"inputName\":\"2017488adiodvpe20_vnf_config_template_version\"},\"bandwidth_units\":{\"displayName\":\"bandwidth_units\",\"command\":\"get_input\",\"inputName\":\"2017488adiodvpe20_bandwidth_units\"},\"bandwidth\":{\"displayName\":\"bandwidth\",\"command\":\"get_input\",\"inputName\":\"2017488adiodvpe20_bandwidth\"},\"AIC_CLLI\":{\"displayName\":\"AIC_CLLI\",\"command\":\"get_input\",\"inputName\":\"2017488adiodvpe20_AIC_CLLI\"},\"ASN\":{\"displayName\":\"ASN\",\"command\":\"get_input\",\"inputName\":\"2017488adiodvpe20_ASN\"},\"vnf_instance_name\":{\"displayName\":\"vnf_instance_name\",\"command\":\"get_input\",\"inputName\":\"2017488adiodvpe20_vnf_instance_name\"}},\"properties\":{\"vmxvre_retype\":\"RE-VMX\",\"vnf_config_template_version\":\"get_input:2017488adiodvpe20_vnf_config_template_version\",\"sriov44_net_id\":\"48d399b3-11ee-48a8-94d2-f0ea94d6be8d\",\"int_ctl_net_id\":\"2f323477-6936-4d01-ac53-d849430281d9\",\"vmxvpfe_sriov41_0_port_mac\":\"00:11:22:EF:AC:DF\",\"int_ctl_net_name\":\"VMX-INTXI\",\"vmx_int_ctl_prefix\":\"128.0.0.0\",\"sriov43_net_id\":\"da349ca1-6de9-4548-be88-2d88e99bfef5\",\"sriov42_net_id\":\"760669ba-013d-4d9b-b0e7-4151fe2e6279\",\"sriov41_net_id\":\"25ad52d5-c165-40f8-b3b0-ddfc2373280a\",\"nf_type\":\"vPE\",\"vmxvpfe_int_ctl_ip_1\":\"128.0.0.16\",\"is_AVPN_service\":\"false\",\"vmx_RSG_name\":\"vREXI-affinity\",\"vmx_int_ctl_forwarding\":\"l2\",\"vmxvre_oam_ip_0\":\"10.40.123.5\",\"vmxvpfe_sriov44_0_port_mac\":\"00:11:22:EF:AC:DF\",\"vmxvpfe_sriov41_0_port_vlanstrip\":\"false\",\"vmxvpfe_sriov42_0_port_vlanfilter\":\"4001\",\"vmxvpfe_sriov44_0_port_unknownunicastallow\":\"true\",\"vmxvre_image_name_0\":\"VRE-ENGINE_17.2-S2.1.qcow2\",\"vmxvre_instance\":\"0\",\"vmxvpfe_sriov43_0_port_mac\":\"00:11:22:EF:AC:DF\",\"vmxvre_flavor_name\":\"ns.c1r16d32.v5\",\"vmxvpfe_volume_size_0\":\"40.0\",\"vmxvpfe_sriov43_0_port_vlanfilter\":\"4001\",\"nf_naming\":\"{ecomp_generated_naming=true}\",\"multi_stage_design\":\"false\",\"nf_naming_code\":\"tvpr\",\"vmxvre_name_0\":\"vREXI\",\"vmxvpfe_sriov42_0_port_vlanstrip\":\"false\",\"vmxvpfe_volume_name_0\":\"vPFEXI_FBVolume\",\"vmx_RSG_id\":\"bd89a33c-13c3-4a04-8fde-1a57eb123141\",\"vmxvpfe_image_name_0\":\"VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2\",\"vmxvpfe_sriov43_0_port_unknownunicastallow\":\"true\",\"vmxvpfe_sriov44_0_port_unknownmulticastallow\":\"true\",\"vmxvre_console\":\"vidconsole\",\"vmxvpfe_sriov44_0_port_vlanfilter\":\"4001\",\"vmxvpfe_sriov42_0_port_mac\":\"00:11:22:EF:AC:DF\",\"vmxvpfe_volume_id_0\":\"47cede15-da2f-4397-a101-aa683220aff3\",\"vmxvpfe_sriov42_0_port_unknownmulticastallow\":\"true\",\"vmxvpfe_sriov44_0_port_vlanstrip\":\"false\",\"vf_module_id\":\"123\",\"nf_function\":\"Firewall\",\"vmxvpfe_sriov43_0_port_unknownmulticastallow\":\"true\",\"vmxvre_int_ctl_ip_0\":\"128.0.0.1\",\"ecomp_generated_naming\":\"true\",\"AIC_CLLI\":\"get_input:2017488adiodvpe20_AIC_CLLI\",\"vnf_name\":\"mtnj309me6vre\",\"vmxvpfe_sriov41_0_port_unknownunicastallow\":\"true\",\"vmxvre_volume_type_1\":\"HITACHI\",\"vmxvpfe_sriov44_0_port_broadcastallow\":\"true\",\"vmxvre_volume_type_0\":\"HITACHI\",\"vmxvpfe_volume_type_0\":\"HITACHI\",\"vmxvpfe_sriov43_0_port_broadcastallow\":\"true\",\"bandwidth_units\":\"get_input:2017488adiodvpe20_bandwidth_units\",\"vnf_id\":\"123\",\"vmxvre_oam_prefix\":\"24\",\"availability_zone_0\":\"mtpocfo-kvm-az01\",\"ASN\":\"get_input:2017488adiodvpe20_ASN\",\"vmxvre_chassis_i2cid\":\"161\",\"vmxvpfe_name_0\":\"vPFEXI\",\"bandwidth\":\"get_input:2017488adiodvpe20_bandwidth\",\"availability_zone_max_count\":\"1\",\"vmxvre_volume_size_0\":\"45.0\",\"vmxvre_volume_size_1\":\"50.0\",\"vmxvpfe_sriov42_0_port_broadcastallow\":\"true\",\"vmxvre_oam_gateway\":\"10.40.123.1\",\"vmxvre_volume_name_1\":\"vREXI_FAVolume\",\"vmxvre_ore_present\":\"0\",\"vmxvre_volume_name_0\":\"vREXI_FBVolume\",\"vmxvre_type\":\"0\",\"vnf_instance_name\":\"get_input:2017488adiodvpe20_vnf_instance_name\",\"vmxvpfe_sriov41_0_port_unknownmulticastallow\":\"true\",\"oam_net_id\":\"b95eeb1d-d55d-4827-abb4-8ebb94941429\",\"vmx_int_ctl_len\":\"24\",\"vmxvpfe_sriov43_0_port_vlanstrip\":\"false\",\"vmxvpfe_sriov41_0_port_broadcastallow\":\"true\",\"vmxvre_volume_id_1\":\"6e86797e-03cd-4fdc-ba72-2957119c746d\",\"vmxvpfe_sriov41_0_port_vlanfilter\":\"4001\",\"nf_role\":\"MIS\",\"vmxvre_volume_id_0\":\"f4eacb79-f687-4e9d-b760-21847c8bb15a\",\"vmxvpfe_sriov42_0_port_unknownunicastallow\":\"true\",\"vmxvpfe_flavor_name\":\"ns.c20r16d25.v5\"},\"type\":\"VF\",\"modelCustomizationName\":\"2017 488 ADIOD vPE 2 0\",\"vfModules\":{\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\":{\"uuid\":\"13bea14d-9405-43c6-920b-97bab64b6a01\",\"invariantUuid\":\"83dc51de-a337-498e-9fee-763603a057b4\",\"customizationUuid\":\"a90865d5-6de0-4ef8-bf53-d45fa3edddfc\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"properties\":{\"minCountInstances\":null,\"maxCountInstances\":null,\"initialCount\":null,\"vfModuleLabel\":\"ADIOD_vPFE_BV\"},\"inputs\":{},\"volumeGroupAllowed\":true},\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vRE_BV..module-1\":{\"uuid\":\"3f6d5e51-a9a0-4c53-bb6d-be836767d96f\",\"invariantUuid\":\"54466b6d-e33c-4f4d-87e2-32bc5b103589\",\"customizationUuid\":\"dba1d1ff-77e2-4f4d-b1b4-1bed564f13b1\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":\"ADIOD_vRE_BV\"},\"inputs\":{},\"volumeGroupAllowed\":true},\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_base_vPE_BV..module-0\":{\"uuid\":\"0a45a870-3a19-4238-a72a-eadfc583d4fe\",\"invariantUuid\":\"c636b302-fba2-4ed7-9f3b-c99715b6bb2e\",\"customizationUuid\":\"a0b634e6-514e-4977-91dd-3b8c295e6bc8\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_base_vPE_BV..module-0\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_base_vPE_BV..module-0\",\"properties\":{\"minCountInstances\":1,\"maxCountInstances\":1,\"initialCount\":1,\"vfModuleLabel\":\"ADIOD_base_vPE_BV\"},\"inputs\":{},\"volumeGroupAllowed\":false}},\"volumeGroups\":{\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\":{\"uuid\":\"13bea14d-9405-43c6-920b-97bab64b6a01\",\"invariantUuid\":\"83dc51de-a337-498e-9fee-763603a057b4\",\"customizationUuid\":\"a90865d5-6de0-4ef8-bf53-d45fa3edddfc\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"properties\":{\"minCountInstances\":null,\"maxCountInstances\":null,\"initialCount\":null,\"vfModuleLabel\":\"ADIOD_vPFE_BV\"},\"inputs\":{}},\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vRE_BV..module-1\":{\"uuid\":\"3f6d5e51-a9a0-4c53-bb6d-be836767d96f\",\"invariantUuid\":\"54466b6d-e33c-4f4d-87e2-32bc5b103589\",\"customizationUuid\":\"dba1d1ff-77e2-4f4d-b1b4-1bed564f13b1\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":\"ADIOD_vRE_BV\"},\"inputs\":{}}},\"vfcInstanceGroups\":{}}},\"networks\":{},\"collectionResource\":{},\"configurations\":{},\"serviceProxies\":{},\"vfModules\":{\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\":{\"uuid\":\"13bea14d-9405-43c6-920b-97bab64b6a01\",\"invariantUuid\":\"83dc51de-a337-498e-9fee-763603a057b4\",\"customizationUuid\":\"a90865d5-6de0-4ef8-bf53-d45fa3edddfc\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"properties\":{\"minCountInstances\":null,\"maxCountInstances\":null,\"initialCount\":null,\"vfModuleLabel\":\"ADIOD_vPFE_BV\"},\"inputs\":{},\"volumeGroupAllowed\":true},\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_base_vPE_BV..module-0\":{\"uuid\":\"0a45a870-3a19-4238-a72a-eadfc583d4fe\",\"invariantUuid\":\"c636b302-fba2-4ed7-9f3b-c99715b6bb2e\",\"customizationUuid\":\"a0b634e6-514e-4977-91dd-3b8c295e6bc8\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_base_vPE_BV..module-0\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_base_vPE_BV..module-0\",\"properties\":{\"minCountInstances\":1,\"maxCountInstances\":1,\"initialCount\":1,\"vfModuleLabel\":\"ADIOD_base_vPE_BV\"},\"inputs\":{},\"volumeGroupAllowed\":false},\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vRE_BV..module-1\":{\"uuid\":\"3f6d5e51-a9a0-4c53-bb6d-be836767d96f\",\"invariantUuid\":\"54466b6d-e33c-4f4d-87e2-32bc5b103589\",\"customizationUuid\":\"dba1d1ff-77e2-4f4d-b1b4-1bed564f13b1\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":\"ADIOD_vRE_BV\"},\"inputs\":{},\"volumeGroupAllowed\":true}},\"volumeGroups\":{\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\":{\"uuid\":\"13bea14d-9405-43c6-920b-97bab64b6a01\",\"invariantUuid\":\"83dc51de-a337-498e-9fee-763603a057b4\",\"customizationUuid\":\"a90865d5-6de0-4ef8-bf53-d45fa3edddfc\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vPFE_BV..module-2\",\"properties\":{\"minCountInstances\":null,\"maxCountInstances\":null,\"initialCount\":null,\"vfModuleLabel\":\"ADIOD_vPFE_BV\"},\"inputs\":{}},\"2017488adiodvpe20..2017488AdiodVpe2..ADIOD_vRE_BV..module-1\":{\"uuid\":\"3f6d5e51-a9a0-4c53-bb6d-be836767d96f\",\"invariantUuid\":\"54466b6d-e33c-4f4d-87e2-32bc5b103589\",\"customizationUuid\":\"dba1d1ff-77e2-4f4d-b1b4-1bed564f13b1\",\"description\":null,\"name\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"2017488AdiodVpe2..ADIOD_vRE_BV..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":\"ADIOD_vRE_BV\"},\"inputs\":{}}},\"pnfs\":{}}";
+
+
+ private static final String MIN_MAX_INITIAL_UUID_OLD_CSAR = "245562de-3984-49ef-a708-6c9d7cfcabd1";
+ private static final String MIN_MAX_INITIAL_INVARIANT_UUID_OLD_CSAR = "24216d6-71d0-41c8-ac81-0c5acfee514a";
+ private static final String MIN_MAX_INITIAL_FILE_PATH_OLD_CSAR = "service-VmmeRvpmsFeAic3011217Svc-csar.csar.zip";
+ private static final String MIN_MAX_INITIAL_EXPECTED_RESPONSE_OLD_CSAR = "{\"service\":{\"uuid\":\"281b5f7d-c7ac-4ea9-92fb-2c1d625ca681\",\"invariantUuid\":\"a977af77-db15-4375-a637-e9b994ecd569\",\"name\":\"vMME_rVPMS_FE AIC3.0-11.2.1.7_SVC\",\"version\":\"1.0\",\"toscaModelURL\":null,\"category\":\"Mobility\",\"serviceType\":null,\"serviceRole\":null,\"description\":\"New service for vMME vProbe Front End AIC3.0 VPMS Radcom 11.2.1.7. Front End includes Qrouter, vProbe aff, vLB Agent aff and vLB.\",\"serviceEcompNaming\":\"true\",\"instantiationType\":null,\"inputs\":{}},\"vnfs\":{\"vMMEvProbe_FE_AIC3-11.2.1_VF 1\":{\"uuid\":\"245562de-3984-49ef-a708-6c9d7cfcabd1\",\"invariantUuid\":\"124216d6-71d0-41c8-ac81-0c5acfee514a\",\"description\":\" New service for vMME vProbe Front End AIC3.0 VPMS Radcom 11.2.1.7. Front End includes Qrouter, vProbe aff, vLB Agent aff and vLB. \",\"name\":\"vMMEvProbe_FE_AIC3-11.2.1_VF\",\"version\":\"1.0\",\"customizationUuid\":\"8293273d-0e76-4661-926f-06a01ad2e683\",\"inputs\":{},\"commands\":{},\"properties\":{},\"type\":null,\"modelCustomizationName\":\"vMMEvProbe_FE_AIC3-11.2.1_VF 1\",\"vfModules\":{\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\":{\"uuid\":\"e67e5b39-1f3b-4692-beec-eda94a0375a5\",\"invariantUuid\":\"21c1b57d-a618-4397-a7f4-9c37169ea09b\",\"customizationUuid\":\"a7d59494-3710-4b05-b4cd-e45dadbdc7ac\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Base_Module..module-0\":{\"uuid\":\"59bb7d14-278f-4ff5-bd5a-1a720c8b0d19\",\"invariantUuid\":\"9b5589c2-e4d1-4456-a23b-e0001c349155\",\"customizationUuid\":\"b9d6f6e8-e24a-4ad9-b863-1c3f6757bfe7\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Base_Module..module-0\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Base_Module..module-0\",\"properties\":{\"minCountInstances\":1,\"maxCountInstances\":1,\"initialCount\":1,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":false},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\":{\"uuid\":\"530e5e9f-2e82-4946-bf59-630f4d7ef4de\",\"invariantUuid\":\"d1fb14d9-0fa8-4ead-b5cc-be311c7a95bd\",\"customizationUuid\":\"c1f95365-716c-4f6c-9477-a8f760a2edce\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\":{\"uuid\":\"064385f9-795b-4fcb-9e3b-51d7d0ccad80\",\"invariantUuid\":\"603e8f71-88ad-4bbf-9992-2e9a72a91e29\",\"customizationUuid\":\"3b5efcd3-d14d-4b0e-91cf-937db5aa65b5\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\":{\"uuid\":\"85b712e0-af62-4255-aeb6-ec9ae0f4eb13\",\"invariantUuid\":\"cba59330-855a-460b-8856-f6bff0dac6c2\",\"customizationUuid\":\"962479d7-b5b7-4129-bf9f-bfe4775e7921\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true}},\"volumeGroups\":{\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\":{\"uuid\":\"e67e5b39-1f3b-4692-beec-eda94a0375a5\",\"invariantUuid\":\"21c1b57d-a618-4397-a7f4-9c37169ea09b\",\"customizationUuid\":\"a7d59494-3710-4b05-b4cd-e45dadbdc7ac\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\":{\"uuid\":\"530e5e9f-2e82-4946-bf59-630f4d7ef4de\",\"invariantUuid\":\"d1fb14d9-0fa8-4ead-b5cc-be311c7a95bd\",\"customizationUuid\":\"c1f95365-716c-4f6c-9477-a8f760a2edce\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\":{\"uuid\":\"064385f9-795b-4fcb-9e3b-51d7d0ccad80\",\"invariantUuid\":\"603e8f71-88ad-4bbf-9992-2e9a72a91e29\",\"customizationUuid\":\"3b5efcd3-d14d-4b0e-91cf-937db5aa65b5\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\":{\"uuid\":\"85b712e0-af62-4255-aeb6-ec9ae0f4eb13\",\"invariantUuid\":\"cba59330-855a-460b-8856-f6bff0dac6c2\",\"customizationUuid\":\"962479d7-b5b7-4129-bf9f-bfe4775e7921\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null}},\"vfcInstanceGroups\":{}}},\"networks\":{},\"collectionResource\":null,\"configurations\":null,\"serviceProxies\":null,\"vfModules\":{\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\":{\"uuid\":\"e67e5b39-1f3b-4692-beec-eda94a0375a5\",\"invariantUuid\":\"21c1b57d-a618-4397-a7f4-9c37169ea09b\",\"customizationUuid\":\"a7d59494-3710-4b05-b4cd-e45dadbdc7ac\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Base_Module..module-0\":{\"uuid\":\"59bb7d14-278f-4ff5-bd5a-1a720c8b0d19\",\"invariantUuid\":\"9b5589c2-e4d1-4456-a23b-e0001c349155\",\"customizationUuid\":\"b9d6f6e8-e24a-4ad9-b863-1c3f6757bfe7\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Base_Module..module-0\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Base_Module..module-0\",\"properties\":{\"minCountInstances\":1,\"maxCountInstances\":1,\"initialCount\":1,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":false},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\":{\"uuid\":\"530e5e9f-2e82-4946-bf59-630f4d7ef4de\",\"invariantUuid\":\"d1fb14d9-0fa8-4ead-b5cc-be311c7a95bd\",\"customizationUuid\":\"c1f95365-716c-4f6c-9477-a8f760a2edce\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\":{\"uuid\":\"064385f9-795b-4fcb-9e3b-51d7d0ccad80\",\"invariantUuid\":\"603e8f71-88ad-4bbf-9992-2e9a72a91e29\",\"customizationUuid\":\"3b5efcd3-d14d-4b0e-91cf-937db5aa65b5\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\":{\"uuid\":\"85b712e0-af62-4255-aeb6-ec9ae0f4eb13\",\"invariantUuid\":\"cba59330-855a-460b-8856-f6bff0dac6c2\",\"customizationUuid\":\"962479d7-b5b7-4129-bf9f-bfe4775e7921\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null,\"volumeGroupAllowed\":true}},\"volumeGroups\":{\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\":{\"uuid\":\"e67e5b39-1f3b-4692-beec-eda94a0375a5\",\"invariantUuid\":\"21c1b57d-a618-4397-a7f4-9c37169ea09b\",\"customizationUuid\":\"a7d59494-3710-4b05-b4cd-e45dadbdc7ac\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vprobe_eph..module-1\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\":{\"uuid\":\"530e5e9f-2e82-4946-bf59-630f4d7ef4de\",\"invariantUuid\":\"d1fb14d9-0fa8-4ead-b5cc-be311c7a95bd\",\"customizationUuid\":\"c1f95365-716c-4f6c-9477-a8f760a2edce\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlbagent_aff..module-2\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\":{\"uuid\":\"064385f9-795b-4fcb-9e3b-51d7d0ccad80\",\"invariantUuid\":\"603e8f71-88ad-4bbf-9992-2e9a72a91e29\",\"customizationUuid\":\"3b5efcd3-d14d-4b0e-91cf-937db5aa65b5\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_qrouter..module-4\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null},\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\":{\"uuid\":\"85b712e0-af62-4255-aeb6-ec9ae0f4eb13\",\"invariantUuid\":\"cba59330-855a-460b-8856-f6bff0dac6c2\",\"customizationUuid\":\"962479d7-b5b7-4129-bf9f-bfe4775e7921\",\"description\":null,\"name\":\"VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"version\":\"1\",\"modelCustomizationName\":\"vmmevprobe_fe_aic31121_vf1..VmmevprobeFeAic31121Vf..FE_Add_On_Module_vlb..module-3\",\"properties\":{\"minCountInstances\":0,\"maxCountInstances\":null,\"initialCount\":0,\"vfModuleLabel\":null},\"inputs\":null}},\"pnfs\":null}";
+
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+ @BeforeMethod
+ public void invalidateTheCache(){
+ if(Features.FLAG_SERVICE_MODEL_CACHE.isActive()) {
+ restTemplate.postForObject(uri + "/rest/models/reset", "", Object.class);
+ }
+ }
+
+ @Test
+ public void getServiceModelALaCarteInstantiation() throws IOException, URISyntaxException {
+ registerToSimulatorWithPresets(A_LA_CARTE_INSTANTIATION_TYPE_UUID, A_LA_CARTE_INSTANTIATION_TYPE_INVARIANT_UUID, A_LA_CARTE_INSTANTIATION_TYPE_FILE_PATH);
+ ResponseEntity<String> response = restTemplate.getForEntity(buildUri(SDC_GET_SERVICE_MODEL + A_LA_CARTE_INSTANTIATION_TYPE_UUID), String.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ assertThat("The response is in the format of JSON", response.getBody(), either(is(A_LA_CARTE_INSTANTIATION_TYPE_EXPECTED_RESPONSE)).or(jsonStringEquals(A_LA_CARTE_INSTANTIATION_TYPE_EXPECTED_RESPONSE)));
+ }
+
+
+ @Test
+ public void getServiceModelMacroInstantiation() throws IOException, URISyntaxException {
+ registerToSimulatorWithPresets(MACRO_INSTANTIATION_TYPE_UUID, MACRO_INSTANTIATION_TYPE_INVARIANT_UUID, MACRO_INSTANTIATION_TYPE_FILE_PATH);
+ ResponseEntity<String> response = restTemplate.getForEntity(buildUri(SDC_GET_SERVICE_MODEL + MACRO_INSTANTIATION_TYPE_UUID), String.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ assertThat("The response is in the format of JSON", response.getBody(), either(is(MACRO_INSTANTIATION_TYPE_EXPECTED_RESPONSE)).or(jsonStringEquals(MACRO_INSTANTIATION_TYPE_EXPECTED_RESPONSE)));
+ }
+
+
+ @Test
+ public void getServiceModelWithoutInstantiationType(){
+ registerToSimulatorWithPresets(MACRO_INSTANTIATION_TYPE_UUID, MACRO_INSTANTIATION_TYPE_INVARIANT_UUID, EMPTY_INSTANTIATION_TYPE_FILE_PATH);
+ ResponseEntity<String> response = restTemplate.getForEntity(buildUri(SDC_GET_SERVICE_MODEL + MACRO_INSTANTIATION_TYPE_UUID), String.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ assertThat("The response is in the format of JSON", response.getBody(), either(is(EMPTY_INSTANTIATION_TYPE_EXPECTED_RESPONSE)).or(jsonStringEquals(EMPTY_INSTANTIATION_TYPE_EXPECTED_RESPONSE)));
+
+ }
+
+ @Test
+ public void getServiceModelBothInstantiationType(){
+ registerToSimulatorWithPresets(MACRO_INSTANTIATION_TYPE_UUID, MACRO_INSTANTIATION_TYPE_INVARIANT_UUID, BOTH_INSTANTIATION_TYPE_FILE_PATH);
+ ResponseEntity<String> response = restTemplate.getForEntity(buildUri(SDC_GET_SERVICE_MODEL + MACRO_INSTANTIATION_TYPE_UUID), String.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ assertThat("The response is in the format of JSON", response.getBody(), either(is(MACRO_INSTANTIATION_TYPE_EXPECTED_RESPONSE)).or(jsonStringEquals(MACRO_INSTANTIATION_TYPE_EXPECTED_RESPONSE)));
+ }
+
+ @Test
+ public void getServiceModelWithGroupsAndCheckMinMaxInitialParams(){
+ registerToSimulatorWithPresets(MIN_MAX_INITIAL_UUID, MIN_MAX_INITIAL_INVARIANT_UUID, MIN_MAX_INITIAL_FILE_PATH);
+ ResponseEntity<String> response = restTemplate.getForEntity(buildUri(SDC_GET_SERVICE_MODEL + MIN_MAX_INITIAL_UUID), String.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ assertThat("The response is in the format of JSON", response.getBody(), either(is(MIN_MAX_INITIAL_EXPECTED_RESPONSE)).or(jsonStringEquals(MIN_MAX_INITIAL_EXPECTED_RESPONSE)));
+ }
+
+ @Test
+ public void getServiceModelWithGroupsAndCheckMinMaxInitialParamsOldCsar(){
+ registerToSimulatorWithPresets(MIN_MAX_INITIAL_UUID_OLD_CSAR, MIN_MAX_INITIAL_INVARIANT_UUID_OLD_CSAR, MIN_MAX_INITIAL_FILE_PATH_OLD_CSAR);
+ ResponseEntity<String> response = restTemplate.getForEntity(buildUri(SDC_GET_SERVICE_MODEL + MIN_MAX_INITIAL_UUID_OLD_CSAR), String.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ assertThat("The response is in the format of JSON", response.getBody(), either(is(MIN_MAX_INITIAL_EXPECTED_RESPONSE_OLD_CSAR)).or(jsonStringEquals(MIN_MAX_INITIAL_EXPECTED_RESPONSE_OLD_CSAR)));
+ }
+
+ private void registerToSimulatorWithPresets(String uuid, String invariantUuid, String pathPath){
+ ImmutableList<BasePreset> presets = ImmutableList.of(
+ new PresetSDCGetServiceToscaModelGet(uuid, pathPath),
+ new PresetSDCGetServiceMetadataGet(uuid,invariantUuid, pathPath));
+ registerExpectationFromPresets(presets, CLEAR_THEN_SET);
+ }
+
+ @Test
+ public void withModelFromE2eWithToscaParserButNewFlow_requestModels_expectVnfRelatedVfModulesNotNull() {
+
+ /*
+ We had a problem that this exact model vnfs returned with no vfModules and
+ volumeGroups, because a 'isNewFlow' value in org.onap.vid.asdc.parser.ToscaParserImpl
+ was always false because a coding error.
+ */
+ registerExpectation("get_sdc_catalog_services_VmmeRvpmsFeAic3011217Svc.json", CLEAR_THEN_SET);
+ registerExpectation("aai_get_full_subscribers.json", APPEND);
+
+ final JsonNode response = restTemplate.getForObject(uri + "/rest/models/services/" + "245562de-3984-49ef-a708-6c9d7cfcabd1", JsonNode.class);
+
+ // using json-pointers instead of path, because vnf name has
+ // dots and spaces
+ final String myVnf = "vMMEvProbe_FE_AIC3-11.2.1_VF 1";
+ final String base = "/vnfs/" + myVnf;
+
+ assertFalse(response.at(base).isMissingNode(),
+ "test relies on '" + myVnf + "' to be in model; got: " + response);
+
+ assertThat("vfModules under '" + myVnf + "' must not be empty; got: " + response,
+ response.at(base + "/vfModules").size(), is(not(0)));
+
+ assertThat("volumeGroups under '" + myVnf + "' must not be empty; got: " + response,
+ response.at(base + "/volumeGroups").size(), is(not(0)));
+
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/ServiceInstanceMsoApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/ServiceInstanceMsoApiTest.java
new file mode 100644
index 000000000..ce290c89f
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/ServiceInstanceMsoApiTest.java
@@ -0,0 +1,121 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.text.StringEscapeUtils;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.testng.annotations.Test;
+import vid.automation.test.infra.FeatureTogglingTest;
+import vid.automation.test.infra.Features;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+public class ServiceInstanceMsoApiTest extends BaseMsoApiTest{
+
+ //Urls
+ private static final String MSO_ACTIVATE_SERVICE_INSTANCE = "mso/mso_activate_service_instance/f36f5734-e9df-4fbf-9f35-61be13f028a1";
+ public static final String MSO_DEACTIVATE_SERVICE_INSTANCE = "mso/mso_deactivate_service_instance/f36f5734-e9df-4fbf-9f35-61be13f028a1";
+ public static final String MSO_DELETE_SERVICE_INSTANCE = "mso/mso_delete_svc_instance/f36f5734-e9df-4fbf-9f35-61be13f028a1?serviceStatus=active";
+ public static final String MSO_UNASSIGN_SERVICE_INSTANCE = "mso/mso_delete_svc_instance/f36f5734-e9df-4fbf-9f35-61be13f028a1?serviceStatus=created";
+
+ //Request Details
+ private static final String ACTIVATE_SERVICE_REQUEST_DETAILS = "registration_to_simulator/body_jsons/mso_request_activate_service_instance.json";
+ private static final String DEACTIVATE_SERVICE_REQUEST_DETAILS = "registration_to_simulator/body_jsons/mso_request_deactivate_service_instance.json";
+ private static final String DELETE_AND_UNASSIGN_SERVICE_REQUEST_DETAILS = "registration_to_simulator/body_jsons/mso_request_delete_or_unassign_service_instance.json";
+
+ //Jsons
+ private static final String ACTIVATE_OK_JSON = "activate_service_instance.json";
+ private static final String ACTIVATE_FAILED_JSON = "activate_service_instance_error.json";
+ public static final String DEACTIVATE_OK_JSON = "deactivate_service_instance.json";
+ private static final String DEACTIVATE_FAILED_JSON = "deactivate_service_instance_error.json";
+ private static final String UNASSIGN_OK_JSON = "unassign_service_instance.json";
+ private static final String DELETE_SERVICE_REQUEST_DETAILS = "delete_service_instance1802.json";
+ private static final String DELETE_OR_UNASSIGN_FAILED_JSON = "delete_or_unassign_service_instance_error.json";
+
+ //Expected Responses
+ private static final String EXPECTED_SUCCESS_MSO_RESPONSE = "{\"requestReferences\": {\"instanceId\": \"f36f5734-e9df-4fbf-9f35-61be13f028a1\", \"requestId\": \"b6dc9806-b094-42f7-9386-a48de8218ce8\"}}";
+ private static final String EXPECTED_ERROR_MSO_RESPONSE = "{\"error\":\"222\",\"message\":\"error message\"}";
+
+ @Test
+ public void testActivateServiceInstanceSucceed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, ACTIVATE_SERVICE_REQUEST_DETAILS);
+ callMsoWithFineRequest(ACTIVATE_OK_JSON, ImmutableMap.of(), buildUri(MSO_ACTIVATE_SERVICE_INSTANCE), requestBody,
+ HttpStatus.ACCEPTED.value(), EXPECTED_SUCCESS_MSO_RESPONSE, HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void testActivateServiceInstanceFailed(int errorCode) throws IOException, URISyntaxException {
+ String requestBody = TestUtils.convertRequest(objectMapper, ACTIVATE_SERVICE_REQUEST_DETAILS);
+ callMsoWithSimulatedErrorResponse(ACTIVATE_FAILED_JSON,
+ ImmutableMap.of("500", Integer.toString(errorCode),"\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(EXPECTED_ERROR_MSO_RESPONSE)),
+ buildUri(MSO_ACTIVATE_SERVICE_INSTANCE), requestBody, errorCode, EXPECTED_ERROR_MSO_RESPONSE, HttpMethod.POST);
+
+ }
+
+ @Test
+ @FeatureTogglingTest(Features.FLAG_UNASSIGN_SERVICE)
+ public void testUnassignServiceInstanceSucceed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, DELETE_AND_UNASSIGN_SERVICE_REQUEST_DETAILS);
+ callMsoWithFineRequest(UNASSIGN_OK_JSON, ImmutableMap.of(), buildUri(MSO_UNASSIGN_SERVICE_INSTANCE), requestBody,
+ HttpStatus.ACCEPTED.value(), EXPECTED_SUCCESS_MSO_RESPONSE, HttpMethod.POST);
+ }
+
+
+ @Test
+ @FeatureTogglingTest(Features.FLAG_UNASSIGN_SERVICE)
+ public void testDeleteServiceInstanceSucceed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, DELETE_AND_UNASSIGN_SERVICE_REQUEST_DETAILS);
+ callMsoWithFineRequest(UNASSIGN_OK_JSON, ImmutableMap.of(
+ "/unassign", "",
+ "POST", "DELETE"), buildUri(MSO_DELETE_SERVICE_INSTANCE), requestBody,
+ HttpStatus.ACCEPTED.value(), EXPECTED_SUCCESS_MSO_RESPONSE, HttpMethod.POST);
+ }
+
+ @Test
+ @FeatureTogglingTest(value = Features.FLAG_UNASSIGN_SERVICE, flagActive = false)
+ public void testUnassignServiceInstanceBecomesDelete() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, DELETE_AND_UNASSIGN_SERVICE_REQUEST_DETAILS);
+ callMsoWithFineRequest(DELETE_SERVICE_REQUEST_DETAILS, ImmutableMap.of(), buildUri(MSO_DELETE_SERVICE_INSTANCE), requestBody,
+ HttpStatus.ACCEPTED.value(), EXPECTED_SUCCESS_MSO_RESPONSE, HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ @FeatureTogglingTest(Features.FLAG_UNASSIGN_SERVICE)
+ public void testUnassignServiceInstanceFailed(int errorCode) throws IOException {
+ String requestBody = TestUtils.convertRequest(objectMapper, DELETE_AND_UNASSIGN_SERVICE_REQUEST_DETAILS);
+ callMsoWithSimulatedErrorResponse(DELETE_OR_UNASSIGN_FAILED_JSON,
+ ImmutableMap.of("500", Integer.toString(errorCode),"\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(EXPECTED_ERROR_MSO_RESPONSE)),
+ buildUri(MSO_UNASSIGN_SERVICE_INSTANCE), requestBody, errorCode, EXPECTED_ERROR_MSO_RESPONSE, HttpMethod.POST);
+
+ }
+
+ @Test(dataProvider = "errorCodes")
+ @FeatureTogglingTest(Features.FLAG_UNASSIGN_SERVICE)
+ public void testDeleteServiceInstanceFailed(int errorCode) throws IOException {
+ String requestBody = TestUtils.convertRequest(objectMapper, DELETE_AND_UNASSIGN_SERVICE_REQUEST_DETAILS);
+ callMsoWithSimulatedErrorResponse(DELETE_OR_UNASSIGN_FAILED_JSON,
+ ImmutableMap.of("/unassign", "",
+ "POST", "DELETE",
+ "500", Integer.toString(errorCode),
+ "\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(EXPECTED_ERROR_MSO_RESPONSE)),
+ buildUri(MSO_DELETE_SERVICE_INSTANCE), requestBody, errorCode, EXPECTED_ERROR_MSO_RESPONSE, HttpMethod.POST);
+
+ }
+
+ @Test
+ public void testDeactivateServiceInstanceSucceed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, DEACTIVATE_SERVICE_REQUEST_DETAILS);
+ callMsoWithFineRequest(DEACTIVATE_OK_JSON, ImmutableMap.of(), buildUri(MSO_DEACTIVATE_SERVICE_INSTANCE), requestBody,
+ HttpStatus.ACCEPTED.value(), EXPECTED_SUCCESS_MSO_RESPONSE, HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void testDeactivateServiceInstanceFailed(int errorCode) throws IOException, URISyntaxException {
+ String requestBody = TestUtils.convertRequest(objectMapper, DEACTIVATE_SERVICE_REQUEST_DETAILS);
+ callMsoWithSimulatedErrorResponse(DEACTIVATE_FAILED_JSON,
+ ImmutableMap.of("500", Integer.toString(errorCode),"\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(EXPECTED_ERROR_MSO_RESPONSE)),
+ buildUri(MSO_DEACTIVATE_SERVICE_INSTANCE), requestBody, errorCode, EXPECTED_ERROR_MSO_RESPONSE, HttpMethod.POST);
+
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/Streams.java b/vid-automation/src/test/java/org/onap/vid/api/Streams.java
new file mode 100644
index 000000000..b53187e09
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/Streams.java
@@ -0,0 +1,47 @@
+package org.onap.vid.api;
+
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+public class Streams {
+ public static <R> Predicate<R> not(Predicate<R> predicate) {
+ return predicate.negate();
+ }
+
+ public static <T> Stream<T> fromIterator(final Iterator<T> iterator) {
+ Iterable<T> iterable = () -> iterator;
+ return StreamSupport.<T>stream(iterable.spliterator(), false);
+ }
+
+
+ // https://stackoverflow.com/questions/20746429/limit-a-stream-by-a-predicate
+ private static <T> Spliterator<T> takeWhile(
+ Spliterator<T> splitr, Predicate<? super T> predicate) {
+ return new Spliterators.AbstractSpliterator<T>(splitr.estimateSize(), 0) {
+ boolean stillGoing = true;
+ @Override public boolean tryAdvance(Consumer<? super T> consumer) {
+ if (stillGoing) {
+ boolean hadNext = splitr.tryAdvance(elem -> {
+ if (predicate.test(elem)) {
+ consumer.accept(elem);
+ } else {
+ stillGoing = false;
+ }
+ });
+ return hadNext && stillGoing;
+ }
+ return false;
+ }
+ };
+ }
+
+ public static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<? super T> predicate) {
+ return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false);
+ }
+
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/TestUtils.java b/vid-automation/src/test/java/org/onap/vid/api/TestUtils.java
new file mode 100644
index 000000000..76c122c48
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/TestUtils.java
@@ -0,0 +1,81 @@
+package org.onap.vid.api;
+
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.http.HttpStatus;
+
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Scanner;
+
+/**
+ * Created by Oren on 6/7/17.
+ */
+public class TestUtils {
+
+ protected static ObjectMapper objectMapper = new ObjectMapper();
+
+ public static void assertStatusOK(Object request, WebTarget webTarget, Response response) throws IOException {
+ assertHttpStatus(request, webTarget, response, HttpStatus.OK);
+ }
+
+ public static void assertHttpStatus(Object request, WebTarget webTarget, Response response, HttpStatus exceptedHttpStatus) throws IOException {
+ objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
+
+ org.testng.Assert.assertEquals(response.getStatus(), exceptedHttpStatus.value(),
+ String.format("Failed post URI: %s with request %s. Got Status:%d and body: %s",
+ webTarget.getUri(),
+ objectMapper.writeValueAsString(request),
+ response.getStatus(),
+ objectMapper.writeValueAsString(response.getEntity())));
+ }
+
+ public static String convertRequest(ObjectMapper objectMapper, String msoRequestDetailsFileName) {
+
+ ClassLoader cl = pProbeMsoApiTest.class.getClassLoader();
+ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
+ Resource[] resources;
+ try {
+ resources = resolver.getResources(msoRequestDetailsFileName);
+ String content;
+ File file = resources[0].getFile();
+ content = new Scanner(file).useDelimiter("\\Z").next();
+ objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
+ return objectMapper.writeValueAsString(objectMapper.readValue(content, Object.class));
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getNestedPropertyInMap(Object item, String path) {
+ return getNestedPropertyInMap(item, path, String.class, "/");
+ }
+
+ public static <T> T getNestedPropertyInMap(Object item, String path, Class<T> valueType) {
+ return getNestedPropertyInMap(item, path, valueType, "/");
+ }
+
+ /*
+ Use this method to extract item from Map that represent Json hierarchy (Map<String,Map>)
+ */
+ public static <T> T getNestedPropertyInMap(Object item, String path, Class<T> valueType, String delimeter) {
+ String[] pathes = path.split(delimeter);
+ return valueType.cast(getNestedPropertyInMap(item,pathes,0));
+ }
+
+ private static Object getNestedPropertyInMap(Object item, String[] pathes, int index) {
+ if (index==pathes.length) {
+ return item;
+ }
+ return getNestedPropertyInMap(((Map<String,Object>)item).get(pathes[index]), pathes, ++index);
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/VidConfigurationApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/VidConfigurationApiTest.java
new file mode 100644
index 000000000..38ce8613d
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/VidConfigurationApiTest.java
@@ -0,0 +1,24 @@
+package org.onap.vid.api;
+
+import org.springframework.http.ResponseEntity;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+public class VidConfigurationApiTest extends BaseApiTest {
+
+ @BeforeClass
+ public void login() {
+ super.login();
+ }
+
+ @Test
+ public void whenGetUserTimezoneProperty_resultIsUTC() {
+ String url = uri.toASCIIString() + "/get_property/user.timezone/abc";
+ ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
+ assertThat(response.getBody(), equalTo("UTC"));
+ }
+
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/pProbeAaiApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/pProbeAaiApiTest.java
new file mode 100644
index 000000000..1765645af
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/pProbeAaiApiTest.java
@@ -0,0 +1,146 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.text.StringEscapeUtils;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy;
+import static vid.automation.test.services.SimulatorApi.registerExpectation;
+
+
+public class pProbeAaiApiTest extends BaseApiAaiTest {
+
+ private static final String GET_SERVICE_INSTANCE_NOT_FOUND_JSON = "get_service_instance_not_found.json";
+ private static final String GET_SERVICE_INSTANCE_JSON = "get_service_instance.json";
+ private static final String GET_LOGICAL_LINK_JSON = "get_logical_link.json";
+ private static final String GET_LOGICAL_LINK_NOT_FOUND_JSON = "get_logical_link_not_found.json";
+ private static final String [] GET_SPECIFIC_PNF_FINE_RESPONSE = {"aai_get_specific_pnf.json"};
+ private static final String [] GET_SPECIFIC_PNF_ERROR_RESPONSE = {"aai_get_specific_pnf_error.json"};
+ private static final String [] GET_PNF_BY_REGION_RESPONSE = {"aai_get_pnf_by_region.json"};
+ private static final String [] GET_PNF_BY_REGION_RESPONSE_EMPTY = {"aai_get_pnf_by_region_error.json"};
+
+ //Request
+ private static final String GET_PNF_BY_REGION_AAI_EXPECTED_RESPONSE = "registration_to_simulator/body_jsons/aai_response_get_pnf_by_region.json";
+
+
+ //URIs
+ private static final String GET_SERVICE_INSTANCE_PNFS = "aai_get_service_instance_pnfs/31739f3e-526b-11e6-beb8-9e71128cae77/AIM Transport/f36f5734-e9df-4fbf-9f35-61be13f028a1";
+ private static final String GET_SPECIFIC_PNF_URI = "aai_get_pnfs/pnf/DEAAI78";
+ private static final String GET_PNF_BY_REGION = "aai_get_pnf_instances/e433710f-9217-458d-a79d-1c7aff376d89/VIRTUAL USP/8a84e59b-45fe-4851-8ff1-34225a0b32c3/83b458fd-5dd3-419b-a9e3-7335814a0911/AAIAIC25/Cisco/Nexus 3048-TP";
+
+
+
+ //Expected strings
+ private static final String GET_SPECIFIC_PNF_EXPECTED = "{\"resourceVersion\":\"1494001797554\",\"relationshipList\":{\"relationship\":[{\"relatedTo\":\"complex\",\"relatedLink\":\"/aai/v11/cloud-infrastructure/complexes/complex/NAMEAAI2\",\"relationshipLabel\": \"onap.pnf\",\"relationshipData\":[{\"relationshipKey\":\"complex.physical-location-id\",\"relationshipValue\":\"NAMEAAI2\"}],\"relatedToProperty\":null,\"relationDataList\":[{\"relationshipKey\":\"complex.physical-location-id\",\"relationshipValue\":\"NAMEAAI2\"}],\"relatedToPropertyList\":null}]},\"pnfName\":\"DEAAI78\",\"pnfName2\":\"DEAAI78-name-2\",\"pnfName2Source\":\"DEAAI78-name-2-source\",\"pnfId\":\"DEAAI78-id\",\"equipType\":\"Switch\",\"equipVendor\":\"Cisco\",\"equipModel\":\"ASR1002-X\"}";
+
+ @DataProvider
+ public static Object[][] getAssociatedPnfs(Method test) {
+ return new Object[][]{
+ {GET_SERVICE_INSTANCE_JSON, GET_LOGICAL_LINK_JSON},
+
+ //no need to call to getLogicalLink if service has direct relation to the pnfs
+ {"get_service_instance_direct_relation_pnf.json", null}
+ };
+ }
+
+ @Test(dataProvider = "getAssociatedPnfs")
+ public void testGetAssociatedPnfs(String getServiceInstanceJson, String getLogicalLinkJson) {
+ registerExpectation(getServiceInstanceJson, RegistrationStrategy.APPEND);
+ if (getLogicalLinkJson!=null) {
+ registerExpectation(getLogicalLinkJson, RegistrationStrategy.APPEND);
+ }
+ ResponseEntity<ArrayList> response = restTemplate.getForEntity(buildUri(GET_SERVICE_INSTANCE_PNFS), ArrayList.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ ArrayList pnfs = response.getBody();
+ Assert.assertNotNull(pnfs);
+ Assert.assertEquals(pnfs.size(), 2);
+ Assert.assertEquals(pnfs.get(0), "tesaaisdgraclz1a1");
+ Assert.assertEquals(pnfs.get(1), "tesai371ve2");
+ }
+
+ @Test
+ public void testGetAssociatedPnfsByRegisteredServiceResponse() throws Exception {
+ registerExpectation(GET_SERVICE_INSTANCE_NOT_FOUND_JSON, RegistrationStrategy.CLEAR_THEN_SET);
+ ResponseEntity<ArrayList> response = restTemplate.getForEntity(buildUri(GET_SERVICE_INSTANCE_PNFS), ArrayList.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ ArrayList pnfs = response.getBody();
+ Assert.assertNotNull(pnfs);
+ Assert.assertEquals(pnfs.size(), 0);
+ }
+
+ @Test
+ public void testGetAssociatedPnfsByRegisteredLogicalLinkResponse() throws Exception {
+ registerExpectation(GET_SERVICE_INSTANCE_JSON, RegistrationStrategy.CLEAR_THEN_SET);
+ registerExpectation(GET_LOGICAL_LINK_NOT_FOUND_JSON, RegistrationStrategy.APPEND);
+ ResponseEntity<ArrayList> response = restTemplate.getForEntity(buildUri(GET_SERVICE_INSTANCE_PNFS), ArrayList.class);
+ Assert.assertEquals(response.getStatusCode(), HttpStatus.OK);
+ ArrayList pnfs = response.getBody();
+ Assert.assertNotNull(pnfs);
+ Assert.assertEquals(pnfs.size(), 0);
+ }
+
+ @Test
+ public void testGetSpecificPnf() throws Exception {
+ callAaiWithSimulatedErrorResponse(GET_SPECIFIC_PNF_FINE_RESPONSE,
+ ImmutableMap.of(),
+ buildUri(GET_SPECIFIC_PNF_URI), "",200,GET_SPECIFIC_PNF_EXPECTED, HttpMethod.GET);
+
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void testGetSpecificPnfError(int errorCode) throws IOException, URISyntaxException {
+ final String expectedResult ="{ \"requestError\": { \"serviceException\": { \"messageId\": \"SVC3001\", \"text\": \"Resource not found for %1 using id %2 (msg=%3) (ec=%4)\", \"variables\": [ \"GET\", \"network/pnfs/pnf/DEAAI78ff\", \"Node Not Found:No Node of type pnf found at: network/pnfs/pnf/DEAAI78ff\", \"ERR.5.4.6114\" ] } } }";
+
+ callAaiWithSimulatedErrorResponse(GET_SPECIFIC_PNF_ERROR_RESPONSE,
+ ImmutableMap.of("500", Integer.toString(errorCode),"\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(expectedResult)),
+ buildUri(GET_SPECIFIC_PNF_URI), "",errorCode,expectedResult,HttpMethod.GET);
+
+ }
+
+ @Test
+ public void testGetPnfDataByRegion() throws Exception {
+ String expected = "{\"results\":[{\"id\":\"901128280\",\"url\":\"/aai/v12/network/pnfs/pnf/AS-pnf2-10219--as988q\",\"properties\":{\"pnfName\":\"AS-pnf2-10219--as988q\",\"equipType\":\"Switch\",\"equipVendor\":\"Cisco\",\"equipModel\":\"Nexus3048-TP\",\"inMaint\":false,\"resourceVersion\":\"1508776538192\"},\"nodeType\":\"pnf\",\"relatedTo\":[{\"id\":\"532488360\",\"url\":\"/aai/v12/business/customers/customer/customer-10219-as988q/service-subscriptions/service-subscription/serviceSub2-test-10219-as988q/service-instances/service-instance/serviceIns2-test-10219-as988q\",\"nodeType\":\"service-instance\",\"relationshipLabel\":\"uses\"},{\"id\":\"860164248\",\"url\":\"/aai/v12/cloud-infrastructure/complexes/complex/complex-10219--as988q\",\"nodeType\":\"complex\",\"relationshipLabel\":\"locatedIn\"}]}],\"additionalProperties\":{}}";
+ callAaiWithSimulatedErrorResponse(GET_PNF_BY_REGION_RESPONSE,
+ ImmutableMap.of(),
+ buildUri(GET_PNF_BY_REGION), "",200,expected, HttpMethod.GET);
+
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void testGetPnfDataByRegionError(int errorCode) throws IOException, URISyntaxException {
+ final String expectedResult ="{\"results\":[]}";
+
+ callAaiWithSimulatedErrorResponse(GET_PNF_BY_REGION_RESPONSE_EMPTY,
+ ImmutableMap.of("500", Integer.toString(errorCode),"\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(expectedResult)),
+ buildUri(GET_PNF_BY_REGION), "",errorCode,expectedResult,HttpMethod.GET);
+
+ }
+
+ @DataProvider
+ public static Object[][] errorCodes(Method test) {
+ return new Object[][]{
+ {500},{505}, {400}, {401}, {405}
+ };
+ }
+
+ @Test
+ public void testGetPnfDataByRegionNoResults() throws IOException, URISyntaxException {
+ final String registratedResult = "{\"results\":[]}";
+ final String expectedResult ="{\"results\":[],\"additionalProperties\":{}}";
+ final int expectedResponseCode = 200;
+ callAaiWithSimulatedErrorResponse(GET_PNF_BY_REGION_RESPONSE_EMPTY,
+ ImmutableMap.of("500", Integer.toString(expectedResponseCode),"\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(registratedResult)),
+ buildUri(GET_PNF_BY_REGION), "",expectedResponseCode,expectedResult,HttpMethod.GET);
+
+ }
+}
diff --git a/vid-automation/src/test/java/org/onap/vid/api/pProbeMsoApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/pProbeMsoApiTest.java
new file mode 100644
index 000000000..c082ef95a
--- /dev/null
+++ b/vid-automation/src/test/java/org/onap/vid/api/pProbeMsoApiTest.java
@@ -0,0 +1,107 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.text.StringEscapeUtils;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+public class pProbeMsoApiTest extends BaseMsoApiTest{
+
+ //Urls
+ private static final String MSO_REMOVE_RELATIONSHIP = "/mso/mso_remove_relationship/f36f5734-e9df-4fbf-9f35-61be13f028a1";
+ private static final String MSO_ADD_RELATIONSHIP = "/mso/mso_add_relationship/f36f5734-e9df-4fbf-9f35-61be13f028a1";
+ public static final String MSO_CREATE_CONFIGURATION = "mso/mso_create_configuration_instance/f36f5734-e9df-4fbf-9f35-61be13f028a1/configurations/";
+ public static final String MSO_ACTIVATE_CONFIGURATION = "mso/mso_activate_configuration/f36f5734-e9df-4fbf-9f35-61be13f028a1/configurations/a53c9ca8-8986-44da-9e5e-9e4179e6c78a";
+
+
+
+ //Request Details
+ private static final String ADD_REMOVE_RELATIONSHIP_REQUEST_DETAILS = "registration_to_simulator/body_jsons/mso_request_dissociate_pnf_from_service.json";
+
+ //Request Details
+ private static final String CREATE_CONFIGURATION_REQUEST_DETAILS = "registration_to_simulator/body_jsons/mso_request_create_configuration.json";
+
+ //Jsons
+ private static final String DISSOCIATE_OK_JSON = "dissociate_pnf_from_service_instance.json";
+ private static final String DISSOCIATE_FAILED_JSON = "dissociate_pnf_from_service_instance_error.json";
+ private static final String ASSOCIATE_OK_JSON = "mso_add_relationships.json";
+ private static final String ASSOCIATE_FAILED_JSON = "mso_add_relationships_error.json";
+ private static final String CREATE_CONFIGURATION_OK_JSON = "mso_create_configurations.json";
+ private static final String CREATE_CONFIGURATION_FAILED_JSON = "mso_create_configurations_error.json";
+ private static final String ACTIVATE_CONFIGURATION_OK_JSON = "mso_activate_configurations.json";
+
+ //Expected Responses
+ private static final String EXPECTED_SUCCESS_MSO_RESPONSE = "{\"requestReferences\": {\"instanceId\": \"f36f5734-e9df-4fbf-9f35-61be13f028a1\", \"requestId\": \"b6dc9806-b094-42f7-9386-a48de8218ce8\"}}";
+ private static final String EXPECTED_ERROR_MSO_RESPONSE = "{\"error\":\"222\",\"message\":\"error message\"}";
+
+
+ @Test
+ public void testRemovePnfFromServiceInstanceSucceed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, ADD_REMOVE_RELATIONSHIP_REQUEST_DETAILS);
+ callMsoWithFineRequest(DISSOCIATE_OK_JSON, ImmutableMap.of(), buildUri(MSO_REMOVE_RELATIONSHIP), requestBody,
+ HttpStatus.ACCEPTED.value(), EXPECTED_SUCCESS_MSO_RESPONSE, HttpMethod.POST);
+ }
+
+ @Test
+ public void testRemovePnfFromServiceInstanceFailed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, ADD_REMOVE_RELATIONSHIP_REQUEST_DETAILS);
+ callMsoWithSimulatedErrorResponse(DISSOCIATE_FAILED_JSON, ImmutableMap.of(), buildUri(MSO_REMOVE_RELATIONSHIP), requestBody,
+ HttpStatus.NOT_FOUND.value(), "", HttpMethod.POST);
+ }
+
+
+ @Test
+ public void testAddPnf2ServiceInstanceSucceed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, ADD_REMOVE_RELATIONSHIP_REQUEST_DETAILS);
+ callMsoWithFineRequest(ASSOCIATE_OK_JSON, ImmutableMap.of(), buildUri(MSO_ADD_RELATIONSHIP), requestBody,
+ HttpStatus.ACCEPTED.value(),EXPECTED_SUCCESS_MSO_RESPONSE , HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void testAddPnf2ServiceInstanceError(int errorCode) throws IOException, URISyntaxException {
+ String requestBody = TestUtils.convertRequest(objectMapper, ADD_REMOVE_RELATIONSHIP_REQUEST_DETAILS);
+ callMsoWithSimulatedErrorResponse(ASSOCIATE_FAILED_JSON,
+ ImmutableMap.of("500", Integer.toString(errorCode),"\"ERROR_PAYLOAD\"", StringEscapeUtils.escapeJson(EXPECTED_ERROR_MSO_RESPONSE)),
+ buildUri(MSO_ADD_RELATIONSHIP), requestBody,errorCode,EXPECTED_ERROR_MSO_RESPONSE,HttpMethod.POST);
+
+ }
+
+ @Test
+ public void testCreateConfigurationSucceed() throws Exception {
+ String requestBody = TestUtils.convertRequest(objectMapper, CREATE_CONFIGURATION_REQUEST_DETAILS);
+ callMsoWithFineRequest(CREATE_CONFIGURATION_OK_JSON, ImmutableMap.of(), buildUri(MSO_CREATE_CONFIGURATION),
+ requestBody, HttpStatus.ACCEPTED.value(),EXPECTED_SUCCESS_MSO_RESPONSE , HttpMethod.POST);
+ }
+
+ @Test
+ public void testActivateConfigurationSucceed() throws Exception {
+ String requestBody = "" +
+ "{" +
+ " \"val\": \"dummy payload\"" +
+ "}";
+ callMsoWithFineRequest(ACTIVATE_CONFIGURATION_OK_JSON, ImmutableMap.of(), buildUri(MSO_ACTIVATE_CONFIGURATION),
+ requestBody, HttpStatus.ACCEPTED.value(),EXPECTED_SUCCESS_MSO_RESPONSE , HttpMethod.POST);
+ }
+
+ @Test(dataProvider = "errorCodes")
+ public void testCreateConfigurationError(int errorCode) throws IOException, URISyntaxException {
+ String requestBody = TestUtils.convertRequest(objectMapper, CREATE_CONFIGURATION_REQUEST_DETAILS);
+ callMsoWithSimulatedErrorResponse(CREATE_CONFIGURATION_FAILED_JSON,
+ ImmutableMap.of("\"<ERROR_CODE>\"", Integer.toString(errorCode),"\"<ERROR_PAYLOAD>\"", StringEscapeUtils.escapeJson(EXPECTED_ERROR_MSO_RESPONSE)),
+ buildUri(MSO_CREATE_CONFIGURATION), requestBody,errorCode,EXPECTED_ERROR_MSO_RESPONSE,HttpMethod.POST);
+
+ }
+
+ @Test
+ public void testCreateConfigurationFail() throws Exception {
+ String requestBody = "498/*ht5ru7 mjhnb";
+ callMsoWithSimulatedErrorResponse(CREATE_CONFIGURATION_FAILED_JSON,
+ ImmutableMap.of("\"<ERROR_CODE>\"", 500),
+ buildUri(MSO_CREATE_CONFIGURATION), requestBody,500,EXPECTED_ERROR_MSO_RESPONSE,HttpMethod.POST);
+
+ }
+}