From 66af8b9b391879be78660d6ccb0a1f1f9340b423 Mon Sep 17 00:00:00 2001 From: Ittay Stern Date: Mon, 11 Mar 2019 09:34:34 +0200 Subject: Merge automation from ECOMP's repository Reference commit in ECOMP: 8e92a8c6 Issue-ID: VID-378 Change-Id: Ia32f4813378ef95097f788246aa5b1172e20ca48 Signed-off-by: Ittay Stern --- .../org/onap/vid/api/AsyncInstantiationBase.java | 573 +++++++++++++++++++++ .../main/java/org/onap/vid/api/BaseApiTest.java | 163 ++++++ .../main/java/org/onap/vid/api/BaseMsoApiTest.java | 108 ++++ .../vid/api/CreateInstanceWithFailedService.java | 87 ++++ .../onap/vid/api/CreateServiceWithFailedVnf.java | 226 ++++++++ .../src/main/java/org/onap/vid/api/TestUtils.java | 99 ++++ .../model/asyncInstantiation/JobAuditStatus.java | 141 +++++ .../vid/model/asyncInstantiation/ServiceInfo.java | 80 +++ .../onap/vid/model/mso/MsoResponseWrapper2.java | 60 +++ .../vid/model/mso/MsoResponseWrapperInterface.java | 15 + .../java/org/onap/vid/model/mso/RestObject.java | 119 +++++ 11 files changed, 1671 insertions(+) create mode 100644 vid-automation/src/main/java/org/onap/vid/api/AsyncInstantiationBase.java create mode 100644 vid-automation/src/main/java/org/onap/vid/api/BaseApiTest.java create mode 100644 vid-automation/src/main/java/org/onap/vid/api/BaseMsoApiTest.java create mode 100644 vid-automation/src/main/java/org/onap/vid/api/CreateInstanceWithFailedService.java create mode 100644 vid-automation/src/main/java/org/onap/vid/api/CreateServiceWithFailedVnf.java create mode 100644 vid-automation/src/main/java/org/onap/vid/api/TestUtils.java create mode 100644 vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/JobAuditStatus.java create mode 100644 vid-automation/src/main/java/org/onap/vid/model/asyncInstantiation/ServiceInfo.java create mode 100644 vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapper2.java create mode 100644 vid-automation/src/main/java/org/onap/vid/model/mso/MsoResponseWrapperInterface.java create mode 100644 vid-automation/src/main/java/org/onap/vid/model/mso/RestObject.java (limited to 'vid-automation/src/main/java/org/onap/vid') 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 getPresets(List presetOnDeleteList, List presetOnCreateList, List presetInProgressList) { + + final ImmutableList.Builder basePresetBuilder = new ImmutableList.Builder<>(); + basePresetBuilder + .add(new PresetGetSessionSlotCheckIntervalGet()) + .add(new PresetAAIGetSubscribersGet()) + .addAll(presetOnDeleteList) + .addAll(presetOnCreateList) + .addAll(presetInProgressList); + return basePresetBuilder.build(); + } + + public List getDeletePresets(List presetOnDeleteList, List presetInProgressList) { + return getPresets(presetOnDeleteList, emptyList(), presetInProgressList); + } + + public List getPresets(List presetOnCreateList, List 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 expectedVidStatuses, List expectedMsoStatuses) { + assertAuditStatuses(jobId, expectedVidStatuses, expectedMsoStatuses, 15); + } + + protected void assertAuditStatuses(String jobId, List expectedVidStatuses, List expectedMsoStatuses, long timeoutInSeconds) { + assertAndRetryIfNeeded(() -> { + final List auditVidStatuses = getAuditStatuses(jobId, JobAuditStatus.SourceStatus.VID.name()); + assertThat(auditVidStatuses, hasItemsFromCollection(expectedVidStatuses)); + if (expectedMsoStatuses!=null) { + final List 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 vidAuditStatusesCompletedWithErrors(String jobId) { + return ImmutableList.of( + vidAuditStatus(jobId, "PENDING", false), + vidAuditStatus(jobId, "IN_PROGRESS", false), + vidAuditStatus(jobId, "COMPLETED_WITH_ERRORS", true) + ); + } + + protected ImmutableList 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 { + 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 generateNames() { + return Stream.of(Keys.values()).collect( + Collectors.toMap(x->x, x -> UUID.randomUUID().toString().replace("-",""))); + } + + protected ImmutableList addPresetsForCreateBulkOfCreateInstances(int bulkSize, Map names){ + ImmutableList msoBulkPresets = generateMsoCreateBulkPresets(bulkSize, names); + ImmutableList presets = new ImmutableList.Builder() + .add(new PresetGetSessionSlotCheckIntervalGet()) + .add(new PresetAAIGetSubscribersGet()) + .add(PresetAAIGetCloudOwnersByCloudRegionId.PRESET_MTN3_TO_ATT_SABABA) + .addAll(msoBulkPresets) + .add(new PresetMSOOrchestrationRequestGet()) + .build(); + return presets; + + } + + protected ImmutableList generateMsoCreateBulkPresets(int bulkSize, Map names) { + return IntStream.rangeClosed(0, bulkSize-1). + mapToObj(i-> new PresetMSOCreateServiceInstanceGen2WithNames(names, i)) + .collect(ImmutableList.toImmutableList()); + } + + protected ResponseEntity> auditStatusCall(String url) { + return restTemplate.exchange( + url, + org.springframework.http.HttpMethod.GET, + null, + new ParameterizedTypeReference>() {}); + } + + @DataProvider + public static Object[][] auditSources() { + return new Object[][]{{JobAuditStatus.SourceStatus.VID},{JobAuditStatus.SourceStatus.MSO}}; + } + + + + protected List createBulkAndWaitForBeCompleted(int bulkSize){ + Map names = generateNames(); + ImmutableList presets = addPresetsForCreateBulkOfCreateInstances(bulkSize, names); + final List 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 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 getAuditStatuses(String jobUUID, String source){ + String url = getJobAuditUrl().replace("{JOB_ID}",jobUUID).replace("{SOURCE}", source); + return callAuditStatus(url); + } + + protected List getAuditStatusesForInstance(String type, String instanceId){ + String url = getInstanceAuditInfoUrl().replace("{TYPE}",type).replace("{INSTANCE_ID}", instanceId); + return callAuditStatus(url); + } + + private List callAuditStatus(String url) { + ResponseEntity> statusesResponse = auditStatusCall(url); + assertThat(statusesResponse.getStatusCode(), CoreMatchers.equalTo(HttpStatus.OK)); + return statusesResponse.getBody(); + } + + protected Map addBulkAllPendingButOneInProgress(){ + return addBulkAllPendingButOneInProgress(3); + } + + protected Map addBulkAllPendingButOneInProgress(int bulkSize){ + Map names = generateNames(); + ImmutableList msoBulkPresets = generateMsoCreateBulkPresets(bulkSize, names); + ImmutableList presets = new ImmutableList.Builder() + .add(new PresetGetSessionSlotCheckIntervalGet()) + .add(new PresetAAIGetSubscribersGet()) + .add(PresetAAIGetCloudOwnersByCloudRegionId.PRESET_MTN3_TO_ATT_SABABA) + .addAll(msoBulkPresets) + .add(new PresetMSOOrchestrationRequestGet("IN_PROGRESS")) + .build(); + final List 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 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 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 createBulkOfInstancesAndAssert(ImmutableList presets, boolean isPause, int bulkSize, JobStatus finalState, Map names){ + List 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 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 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 createBulkOfMacroInstances(ImmutableList presets, boolean isPause, int bulkSize, Map names) { + SimulatorApi.registerExpectationFromPresets(presets, SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET); + return createBulkOfInstances(isPause, bulkSize, names, CREATE_BULK_OF_MACRO_REQUEST); + } + + public List createBulkOfInstances(boolean isPause, int bulkSize, Map 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 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)responseWrapper2.getEntity(); + } + + protected List retryJob(String jobId) { + ResponseEntity retryBulkPayload = getRetryBulk(jobId); + return retryJobWithChangedData(jobId, retryBulkPayload.getBody()); + } + + protected List 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)responseWrapper2.getEntity(); + } + + protected ResponseEntity 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 implements Predicate { + + protected final RestTemplate restTemplate; + protected Set expectedJobStatus; + protected ServiceInfo expectedServiceInfo; + protected final String jobId; + protected JobStatus lastStatus; + + public JobInfoChecker(RestTemplate restTemplate, Set expectedJobStatus, String jobId, ServiceInfo expectedServiceInfo) { + this.restTemplate = restTemplate; + this.expectedJobStatus = expectedJobStatus; + this.jobId = jobId; + this.expectedServiceInfo = expectedServiceInfo; + } + + public void setExpectedJobStatus(Set expectedJobStatus) { + this.expectedJobStatus = expectedJobStatus; + } + + @Override + public boolean test(Integer integer) { + ResponseEntity> 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> serviceListCall() { + return restTemplate.exchange( + getServiceInfoUrl(), + org.springframework.http.HttpMethod.GET, + null, + new ParameterizedTypeReference>() {}); + } + + //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 customPresets){ + Map names = generateNames(); + final int bulkSize = 2 + customPresets.size(); + + List msoBulkPresets = generateMsoCreateBulkPresets(bulkSize, names); + ImmutableList presets = new ImmutableList.Builder() + .add(new PresetGetSessionSlotCheckIntervalGet()) + .add(new PresetAAIGetSubscribersGet()) + .addAll(msoBulkPresets) + .addAll(customPresets) + .build(); + + List jobIds = createBulkOfMacroInstances(presets, false, bulkSize, names); + Assert.assertEquals(jobIds.size(),bulkSize); + } + + protected void verifyAuditStatuses(String jobId, List statuses, JobAuditStatus.SourceStatus source) { + int statusesSize = statuses.size(); + AtomicReference> 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 expectedStatuses, List 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 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 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 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 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 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 createPresets; + private String serviceInstanceName = TestUtils.generateRandomAlphaNumeric(10); + private ImmutableMap names; + private List inProgressPresets; + private List 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 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 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 names; + private List createPresets; + private List inProgressPresets; + private List uuids; + private List 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 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 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 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 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 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 serviceInstantiation = null; + try { + serviceInstantiation = objectMapper.readValue(bulk, new TypeReference>(){}); + Map 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 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 getNestedPropertyInMap(Object item, String path, Class valueType) { + return getNestedPropertyInMap(item, path, valueType, "/"); + } + + /* + Use this method to extract item from Map that represent Json hierarchy (Map) + */ + public static T getNestedPropertyInMap(Object item, String path, Class 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)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 implements MsoResponseWrapperInterface { + + final static ObjectMapper objectMapper = new ObjectMapper(); + + private final int status; + private final T entity; + private final String raw; + + public MsoResponseWrapper2(RestObject 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 the generic type + */ +public class RestObject { + + 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(); + } +} + -- cgit 1.2.3-korg