diff options
author | Sonsino, Ofir (os0695) <os0695@intl.att.com> | 2018-08-12 14:51:28 +0300 |
---|---|---|
committer | Sonsino, Ofir (os0695) <os0695@intl.att.com> | 2018-08-12 15:02:57 +0300 |
commit | 4a4dcc5185f8ba5a28c7f9fef509f32c0c2389e6 (patch) | |
tree | 23e55ee7e1ad9b91bcc3ef1dbe1fb7b183f8b2b6 /vid-automation/src/test/java/org | |
parent | 661a24fd57de02869a9771761e0fcba7eb77d121 (diff) |
vid-automation selenium tests
Change-Id: I6c1b0a0cf3bbfa4314c81f0cc72507db805ec632
Issue-ID: VID-281
Signed-off-by: Sonsino, Ofir (os0695) <os0695@intl.att.com>
Diffstat (limited to 'vid-automation/src/test/java/org')
63 files changed, 6799 insertions, 0 deletions
diff --git a/vid-automation/src/test/java/org/opencomp/vid/api/AaiApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/AaiApiTest.java new file mode 100644 index 00000000..e8d634ee --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/AaiApiTest.java @@ -0,0 +1,547 @@ +package org.opencomp.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.opencomp.simulator.presetGenerator.presets.aai.*; +import org.opencomp.vid.model.aai.AaiResponse; +import org.opencomp.vid.model.mso.OperationalEnvironmentList; +import org.opencomp.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.opencomp.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/opencomp/vid/api/AsyncInfraApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/AsyncInfraApiTest.java new file mode 100644 index 00000000..ffabcaf3 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/AsyncInfraApiTest.java @@ -0,0 +1,234 @@ +package org.opencomp.vid.api; + +import com.google.common.collect.ImmutableList; +import com.google.gson.JsonObject; +import net.codestory.http.WebServer; +import org.opencomp.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet; +import org.opencomp.simulator.presetGenerator.presets.ecompportal_att.PresetGetSessionSlotCheckIntervalGet; +import org.opencomp.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.time.LocalDate; +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/opencomp/vid/api/AsyncInstantiationApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/AsyncInstantiationApiTest.java new file mode 100644 index 00000000..52fecc04 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/AsyncInstantiationApiTest.java @@ -0,0 +1,520 @@ +package org.opencomp.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.opencomp.simulator.presetGenerator.presets.BasePresets.BasePreset; +import org.opencomp.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet; +import org.opencomp.simulator.presetGenerator.presets.aai.PresetAAISearchNodeQueryEmptyResult; +import org.opencomp.simulator.presetGenerator.presets.ecompportal_att.PresetGetSessionSlotCheckIntervalGet; +import org.opencomp.simulator.presetGenerator.presets.mso.*; +import org.opencomp.vid.model.asyncInstantiation.JobAuditStatus; +import org.opencomp.vid.model.asyncInstantiation.ServiceInfo; +import org.opencomp.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.opencomp.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/opencomp/vid/api/BaseApiAaiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/BaseApiAaiTest.java new file mode 100644 index 00000000..af8833ca --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/BaseApiAaiTest.java @@ -0,0 +1,70 @@ +package org.opencomp.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/opencomp/vid/api/BaseApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/BaseApiTest.java new file mode 100644 index 00000000..f4e7fb5f --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/BaseApiTest.java @@ -0,0 +1,206 @@ +package org.opencomp.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/opencomp/vid/api/BaseMsoApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/BaseMsoApiTest.java new file mode 100644 index 00000000..2e00fc61 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/BaseMsoApiTest.java @@ -0,0 +1,80 @@ +package org.opencomp.vid.api; + +import com.att.automation.common.report_portal_integration.annotations.Step; +import com.google.common.collect.ImmutableMap; +import org.json.JSONException; +import org.opencomp.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/opencomp/vid/api/CategoryParametersApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/CategoryParametersApiTest.java new file mode 100644 index 00000000..5c7d4fcb --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/CategoryParametersApiTest.java @@ -0,0 +1,120 @@ +package org.opencomp.vid.api; + +import org.opencomp.vid.model.category.AddCategoryOptionsRequest; +import org.opencomp.vid.model.category.CategoryParameterOption; +import org.opencomp.vid.model.category.CategoryParameterOptionRep; +import org.opencomp.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.Random; +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/opencomp/vid/api/ChangeManagementApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/ChangeManagementApiTest.java new file mode 100644 index 00000000..8df4ad7e --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/ChangeManagementApiTest.java @@ -0,0 +1,733 @@ +package org.opencomp.vid.api; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +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.opencomp.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( + 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( + getNestedPropertyInMap(body.getEntity(), "serviceException/messageId"), + "SVC2000", + String.format("Failed to find messageId: %s in " + requestType + " response. Actual body:%s", + "SVC2000", body.getEntity())); + + + assertThat(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.openecomp.vid.domain.mso.CloudConfiguration cloudConfiguration = new org.openecomp.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/opencomp/vid/api/OperationalEnvironmentControllerApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/OperationalEnvironmentControllerApiTest.java new file mode 100644 index 00000000..65b0253b --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/OperationalEnvironmentControllerApiTest.java @@ -0,0 +1,431 @@ +package org.opencomp.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/opencomp/vid/api/ProbeApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/ProbeApiTest.java new file mode 100644 index 00000000..3ed74641 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/ProbeApiTest.java @@ -0,0 +1,109 @@ +package org.opencomp.vid.api; + +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.junit.Assert; +import org.opencomp.simulator.presetGenerator.presets.BasePresets.BasePreset; +import org.opencomp.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet; +import org.opencomp.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGetInvalidResponse; +import org.opencomp.vid.model.probe.ExternalComponentStatus; +import org.opencomp.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/opencomp/vid/api/SampleApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/SampleApiTest.java new file mode 100644 index 00000000..3d8cd566 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/SampleApiTest.java @@ -0,0 +1,68 @@ +package org.opencomp.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 java.util.Collections.singletonList; +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/opencomp/vid/api/SdcApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/SdcApiTest.java new file mode 100644 index 00000000..8a924338 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/SdcApiTest.java @@ -0,0 +1,163 @@ +package org.opencomp.vid.api; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.collect.ImmutableList; +import org.opencomp.simulator.presetGenerator.presets.BasePresets.BasePreset; +import org.opencomp.simulator.presetGenerator.presets.sdc.PresetSDCGetServiceMetadataGet; +import org.opencomp.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.FeatureTogglingTest; +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/opencomp/vid/api/ServiceInstanceMsoApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/ServiceInstanceMsoApiTest.java new file mode 100644 index 00000000..8e32f853 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/ServiceInstanceMsoApiTest.java @@ -0,0 +1,121 @@ +package org.opencomp.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/opencomp/vid/api/Streams.java b/vid-automation/src/test/java/org/opencomp/vid/api/Streams.java new file mode 100644 index 00000000..c1c6cea4 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/Streams.java @@ -0,0 +1,47 @@ +package org.opencomp.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/opencomp/vid/api/TestUtils.java b/vid-automation/src/test/java/org/opencomp/vid/api/TestUtils.java new file mode 100644 index 00000000..4ce43e68 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/TestUtils.java @@ -0,0 +1,81 @@ +package org.opencomp.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/opencomp/vid/api/VidConfigurationApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/VidConfigurationApiTest.java new file mode 100644 index 00000000..fd8cc07d --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/VidConfigurationApiTest.java @@ -0,0 +1,25 @@ +package org.opencomp.vid.api; + +import org.springframework.http.ResponseEntity; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import static java.util.Collections.singletonList; +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/opencomp/vid/api/pProbeAaiApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/pProbeAaiApiTest.java new file mode 100644 index 00000000..d8049f99 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/pProbeAaiApiTest.java @@ -0,0 +1,146 @@ +package org.opencomp.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/opencomp/vid/api/pProbeMsoApiTest.java b/vid-automation/src/test/java/org/opencomp/vid/api/pProbeMsoApiTest.java new file mode 100644 index 00000000..5c028284 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/api/pProbeMsoApiTest.java @@ -0,0 +1,107 @@ +package org.opencomp.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); + + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/aai/AaiResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/aai/AaiResponse.java new file mode 100644 index 00000000..3124ca40 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/aai/AaiResponse.java @@ -0,0 +1,34 @@ +package org.opencomp.vid.model.aai; + +import com.google.common.base.MoreObjects; +import org.opencomp.vid.model.mso.ProxyResponse; + +/** + * Created by Oren on 7/10/17. + */ +public class AaiResponse<T> extends ProxyResponse { + + T t; + + public AaiResponse() { + } + + public AaiResponse(T t, String errorMessage, int aaiHttpCode) { + this.t = t; + this.errorMessage = errorMessage; + this.httpCode = aaiHttpCode; + } + + public T getT() { + return t; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("httpCode", httpCode) + .add("errorMessage", errorMessage) + .add("t", t) + .toString(); + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/asyncInstantiation/JobAuditStatus.java b/vid-automation/src/test/java/org/opencomp/vid/model/asyncInstantiation/JobAuditStatus.java new file mode 100644 index 00000000..254eb9c0 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/asyncInstantiation/JobAuditStatus.java @@ -0,0 +1,124 @@ +package org.opencomp.vid.model.asyncInstantiation; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import vid.automation.test.model.JobStatus; + +import java.util.Date; +import java.util.UUID; + + +public class JobAuditStatus { + + public JobAuditStatus(){} + + + public JobAuditStatus(UUID jobId, String jobStatus, SourceStatus source){ + this.jobId = jobId; + this.jobStatus = jobStatus; + this.source = source; + this.isFinal = isFinal(); + } + + public JobAuditStatus(UUID jobId, String jobStatus, SourceStatus source, UUID requestId, String additionalInfo, Boolean isFinal) { + this(jobId, jobStatus, source); + this.requestId = requestId; + this.additionalInfo = additionalInfo; + this.isFinal = isFinal; + } + + + + public enum SourceStatus { + MSO, + VID + } + + private UUID jobId; + private String jobStatus; + private SourceStatus source; + private UUID requestId; + private String additionalInfo; + + + + private Boolean isFinal; + + public String getJobStatus() { + return jobStatus; + } + + public UUID getJobId() { + return jobId; + } + + public SourceStatus getSource() { + return source; + } + + public String getAdditionalInfo() { + return additionalInfo; + } + + public UUID getRequestId() { + return requestId; + } + + + + public Boolean isFinal(){ + return isFinal; + } + + public void setFinal(Boolean aFinal) { + isFinal = aFinal; + } + + @Override + public String toString() { + return "JobAuditStatus{" + + "jobId=" + jobId + + ", jobStatus='" + jobStatus + '\'' + + ", source=" + source + + ", requestId=" + requestId + + ", additionalInfo='" + additionalInfo + '\'' + + ", isFinal=" + isFinal + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + JobAuditStatus that = (JobAuditStatus) o; + + return new EqualsBuilder() + .append(jobId, that.jobId) + .append(jobStatus, that.jobStatus) + .append(source, that.source) + .append(requestId, that.requestId) + .append(additionalInfo, that.additionalInfo) + .append(isFinal, that.isFinal) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(jobId) + .append(jobStatus) + .append(source) + .append(requestId) + .append(additionalInfo) + .append(isFinal) + .toHashCode(); + } + + + + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/asyncInstantiation/ServiceInfo.java b/vid-automation/src/test/java/org/opencomp/vid/model/asyncInstantiation/ServiceInfo.java new file mode 100644 index 00000000..ee3cd7a7 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/asyncInstantiation/ServiceInfo.java @@ -0,0 +1,75 @@ +package org.opencomp.vid.model.asyncInstantiation; + + +import vid.automation.test.model.JobStatus; + +import java.util.Date; + +public class ServiceInfo { + + public String jobId; + public String templateId; + public String userId; + public JobStatus jobStatus; + public Date statusModifiedDate; + public boolean hidden; + public boolean pause; + public String owningEntityId; + public String owningEntityName; + public String project; + public String aicZoneId; + public String aicZoneName; + public String tenantId; + public String tenantName; + public String regionId; + public String regionName; + public String serviceType; + public String subscriberName; + public String serviceInstanceId; + public String serviceInstanceName; + public String serviceModelId; + public String serviceModelName; + public String serviceModelVersion; + public Date createdBulkDate; + + public ServiceInfo(){ + + } + + public ServiceInfo(String userId, JobStatus jobStatus, boolean pause, String owningEntityId, String owningEntityName, String project, String aicZoneId, String aicZoneName, String tenantId, String tenantName, String regionId, String regionName, String serviceType, String subscriberName, String serviceInstanceId, String serviceInstanceName, String serviceModelId, String serviceModelName, String serviceModelVersion, String jobId, String templateId) { + this.userId = userId; + this.jobStatus = jobStatus; + this.pause = pause; + this.owningEntityId = owningEntityId; + this.owningEntityName = owningEntityName; + this.project = project; + this.aicZoneId = aicZoneId; + this.aicZoneName = aicZoneName; + this.tenantId = tenantId; + this.tenantName = tenantName; + this.regionId = regionId; + this.regionName = regionName; + this.serviceType = serviceType; + this.subscriberName = subscriberName; + this.serviceInstanceId = serviceInstanceId; + this.serviceInstanceName = serviceInstanceName; + this.serviceModelId = serviceModelId; + this.serviceModelName = serviceModelName; + this.serviceModelVersion = serviceModelVersion; + this.jobId = jobId; + this.templateId = templateId; + } + + public JobStatus getJobStatus() { + return jobStatus; + } + + public String getServiceInstanceName() { + return serviceInstanceName; + } + + public String getJobId() { + return jobId; + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/category/AddCategoryOptionResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/category/AddCategoryOptionResponse.java new file mode 100644 index 00000000..9cfaec95 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/category/AddCategoryOptionResponse.java @@ -0,0 +1,15 @@ +package org.opencomp.vid.model.category; + +import org.opencomp.vid.model.workflow.ListOfErrorsResponse; + +import java.util.List; + +public class AddCategoryOptionResponse extends ListOfErrorsResponse { + + public AddCategoryOptionResponse() { + } + + public AddCategoryOptionResponse(List<String> errors) { + super(errors); + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/category/AddCategoryOptionsRequest.java b/vid-automation/src/test/java/org/opencomp/vid/model/category/AddCategoryOptionsRequest.java new file mode 100644 index 00000000..2c3edfde --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/category/AddCategoryOptionsRequest.java @@ -0,0 +1,13 @@ +package org.opencomp.vid.model.category; + +import java.util.ArrayList; +import java.util.List; + +public class AddCategoryOptionsRequest { + + public List<String> options; + + public AddCategoryOptionsRequest() { + options = new ArrayList<>(); + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParameterOption.java b/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParameterOption.java new file mode 100644 index 00000000..2aa83924 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParameterOption.java @@ -0,0 +1,34 @@ +package org.opencomp.vid.model.category; + +public class CategoryParameterOption { + + private String appId; + private String name; + + + public CategoryParameterOption() { + } + + public CategoryParameterOption(String appId, String name) { + setAppId(appId); + setName(name); + } + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParameterOptionRep.java b/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParameterOptionRep.java new file mode 100644 index 00000000..27b42e66 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParameterOptionRep.java @@ -0,0 +1,31 @@ +package org.opencomp.vid.model.category; + +public class CategoryParameterOptionRep { + + private String id; + private String name; + + public CategoryParameterOptionRep() { + } + + public CategoryParameterOptionRep(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParametersResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParametersResponse.java new file mode 100644 index 00000000..9b9cc840 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/category/CategoryParametersResponse.java @@ -0,0 +1,27 @@ +package org.opencomp.vid.model.category; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; +import java.util.Map; + +public class CategoryParametersResponse { + + private Map<String, List<CategoryParameterOptionRep>> categoryParameters; + + public CategoryParametersResponse() { + } + + public CategoryParametersResponse(Map<String, List<CategoryParameterOptionRep>> categoryParameters) { + this.categoryParameters = categoryParameters; + } + + @JsonProperty("categoryParameters") + public Map<String, List<CategoryParameterOptionRep>> getCategoryParameters() { + return categoryParameters; + } + + public void setCategoryParameters(Map<String, List<CategoryParameterOptionRep>> categoryParameters) { + this.categoryParameters = categoryParameters; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/ChangeManagementRequest.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ChangeManagementRequest.java new file mode 100644 index 00000000..27370668 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ChangeManagementRequest.java @@ -0,0 +1,70 @@ +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@JsonPropertyOrder({ + "requestDetails", + "requestType" +}) + +public class ChangeManagementRequest { + + public static class MsoChangeManagementRequest { + public final static String SOFTWARE_UPDATE = "inPlaceSoftwareUpdate"; + public static final String REPLACE = "replace"; + public final static String CONFIG_UPDATE = "applyUpdatedConfig"; + + } + + public final static String VNF_IN_PLACE_SOFTWARE_UPDATE = "vnf in place software update"; + public static final String UPDATE = "update"; + public static final String REPLACE = "replace"; + public final static String CONFIG_UPDATE = "vnf config update"; + + @JsonProperty("requestDetails") + private List<ChangeManagementRequestDetails> requestDetails; + + @JsonProperty("requestType") + private String requestType; + + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + @JsonProperty("requestDetails") + public List<ChangeManagementRequestDetails> getRequestDetails() { + return requestDetails; + } + + @JsonProperty("requestDetails") + public void setRequestDetails(List<ChangeManagementRequestDetails> requestDetails) { + this.requestDetails = requestDetails; + } + + @JsonProperty("requestType") + public String getRequestType() { + return requestType; + } + + @JsonProperty("requestType") + public void setRequestType(String requestType) { + this.requestType = requestType; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/ChangeManagementRequestDetails.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ChangeManagementRequestDetails.java new file mode 100644 index 00000000..4e50e10c --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ChangeManagementRequestDetails.java @@ -0,0 +1,41 @@ +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"modelInfo", +"cloudConfiguration", +"requestInfo", +"requestParameters", +"vnfName", +"vnfInstanceId" +}) +public class ChangeManagementRequestDetails extends RequestDetails{ + + @JsonProperty("vnfName") + private String vnfName; + @JsonProperty("vnfInstanceId") + private String vnfInstanceId; + + @JsonProperty("vnfName") + public String getVnfName() { + return vnfName; + } + + @JsonProperty("vnfName") + public void setVnfName(String vnfName) { + this.vnfName = vnfName; + } + @JsonProperty("vnfInstanceId") + public String getVnfInstanceId() { + return vnfInstanceId; + } + + @JsonProperty("vnfInstanceId") + public void setVnfInstanceId(String vnfInstanceId) { + this.vnfInstanceId = vnfInstanceId; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/CloudConfiguration.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/CloudConfiguration.java new file mode 100644 index 00000000..279fda1b --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/CloudConfiguration.java @@ -0,0 +1,13 @@ +package org.opencomp.vid.model.mso; + + +public class CloudConfiguration { + + public CloudConfiguration() { + } + + public String lcpCloudRegionId; + + public String tenantId; + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/ExceptionResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ExceptionResponse.java new file mode 100644 index 00000000..b7711b57 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ExceptionResponse.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.opencomp.vid.model.mso; + +/** + * The Class ExceptionResponse. + */ +public class ExceptionResponse { + + public ExceptionResponse() { + } + + /** The exception. */ + private String exception; + + /** The message. */ + private String message; + + public ExceptionResponse(String exception, String message) { + this.exception = exception; + this.message = message; + } + + public ExceptionResponse(Exception exception) { + setException(exception); + } + + /** + * Gets the exception. + * + * @return the exception + */ + public String getException() { + return exception; + } + + /** + * Sets the exception. + * + * @param exception the new exception + */ + public void setException(String exception) { + this.exception = exception; + } + + public void setException(Exception exception) { + setException(exception.getClass().toString().replaceFirst("^.*[\\.$]", "")); + setMessage(exception.getMessage()); + } + + /** + * Gets the message. + * + * @return the message + */ + public String getMessage() { + return message; + } + + /** + * Sets the message. + * + * @param message the new message + */ + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/ModelInfo.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ModelInfo.java new file mode 100644 index 00000000..c636760e --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ModelInfo.java @@ -0,0 +1,124 @@ +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; + +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"modelType", +"modelInvariantId", +"modelVersionId", +"modelName", +"modelVersion", +"modelCustomizationName", +"modelCustomizationId" +}) +public class ModelInfo { + + public ModelInfo(){ + + } + + @JsonProperty("modelType") + private String modelType; + @JsonProperty("modelInvariantId") + private String modelInvariantId; + @JsonProperty("modelVersionId") + private String modelVersionId; + @JsonProperty("modelName") + private String modelName; + @JsonProperty("modelVersion") + private String modelVersion; + @JsonProperty("modelCustomizationName") + private String modelCustomizationName; + @JsonProperty("modelCustomizationId") + private String modelCustomizationId; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + @JsonProperty("modelType") + public String getModelType() { + return modelType; + } + + @JsonProperty("modelType") + public void setModelType(String modelType) { + this.modelType = modelType; + } + + @JsonProperty("modelInvariantId") + public String getModelInvariantId() { + return modelInvariantId; + } + + @JsonProperty("modelInvariantId") + public void setModelInvariantId(String modelInvariantId) { + this.modelInvariantId = modelInvariantId; + } + + @JsonProperty("modelVersionId") + public String getModelVersionId() { + return modelVersionId; + } + + @JsonProperty("modelVersionId") + public void setModelVersionId(String modelVersionId) { + this.modelVersionId = modelVersionId; + } + + @JsonProperty("modelName") + public String getModelName() { + return modelName; + } + + @JsonProperty("modelName") + public void setModelName(String modelName) { + this.modelName = modelName; + } + + @JsonProperty("modelVersion") + public String getModelVersion() { + return modelVersion; + } + + @JsonProperty("modelVersion") + public void setModelVersion(String modelVersion) { + this.modelVersion = modelVersion; + } + + @JsonProperty("modelCustomizationName") + public String getModelCustomizationName() { + return modelCustomizationName; + } + + @JsonProperty("modelCustomizationName") + public void setModelCustomizationName(String modelCustomizationName) { + this.modelCustomizationName = modelCustomizationName; + } + + @JsonProperty("modelCustomizationId") + public String getModelCustomizationId() { + return modelCustomizationId; + } + + @JsonProperty("modelCustomizationId") + public void setModelCustomizationId(String modelCustomizationId) { + this.modelCustomizationId = modelCustomizationId; + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoExceptionResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoExceptionResponse.java new file mode 100644 index 00000000..4f11f67f --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoExceptionResponse.java @@ -0,0 +1,32 @@ +package org.opencomp.vid.model.mso; + +public class MsoExceptionResponse { + + public static class ServiceException { + + public ServiceException(String messageId, String text) { + this.messageId = messageId; + this.text = text; + } + + public ServiceException() { + } + + public String messageId; + public String text; + } + + public ServiceException serviceException; + + public MsoExceptionResponse() { + } + + public MsoExceptionResponse(String messageId, String text) { + this.serviceException = new ServiceException(messageId, text); + } + + public MsoExceptionResponse(Exception exception) { + ExceptionResponse exceptionResponse = new ExceptionResponse(exception); + this.serviceException = new ServiceException(exceptionResponse.getException(), exceptionResponse.getMessage()); + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoResponseWrapper2.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoResponseWrapper2.java new file mode 100644 index 00000000..d0487e19 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoResponseWrapper2.java @@ -0,0 +1,60 @@ +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +@JsonPropertyOrder({ + "status", + "entity" +}) + +/* +This is a brother of MsoResponseWrapper. I (Ittay) think it's better. +It is generic, immutable, and has some knowledge about RestObject. +The serialized "entity" field may be either String or nested object. + */ +public class MsoResponseWrapper2<T> implements MsoResponseWrapperInterface { + + final static ObjectMapper objectMapper = new ObjectMapper(); + + private final int status; + private final T entity; + private final String raw; + + public MsoResponseWrapper2(RestObject<T> msoResponse) { + this.status = msoResponse.getStatusCode(); + this.entity = msoResponse.get(); + this.raw = msoResponse.getRaw(); + } + + public MsoResponseWrapper2( + @JsonProperty(value = "status", required = true) int status, + @JsonProperty(value = "entity", required = true) T entity) { + this.status = status; + this.entity = entity; + this.raw = null; + } + + public int getStatus() { + return status; + } + + @Override + @org.codehaus.jackson.annotate.JsonIgnore + @com.fasterxml.jackson.annotation.JsonIgnore + public String getResponse() { + try { + return objectMapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + return getEntity() != null ? getEntity().toString() : null; + } + } + + @JsonProperty + public Object getEntity() { + return entity != null ? entity : raw; + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoResponseWrapperInterface.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoResponseWrapperInterface.java new file mode 100644 index 00000000..aafa4c33 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/MsoResponseWrapperInterface.java @@ -0,0 +1,15 @@ +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public interface MsoResponseWrapperInterface { + @JsonProperty("entity") + Object getEntity(); + + @JsonProperty("status") + int getStatus(); + + @org.codehaus.jackson.annotate.JsonIgnore + @com.fasterxml.jackson.annotation.JsonIgnore + String getResponse(); +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/OperationalEnvironment.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/OperationalEnvironment.java new file mode 100644 index 00000000..66c5b183 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/OperationalEnvironment.java @@ -0,0 +1,103 @@ +package org.opencomp.vid.model.mso; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class OperationalEnvironment { + + private String operationalEnvironmentId; + private String operationalEnvironmentName; + private String operationalEnvironmentType; + private String operationalEnvironmentStatus; + private String tenantContext; + private String workloadContext; + private String resourceVersion; + private RelationshipList relationshipList; + + public OperationalEnvironment() { + } + + public OperationalEnvironment(String operationalEnvironmentId, String operationalEnvironmentName, String operationalEnvironmentType, String operationalEnvironmentStatus, String tenantContext, String workloadContext, String resourceVersion, RelationshipList relationshipList) { + this.operationalEnvironmentId = operationalEnvironmentId; + this.operationalEnvironmentName = operationalEnvironmentName; + this.operationalEnvironmentType = operationalEnvironmentType; + this.operationalEnvironmentStatus = operationalEnvironmentStatus; + this.tenantContext = tenantContext; + this.workloadContext = workloadContext; + this.resourceVersion = resourceVersion; + this.relationshipList = relationshipList; + } + + @JsonProperty("operational-environment-id") + public String getOperationalEnvironmentId() { + return operationalEnvironmentId; + } + + public void setOperationalEnvironmentId(String operationalEnvironmentId) { + this.operationalEnvironmentId = operationalEnvironmentId; + } + + @JsonProperty("operational-environment-name") + public String getOperationalEnvironmentName() { + return operationalEnvironmentName; + } + + public void setOperationalEnvironmentName(String operationalEnvironmentName) { + this.operationalEnvironmentName = operationalEnvironmentName; + } + + @JsonProperty("operational-environment-type") + public String getOperationalEnvironmentType() { + return operationalEnvironmentType; + } + + public void setOperationalEnvironmentType(String operationalEnvironmentType) { + this.operationalEnvironmentType = operationalEnvironmentType; + } + + @JsonProperty("operational-environment-status") + public String getOperationalEnvironmentStatus() { + return operationalEnvironmentStatus; + } + + public void setOperationalEnvironmentStatus(String operationalEnvironmentStatus) { + this.operationalEnvironmentStatus = operationalEnvironmentStatus; + } + + @JsonProperty("tenant-context") + public String getTenantContext() { + return tenantContext; + } + + public void setTenantContext(String tenantContext) { + this.tenantContext = tenantContext; + } + + @JsonProperty("workload-context") + public String getWorkloadContext() { + return workloadContext; + } + + public void setWorkloadContext(String workloadContext) { + this.workloadContext = workloadContext; + } + + @JsonProperty("resource-version") + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + @JsonProperty("relationship-list") + public RelationshipList getRelationshipList() { + return relationshipList; + } + + public void setRelationshipList(RelationshipList relationshipList) { + this.relationshipList = relationshipList; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/OperationalEnvironmentList.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/OperationalEnvironmentList.java new file mode 100644 index 00000000..9cd0b7ab --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/OperationalEnvironmentList.java @@ -0,0 +1,29 @@ +package org.opencomp.vid.model.mso; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; + +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class OperationalEnvironmentList { + + @JsonProperty("operational-environment") + public List<OperationalEnvironment> getOperationalEnvironment() { + return operationalEnvironment; + } + + @JsonProperty("operational-environment") + public void setOperationalEnvironment(List<OperationalEnvironment> operationalEnvironment) { + this.operationalEnvironment = operationalEnvironment; + } + + public OperationalEnvironmentList() { + } + + public OperationalEnvironmentList(List<OperationalEnvironment> operationalEnvironment) { + this.operationalEnvironment = operationalEnvironment; + } + + private List<OperationalEnvironment> operationalEnvironment; +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/ProxyResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ProxyResponse.java new file mode 100644 index 00000000..b8c387d8 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/ProxyResponse.java @@ -0,0 +1,30 @@ +package org.opencomp.vid.model.mso; + +import com.google.common.base.MoreObjects; + +/** + * Created by Oren on 7/10/17. + */ +public class ProxyResponse { + + protected String errorMessage; + + protected int httpCode; + + public String getErrorMessage() { + return errorMessage; + } + + + public int getHttpCode() { + return httpCode; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("httpCode", httpCode) + .add("errorMessage", errorMessage) + .toString(); + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedInstance.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedInstance.java new file mode 100644 index 00000000..fad7c32b --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedInstance.java @@ -0,0 +1,29 @@ +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "instanceId", + "modelInfo" +}) +public class RelatedInstance { + + @JsonProperty("instanceId") + public String instanceId; + + + @JsonProperty("modelInfo") + public ModelInfo modelInfo; + + @JsonGetter + public String getInstanceId() { + return instanceId; + } + + @JsonSetter + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedInstanceList.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedInstanceList.java new file mode 100644 index 00000000..5e6ccae6 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedInstanceList.java @@ -0,0 +1,26 @@ +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonSetter; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "relatedInstance" +}) +public class RelatedInstanceList { + + @JsonProperty("relatedInstance") + public RelatedInstance relatedInstance; + + @JsonSetter + public RelatedInstance getRelatedInstance() { + return relatedInstance; + } + + @JsonSetter + public void setRelatedInstance(RelatedInstance relatedInstance) { + this.relatedInstance = relatedInstance; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedToProperty.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedToProperty.java new file mode 100644 index 00000000..6d012f98 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelatedToProperty.java @@ -0,0 +1,35 @@ +package org.opencomp.vid.model.mso; + + +import org.codehaus.jackson.annotate.JsonProperty; + +public class RelatedToProperty { + + public String getPropertyKey() { + return propertyKey; + } + + + public void setPropertyKey(String propertyKey) { + this.propertyKey = propertyKey; + } + + + public String getPropertyValue() { + return propertyValue; + } + + + public void setPropertyValue(String propertyValue) { + this.propertyValue = propertyValue; + } + + + @JsonProperty("property-key") + public String propertyKey; + + + @JsonProperty("property-value") + public String propertyValue; + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/Relationship.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/Relationship.java new file mode 100644 index 00000000..814237db --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/Relationship.java @@ -0,0 +1,56 @@ +package org.opencomp.vid.model.mso; + +import org.codehaus.jackson.annotate.JsonProperty; + +import java.util.List; + + +public class Relationship { + + @JsonProperty("related-to") + public String relatedTo; + + @JsonProperty("related-link") + public String relatedLink; + + @JsonProperty("relationship-data") + public List<RelationshipData> relationshipData; + + @JsonProperty("related-to-property") + public List<RelatedToProperty> relatedToProperty; + + + public String getRelatedTo() { + return relatedTo; + } + + public void setRelatedTo(String relatedTo) { + this.relatedTo = relatedTo; + } + + public String getRelatedLink() { + return relatedLink; + } + + public void setRelatedLink(String relatedLink) { + this.relatedLink = relatedLink; + } + + public List<RelationshipData> getRelationDataList() { + return relationshipData; + } + + public void setRelationDataList(List<RelationshipData> relationDataList) { + this.relationshipData = relationDataList; + } + + public List<RelatedToProperty> getRelatedToPropertyList() { + return relatedToProperty; + } + + public void setRelatedToPropertyList(List<RelatedToProperty> relatedToPropertyList) { + this.relatedToProperty = relatedToPropertyList; + } + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelationshipData.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelationshipData.java new file mode 100644 index 00000000..4fdac42a --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelationshipData.java @@ -0,0 +1,30 @@ +package org.opencomp.vid.model.mso; + + +import org.codehaus.jackson.annotate.JsonProperty; + +public class RelationshipData { + @JsonProperty("relationship-key") + public String getRelationshipKey() { + return relationshipKey; + } + @JsonProperty("relationship-key") + public void setRelationshipKey(String relationshipKey) { + this.relationshipKey = relationshipKey; + } + @JsonProperty("relationship-value") + public String getRelationshipValue() { + return relationshipValue; + } + @JsonProperty("relationship-value") + public void setRelationshipValue(String relationshipValue) { + this.relationshipValue = relationshipValue; + } + + @JsonProperty("relationship-key") + public String relationshipKey; + + @JsonProperty("relationship-value") + public String relationshipValue; + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelationshipList.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelationshipList.java new file mode 100644 index 00000000..e2b5d5ef --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RelationshipList.java @@ -0,0 +1,26 @@ +package org.opencomp.vid.model.mso; + +import org.codehaus.jackson.annotate.JsonProperty; + +import java.util.List; + + +public class RelationshipList { + + @JsonProperty("relationship") + public List<Relationship> getRelationship() { + return relationship; + } + + @JsonProperty("relationship") + public void setRelationship(List<Relationship> relationship) { + this.relationship = relationship; + } + + @JsonProperty("relationship") + public List<Relationship> relationship; + + + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestDetails.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestDetails.java new file mode 100644 index 00000000..b56a7d98 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestDetails.java @@ -0,0 +1,218 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * aggregates the context, configuraiton and detailed parameters associated with the request into a single structure. + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "cloudConfiguration", + "modelInfo", + "relatedModelList", + "requestInfo", + "subscriberInfo", + "requestParameters" +}) +public class RequestDetails { + + /** The related model list. */ + @JsonProperty("relatedInstanceList") + public List<RelatedInstanceList> relatedInstList; + /** The cloud configuration. */ + @JsonProperty("cloudConfiguration") + private CloudConfiguration cloudConfiguration; + + /** The model info. */ + @JsonProperty("modelInfo") + private ModelInfo modelInfo; + + /** The request info. */ + @JsonProperty("requestInfo") + private RequestInfo requestInfo; + + /** The subscriber info. */ + @JsonProperty("subscriberInfo") + private SubscriberInfo subscriberInfo; + + /** The request parameters. */ + @JsonProperty("requestParameters") + private RequestParameters requestParameters; + + /** The additional properties. */ + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * Gets the cloud configuration. + * + * @return The cloudConfiguration + */ + @JsonProperty("cloudConfiguration") + public CloudConfiguration getCloudConfiguration() { + return cloudConfiguration; + } + + /** + * Sets the cloud configuration. + * + * @param cloudConfiguration The cloudConfiguration + */ + @JsonProperty("cloudConfiguration") + public void setCloudConfiguration(CloudConfiguration cloudConfiguration) { + this.cloudConfiguration = cloudConfiguration; + } + + /** + * Gets the model info. + * + * @return The modelInfo + */ + @JsonProperty("modelInfo") + public ModelInfo getModelInfo() { + return modelInfo; + } + + /** + * Sets the model info. + * + * @param modelInfo The modelInfo + */ + @JsonProperty("modelInfo") + public void setModelInfo(ModelInfo modelInfo) { + this.modelInfo = modelInfo; + } + + /** + * Gets the request info. + * + * @return The requestInfo + */ + @JsonProperty("requestInfo") + public RequestInfo getRequestInfo() { + return requestInfo; + } + + /** + * Sets the request info. + * + * @param requestInfo The requestInfo + */ + @JsonProperty("requestInfo") + public void setRequestInfo(RequestInfo requestInfo) { + this.requestInfo = requestInfo; + } + + /** + * Gets the subscriber info. + * + * @return The subscriberInfo + */ + @JsonProperty("subscriberInfo") + public SubscriberInfo getSubscriberInfo() { + return subscriberInfo; + } + + /** + * Sets the subscriber info. + * + * @param subscriberInfo The subscriberInfo + */ + @JsonProperty("subscriberInfo") + public void setSubscriberInfo(SubscriberInfo subscriberInfo) { + this.subscriberInfo = subscriberInfo; + } + + /* (non-Javadoc) + * @see org.openecomp.vid.domain.mso.RequestDetails#toString() + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + /* (non-Javadoc) + * @see org.openecomp.vid.domain.mso.RequestDetails#getAdditionalProperties() + */ + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + /* (non-Javadoc) + * @see org.openecomp.vid.domain.mso.RequestDetails#setAdditionalProperty(java.lang.String, java.lang.Object) + */ + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + /* (non-Javadoc) + * @see org.openecomp.vid.domain.mso.RequestDetails#hashCode() + */ + @Override + public int hashCode() { + return new HashCodeBuilder().append(cloudConfiguration).append(modelInfo).append(requestInfo).append(getRequestParameters()).append(subscriberInfo).append(additionalProperties).toHashCode(); + } + + /* (non-Javadoc) + * @see org.openecomp.vid.domain.mso.RequestDetails#equals(java.lang.Object) + */ + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof RequestDetails) == false) { + return false; + } + RequestDetails rhs = ((RequestDetails) other); + return new EqualsBuilder().append(cloudConfiguration, rhs.cloudConfiguration).append(modelInfo, rhs.modelInfo).append(requestInfo, rhs.requestInfo).append(getRequestParameters(), rhs.getRequestParameters()).append(subscriberInfo, rhs.subscriberInfo).append(additionalProperties, rhs.additionalProperties).isEquals(); + } + + public RequestParameters getRequestParameters() { + return requestParameters; + } + + public void setRequestParameters(RequestParameters requestParameters) { + this.requestParameters = requestParameters; + } + + @JsonGetter + public List<RelatedInstanceList> getRelatedInstList() { + return relatedInstList; + } + + @JsonSetter + public void setRelatedInstList(List<RelatedInstanceList> relatedInstList) { + this.relatedInstList = relatedInstList; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestInfo.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestInfo.java new file mode 100644 index 00000000..6a6844bc --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestInfo.java @@ -0,0 +1,378 @@ + +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.annotation.Generated; +import java.util.HashMap; +import java.util.Map; + + +/** + * fields providing general context information for the request + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "billingAccountNumber", + "callbackUrl", + "correlator", + "instanceName", + "orderNumber", + "orderVersion", + "productFamilyId", + "source", + "suppressRollback", + "responseValue", + "requestorId" +}) +public class RequestInfo { + + /** + * billing account associated with the model being operated on + * + */ + @JsonProperty("billingAccountNumber") + private String billingAccountNumber; + /** + * client URL to use for asynchronous responses + * + */ + @JsonProperty("callbackUrl") + private String callbackUrl; + /** + * Optional correlationId for async callback requests + * + */ + @JsonProperty("correlator") + private String correlator; + /** + * Client provided name for the instance being operated on by the operation (note: not guaranteed to be unique) + * + */ + @JsonProperty("instanceName") + private String instanceName; + /** + * reference to an order + * + */ + @JsonProperty("orderNumber") + private String orderNumber; + /** + * order version number + * + */ + @JsonProperty("orderVersion") + private Double orderVersion; + /** + * UUID for the product family associated with the model being operated on + * + */ + @JsonProperty("productFamilyId") + private String productFamilyId; + /** + * source of the request--not authoritative--actual source revealed via authentication + * + */ + @JsonProperty("source") + private String source; + /** + * true or false boolean indicating whether rollbacks should be suppressed on failures + * + */ + @JsonProperty("suppressRollback") + private Boolean suppressRollback; + /** + * Is the user selected value based on the validResponses list provided to complete the manual task + * + */ + @JsonProperty("responseValue") + private String responseValue; + /** + * The id of the person who initiated the completion request + * + */ + @JsonProperty("requestorId") + private String requestorId; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * billing account associated with the model being operated on + * + * @return + * The billingAccountNumber + */ + @JsonProperty("billingAccountNumber") + public String getBillingAccountNumber() { + return billingAccountNumber; + } + + /** + * billing account associated with the model being operated on + * + * @param billingAccountNumber + * The billingAccountNumber + */ + @JsonProperty("billingAccountNumber") + public void setBillingAccountNumber(String billingAccountNumber) { + this.billingAccountNumber = billingAccountNumber; + } + + /** + * client URL to use for asynchronous responses + * + * @return + * The callbackUrl + */ + @JsonProperty("callbackUrl") + public String getCallbackUrl() { + return callbackUrl; + } + + /** + * client URL to use for asynchronous responses + * + * @param callbackUrl + * The callbackUrl + */ + @JsonProperty("callbackUrl") + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + + /** + * Optional correlationId for async callback requests + * + * @return + * The correlator + */ + @JsonProperty("correlator") + public String getCorrelator() { + return correlator; + } + + /** + * Optional correlationId for async callback requests + * + * @param correlator + * The correlator + */ + @JsonProperty("correlator") + public void setCorrelator(String correlator) { + this.correlator = correlator; + } + + /** + * Client provided name for the instance being operated on by the operation (note: not guaranteed to be unique) + * + * @return + * The instanceName + */ + @JsonProperty("instanceName") + public String getInstanceName() { + return instanceName; + } + + /** + * Client provided name for the instance being operated on by the operation (note: not guaranteed to be unique) + * + * @param instanceName + * The instanceName + */ + @JsonProperty("instanceName") + public void setInstanceName(String instanceName) { + this.instanceName = instanceName; + } + + /** + * reference to an order + * + * @return + * The orderNumber + */ + @JsonProperty("orderNumber") + public String getOrderNumber() { + return orderNumber; + } + + /** + * reference to an order + * + * @param orderNumber + * The orderNumber + */ + @JsonProperty("orderNumber") + public void setOrderNumber(String orderNumber) { + this.orderNumber = orderNumber; + } + + /** + * order version number + * + * @return + * The orderVersion + */ + @JsonProperty("orderVersion") + public Double getOrderVersion() { + return orderVersion; + } + + /** + * order version number + * + * @param orderVersion + * The orderVersion + */ + @JsonProperty("orderVersion") + public void setOrderVersion(Double orderVersion) { + this.orderVersion = orderVersion; + } + + /** + * UUID for the product family associated with the model being operated on + * + * @return + * The productFamilyId + */ + @JsonProperty("productFamilyId") + public String getProductFamilyId() { + return productFamilyId; + } + + /** + * UUID for the product family associated with the model being operated on + * + * @param productFamilyId + * The productFamilyId + */ + @JsonProperty("productFamilyId") + public void setProductFamilyId(String productFamilyId) { + this.productFamilyId = productFamilyId; + } + + /** + * source of the request--not authoritative--actual source revealed via authentication + * + * @return + * The source + */ + @JsonProperty("source") + public String getSource() { + return source; + } + + /** + * source of the request--not authoritative--actual source revealed via authentication + * + * @param source + * The source + */ + @JsonProperty("source") + public void setSource(String source) { + this.source = source; + } + + /** + * true or false boolean indicating whether rollbacks should be suppressed on failures + * + * @return + * The suppressRollback + */ + @JsonProperty("suppressRollback") + public Boolean getSuppressRollback() { + return suppressRollback; + } + + /** + * true or false boolean indicating whether rollbacks should be suppressed on failures + * + * @param suppressRollback + * The suppressRollback + */ + @JsonProperty("suppressRollback") + public void setSuppressRollback(Boolean suppressRollback) { + this.suppressRollback = suppressRollback; + } + + /** + * Is the user selected value based on the validResponses list provided to complete the manual task + * + * @return + * The responseValue + */ + @JsonProperty("responseValue") + public String getResponseValue() { + return responseValue; + } + + /** + * Is the user selected value based on the validResponses list provided to complete the manual task + * + * @param responseValue + * The responseValue + */ + @JsonProperty("responseValue") + public void setResponseValue(String responseValue) { + this.responseValue = responseValue; + } + + /** + * The id of the person who initiated the completion request + * + * @return + * The requestorId + */ + @JsonProperty("requestorId") + public String getRequestorId() { + return requestorId; + } + + /** + * The id of the person who initiated the completion request + * + * @param requestorId + * The requestorId + */ + @JsonProperty("requestorId") + public void setRequestorId(String requestorId) { + this.requestorId = requestorId; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(billingAccountNumber).append(callbackUrl).append(correlator).append(instanceName).append(orderNumber).append(orderVersion).append(productFamilyId).append(source).append(suppressRollback).append(responseValue).append(requestorId).append(additionalProperties).toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof RequestInfo) == false) { + return false; + } + RequestInfo rhs = ((RequestInfo) other); + return new EqualsBuilder().append(billingAccountNumber, rhs.billingAccountNumber).append(callbackUrl, rhs.callbackUrl).append(correlator, rhs.correlator).append(instanceName, rhs.instanceName).append(orderNumber, rhs.orderNumber).append(orderVersion, rhs.orderVersion).append(productFamilyId, rhs.productFamilyId).append(source, rhs.source).append(suppressRollback, rhs.suppressRollback).append(responseValue, rhs.responseValue).append(requestorId, rhs.requestorId).append(additionalProperties, rhs.additionalProperties).isEquals(); + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestParameters.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestParameters.java new file mode 100644 index 00000000..63157e6e --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RequestParameters.java @@ -0,0 +1,102 @@ + +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.annotation.Generated; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "subscriptionServiceType", + "userParams" +}) +public class RequestParameters { + + @JsonProperty("subscriptionServiceType") + private String subscriptionServiceType; + @JsonProperty("userParams") + private List<UserParam> userParams = new ArrayList<UserParam>(); + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The subscriptionServiceType + */ + @JsonProperty("subscriptionServiceType") + public String getSubscriptionServiceType() { + return subscriptionServiceType; + } + + /** + * + * @param subscriptionServiceType + * The subscriptionServiceType + */ + @JsonProperty("subscriptionServiceType") + public void setSubscriptionServiceType(String subscriptionServiceType) { + this.subscriptionServiceType = subscriptionServiceType; + } + + /** + * + * @return + * The userParams + */ + @JsonProperty("userParams") + public List<UserParam> getUserParams() { + return userParams; + } + + /** + * + * @param userParams + * The userParams + */ + @JsonProperty("userParams") + public void setUserParams(List<UserParam> userParams) { + this.userParams = userParams; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(subscriptionServiceType).append(userParams).append(additionalProperties).toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof RequestParameters) == false) { + return false; + } + RequestParameters rhs = ((RequestParameters) other); + return new EqualsBuilder().append(subscriptionServiceType, rhs.subscriptionServiceType).append(userParams, rhs.userParams).append(additionalProperties, rhs.additionalProperties).isEquals(); + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/RestObject.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RestObject.java new file mode 100644 index 00000000..1734d25f --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/RestObject.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.MoreObjects; + +import javax.ws.rs.core.Response; +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +/** + * The Class RestObject. + * + * @param <T> the generic type + */ +public class RestObject<T> { + + final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS"); + + final static ObjectMapper objectMapper = new ObjectMapper(); + + /** + * Generic version of the RestObject class. + * + */ + // T stands for "Type" + private T t; + + // The string source of t, if available + private String rawT; + + /** The status code. */ + private int statusCode= 0; + + public RestObject() { + } + + public RestObject(Response cres, Class<?> tClass) { + + String rawEntity = null; + try { + cres.bufferEntity(); + rawEntity = cres.readEntity(String.class); + T t = (T) objectMapper.readValue(rawEntity, tClass); + this.set(t); + } + catch ( Exception e ) { + try { + this.setRaw(rawEntity); + } catch (Exception e2) { + } + } + + int status = cres.getStatus(); + this.setStatusCode (status); + } + + + /** + * Sets the. + * + * @param t the t + */ + public void set(T t) { this.t = t; } + + /** + * Gets the. + * + * @return the t + */ + public T get() { return t; } + + /** + * Sets the status code. + * + * @param v the new status code + */ + public void setStatusCode(int v) { this.statusCode = v; } + + /** + * Gets the status code. + * + * @return the status code + */ + public int getStatusCode() { return this.statusCode; } + + public String getRaw() { + return rawT; + } + + public void setRaw(String rawT) { + this.rawT = rawT; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("t", t) + .add("rawT", rawT) + .add("statusCode", statusCode) + .toString(); + } +} + diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/SubscriberInfo.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/SubscriberInfo.java new file mode 100644 index 00000000..2f176f77 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/SubscriberInfo.java @@ -0,0 +1,146 @@ + +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.annotation.Generated; +import java.util.HashMap; +import java.util.Map; + + +/** + * fields providing information about the subscriber associated with the request + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "globalSubscriberId", + "subscriberCommonSiteId", + "subscriberName" +}) +public class SubscriberInfo { + + /** + * global Customer Id understood by A&AI + * + */ + @JsonProperty("globalSubscriberId") + private String globalSubscriberId; + /** + * id representing the location of the subscriber + * + */ + @JsonProperty("subscriberCommonSiteId") + private String subscriberCommonSiteId; + /** + * name of the customer or subscriber + * + */ + @JsonProperty("subscriberName") + private String subscriberName; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * global Customer Id understood by A&AI + * + * @return + * The globalSubscriberId + */ + @JsonProperty("globalSubscriberId") + public String getGlobalSubscriberId() { + return globalSubscriberId; + } + + /** + * global Customer Id understood by A&AI + * + * @param globalSubscriberId + * The globalSubscriberId + */ + @JsonProperty("globalSubscriberId") + public void setGlobalSubscriberId(String globalSubscriberId) { + this.globalSubscriberId = globalSubscriberId; + } + + /** + * id representing the location of the subscriber + * + * @return + * The subscriberCommonSiteId + */ + @JsonProperty("subscriberCommonSiteId") + public String getSubscriberCommonSiteId() { + return subscriberCommonSiteId; + } + + /** + * id representing the location of the subscriber + * + * @param subscriberCommonSiteId + * The subscriberCommonSiteId + */ + @JsonProperty("subscriberCommonSiteId") + public void setSubscriberCommonSiteId(String subscriberCommonSiteId) { + this.subscriberCommonSiteId = subscriberCommonSiteId; + } + + /** + * name of the customer or subscriber + * + * @return + * The subscriberName + */ + @JsonProperty("subscriberName") + public String getSubscriberName() { + return subscriberName; + } + + /** + * name of the customer or subscriber + * + * @param subscriberName + * The subscriberName + */ + @JsonProperty("subscriberName") + public void setSubscriberName(String subscriberName) { + this.subscriberName = subscriberName; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(globalSubscriberId).append(subscriberCommonSiteId).append(subscriberName).append(additionalProperties).toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof SubscriberInfo) == false) { + return false; + } + SubscriberInfo rhs = ((SubscriberInfo) other); + return new EqualsBuilder().append(globalSubscriberId, rhs.globalSubscriberId).append(subscriberCommonSiteId, rhs.subscriberCommonSiteId).append(subscriberName, rhs.subscriberName).append(additionalProperties, rhs.additionalProperties).isEquals(); + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/mso/UserParam.java b/vid-automation/src/test/java/org/opencomp/vid/model/mso/UserParam.java new file mode 100644 index 00000000..ab449c2a --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/mso/UserParam.java @@ -0,0 +1,100 @@ + +package org.opencomp.vid.model.mso; + +import com.fasterxml.jackson.annotation.*; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.annotation.Generated; +import java.util.HashMap; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "name", + "value" +}) +public class UserParam { + + @JsonProperty("name") + private String name; + @JsonProperty("value") + private String value; + @JsonIgnore + private Map<String, Object> additionalProperties = new HashMap<String, Object>(); + + /** + * + * @return + * The name + */ + @JsonProperty("name") + public String getName() { + return name; + } + + /** + * + * @param name + * The name + */ + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + /** + * + * @return + * The value + */ + @JsonProperty("value") + public String getValue() { + return value; + } + + /** + * + * @param value + * The value + */ + @JsonProperty("value") + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map<String, Object> getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(name).append(value).append(additionalProperties).toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof UserParam) == false) { + return false; + } + UserParam rhs = ((UserParam) other); + return new EqualsBuilder().append(name, rhs.name).append(value, rhs.value).append(additionalProperties, rhs.additionalProperties).isEquals(); + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/probe/ExternalComponentStatus.java b/vid-automation/src/test/java/org/opencomp/vid/model/probe/ExternalComponentStatus.java new file mode 100644 index 00000000..8d548842 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/probe/ExternalComponentStatus.java @@ -0,0 +1,28 @@ +package org.opencomp.vid.model.probe; + +public class ExternalComponentStatus { + public enum Component {AAI, MSO} + private Component component; + private boolean available; + private HttpRequestMetadata metadata; + + public ExternalComponentStatus(){} + + public ExternalComponentStatus(Component component, boolean isAvailable, HttpRequestMetadata metadata) { + this.component = component; + this.available = isAvailable; + this.metadata = metadata; + } + + public Component getComponent() { + return component; + } + + public boolean isAvailable() { + return available; + } + + public HttpRequestMetadata getMetadata() { + return metadata; + } +}
\ No newline at end of file diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/probe/HttpRequestMetadata.java b/vid-automation/src/test/java/org/opencomp/vid/model/probe/HttpRequestMetadata.java new file mode 100644 index 00000000..4ab5ae4a --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/probe/HttpRequestMetadata.java @@ -0,0 +1,49 @@ +package org.opencomp.vid.model.probe; + +import org.springframework.http.HttpMethod; + +public class HttpRequestMetadata { + + + public HttpMethod getHttpMethod() { + return httpMethod; + } + + public int getHttpCode() { + return httpCode; + } + + public String getUrl() { + return url; + } + + public String getRawData() { + return rawData; + } + + public float getDuration() { + return duration; + } + + public String getDescription() { + return description; + } + + private HttpMethod httpMethod; + private int httpCode; + private String url; + private String rawData; + private String description; + private float duration; + + public HttpRequestMetadata(){ + } + + public HttpRequestMetadata(HttpMethod httpMethod,int httpCode, String url, String rawData, String description) { + this.httpMethod = httpMethod; + this.httpCode = httpCode; + this.url = url; + this.rawData = rawData; + this.description = description; + } +}
\ No newline at end of file diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/GetVnfWorkflowRelationRequest.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/GetVnfWorkflowRelationRequest.java new file mode 100644 index 00000000..e2f15ba9 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/GetVnfWorkflowRelationRequest.java @@ -0,0 +1,28 @@ +package org.opencomp.vid.model.workflow; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class GetVnfWorkflowRelationRequest { + + public GetVnfWorkflowRelationRequest() { + } + + public GetVnfWorkflowRelationRequest(List<VnfDetails> vnfsDetails) { + this.vnfsDetails = vnfsDetails; + } + + @JsonProperty("vnfsDetails") + private List<VnfDetails> vnfsDetails; + + @JsonProperty("vnfsDetails") + public List<VnfDetails> getVnfDetails() { + return vnfsDetails; + } + + @JsonProperty("vnfsDetails") + public void setVnfDetails(List<VnfDetails> vnfDetails) { + this.vnfsDetails = vnfDetails; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/GetWorkflowsResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/GetWorkflowsResponse.java new file mode 100644 index 00000000..f1005b2a --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/GetWorkflowsResponse.java @@ -0,0 +1,24 @@ +package org.opencomp.vid.model.workflow; + +import java.util.List; + +public class GetWorkflowsResponse { + private List<String> workflows; + + public GetWorkflowsResponse() { + } + + public GetWorkflowsResponse(List<String> workflows) { + this.workflows = workflows; + } + + public List<String> getWorkflows() { + return workflows; + } + + public void setWorkflows(List<String> workflows) { + this.workflows = workflows; + } + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/ListOfErrorsResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/ListOfErrorsResponse.java new file mode 100644 index 00000000..60b733fe --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/ListOfErrorsResponse.java @@ -0,0 +1,24 @@ +package org.opencomp.vid.model.workflow; + +import java.util.ArrayList; +import java.util.List; + +public class ListOfErrorsResponse { + protected List<String> errors; + + public ListOfErrorsResponse() { + this.errors = new ArrayList<>(); + } + + public ListOfErrorsResponse(List<String> errors) { + this.errors = errors; + } + + public List<String> getErrors() { + return errors; + } + + public void setErrors(List<String> errors) { + this.errors = errors; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfDetails.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfDetails.java new file mode 100644 index 00000000..a7b27356 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfDetails.java @@ -0,0 +1,66 @@ +package org.opencomp.vid.model.workflow; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class VnfDetails { + + public VnfDetails() { + } + + public VnfDetails(String UUID, String invariantUUID) { + this.UUID = UUID; + this.invariantUUID = invariantUUID; + } + + @JsonProperty("UUID") + private String UUID; + + @JsonProperty("invariantUUID") + private String invariantUUID; + + @JsonProperty("UUID") + public String getUUID() { + return UUID; + } + + @JsonProperty("UUID") + public void setUUID(String uUID) { + UUID = uUID; + } + + @JsonProperty("invariantUUID") + public String getInvariantUUID() { + return invariantUUID; + } + + @JsonProperty("invariantUUID") + public void setInvariantUUID(String invariantUUID) { + this.invariantUUID = invariantUUID; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + VnfDetails that = (VnfDetails) o; + + if (getUUID() != null ? !getUUID().equals(that.getUUID()) : that.getUUID() != null) return false; + return getInvariantUUID() != null ? getInvariantUUID().equals(that.getInvariantUUID()) : that.getInvariantUUID() == null; + } + + @Override + public int hashCode() { + int result = getUUID() != null ? getUUID().hashCode() : 0; + result = 31 * result + (getInvariantUUID() != null ? getInvariantUUID().hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "VnfDetails{" + + "UUID='" + UUID + '\'' + + ", invariantUUID='" + invariantUUID + '\'' + + '}'; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfDetailsWithWorkflows.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfDetailsWithWorkflows.java new file mode 100644 index 00000000..953e25b7 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfDetailsWithWorkflows.java @@ -0,0 +1,27 @@ +package org.opencomp.vid.model.workflow; + + +import java.util.List; + +public class VnfDetailsWithWorkflows extends VnfDetails { + + private List<String> workflows; + + public VnfDetailsWithWorkflows() { + } + + + @SuppressWarnings("WeakerAccess") + public VnfDetailsWithWorkflows(String UUID, String invariantUUID, List<String> workflows) { + super(UUID, invariantUUID); + this.workflows = workflows; + } + + public List<String> getWorkflows() { + return workflows; + } + + public void setWorkflows(List<String> workflows) { + this.workflows = workflows; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationAllResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationAllResponse.java new file mode 100644 index 00000000..3f0cc3ef --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationAllResponse.java @@ -0,0 +1,23 @@ +package org.opencomp.vid.model.workflow; + +import java.util.List; + +public class VnfWorkflowRelationAllResponse { + + private List<VnfDetailsWithWorkflows> vnfs; + + public VnfWorkflowRelationAllResponse() { + } + + public VnfWorkflowRelationAllResponse(List<VnfDetailsWithWorkflows> vnfs) { + this.vnfs = vnfs; + } + + public List<VnfDetailsWithWorkflows> getVnfs() { + return vnfs; + } + + public void setVnfs(List<VnfDetailsWithWorkflows> vnfs) { + this.vnfs = vnfs; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationRequest.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationRequest.java new file mode 100644 index 00000000..86ac2b40 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationRequest.java @@ -0,0 +1,31 @@ +package org.opencomp.vid.model.workflow; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public class VnfWorkflowRelationRequest { + + public VnfWorkflowRelationRequest() { + } + + public VnfWorkflowRelationRequest(List<WorkflowsDetail> workflowsDetails) { + this.workflowsDetails = workflowsDetails; + } + + @JsonProperty("workflowsDetails") + private List<WorkflowsDetail> workflowsDetails; + + @JsonProperty("workflowsDetails") + public List<WorkflowsDetail> getWorkflowsDetails() { + return workflowsDetails; + } + + @JsonProperty("workflowsDetails") + public void setWorkflowsDetails(List<WorkflowsDetail> workflowsDetails) { + this.workflowsDetails = workflowsDetails; + } + + + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationResponse.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationResponse.java new file mode 100644 index 00000000..fdc57ad1 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/VnfWorkflowRelationResponse.java @@ -0,0 +1,14 @@ +package org.opencomp.vid.model.workflow; + + +import java.util.List; + +public class VnfWorkflowRelationResponse extends ListOfErrorsResponse { + + public VnfWorkflowRelationResponse() { + } + + public VnfWorkflowRelationResponse(List<String> errors) { + super(errors); + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/model/workflow/WorkflowsDetail.java b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/WorkflowsDetail.java new file mode 100644 index 00000000..a67f724c --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/model/workflow/WorkflowsDetail.java @@ -0,0 +1,43 @@ +package org.opencomp.vid.model.workflow; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class WorkflowsDetail { + + public WorkflowsDetail() { + } + + public WorkflowsDetail(VnfDetails vnfDetails, String workflowName) { + this.vnfDetails = vnfDetails; + this.workflowName = workflowName; + } + + @JsonProperty("vnfDetails") + private VnfDetails vnfDetails; + + @JsonProperty("workflowName") + private String workflowName; + + @JsonProperty("vnfDetails") + public VnfDetails getVnfDetails() { + return vnfDetails; + } + @JsonProperty("vnfDetails") + public void setVnfDetails(VnfDetails vnfDetails) { + this.vnfDetails = vnfDetails; + } + @JsonProperty("workflowName") + public String getWorkflowName() { + return workflowName; + } + @JsonProperty("workflowName") + public void setWorkflowName(String workflowName) { + this.workflowName = workflowName; + } + + @Override + public String toString() { + return vnfDetails + + ", workflowName='" + workflowName; + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/more/LoggerFormatTest.java b/vid-automation/src/test/java/org/opencomp/vid/more/LoggerFormatTest.java new file mode 100644 index 00000000..8b3d244b --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/more/LoggerFormatTest.java @@ -0,0 +1,97 @@ +package org.opencomp.vid.more; + +import com.fasterxml.jackson.databind.JsonNode; +import org.apache.commons.lang3.StringUtils; +import org.opencomp.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet; +import org.opencomp.vid.api.BaseApiTest; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.web.client.RestTemplate; +import org.testng.SkipException; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import vid.automation.test.services.SimulatorApi; + +import java.net.URI; +import java.time.LocalDate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static java.util.Collections.singletonList; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.junit.Assert.assertThat; + +public class LoggerFormatTest extends BaseApiTest { + + + // See: https://wiki.web.att.com/display/KSAT/REST-based+Log+Checker + private final static String logChecker = "http://eelflogcheck.it.att.com:31820/validate"; + + @BeforeClass + public void login() { + super.login(); + } + + @BeforeClass + public void setAaiSubscribers() { + SimulatorApi.registerExpectationFromPreset(new PresetAAIGetSubscribersGet(), SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET); + } + + @Test + public void validateAuditLogsFormat() { + validateLogsFormat("audit"); + } + + @Test(enabled = false) // no total-score is returned for error-log + public void validateErrorLogsFormat() { + validateLogsFormat("error"); + } + + @Test + public void validateMetricsLogsFormat() { + validateLogsFormat("metrics", "metric"); + } + + private void validateLogsFormat(String logName) { + validateLogsFormat(logName, logName); + } + + private void validateLogsFormat(String logName, String logType) { + + String logLines = getLogLines(logName); + JsonNode response = getCheckerResults(logType, logLines); + + System.out.println(response); + double fieldscore = response.path("summary").path("score").path("fieldscore").asDouble(); + double overall = response.path("summary").path("score").path("overallscore").asDouble(); + + assertThat(fieldscore, is(greaterThan(0.95))); + assertThat(overall, is(greaterThan(0.95))); + + } + + private String getLogLines(String logname) { + return getLogLines(logname, 5000, 30, restTemplate, uri); + } + + public static String getLogLines(String logname, int maxRows, int minRows, RestTemplate restTemplate, URI uri) { + String logLines = restTemplate.getForObject(uri + "/logger/" + logname + "?limit={maxRows}", String.class, maxRows); + assertThat("expecting at least " + minRows + " rows in " + logname, + StringUtils.countMatches(logLines, '\n') + 1, + is(greaterThanOrEqualTo(minRows))); + return logLines; + } + + private JsonNode getCheckerResults(String logtype, String logLines) { + Map<String, String> params = new HashMap<>(); + params.put("format", "raw"); + params.put("type", logtype); + params.put("component", "vid"); + params.put("data", logLines); + + return restTemplate.postForObject(logChecker, params, JsonNode.class); + } +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/more/RequestIdFilterInstalled.java b/vid-automation/src/test/java/org/opencomp/vid/more/RequestIdFilterInstalled.java new file mode 100644 index 00000000..63790476 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/more/RequestIdFilterInstalled.java @@ -0,0 +1,184 @@ +package org.opencomp.vid.more; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.opencomp.vid.api.BaseApiTest; +import org.opencomp.vid.api.OperationalEnvironmentControllerApiTest; +import org.opencomp.vid.api.ServiceInstanceMsoApiTest; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import vid.automation.test.services.SimulatorApi; + +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.opencomp.vid.api.CategoryParametersApiTest.GET_CATEGORY_PARAMETER_PROPERTIES; +import static org.opencomp.vid.api.pProbeMsoApiTest.MSO_CREATE_CONFIGURATION; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND; + +public class RequestIdFilterInstalled extends BaseApiTest { + + /* + Tests whether every incoming request to VID goes through + the requestId filter. This happens by checking the log + AND by checking the echoed header. + + The correctness of the Filter itself is done by unit- + tests. + + The outgoing (outgress) headers are checked by the REST + Clients unit-tests. + */ + + private static final String ECOMP_REQUEST_ID = "x-ecomp-requestid"; + private final String ECOMP_REQUEST_ID_ECHO = ECOMP_REQUEST_ID + "-echo"; + + @BeforeClass + public void login() { + super.login(); + } + + @Test + public void frontendApi_doGET_RequestIdReceived() { + + final Pair<HttpEntity, String> responseAndUuid = makeRequest( + HttpMethod.GET, + "/operationalEnvironment/requestStatus?requestId=" + OperationalEnvironmentControllerApiTest.GET_STATUS_REQUEST_UUID, + null, + OperationalEnvironmentControllerApiTest.GET_CLOUD_RESOURCES_REQUEST_STATUS + ); + assertThatUuidInResponseAndUuidIsInARecentLog(responseAndUuid); + + } + + @Test + public void frontendApi_doPOST_RequestIdReceived() { + + final Pair<HttpEntity, String> responseAndUuid = makeRequest( + HttpMethod.POST, + "/" + ServiceInstanceMsoApiTest.MSO_DEACTIVATE_SERVICE_INSTANCE, + "{}", + ServiceInstanceMsoApiTest.DEACTIVATE_OK_JSON + ); + assertThatUuidInResponseAndUuidIsInARecentLog(responseAndUuid); + } + + @Test + public void frontendApi_doPOSTWithClientError_RequestIdReceived() { + + final Pair<HttpEntity, String> responseAndUuid = makeRequest( + HttpMethod.POST, + "/" + MSO_CREATE_CONFIGURATION, + "i'm not a json" + ); + assertThatUuidInResponseAndUuidIsInARecentLog(responseAndUuid); + + } + + + @Test(groups = { "worksOnlyWithLocalhostVID" }) + public void mopOwningEntityApi_doGET_RequestIdReceived() { + + final Pair<HttpEntity, String> responseAndUuid = makeRequest( + HttpMethod.GET, + "/" + GET_CATEGORY_PARAMETER_PROPERTIES + "?familyName=PARAMETER_STANDARDIZATION", + null + ); + + assertThatUuidInResponseAndUuidIsInARecentLog(responseAndUuid); + + /* + test should be for: + x few FE requests; + x few FE errors requests; + - few UI elements requests; + x scheduler callback; + - MOP of workflows; + x MOP of OE; + - health-check + */ + } + + @Test + public void schedulerApi_doPOST_RequestIdReceived() { + + final String anyInstanceId = "any instance id"; + SimulatorApi.registerExpectation( + "mso_in_place_software_update_ok.json", + ImmutableMap.of("SERVICE_INSTANCE_ID", anyInstanceId, "VNF_INSTANCE_ID", anyInstanceId), SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET); + final Pair<HttpEntity, String> responseAndUuid = makeRequest( + HttpMethod.POST, + "/change-management/workflow/" + anyInstanceId, + "{}" + ); + assertThatUuidInResponseAndUuidIsInARecentLog(responseAndUuid); + + } + + @Test + public void healthcheck_doGET_RequestIdReceived(){ + final Pair<HttpEntity, String> responseAndUuid = makeRequest( + HttpMethod.GET, "/healthCheck", null + ); + assertThatUuidInResponseAndUuidIsInARecentLog(responseAndUuid); + } + + private void assertThatUuidInResponseAndUuidIsInARecentLog(Pair<HttpEntity, String> responseAndUuid) { + assertThatResponseHasUuid(responseAndUuid.getLeft(), responseAndUuid.getRight()); + assertThatTermIsInARecentLog(responseAndUuid.getRight()); + } + + private void assertThatResponseHasUuid(HttpEntity response, String uuid) { + // THIS TEST IS NOT JUST NICE TO HAVE, it also lets us know + // that the request/response ran through our "promise request + // id" filter, which is great! + assertThat(response, not(nullValue())); + assertThat(response.getHeaders().get(ECOMP_REQUEST_ID_ECHO), containsInAnyOrder(uuid)); + } + + private void assertThatTermIsInARecentLog(String uuid) { + final ImmutableList<String> logLines = ImmutableList.of( + LoggerFormatTest.getLogLines("audit", 5, 0, restTemplate, uri), + LoggerFormatTest.getLogLines("error", 5, 0, restTemplate, uri) + ); + + // Assert that audit *OR* error has the uuid + assertThat("uuid not found in any log", logLines, hasItem(containsString(uuid))); + } + + private Pair<HttpEntity, String> makeRequest(HttpMethod httpMethod, String url, String body) { + return makeRequest(httpMethod, url, body, null); + } + + private Pair<HttpEntity, String> makeRequest(HttpMethod httpMethod, String url, String body, String expectationFilename) { + final String uuid = UUID.randomUUID().toString(); + final HttpHeaders headers = new HttpHeaders(); + headers.add(ECOMP_REQUEST_ID, uuid); + headers.add(AUTHORIZATION, "Basic 123=="); + + SimulatorApi.clearExpectations(); + if (!StringUtils.isEmpty(expectationFilename)) { + SimulatorApi.registerExpectation(expectationFilename, APPEND); + } + SimulatorApi.registerExpectation("aai_get_full_subscribers.json", APPEND); + SimulatorApi.registerExpectation("ecompportal_getSessionSlotCheckInterval.json", APPEND); + + HttpEntity entity = new HttpEntity<>(body, headers); + ResponseEntity<String> response = null; + response = restTemplateErrorAgnostic.exchange(uri + url, + httpMethod, entity, String.class); + + return Pair.of(response, uuid); + } + +} diff --git a/vid-automation/src/test/java/org/opencomp/vid/more/SimulatorLoaderTest.java b/vid-automation/src/test/java/org/opencomp/vid/more/SimulatorLoaderTest.java new file mode 100644 index 00000000..2bcf0698 --- /dev/null +++ b/vid-automation/src/test/java/org/opencomp/vid/more/SimulatorLoaderTest.java @@ -0,0 +1,127 @@ +package org.opencomp.vid.more; + +import org.opencomp.simulator.presetGenerator.presets.BasePresets.BasePreset; +import org.opencomp.simulator.presetGenerator.presets.aai.*; +import org.opencomp.simulator.presetGenerator.presets.ecompportal_att.PresetGetSessionSlotCheckIntervalGet; +import org.opencomp.simulator.presetGenerator.presets.ecompportal_att.PresetGetUserGet; +import org.opencomp.simulator.presetGenerator.presets.mso.PresetActivateServiceInstancePost; +import org.opencomp.simulator.presetGenerator.presets.mso.PresetDeactivateServiceInstancePost; +import org.opencomp.simulator.presetGenerator.presets.mso.PresetMSOCreateServiceInstancePost; +import org.opencomp.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGet; +import org.opencomp.simulator.presetGenerator.presets.sdc.PresetSDCGetServiceMetadataGet; +import org.opencomp.simulator.presetGenerator.presets.sdc.PresetSDCGetServiceToscaModelGet; +import org.opencomp.vid.api.BaseApiTest; +import org.springframework.http.HttpMethod; +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.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static org.testng.Assert.assertEquals; +import static vid.automation.test.services.SimulatorApi.registerExpectationFromPreset; +import static vid.automation.test.services.SimulatorApi.registerExpectationFromPresets; + +public class SimulatorLoaderTest extends BaseApiTest { + + + protected Invocation.Builder createSimulatorRequestBuilder(BasePreset preset) { + WebTarget webTarget = client.target(SimulatorApi.getSimulationUri() + preset.getReqPath()); + webTarget = addQueryParamsToWebTarget(preset, webTarget); + return webTarget.request() + .accept("application/json"); + } + + private WebTarget addQueryParamsToWebTarget(BasePreset preset, WebTarget webTarget) { + if (preset.getQueryParams() != null) { + for (Map.Entry<String, List> entry : preset.getQueryParams().entrySet()) { + webTarget = webTarget.queryParam(entry.getKey(), entry.getValue().toArray()); + } + } + return webTarget; + } + + @DataProvider + public static Object[][] presetClassesWithPutPost(Method test) { + return new Object[][]{ + {new PresetAAIGetPNFByRegionErrorPut()}, + {new PresetAAIServiceDesignAndCreationPut("a","b")}, + {new PresetDeactivateServiceInstancePost()}, + {new PresetActivateServiceInstancePost()}, + {new PresetMSOCreateServiceInstancePost()} + }; + } + + @Test(dataProvider = "presetClassesWithPutPost") + public<C extends BasePreset> void presetPutPost_WhenLoaded_SimulatorReturnsFakeValues(C preset) { + registerExpectationFromPreset(preset, RegistrationStrategy.CLEAR_THEN_SET); + + Response cres = createSimulatorRequestBuilder(preset) + .method(preset.getReqMethod().name(), + Entity.entity(preset.getRequestBody(), MediaType.APPLICATION_JSON)); + + int status = cres.getStatus(); + + assertEquals(status, preset.getResponseCode()); + } + + @DataProvider + public static Object[][] presetWithGetInstances(Method test) { + return new Object[][]{ + {new PresetAAIGetSubscribersGet()}, + {new PresetGetSessionSlotCheckIntervalGet()}, + {new PresetGetUserGet()}, + {new PresetAAIGetServicesGet()}, + {new PresetSDCGetServiceMetadataGet("a" , "b", "serviceCreationTest.zip")}, + {new PresetSDCGetServiceToscaModelGet( "a", "serviceCreationTest.zip")}, + {new PresetMSOOrchestrationRequestGet()}, + {new PresetAAIGetNetworkZones()}, + {new PresetAAISearchNodeQueryEmptyResult()}, + {new PresetAAIBadBodyForGetServicesGet("not a json")}, + }; + } + + @Test(dataProvider = "presetWithGetInstances") + public <C extends BasePreset> void assertPresetWithGetMethod(C preset) { + registerExpectationFromPreset(preset, RegistrationStrategy.CLEAR_THEN_SET); + + Response cres = createSimulatorRequestBuilder(preset).get(); + + int status = cres.getStatus(); + + assertEquals(status, preset.getResponseCode()); + } + + @Test(expectedExceptions = { RuntimeException.class }, expectedExceptionsMessageRegExp = ".*SimulatorLoaderTest.*") + public void assertPresetThatThrowException() { + + registerExpectationFromPresets(Collections.singletonList( + new BasePreset() { + + @Override + public HttpMethod getReqMethod() { + throw new RuntimeException(); + } + + @Override + public String getReqPath() { + return null; + } + + @Override + protected String getRootPath() { + return null; + } + }), RegistrationStrategy.CLEAR_THEN_SET); + } + +} |