diff options
author | Amichai Hemli <amichai.hemli@intl.att.com> | 2019-12-09 13:17:24 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2019-12-09 13:17:24 +0000 |
commit | cbcca6ed1783b41eb10fbcaa456f3a1cfb8c9a39 (patch) | |
tree | d308c7059cce4c6968cabb7a73e85f7a0d03c63c | |
parent | bae7a355deae5b9b16ac0343d4ec13018963e900 (diff) | |
parent | 57e44972ab82fcd166eb6c0a3a948bd2c4287661 (diff) |
Merge "Change ServiceInstance's top-level rollbackOnFailure serialization to String"
-rw-r--r-- | vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java | 20 | ||||
-rw-r--r-- | vid-app-common/src/main/java/org/onap/vid/utils/jackson/BooleanAsStringSerializer.java | 39 | ||||
-rw-r--r-- | vid-automation/src/test/java/org/onap/vid/api/InstantiationTemplatesApiTest.java | 138 | ||||
-rw-r--r-- | vid-automation/src/test/resources/asyncInstantiation/ServiceTreeForRetry_serviceInstance.json | 2 | ||||
-rw-r--r-- | vid-automation/src/test/resources/asyncInstantiation/ServiceWithFailedServiceInstance.json | 2 | ||||
-rw-r--r-- | vid-automation/src/test/resources/asyncInstantiation/templates__instance_template.json (renamed from vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__instance_template.json) | 10 | ||||
-rw-r--r-- | vid-webpack-master/cypress/integration/iFrames/instantiation-templates.e2e.ts | 4 |
7 files changed, 204 insertions, 11 deletions
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java index 8828faf1d..e7e5783c4 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java @@ -21,18 +21,19 @@ package org.onap.vid.model.serviceInstantiation; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.ObjectUtils; -import org.onap.vid.job.JobAdapter; -import org.onap.vid.job.JobType; -import org.onap.vid.model.VidNotions; -import org.onap.vid.mso.model.ModelInfo; - +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.commons.lang3.ObjectUtils; +import org.onap.vid.job.JobAdapter; +import org.onap.vid.job.JobType; +import org.onap.vid.model.VidNotions; +import org.onap.vid.mso.model.ModelInfo; +import org.onap.vid.utils.jackson.BooleanAsStringSerializer; public class ServiceInstantiation extends BaseResource implements JobAdapter.AsyncJobRequest { @@ -127,6 +128,13 @@ public class ServiceInstantiation extends BaseResource implements JobAdapter.Asy this.vidNotions = vidNotions; } + @Override + @JsonSerialize(using=BooleanAsStringSerializer.class) + public boolean isRollbackOnFailure() { + // this override is for the BooleanAsStringSerializer annotation, + // but for Service-Instance level only + return super.isRollbackOnFailure(); + } public String getOwningEntityId() { return owningEntityId; diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/jackson/BooleanAsStringSerializer.java b/vid-app-common/src/main/java/org/onap/vid/utils/jackson/BooleanAsStringSerializer.java new file mode 100644 index 000000000..a61044294 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/utils/jackson/BooleanAsStringSerializer.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * VID + * ================================================================================ + * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.vid.utils.jackson; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import java.io.IOException; + +public class BooleanAsStringSerializer extends JsonSerializer<Boolean> { + + /** + * Annotate a Jackson getter with <code>@JsonSerialize(using=BooleanAsStringSerializer.class)</code> + * to get a boolean value be serialized as quoted string. + */ + @Override + public void serialize(Boolean bool, JsonGenerator generator, SerializerProvider provider) throws IOException { + // bool is guaranteed not to be null + generator.writeString(bool.toString()); + } +} diff --git a/vid-automation/src/test/java/org/onap/vid/api/InstantiationTemplatesApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/InstantiationTemplatesApiTest.java new file mode 100644 index 000000000..a14e81f44 --- /dev/null +++ b/vid-automation/src/test/java/org/onap/vid/api/InstantiationTemplatesApiTest.java @@ -0,0 +1,138 @@ +package org.onap.vid.api; + +import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.arrayWithSize; +import static org.hamcrest.Matchers.greaterThan; +import static org.onap.vid.api.TestUtils.convertRequest; +import static vid.automation.test.services.SimulatorApi.registerExpectationFromPreset; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import java.util.Map.Entry; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.onap.sdc.ci.tests.datatypes.UserCredentials; +import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet; +import org.onap.vid.model.mso.MsoResponseWrapper2; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.Test; +import vid.automation.test.Constants; +import vid.automation.test.model.User; +import vid.automation.test.services.AsyncJobsService; +import vid.automation.test.services.SimulatorApi.RegistrationStrategy; + +public class InstantiationTemplatesApiTest extends AsyncInstantiationBase { + + /* + Testing the Template Topology API should be very thin, given the following + assumptions: + + - Template topology API is relying on Retry's logic. + + - The templates themselves are an actual representation of the initial + state in VID's backend. This is all the knowledge that used to create + a service in the first time. So if API is fed with same state, it already + should be able to reiterate another instance. + + + The tests below will verify that: + + - A request resulting from Cypress test on "instantiation-templates.e2e.ts" + is accepted by API endpoint + + - A valid "regular" (not from template) request, yields a template that a + Cypress is able to deploy. + + These two tests are, technically, cyclic. + + Currently the only test below is shortcutting the both tests, by checking + that feeding a Cypress input yields a Template that is the same. This is + not perfect, but currently what we have. + + */ + + @Override + public UserCredentials getUserCredentials() { + User user = usersService.getUser(Constants.Users.EMANUEL_EMANUEL); + return new UserCredentials(user.credentials.userId, user.credentials.password, Constants.Users.EMANUEL_EMANUEL, "", ""); + } + + @AfterMethod + protected void dropAllFromNameCounter() { + AsyncJobsService asyncJobsService = new AsyncJobsService(); + asyncJobsService.muteAllAsyncJobs(); + asyncJobsService.dropAllFromNameCounter(); + } + + protected String templateTopologyUri(String jobId) { + return uri.toASCIIString() + "/asyncInstantiation/templateTopology/" + jobId; + } + + @Test(groups = "underDevelopment") + public void templateTopology_givenDeployFromCypressE2E_getTemplateTopologyDataIsEquivalent() throws IOException { + templateTopology_givenDeploy_templateTopologyIsEquivalent(objectMapper.readValue( + convertRequest(objectMapper, "asyncInstantiation/templates__instance_template.json"), + JsonNode.class)); + } + + public void templateTopology_givenDeploy_templateTopologyIsEquivalent(JsonNode body) { + registerExpectationFromPreset(new PresetAAIGetSubscribersGet(), RegistrationStrategy.CLEAR_THEN_SET); + + String uuid1 = postAsyncInstanceRequest(body); + JsonNode templateTopology1 = restTemplate.getForObject(templateTopologyUri(uuid1), JsonNode.class); + + assertThat(cleanupTemplate(templateTopology1), jsonEquals(cleanupTemplate(body))); + } + + private JsonNode cleanupTemplate(JsonNode templateTopology) { + return Stream.of(templateTopology) + .map(this::removeTrackById) + .map(this::removeNullValues) + .findAny().get(); + } + + private JsonNode removeTrackById(JsonNode node) { + return removeAny(node, it -> it.getKey().equals("trackById")); + } + + private JsonNode removeNullValues(JsonNode node) { + return removeAny(node, it -> it.getValue().isNull()); + } + + private JsonNode removeAny(JsonNode node, Predicate<Entry<String, JsonNode>> entryPredicate) { + if (node.isObject()) { + ((ObjectNode) node).remove( + Streams.fromIterator(node.fields()) + .filter(entryPredicate) + .map(Entry::getKey) + .collect(Collectors.toList()) + ); + + for (JsonNode child : node) { + removeAny(child, entryPredicate); + } + } + + return node; + } + + private <T> String postAsyncInstanceRequest(T body) { + String[] jobsUuids = (String[]) restTemplate.exchange( + getCreateBulkUri(), + HttpMethod.POST, + new HttpEntity<>(body), + new ParameterizedTypeReference<MsoResponseWrapper2<String[]>>() { + }) + .getBody().getEntity(); + + assertThat(jobsUuids, arrayWithSize(greaterThan(0))); + return jobsUuids[0]; + } + +} diff --git a/vid-automation/src/test/resources/asyncInstantiation/ServiceTreeForRetry_serviceInstance.json b/vid-automation/src/test/resources/asyncInstantiation/ServiceTreeForRetry_serviceInstance.json index 5139aa0c0..d5b282e89 100644 --- a/vid-automation/src/test/resources/asyncInstantiation/ServiceTreeForRetry_serviceInstance.json +++ b/vid-automation/src/test/resources/asyncInstantiation/ServiceTreeForRetry_serviceInstance.json @@ -55,7 +55,7 @@ "instanceParams": [], "pause": false, "bulkSize": 1, - "rollbackOnFailure": false, + "rollbackOnFailure": "false", "isALaCarte": true, "testApi": "VNF_API", "instanceId": "INSTANCE_ID", diff --git a/vid-automation/src/test/resources/asyncInstantiation/ServiceWithFailedServiceInstance.json b/vid-automation/src/test/resources/asyncInstantiation/ServiceWithFailedServiceInstance.json index 849cb7e43..28761f393 100644 --- a/vid-automation/src/test/resources/asyncInstantiation/ServiceWithFailedServiceInstance.json +++ b/vid-automation/src/test/resources/asyncInstantiation/ServiceWithFailedServiceInstance.json @@ -27,7 +27,7 @@ "pause": false, "productFamilyId": "ddf9cc0f-6331-4d35-bed0-a37f2d5e9cb3", "projectName": "zasaki", - "rollbackOnFailure": false, + "rollbackOnFailure": "false", "statusMessage": "The service instantiation is failed.", "subscriberName": "SILVIA ROBBINS", "subscriptionServiceType": "TYLER SILVIA", diff --git a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__instance_template.json b/vid-automation/src/test/resources/asyncInstantiation/templates__instance_template.json index 10ddc7384..5de1f4792 100644 --- a/vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__instance_template.json +++ b/vid-automation/src/test/resources/asyncInstantiation/templates__instance_template.json @@ -46,6 +46,7 @@ {} ], "rollbackOnFailure": true, + "instanceId": null, "vfModules": { "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0": { "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0ahubg": { @@ -66,7 +67,8 @@ {} ], "rollbackOnFailure": true, - "trackById": "ea2879a6-10bc-4697-90d7-7bc3e71da0fd" + "trackById": "ea2879a6-10bc-4697-90d7-7bc3e71da0fd", + "isFailed": false } }, "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1": { @@ -89,12 +91,15 @@ ], "rollbackOnFailure": true, "trackById": "b134410e-3bc0-478e-883e-1b6bdf8a28df", + "isFailed": false, "volumeGroupInstanceName": "zolson57arlba007_lba_dj_01_vol", "usePreload": true } } }, "trackById": "1d2848a0-3573-4d29-b3dd-60bb263260ea", + "isFailed": false, + "statusMessage": null, "position": null, "lineOfBusiness": "EMANUEL-CONSUMER" } @@ -107,6 +112,9 @@ ], "pause": false, "bulkSize": 1, + "instanceId": null, + "isFailed": false, + "statusMessage": null, "vidNotions": { "instantiationUI": "anyAlacarteWhichNotExcluded", "modelCategory": "5G Fabric Configuration", diff --git a/vid-webpack-master/cypress/integration/iFrames/instantiation-templates.e2e.ts b/vid-webpack-master/cypress/integration/iFrames/instantiation-templates.e2e.ts index 253352729..8eb70b1fe 100644 --- a/vid-webpack-master/cypress/integration/iFrames/instantiation-templates.e2e.ts +++ b/vid-webpack-master/cypress/integration/iFrames/instantiation-templates.e2e.ts @@ -30,7 +30,7 @@ describe('Drawing Board: Instantiation Templates', function () { .as('serviceModel'); cy.route(`**/asyncInstantiation/${templateTopologyEndpoint}/${templateUuid}`, - 'fixture:../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__instance_template.json') + 'fixture:../../../vid-automation/src/test/resources/asyncInstantiation/templates__instance_template.json') .as('templateTopology'); // When... @@ -48,7 +48,7 @@ describe('Drawing Board: Instantiation Templates', function () { // Then... cy.wait('@expectedPostAsyncInstantiation').then(xhr => { - cy.readFile('cypress/support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__instance_template.json').then((expectedResult) => { + cy.readFile('../vid-automation/src/test/resources/asyncInstantiation/templates__instance_template.json').then((expectedResult) => { convertRollbackOnFailureValueFromStringToBoolean(expectedResult); cy.deepCompare(xhr.request.body, expectedResult); }); |