aboutsummaryrefslogtreecommitdiffstats
path: root/vid-automation/src/main/java/org/onap/vid
diff options
context:
space:
mode:
Diffstat (limited to 'vid-automation/src/main/java/org/onap/vid')
-rw-r--r--vid-automation/src/main/java/org/onap/vid/api/AsyncInstantiationBase.java573
-rw-r--r--vid-automation/src/main/java/org/onap/vid/api/BaseApiTest.java163
-rw-r--r--vid-automation/src/main/java/org/onap/vid/api/BaseMsoApiTest.java108
-rw-r--r--vid-automation/src/main/java/org/onap/vid/api/CreateInstanceWithFailedService.java87
-rw-r--r--vid-automation/src/main/java/org/onap/vid/api/CreateServiceWithFailedVnf.java226
-rw-r--r--vid-automation/src/main/java/org/onap/vid/api/TestUtils.java99
-rw-r--r--vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/JobAuditStatus.java141
-rw-r--r--vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/ServiceInfo.java80
-rw-r--r--vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapper2.java60
-rw-r--r--vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapperInterface.java15
-rw-r--r--vid-automation/src/main/java/org/onap/vid/model/mso/RestObject.java119
11 files changed, 1671 insertions, 0 deletions
diff --git a/vid-automation/src/main/java/org/onap/vid/api/AsyncInstantiationBase.java b/vid-automation/src/main/java/org/onap/vid/api/AsyncInstantiationBase.java
new file mode 100644
index 000000000..2a6b012fe
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/api/AsyncInstantiationBase.java
@@ -0,0 +1,573 @@
+package org.onap.vid.api;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toMap;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasSize;
+import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+import static vid.automation.test.utils.ExtendedHamcrestMatcher.hasItemsFromCollection;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Uninterruptibles;
+import java.time.Instant;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import org.apache.commons.lang3.StringUtils;
+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.hamcrest.MatcherAssert;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetCloudOwnersByCloudRegionId;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
+import org.onap.simulator.presetGenerator.presets.ecompportal_att.PresetGetSessionSlotCheckIntervalGet;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOBaseCreateInstancePost;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOBaseDelete;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOCreateServiceInstanceGen2WithNames;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGet;
+import org.onap.vid.model.asyncInstantiation.JobAuditStatus;
+import org.onap.vid.model.asyncInstantiation.ServiceInfo;
+import org.onap.vid.model.mso.MsoResponseWrapper2;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import vid.automation.test.infra.Features;
+import vid.automation.test.infra.Wait;
+import vid.automation.test.model.JobStatus;
+import vid.automation.test.model.ServiceAction;
+import vid.automation.test.services.AsyncJobsService;
+import vid.automation.test.services.SimulatorApi;
+
+public class AsyncInstantiationBase extends BaseMsoApiTest {
+
+ public static final String CREATE_BULK_OF_ALACARTE_REQUEST_WITH_VNF = "asyncInstantiation/vidRequestCreateALaCarteWithVnf.json";
+ protected static final String CREATE_BULK_OF_MACRO_REQUEST = "asyncInstantiation/vidRequestCreateBulkOfMacro.json";
+
+ protected static final String MSO_BASE_ERROR =
+ "Received error from SDN-C: java.lang.IllegalArgumentException: All keys must be specified for class org."+
+ "opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.vf.module.assignments.vf."+
+ "module.assignments.vms.VmKey. Missing key is getVmType. Supplied key is VmKey [].";
+ protected static final String MSO_ERROR = MSO_BASE_ERROR + StringUtils.repeat(" and a lot of sentences for long message", 60);
+
+ @BeforeClass
+ protected void muteAndDropNameCounter() {
+ AsyncJobsService asyncJobsService = new AsyncJobsService();
+ asyncJobsService.muteAllAsyncJobs();
+ asyncJobsService.dropAllFromNameCounter();
+ }
+
+ @AfterMethod
+ protected void muteAllAsyncJobs() {
+ AsyncJobsService asyncJobsService = new AsyncJobsService();
+ asyncJobsService.muteAllAsyncJobs();
+ }
+
+ @DataProvider
+ public static Object[][] trueAndFalse() {
+ return new Object[][]{{TRUE},{FALSE}};
+ }
+
+ protected String getCreateBulkUri() {
+ return uri.toASCIIString() + "/asyncInstantiation/bulk";
+ }
+
+ protected String getHideServiceUri(String jobId) {
+ return uri.toASCIIString() + "/asyncInstantiation/hide/"+jobId;
+ }
+
+ protected String getServiceInfoUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation";
+ }
+
+ protected String getJobAuditUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation/auditStatus/{JOB_ID}?source={SOURCE}";
+ }
+
+ protected String getMsoJobAuditUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation/auditStatus/{JOB_ID}/mso";
+ }
+
+ protected String getDeleteServiceUrl(String uuid) {
+ return uri.toASCIIString() + "/asyncInstantiation/job/" + uuid;
+ }
+
+ protected String getInstanceAuditInfoUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation/auditStatus/{TYPE}/{INSTANCE_ID}/mso";
+ }
+
+ protected String getRetryJobUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation/retry/{JOB_ID}";
+ }
+ protected String getTopologyForRetryUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation/bulkForRetry/{JOB_ID}";
+ }
+
+
+ protected String getRetryJobWithChangedDataUrl() {
+ return uri.toASCIIString() + "/asyncInstantiation/retryJobWithChangedData/{JOB_ID}";
+ }
+
+ protected boolean getExpectedRetryEnabled(JobStatus jobStatus) {
+ return Features.FLAG_1902_RETRY_JOB.isActive() && (jobStatus==JobStatus.FAILED || jobStatus==JobStatus.COMPLETED_WITH_ERRORS);
+ }
+
+ public List<BasePreset> getPresets(List<PresetMSOBaseDelete> presetOnDeleteList, List<PresetMSOBaseCreateInstancePost> presetOnCreateList, List<PresetMSOOrchestrationRequestGet> presetInProgressList) {
+
+ final ImmutableList.Builder<BasePreset> basePresetBuilder = new ImmutableList.Builder<>();
+ basePresetBuilder
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .addAll(presetOnDeleteList)
+ .addAll(presetOnCreateList)
+ .addAll(presetInProgressList);
+ return basePresetBuilder.build();
+ }
+
+ public List<BasePreset> getDeletePresets(List<PresetMSOBaseDelete> presetOnDeleteList, List<PresetMSOOrchestrationRequestGet> presetInProgressList) {
+ return getPresets(presetOnDeleteList, emptyList(), presetInProgressList);
+ }
+
+ public List<BasePreset> getPresets(List<PresetMSOBaseCreateInstancePost> presetOnCreateList, List<PresetMSOOrchestrationRequestGet> presetInProgressList) {
+ return getPresets(emptyList(), presetOnCreateList, presetInProgressList);
+ }
+
+ public void assertServiceInfoSpecific1(String jobId, JobStatus jobStatus, String serviceInstanceName, String userName) {
+ assertServiceInfoSpecific1(jobId, jobStatus, serviceInstanceName, userName, null, ServiceAction.INSTANTIATE);
+ }
+
+ public void assertServiceInfoSpecific1(String jobId, JobStatus jobStatus, String serviceInstanceName, String userName, String instanceId, ServiceAction action) {
+ assertExpectedStatusAndServiceInfo(jobStatus, jobId, new ServiceInfo(
+ userName, jobStatus, false,
+ "038d99af-0427-42c2-9d15-971b99b9b489", "Lucine Sarika", "zasaki",
+ "de738e5f-3704-4a14-b98f-3bf86ac0c0a0", "voloyakane-senamo",
+ "c85f0e80-0636-44a4-8cb2-4ec00d056e79", "Hedvika Wendelin",
+ "a93f8383-707e-43fa-8191-a6e69a1aab17", null,
+ "TYLER SILVIA", "SILVIA ROBBINS",
+ instanceId, serviceInstanceName,
+ "e3c34d88-a216-4f1d-a782-9af9f9588705", "gayawabawe", "5.1",
+ jobId, null, action, false)
+ );
+ }
+
+ public void assertServiceInfoSpecific1(String jobId, JobStatus jobStatus, String serviceInstanceName) {
+ assertServiceInfoSpecific1(jobId, jobStatus, serviceInstanceName, "us16807000");
+ }
+
+ protected void assertAuditStatuses(String jobId, List<JobAuditStatus> expectedVidStatuses, List<JobAuditStatus> expectedMsoStatuses) {
+ assertAuditStatuses(jobId, expectedVidStatuses, expectedMsoStatuses, 15);
+ }
+
+ protected void assertAuditStatuses(String jobId, List<JobAuditStatus> expectedVidStatuses, List<JobAuditStatus> expectedMsoStatuses, long timeoutInSeconds) {
+ assertAndRetryIfNeeded(() -> {
+ final List<JobAuditStatus> auditVidStatuses = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.VID.name());
+ assertThat(auditVidStatuses, hasItemsFromCollection(expectedVidStatuses));
+ if (expectedMsoStatuses!=null) {
+ final List<JobAuditStatus> auditMsoStatuses = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name());
+ assertThat(auditMsoStatuses, containsInAnyOrder(expectedMsoStatuses.toArray()));
+ }
+ }, timeoutInSeconds);
+ }
+
+ protected void assertAndRetryIfNeeded(Runnable asserter, long timeoutInSeconds) {
+ final Instant expiry = Instant.now().plusSeconds(timeoutInSeconds);
+ while (true) {
+ try {
+ asserter.run();
+ break; // we're cool, assertion passed
+ } catch (AssertionError fail) {
+ Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
+ if (Instant.now().isAfter(expiry)) {
+ throw fail;
+ } else {
+ System.out.println("retrying after: " + fail);
+ }
+ }
+ }
+ }
+
+ protected ImmutableList<JobAuditStatus> vidAuditStatusesCompletedWithErrors(String jobId) {
+ return ImmutableList.of(
+ vidAuditStatus(jobId, "PENDING", false),
+ vidAuditStatus(jobId, "IN_PROGRESS", false),
+ vidAuditStatus(jobId, "COMPLETED_WITH_ERRORS", true)
+ );
+ }
+
+ protected ImmutableList<JobAuditStatus> vidAuditStatusesFailed(String jobId) {
+ return ImmutableList.of(
+ vidAuditStatus(jobId, "PENDING", false),
+ vidAuditStatus(jobId, "IN_PROGRESS", false),
+ vidAuditStatus(jobId, "FAILED", true)
+ );
+ }
+
+ protected JobAuditStatus vidAuditStatus(String jobId, String jobStatus, boolean isFinal) {
+ return new JobAuditStatus(UUID.fromString(jobId), jobStatus, JobAuditStatus.SourceStatus.VID, null, null, isFinal);
+ }
+
+ public static class JobIdAndStatusMatcher extends BaseMatcher<ServiceInfo> {
+ protected 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);
+ }
+ }
+
+
+
+ protected Map<Keys,String> generateNames() {
+ return Stream.of(Keys.values()).collect(
+ Collectors.toMap(x->x, x -> UUID.randomUUID().toString().replace("-","")));
+ }
+
+ protected ImmutableList<BasePreset> addPresetsForCreateBulkOfCreateInstances(int bulkSize, Map<Keys, String> names){
+ ImmutableList<BasePreset> msoBulkPresets = generateMsoCreateBulkPresets(bulkSize, names);
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .add(PresetAAIGetCloudOwnersByCloudRegionId.PRESET_MTN3_TO_ATT_SABABA)
+ .addAll(msoBulkPresets)
+ .add(new PresetMSOOrchestrationRequestGet())
+ .build();
+ return presets;
+
+ }
+
+ protected ImmutableList<BasePreset> generateMsoCreateBulkPresets(int bulkSize, Map<Keys, String> names) {
+ return IntStream.rangeClosed(0, bulkSize-1).
+ mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i))
+ .collect(ImmutableList.toImmutableList());
+ }
+
+ protected 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}};
+ }
+
+
+
+ protected List<String> createBulkAndWaitForBeCompleted(int bulkSize){
+ Map<Keys, String> names = generateNames();
+ ImmutableList<BasePreset> presets = addPresetsForCreateBulkOfCreateInstances(bulkSize, names);
+ final List<String> jobIds = createBulkOfMacroInstances(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;
+ }
+
+ protected List<JobAuditStatus> getJobMsoAuditStatusForAlaCarte(String jobUUID, String requestId, String serviceInstanceId){
+ String url = getMsoJobAuditUrl().replace("{JOB_ID}",jobUUID);
+
+ if(!StringUtils.isEmpty(requestId)) {
+ url = url + "?requestId=" + requestId;
+ if(!StringUtils.isEmpty(serviceInstanceId)) {
+ url = url + "&serviceInstanceId=" + serviceInstanceId;
+ }
+ }
+ return callAuditStatus(url);
+ }
+
+ protected List<JobAuditStatus> getAuditStatuses(String jobUUID, String source){
+ String url = getJobAuditUrl().replace("{JOB_ID}",jobUUID).replace("{SOURCE}", source);
+ return callAuditStatus(url);
+ }
+
+ protected List<JobAuditStatus> getAuditStatusesForInstance(String type, String instanceId){
+ String url = getInstanceAuditInfoUrl().replace("{TYPE}",type).replace("{INSTANCE_ID}", instanceId);
+ return callAuditStatus(url);
+ }
+
+ private List<JobAuditStatus> callAuditStatus(String url) {
+ ResponseEntity<List<JobAuditStatus>> statusesResponse = auditStatusCall(url);
+ assertThat(statusesResponse.getStatusCode(), CoreMatchers.equalTo(HttpStatus.OK));
+ return statusesResponse.getBody();
+ }
+
+ protected Map<String, JobStatus> addBulkAllPendingButOneInProgress(){
+ return addBulkAllPendingButOneInProgress(3);
+ }
+
+ protected Map<String, JobStatus> addBulkAllPendingButOneInProgress(int bulkSize){
+ Map<Keys, String> names = generateNames();
+ ImmutableList<BasePreset> msoBulkPresets = generateMsoCreateBulkPresets(bulkSize, names);
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .add(PresetAAIGetCloudOwnersByCloudRegionId.PRESET_MTN3_TO_ATT_SABABA)
+ .addAll(msoBulkPresets)
+ .add(new PresetMSOOrchestrationRequestGet("IN_PROGRESS"))
+ .build();
+ final List<String> jobIds = createBulkOfMacroInstances(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;
+ }
+
+ protected 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;
+ }
+
+
+ protected MsoResponseWrapper2 hideService(String jobId) {
+ MsoResponseWrapper2 responseWrapper2 = callMsoForResponseWrapper(org.springframework.http.HttpMethod.POST, getHideServiceUri(jobId), "");
+ return responseWrapper2;
+ }
+
+ protected List<String> createBulkOfInstancesAndAssert(ImmutableList<BasePreset> presets, boolean isPause, int bulkSize, JobStatus finalState, Map<Keys, String> names){
+ List<String> jobIds = createBulkOfMacroInstances(presets, isPause, bulkSize, names);
+ Assert.assertEquals(jobIds.size(), bulkSize);
+ for(String jobId: jobIds) {
+ assertExpectedStatusAndServiceInfo(isPause, finalState, names, jobId);
+ }
+
+ return jobIds;
+ }
+
+ protected void assertExpectedStatusAndServiceInfo(boolean isPause, JobStatus finalState, Map<Keys, String> names, String jobId) {
+ assertExpectedStatusAndServiceInfo(finalState, jobId, new ServiceInfo("us16807000", JobStatus.IN_PROGRESS, isPause, "someID",
+ "someName", "myProject", "NFT1", "NFTJSSSS-NFT1", "greatTenant", "greatTenant", "hvf3", null,
+ "mySubType", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", null, names.get(Keys.SERVICE_NAME),
+ "5c9e863f-2716-467b-8799-4a67f378dcaa", "AIM_TRANSPORT_00004", "1.0", jobId, null, ServiceAction.INSTANTIATE, false));
+ }
+
+ protected void assertExpectedStatusAndServiceInfo(JobStatus finalState, String jobId, ServiceInfo expectedServiceInfo) {
+ assertExpectedStatusAndServiceInfo(finalState, jobId, false, expectedServiceInfo);
+ }
+
+ protected void assertExpectedStatusAndServiceInfo(JobStatus finalState, String jobId, boolean longWait, ServiceInfo expectedServiceInfo) {
+ JobInfoChecker<Integer> 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==null) {
+ expectedServiceInfo.serviceInstanceId = BaseMSOPreset.DEFAULT_INSTANCE_ID;
+ }
+ result = Wait.waitFor(jobInfoChecker, null, 30, longWait ? 2 : 1);
+ assertTrue("service info of jobId: " + jobId + " was in status: " + jobInfoChecker.lastStatus, result);
+ }
+
+ protected List<String> createBulkOfMacroInstances(ImmutableList<BasePreset> presets, boolean isPause, int bulkSize, Map<Keys, String> names) {
+ SimulatorApi.registerExpectationFromPresets(presets, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+ return createBulkOfInstances(isPause, bulkSize, names, CREATE_BULK_OF_MACRO_REQUEST);
+ }
+
+ public List<String> createBulkOfInstances(boolean isPause, int bulkSize, Map<Keys, String> names, String requestDetailsFileName){
+
+ String requestBody = TestUtils.convertRequest(objectMapper, requestDetailsFileName);
+ 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();
+ }
+
+ protected List<String> retryJob(String jobId) {
+ ResponseEntity<String> retryBulkPayload = getRetryBulk(jobId);
+ return retryJobWithChangedData(jobId, retryBulkPayload.getBody());
+ }
+
+ protected List<String> retryJobWithChangedData(String jobId, String requestBody) {
+ String retryUri = getRetryJobWithChangedDataUrl();
+ retryUri = retryUri.replace("{JOB_ID}", jobId);
+ MsoResponseWrapper2 responseWrapper2 = callMsoForResponseWrapper(HttpMethod.POST, retryUri, requestBody);
+ assertNotNull(responseWrapper2);
+ return (List<String>)responseWrapper2.getEntity();
+ }
+
+ protected ResponseEntity<String> getRetryBulk(String jobId) {
+ String retryUri = getTopologyForRetryUrl();
+ retryUri = retryUri.replace("{JOB_ID}", jobId);
+ return restTemplateErrorAgnostic.getForEntity(retryUri, String.class);
+ }
+
+ protected Object getResourceAuditInfo(String trackById) {
+ return restTemplate.getForObject(buildUri("/asyncInstantiation/auditStatusForRetry/{trackById}"), Object.class, trackById);
+ }
+
+ public class JobInfoChecker<Integer> implements Predicate<Integer> {
+
+ protected final RestTemplate restTemplate;
+ protected Set<JobStatus> expectedJobStatus;
+ protected ServiceInfo expectedServiceInfo;
+ protected final String jobId;
+ protected 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(expectedServiceInfo), serviceInfoDataReflected(serviceInfoFromDB));
+ assertTrue("actual service instance doesn't contain template service name:" + expectedServiceInfo.serviceInstanceName,
+ serviceInfoFromDB.serviceInstanceName.contains(expectedServiceInfo.serviceInstanceName));
+
+ if (expectedServiceInfo.serviceInstanceId != null && ImmutableList.of(JobStatus.COMPLETED, JobStatus.PAUSE, JobStatus.COMPLETED_WITH_ERRORS).contains(serviceInfoFromDB.jobStatus)) {
+ MatcherAssert.assertThat("service instance id is wrong", serviceInfoFromDB.serviceInstanceId, CoreMatchers.is(expectedServiceInfo.serviceInstanceId));
+ }
+ if (expectedJobStatus.size()==1) {
+ assertEquals("job status is wrong", getExpectedRetryEnabled((JobStatus)(expectedJobStatus.toArray()[0])), serviceInfoFromDB.isRetryEnabled);
+ }
+ lastStatus = serviceInfoFromDB.jobStatus;
+ return expectedJobStatus.contains(serviceInfoFromDB.jobStatus);
+ }
+ }
+
+ protected 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
+ protected static String serviceInfoDataReflected(ServiceInfo service1) {
+ return new ReflectionToStringBuilder(service1, ToStringStyle.SHORT_PREFIX_STYLE)
+ .setExcludeFieldNames("jobStatus", "templateId", "statusModifiedDate", "createdBulkDate", "serviceInstanceId", "serviceInstanceName", "isRetryEnabled")
+ .toString();
+ }
+
+ protected void addBulkPendingWithCustomList(List<BasePreset> customPresets){
+ Map<Keys, String> names = generateNames();
+ final int bulkSize = 2 + customPresets.size();
+
+ List<BasePreset> msoBulkPresets = generateMsoCreateBulkPresets(bulkSize, names);
+ ImmutableList<BasePreset> presets = new ImmutableList.Builder<BasePreset>()
+ .add(new PresetGetSessionSlotCheckIntervalGet())
+ .add(new PresetAAIGetSubscribersGet())
+ .addAll(msoBulkPresets)
+ .addAll(customPresets)
+ .build();
+
+ List<String> jobIds = createBulkOfMacroInstances(presets, false, bulkSize, names);
+ Assert.assertEquals(jobIds.size(),bulkSize);
+ }
+
+ protected void verifyAuditStatuses(String jobId, List<String> statuses, JobAuditStatus.SourceStatus source) {
+ int statusesSize = statuses.size();
+ AtomicReference<List<JobAuditStatus>> actualAudits = new AtomicReference<>();
+ if (source.equals(JobAuditStatus.SourceStatus.VID)) {
+ actualAudits.set(getAuditStatuses(jobId, JobAuditStatus.SourceStatus.VID.name()));
+ org.junit.Assert.assertEquals("Received number of VID statuses is not as expected", statusesSize, actualAudits.get().size());
+ } else {
+ boolean isStatusedSizeAsExpected = Wait.waitFor(x-> {
+ actualAudits.set(getAuditStatuses(jobId, JobAuditStatus.SourceStatus.MSO.name()));
+ return actualAudits.get().size() == statusesSize;
+ },null,5,1);
+ org.junit.Assert.assertTrue("Received number of MSO statuses is not as expected. Expected: " + statusesSize + ". Received: " + actualAudits.get().size(), isStatusedSizeAsExpected);
+ }
+ IntStream.range(0, statusesSize).forEach(i-> org.junit.Assert.assertEquals(source + " status #" + i + " is not as expected", statuses.get(i), actualAudits.get().get(i).getJobStatus()));
+ }
+
+ protected void verifyInstanceAuditStatuses(List<JobAuditStatus> expectedStatuses, List<JobAuditStatus> actualStatuses) {
+ final int expectedSize = expectedStatuses.size();
+ assertTrue("Expected statuses size is "+ expectedSize +", actual size is "+actualStatuses.size(), new Integer(expectedSize).equals(actualStatuses.size()));
+ IntStream.range(0, expectedSize).forEach(i-> {
+
+ final JobAuditStatus expectedStatus = expectedStatuses.get(i);
+ final JobAuditStatus actualStatus = actualStatuses.get(i);
+ org.junit.Assert.assertEquals("MSO status #" + i + " is not as expected", expectedStatus.getJobStatus(), actualStatus.getJobStatus());
+ org.junit.Assert.assertEquals("MSO requestId #" + i + " is not as expected", expectedStatus.getRequestId(), actualStatus.getRequestId());
+ org.junit.Assert.assertEquals("MSO additionalInfo #" + i + " is not as expected", expectedStatus.getAdditionalInfo(), actualStatus.getAdditionalInfo());
+ org.junit.Assert.assertEquals("MSO jobID #" + i + " is not as expected", expectedStatus.getJobId(), actualStatus.getJobId());
+ org.junit.Assert.assertEquals("MSO instanceName #" + i + " is not as expected", expectedStatus.getInstanceName(), actualStatus.getInstanceName());
+ org.junit.Assert.assertEquals("MSO instanceType #" + i + " is not as expected", expectedStatus.getInstanceType(), actualStatus.getInstanceType());
+ });
+ }
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/api/BaseApiTest.java b/vid-automation/src/main/java/org/onap/vid/api/BaseApiTest.java
new file mode 100644
index 000000000..5b7b1b214
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/api/BaseApiTest.java
@@ -0,0 +1,163 @@
+package org.onap.vid.api;
+
+import static java.util.Collections.singletonList;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
+import static org.apache.commons.text.StringEscapeUtils.unescapeJson;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.not;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.TimeZone;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import org.apache.commons.io.IOUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.uri.internal.JerseyUriBuilder;
+import org.onap.sdc.ci.tests.datatypes.UserCredentials;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.DefaultResponseErrorHandler;
+import org.springframework.web.client.HttpStatusCodeException;
+import org.springframework.web.client.RestTemplate;
+import org.testng.annotations.BeforeClass;
+import vid.automation.test.infra.FeaturesTogglingConfiguration;
+import vid.automation.test.services.UsersService;
+import vid.automation.test.utils.CookieAndJsonHttpHeadersInterceptor;
+
+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(SerializationFeature.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", "10.0.0.10");
+ int port = Integer.valueOf(System.getProperty("VID_PORT", "8080"));
+ return new JerseyUriBuilder().host(host).port(port).scheme("http").path("vid").build();
+ }
+
+ public void login() {
+ login(getUserCredentials());
+ }
+
+ public void login(UserCredentials userCredentials) {
+ final List<ClientHttpRequestInterceptor> interceptors = singletonList(new CookieAndJsonHttpHeadersInterceptor(getUri(), userCredentials));
+ restTemplate.setInterceptors(interceptors);
+ restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
+ @Override
+ public void handleError(ClientHttpResponse response) throws IOException {
+ try {
+ super.handleError(response);
+ } catch (HttpStatusCodeException e) {
+ LOGGER.error("HTTP {}: {}", e.getStatusCode(), e.getResponseBodyAsString(), e);
+ throw e;
+ }
+ }
+ });
+
+ restTemplateErrorAgnostic.setInterceptors(interceptors);
+ restTemplateErrorAgnostic.setErrorHandler(new DefaultResponseErrorHandler() {
+ @Override
+ public boolean hasError(ClientHttpResponse response) {
+ return false;
+ }
+ });
+ }
+
+
+ //set time zone to UTC so clock will go closely with VID app
+ @BeforeClass
+ public void setDefaultTimeZoneToUTC() {
+ System.setProperty("user.timezone", "UTC");
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC")); //since TimeZone cache previous user.timezone
+ }
+
+ public 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);
+ }
+
+ 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);
+ }
+ }
+
+ protected void assertJsonEquals(String actual, String expected) {
+ LOGGER.info(actual);
+ assertThat(actual, not(isEmptyOrNullString()));
+
+ assertThat(actual, jsonEquals(expected)
+ .when(IGNORING_ARRAY_ORDER)
+ );
+ }
+
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/api/BaseMsoApiTest.java b/vid-automation/src/main/java/org/onap/vid/api/BaseMsoApiTest.java
new file mode 100644
index 000000000..175638008
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/api/BaseMsoApiTest.java
@@ -0,0 +1,108 @@
+package org.onap.vid.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.json.JSONException;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
+import org.onap.vid.model.mso.MsoResponseWrapper2;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.skyscreamer.jsonassert.JSONCompareMode;
+import org.springframework.http.HttpMethod;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import vid.automation.test.services.SimulatorApi;
+import vid.automation.test.services.SimulatorApi.RegistrationStrategy;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+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);
+ callMsoAndAssertError(targetUri, basicRequestBody, expectedErrorCode, expectedResult, method);
+ }
+
+ protected void callMsoWithSimulatedErrorResponse(BaseMSOPreset expectation, String targetUri, String basicRequestBody, int expectedErrorCode, String expectedResult, HttpMethod method) throws IOException {
+ SimulatorApi.registerExpectationFromPreset(expectation, RegistrationStrategy.CLEAR_THEN_SET);
+ callMsoAndAssertError(targetUri, basicRequestBody, expectedErrorCode, expectedResult, method);
+ }
+
+ protected void callMsoWithSimulatedErrorResponse(List<BasePreset> expectations, String targetUri, String basicRequestBody, int expectedErrorCode, String expectedResult, HttpMethod method) throws IOException {
+ SimulatorApi.registerExpectationFromPresets(expectations, RegistrationStrategy.CLEAR_THEN_SET);
+ callMsoAndAssertError(targetUri, basicRequestBody, expectedErrorCode, expectedResult, method);
+ }
+
+ private void callMsoAndAssertError(String targetUri, String basicRequestBody, int expectedErrorCode, String expectedResult, HttpMethod method) throws IOException {
+ 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);
+ callMsoAndAssertSuccess(targetUri, requestBody, expectedStatusCode, expectedResult, method);
+ }
+
+ protected void callMsoWithFineRequest(BaseMSOPreset expectation, String targetUri, String requestBody, int expectedStatusCode, String expectedResult, HttpMethod method) throws IOException {
+ SimulatorApi.registerExpectationFromPreset(expectation, RegistrationStrategy.CLEAR_THEN_SET);
+ callMsoAndAssertSuccess(targetUri, requestBody, expectedStatusCode, expectedResult, method);
+ }
+
+ protected void callMsoWithFineRequest(List<BasePreset> expectations, String targetUri, String requestBody, int expectedStatusCode, String expectedResult, HttpMethod method) throws IOException {
+ SimulatorApi.registerExpectationFromPresets(expectations, RegistrationStrategy.CLEAR_THEN_SET);
+ callMsoAndAssertSuccess(targetUri, requestBody, expectedStatusCode, expectedResult, method);
+ }
+
+ private void callMsoAndAssertSuccess(String targetUri, String requestBody, int expectedStatusCode, String expectedResult, HttpMethod method) throws IOException {
+ 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);
+ }
+ }
+
+ 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/main/java/org/onap/vid/api/CreateInstanceWithFailedService.java b/vid-automation/src/main/java/org/onap/vid/api/CreateInstanceWithFailedService.java
new file mode 100644
index 000000000..6c8f3fade
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/api/CreateInstanceWithFailedService.java
@@ -0,0 +1,87 @@
+package org.onap.vid.api;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetCloudOwnersByCloudRegionId;
+import org.onap.simulator.presetGenerator.presets.mso.*;
+import org.springframework.http.ResponseEntity;
+import vid.automation.test.model.JobStatus;
+import vid.automation.test.model.ServiceAction;
+import vid.automation.test.services.SimulatorApi;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys.SERVICE_NAME;
+import static org.onap.vid.api.AsyncInstantiationBase.CREATE_BULK_OF_ALACARTE_REQUEST_WITH_VNF;
+import static org.onap.vid.api.TestUtils.hasOrLacksOfEntry;
+import static vid.automation.test.services.SimulatorApi.registerExpectationFromPreset;
+import static vid.automation.test.services.SimulatorApi.registerExpectationFromPresets;
+
+public class CreateInstanceWithFailedService {
+ private CreateServiceWithFailedVnf.ResourceIds firstIds = new CreateServiceWithFailedVnf.ResourceIds();
+ private AsyncInstantiationBase asyncInstantiationBase;
+ private List<PresetMSOBaseCreateInstancePost> createPresets;
+ private String serviceInstanceName = TestUtils.generateRandomAlphaNumeric(10);
+ private ImmutableMap<PresetMSOServiceInstanceGen2WithNames.Keys, String> names;
+ private List<PresetMSOOrchestrationRequestGet> inProgressPresets;
+ private List<String> uuids;
+ private String originalJobId;
+ ObjectMapper objectMapper = new ObjectMapper();
+
+
+ public CreateInstanceWithFailedService(AsyncInstantiationBase asyncInstantiationALaCarteApiTest) {
+ this.asyncInstantiationBase = asyncInstantiationALaCarteApiTest;
+ }
+
+ private CreateInstanceWithFailedService createInstanceWithFailedService() {
+
+ names = ImmutableMap.of(SERVICE_NAME, serviceInstanceName);
+
+ final String serviceFailedStatusMessage = "The service instantiation is failed.";
+ createPresets = ImmutableList.of(
+ new PresetMSOCreateServiceInstanceGen2WithNamesAlacarteService(names, 0, firstIds.serviceReqId, firstIds.serviceId)
+ );
+ inProgressPresets = ImmutableList.of(
+ new PresetMSOOrchestrationRequestGet("FAILED", firstIds.serviceReqId, serviceFailedStatusMessage)
+ );
+ List<BasePreset> presets = asyncInstantiationBase.getPresets(createPresets, inProgressPresets);
+
+ registerExpectationFromPresets(presets, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+ registerExpectationFromPreset(PresetAAIGetCloudOwnersByCloudRegionId.PRESET_MDT1_TO_ATT_NC, SimulatorApi.RegistrationStrategy.APPEND);
+
+ uuids = asyncInstantiationBase.createBulkOfInstances(false, 1, names, CREATE_BULK_OF_ALACARTE_REQUEST_WITH_VNF);
+ return this;
+ }
+
+ protected void deployServiceFailedInstance() {
+ createInstanceWithFailedService();
+ firstTimeAssertion();
+ prepareAndAssertJsonFileForCypressTest();
+ }
+
+ private void prepareAndAssertJsonFileForCypressTest() {
+ final ResponseEntity<String> responseEntity = asyncInstantiationBase.getRetryBulk(originalJobId);
+ String expected = TestUtils.convertRequest(objectMapper, "asyncInstantiation/ServiceWithFailedServiceInstance.json");
+ expected = expected
+ .replace("SERVICE_NAME", serviceInstanceName);
+ String originalResponse = responseEntity.getBody();
+ String responseToCompare = originalResponse.replaceFirst("(instanceName\":\")(.*?)(\")", "$1INSTANCE_NAME$3").replaceAll("(trackById\":\")(.*?)(\")", "$1TRACK_BY_ID$3");
+ asyncInstantiationBase.assertJsonEquals(responseToCompare, expected);
+ }
+
+ private void firstTimeAssertion() {
+ assertThat(uuids, hasSize(1));
+ originalJobId = uuids.get(0);
+ asyncInstantiationBase.assertServiceInfoSpecific1(originalJobId, JobStatus.FAILED, names.get(SERVICE_NAME), "us16807000", firstIds.serviceId, ServiceAction.INSTANTIATE);
+ asyncInstantiationBase.assertAuditStatuses(originalJobId, asyncInstantiationBase.vidAuditStatusesFailed(originalJobId), null);
+ assertThat(SimulatorApi.retrieveRecordedRequestsPathCounter(), allOf(
+ hasOrLacksOfEntry(createPresets.get(0).getReqPath(), 1L),
+ hasOrLacksOfEntry(inProgressPresets.get(0).getReqPath(), 1L)
+ ));
+ }
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/api/CreateServiceWithFailedVnf.java b/vid-automation/src/main/java/org/onap/vid/api/CreateServiceWithFailedVnf.java
new file mode 100644
index 000000000..30076a964
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/api/CreateServiceWithFailedVnf.java
@@ -0,0 +1,226 @@
+package org.onap.vid.api;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.hamcrest.Matchers;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BasePreset;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetCloudOwnersByCloudRegionId;
+import org.onap.simulator.presetGenerator.presets.mso.*;
+import org.onap.simulator.presetGenerator.presets.sdc.PresetSDCGetServiceMetadataGet;
+import org.onap.simulator.presetGenerator.presets.sdc.PresetSDCGetServiceToscaModelGet;
+import org.onap.vid.model.asyncInstantiation.ServiceInfo;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import vid.automation.test.infra.ModelInfo;
+import vid.automation.test.model.JobStatus;
+import vid.automation.test.model.ServiceAction;
+import vid.automation.test.services.SimulatorApi;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys.SERVICE_NAME;
+import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys.VNF_NAME;
+import static org.onap.vid.api.TestUtils.hasOrLacksOfEntry;
+import static org.testng.Assert.assertTrue;
+import static org.testng.AssertJUnit.assertFalse;
+import static vid.automation.test.services.SimulatorApi.registerExpectationFromPreset;
+import static vid.automation.test.services.SimulatorApi.registerExpectationFromPresets;
+
+//CreateServiceWithFailedVnf is common for API test and UI test,
+//so if you change it, make sure both test are compatible with your changes
+public class CreateServiceWithFailedVnf {
+ private AsyncInstantiationBase asyncInstantiationBase;
+ private ImmutableMap<PresetMSOServiceInstanceGen2WithNames.Keys, String> names;
+ private List<PresetMSOBaseCreateInstancePost> createPresets;
+ private List<PresetMSOOrchestrationRequestGet> inProgressPresets;
+ private List<String> uuids;
+ private List<String> retryUuids;
+ private String originalJobId;
+ private String serviceInstanceName = TestUtils.generateRandomAlphaNumeric(10);
+ private ResourceIds firstIds = new ResourceIds();
+ private ResourceIds retryIds = new ResourceIds();
+ private String vnfEditedName = TestUtils.generateRandomAlphaNumeric(10);
+ ObjectMapper objectMapper = new ObjectMapper();
+ public final ModelInfo serviceComplexService = new ModelInfo("e3c34d88-a216-4f1d-a782-9af9f9588705", "0367689e-d41e-483f-b200-eab17e4a7f8d", "service-Complexservice-aLaCarte-csar-2.zip");
+
+ public CreateServiceWithFailedVnf(AsyncInstantiationBase asyncInstantiationALaCarteApiTest) {
+ this.asyncInstantiationBase = asyncInstantiationALaCarteApiTest;
+ }
+
+ public ImmutableMap<PresetMSOServiceInstanceGen2WithNames.Keys, String> getNames() {
+ return names;
+ }
+
+ public ResourceIds getFirstIds() {
+ return firstIds;
+ }
+
+ public static class ResourceIds {
+ public String serviceId =UUID.randomUUID().toString();
+ public String serviceReqId =UUID.randomUUID().toString();
+ public String vnfId =UUID.randomUUID().toString();
+ public String vnfReqId =UUID.randomUUID().toString();
+ }
+
+
+ public CreateServiceWithFailedVnf createServicesWithVnfCompletedWithError() {
+/*
+Legit Preset || deploy 1 Service, 1 VNF which will fail
+ -> JobStatus of service is COMPLETED_WITH_ERRORS, audit
+ is adequate; strict simulator comapre
+ */
+
+ names = ImmutableMap.of(SERVICE_NAME, serviceInstanceName, VNF_NAME, serviceInstanceName+"_vnf");
+
+
+
+ final String vnfFailedStatusMessage = "Vnf failed.";
+ createPresets = ImmutableList.of(
+ new PresetMSOCreateServiceInstanceGen2WithNamesAlacarteService(names, 0, firstIds.serviceReqId, firstIds.serviceId),
+ new PresetMSOCreateVNFInstanceOnlyRelatedServiceInstance(names.get(VNF_NAME),firstIds.vnfReqId , firstIds.serviceId, firstIds.vnfId, 0)
+ );
+ inProgressPresets = ImmutableList.of(
+ new PresetMSOOrchestrationRequestGet("COMPLETE", firstIds.serviceReqId),
+ new PresetMSOOrchestrationRequestGet("FAILED", firstIds.vnfReqId, vnfFailedStatusMessage)
+ );
+ List<BasePreset> presets = asyncInstantiationBase.getPresets(createPresets, inProgressPresets);
+
+ registerExpectationFromPresets(presets, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+ registerExpectationFromPreset(PresetAAIGetCloudOwnersByCloudRegionId.PRESET_MDT1_TO_ATT_NC, SimulatorApi.RegistrationStrategy.APPEND);
+
+ uuids = asyncInstantiationBase.createBulkOfInstances(false, 1, names, AsyncInstantiationBase.CREATE_BULK_OF_ALACARTE_REQUEST_WITH_VNF);
+ return this;
+ }
+
+ public void firstTimeAssertion() {
+ assertThat(uuids, hasSize(1));
+ originalJobId = uuids.get(0);
+
+ asyncInstantiationBase.assertServiceInfoSpecific1(originalJobId, JobStatus.COMPLETED_WITH_ERRORS, names.get(SERVICE_NAME), "us16807000", firstIds.serviceId, ServiceAction.INSTANTIATE);
+ asyncInstantiationBase.assertAuditStatuses(originalJobId, asyncInstantiationBase.vidAuditStatusesCompletedWithErrors(originalJobId),null);
+ assertThat(SimulatorApi.retrieveRecordedRequestsPathCounter(), allOf(
+ hasOrLacksOfEntry(createPresets.get(0).getReqPath(), 1L),
+ hasOrLacksOfEntry(createPresets.get(1).getReqPath(), 1L),
+ hasOrLacksOfEntry(inProgressPresets.get(0).getReqPath(), 1L),
+ hasOrLacksOfEntry(inProgressPresets.get(1).getReqPath(), 1L)
+ ));
+ }
+
+ public String getBulkForRetry(){
+ final ResponseEntity<String> responseEntity= asyncInstantiationBase.getRetryBulk(originalJobId);
+ String expected = TestUtils.convertRequest(objectMapper, "asyncInstantiation/ServiceTreeForRetry_serviceInstance.json");
+ expected = expected
+ .replace("SERVICE_NAME", serviceInstanceName);
+ String originalResponse = responseEntity.getBody();
+ String responseToCompare = originalResponse.replaceFirst( "(instanceId\":\")(.*?)(\")", "$1INSTANCE_ID$3")
+ .replaceAll( "(trackById\":\")(.*?)(\")", "$1TRACK_BY_ID$3");
+ asyncInstantiationBase.assertJsonEquals(responseToCompare, expected);
+ return originalResponse;
+ }
+
+ public void getBulkForRetryNotFound() {
+ UUID jobId= UUID.randomUUID();
+ final ResponseEntity<String> response = asyncInstantiationBase.getRetryBulk(jobId.toString());
+ assertThat(response.getStatusCode(), is(HttpStatus.NOT_FOUND));
+ assertThat(response.getBody(),containsString("Failed to retrieve class org.onap.vid.dao.JobRequest with JOB_ID "+jobId+" from table. no resource found"));
+ }
+
+ private void secondRegistration(String vnfName) {
+ createPresets = ImmutableList.of(
+ new PresetMSOCreateVNFInstanceOnlyRelatedServiceInstance(vnfName, retryIds.vnfReqId, firstIds.serviceId, retryIds.vnfId, 0)
+ );
+ inProgressPresets = ImmutableList.of(
+ new PresetMSOOrchestrationRequestGet("COMPLETE", retryIds.vnfReqId)
+ );
+
+ registerExpectationFromPresets(asyncInstantiationBase.getPresets(createPresets, inProgressPresets), SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET);
+ registerExpectationFromPresets(ImmutableList.of(
+ PresetAAIGetCloudOwnersByCloudRegionId.PRESET_MDT1_TO_ATT_NC,
+ new PresetSDCGetServiceMetadataGet(serviceComplexService),
+ new PresetSDCGetServiceToscaModelGet(serviceComplexService)),
+ SimulatorApi.RegistrationStrategy.APPEND);
+
+
+ }
+
+ public String deployService1FailedVnf(){
+ createServicesWithVnfCompletedWithError();
+ firstTimeAssertion();
+ return getBulkForRetry();
+ }
+
+ public void assertResourceAuditStatus(String bulkForRetry) {
+ String vnfTrackById = extractVnfTrackById(bulkForRetry);
+
+ Map<String, Object> auditStatus = (Map) asyncInstantiationBase.getResourceAuditInfo(vnfTrackById);
+ assertThat(auditStatus.get("jobStatus"), equalTo("FAILED"));
+ assertThat(auditStatus.get("additionalInfo"), equalTo("Vnf failed."));
+ assertThat(auditStatus.get("requestId"), equalTo(firstIds.vnfReqId));
+ }
+
+ private String extractVnfTrackById(String bulk) {
+ Map<String, Object> serviceInstantiation = null;
+ try {
+ serviceInstantiation = objectMapper.readValue(bulk, new TypeReference<Map<String, Object>>(){});
+ Map<String, Object> vnf = (Map) ((Map) serviceInstantiation.get("vnfs")).get("vSAMP12 1");
+ return vnf.get("trackById").toString();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+
+ public void secondRegistration() {
+ secondRegistration(names.get(VNF_NAME));
+ }
+
+ public void retryJob() {
+ //retry the previous job
+ retryUuids = asyncInstantiationBase.retryJob(originalJobId);
+ }
+
+ public void retryJobWithOtherDataAndAssert(String requestBody){
+ retryUuids = asyncInstantiationBase.retryJobWithChangedData(originalJobId, requestBody);
+ retryAssertion();
+ simulatorCallsAssertion();
+ }
+
+ public String changeSomeDataAndRegisterToSimulator(String payload){
+ payload = payload.replace(names.get(VNF_NAME), vnfEditedName);
+ secondRegistration(vnfEditedName);
+ return payload;
+ }
+
+
+ public void retryAssertion() {
+
+ assertThat(retryUuids, Matchers.hasSize(1));
+ String retryJobId = retryUuids.get(0);
+ assertThat(retryJobId, not(equalTo(originalJobId)));
+ asyncInstantiationBase.assertServiceInfoSpecific1(retryJobId, JobStatus.COMPLETED, names.get(SERVICE_NAME), "us16807000", firstIds.serviceId, ServiceAction.UPDATE);
+
+ //make sure original job is retry is disabled.
+ Optional<ServiceInfo> optionalServiceInfo = asyncInstantiationBase.serviceListCall().getBody().stream().filter(si -> originalJobId.equals(si.jobId)).findFirst();
+ assertTrue(optionalServiceInfo.isPresent());
+ assertFalse(optionalServiceInfo.get().isRetryEnabled);
+ }
+
+ public void simulatorCallsAssertion() {
+ assertThat(SimulatorApi.retrieveRecordedRequestsPathCounter(), allOf(
+ hasOrLacksOfEntry(createPresets.get(0).getReqPath(), 1L),
+ hasOrLacksOfEntry(inProgressPresets.get(0).getReqPath(), 1L)
+ ));
+ }
+
+
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/api/TestUtils.java b/vid-automation/src/main/java/org/onap/vid/api/TestUtils.java
new file mode 100644
index 000000000..a2fe82e9d
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/api/TestUtils.java
@@ -0,0 +1,99 @@
+package org.onap.vid.api;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.apache.commons.text.RandomStringGenerator;
+import org.hamcrest.Matcher;
+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.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Scanner;
+
+import static org.apache.commons.text.CharacterPredicates.DIGITS;
+import static org.apache.commons.text.CharacterPredicates.LETTERS;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.*;
+import static vid.automation.test.utils.RegExMatcher.matchesRegEx;
+
+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(SerializationFeature.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 = TestUtils.class.getClassLoader();
+ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
+ Resource[] resources;
+ try {
+ resources = resolver.getResources(msoRequestDetailsFileName);
+ //using InputStream and not file. see https://stackoverflow.com/questions/14876836/file-inside-jar-is-not-visible-for-spring/51131841#51131841
+ InputStream inputStream = resources[0].getInputStream();
+ String content = new Scanner(inputStream).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);
+ }
+
+ static Matcher hasOrLacksOfEntry(String pathRegex, Long expectedCounter) {
+ return expectedCounter.equals(0L) ? not(hasKey(matchesRegEx(pathRegex))) : hasEntry(matchesRegEx(pathRegex), is(expectedCounter));
+ }
+
+ private static RandomStringGenerator generator = new RandomStringGenerator.Builder()
+ .withinRange('0', 'z')
+ .filteredBy(LETTERS, DIGITS)
+ .build();
+
+ public static String generateRandomAlphaNumeric(int length) {
+ return generator.generate(length);
+ }
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/JobAuditStatus.java b/vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/JobAuditStatus.java
new file mode 100644
index 000000000..b012628e0
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/JobAuditStatus.java
@@ -0,0 +1,141 @@
+package org.onap.vid.model.asyncInstantiation;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+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 JobAuditStatus(UUID jobId, String jobStatus, SourceStatus source, UUID requestId, String additionalInfo, Boolean isFinal, String instanceName) {
+ this(jobId, jobStatus, source, requestId, additionalInfo, isFinal);
+ this.instanceName = instanceName;
+ }
+
+ public JobAuditStatus(String instanceName, String jobStatus, UUID requestId, String additionalInfo, Boolean isFinal, String instanceType) {
+ this.instanceType = instanceType;
+ this.instanceName = instanceName;
+ this.jobStatus = jobStatus;
+ 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 String instanceName;
+ private String instanceType;
+
+ public String getInstanceType() {return instanceType;}
+
+ public void setInstanceType(String instanceType) {this.instanceType = instanceType; }
+
+ 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 String getInstanceName() {
+ return instanceName;
+ }
+
+ 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 + '\'' +
+ ", instanceName='" + instanceName + '\'' +
+ ", isFinal=" + isFinal +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (!(o instanceof JobAuditStatus)) 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(instanceName, that.instanceName)
+ .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(instanceName)
+ .append(isFinal)
+ .toHashCode();
+ }
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/ServiceInfo.java b/vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/ServiceInfo.java
new file mode 100644
index 000000000..8f40fc098
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/ServiceInfo.java
@@ -0,0 +1,80 @@
+package org.onap.vid.model.asyncInstantiation;
+
+
+import vid.automation.test.model.JobStatus;
+import vid.automation.test.model.ServiceAction;
+
+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 ServiceAction action;
+ public boolean isRetryEnabled;
+
+ 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, ServiceAction action, boolean isRetryEnabled) {
+ 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;
+ this.action = action;
+ this.isRetryEnabled = isRetryEnabled;
+ }
+
+ public JobStatus getJobStatus() {
+ return jobStatus;
+ }
+
+ public String getServiceInstanceName() {
+ return serviceInstanceName;
+ }
+
+ public String getJobId() {
+ return jobId;
+ }
+
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapper2.java b/vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapper2.java
new file mode 100644
index 000000000..40bf86b26
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapper2.java
@@ -0,0 +1,60 @@
+package org.onap.vid.model.mso;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+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
+ @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/main/java/org/onap/vid/model/mso/MsoResponseWrapperInterface.java b/vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapperInterface.java
new file mode 100644
index 000000000..8a20ff187
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapperInterface.java
@@ -0,0 +1,15 @@
+package org.onap.vid.model.mso;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public interface MsoResponseWrapperInterface {
+ @JsonProperty("entity")
+ Object getEntity();
+
+ @JsonProperty("status")
+ int getStatus();
+
+ @JsonIgnore
+ String getResponse();
+}
diff --git a/vid-automation/src/main/java/org/onap/vid/model/mso/RestObject.java b/vid-automation/src/main/java/org/onap/vid/model/mso/RestObject.java
new file mode 100644
index 000000000..043766dac
--- /dev/null
+++ b/vid-automation/src/main/java/org/onap/vid/model/mso/RestObject.java
@@ -0,0 +1,119 @@
+/*-
+ * ============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.onap.vid.model.mso;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.MoreObjects;
+
+import javax.ws.rs.core.Response;
+
+/**
+ * The Class RestObject.
+ *
+ * @param <T> the generic type
+ */
+public class RestObject<T> {
+
+ 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();
+ }
+}
+