diff options
6 files changed, 143 insertions, 12 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java index 7214d011e0..2c051b2b94 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java @@ -1196,7 +1196,7 @@ public class ElementBusinessLogic extends BaseBusinessLogic { if(subcategories != null){ return fetchByMainCategory(subcategories.left().value(), inTransaction, resourceType); } - return fetchByResourceType(filters.get(FilterKeyEnum.RESOURCE_TYPE), inTransaction); + return fetchComponentMetaDataByResourceType(filters.get(FilterKeyEnum.RESOURCE_TYPE), inTransaction); } private Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> getAllSubCategories(String categoryName) { @@ -1320,14 +1320,14 @@ public class ElementBusinessLogic extends BaseBusinessLogic { return Either.left(components); } - private Either<List<Component>, StorageOperationStatus> fetchByResourceType(String resourceType, boolean inTransaction) { + private Either<List<Component>, StorageOperationStatus> fetchComponentMetaDataByResourceType(String resourceType, boolean inTransaction) { List<Component> components = null; StorageOperationStatus status; Wrapper<StorageOperationStatus> statusWrapper = new Wrapper<>(); Either<List<Component>, StorageOperationStatus> result; try { - - Either<List<Component>, StorageOperationStatus> getResources = toscaOperationFacade.fetchByResourceType(resourceType); //titanGenericDao.getByCriteria(nodeType, props, clazz); + ComponentParametersView fetchUsersAndCategoriesFilter = new ComponentParametersView(Arrays.asList(ComponentFieldsEnum.USERS.getValue(), ComponentFieldsEnum.CATEGORIES.getValue())); + Either<List<Component>, StorageOperationStatus> getResources = toscaOperationFacade.fetchMetaDataByResourceType(resourceType, fetchUsersAndCategoriesFilter); if (getResources.isRight()) { status = getResources.right().value(); if(status != StorageOperationStatus.NOT_FOUND){ diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java index 82382f961d..8fd28e1224 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -4858,7 +4858,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { Either<Resource, ResponseFormat> result = null; try { - if(resource.getLifecycleState() != LifecycleStateEnum.CERTIFIED && forceCertificationAllowed){ + if(resource.getLifecycleState() != LifecycleStateEnum.CERTIFIED && forceCertificationAllowed && lifecycleBusinessLogic.isFirstCertification(resource.getVersion())){ result = nodeForceCertification(resource, user, lifecycleChangeInfo, inTransaction, needLock); if(result.isRight()){ return result; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java index dfe04f919d..f0b369072e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java @@ -464,7 +464,18 @@ public class LifecycleBusinessLogic { return Either.left(latestComponent); } - +/** + * Performs Force certification. + * Note that a Force certification is allowed for the first certification only, + * as only a state and a version is promoted due a Force certification, + * skipping other actions required if a previous certified version exists. + * @param resource + * @param user + * @param lifecycleChangeInfo + * @param inTransaction + * @param needLock + * @return + */ public Either<Resource, ResponseFormat> forceResourceCertification(Resource resource, User user, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction, boolean needLock) { Either<Resource, ResponseFormat> result = null; Either<ToscaElement, StorageOperationStatus> certifyResourceRes = null; @@ -472,6 +483,10 @@ public class LifecycleBusinessLogic { log.debug("Force certification is not allowed for the action {}. ", lifecycleChangeInfo.getAction().name()); result = Either.right(componentUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); } + if(!isFirstCertification(resource.getVersion())){ + log.debug("Failed to perform a force certification of resource{}. Force certification is allowed for the first certification only. ", resource.getName()); + result = Either.right(componentUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); + } // lock resource if(result == null && !inTransaction && needLock){ log.info("lock component {}", resource.getUniqueId()); @@ -512,4 +527,8 @@ public class LifecycleBusinessLogic { return result; } + public boolean isFirstCertification(String previousVersion) { + return previousVersion.split("\\.")[0].equals("0"); + } + } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java index e3ed9d6471..3cc80eaf36 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java @@ -1782,12 +1782,11 @@ public class ToscaOperationFacade { return (currentTemplateNameChecked != null && currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) ? Either.left(true) : Either.left(false); } - public Either<List<Component>, StorageOperationStatus> fetchByResourceType(String resourceType) { - + public Either<List<Component>, StorageOperationStatus> fetchMetaDataByResourceType(String resourceType, ComponentParametersView filterBy) { Map<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class); props.put(GraphPropertyEnum.RESOURCE_TYPE, resourceType); props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true); - Either<List<GraphVertex>, TitanOperationStatus> resourcesByTypeEither = titanDao.getByCriteria(null, props); + Either<List<GraphVertex>, TitanOperationStatus> resourcesByTypeEither = titanDao.getByCriteria(null, props, JsonParseFlagEnum.ParseMetadata); if (resourcesByTypeEither.isRight()) { return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourcesByTypeEither.right().value())); @@ -1797,11 +1796,10 @@ public class ToscaOperationFacade { List<Component> components = new ArrayList<>(); for (GraphVertex vertex : vertexList) { - components.add(getToscaElementByOperation(vertex).left().value()); + components.add(getToscaElementByOperation(vertex, filterBy).left().value()); } return Either.left(components); - } public void commit() { diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadeTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadeTest.java new file mode 100644 index 0000000000..d2d26e79d5 --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacadeTest.java @@ -0,0 +1,111 @@ +package org.openecomp.sdc.be.model.jsontitan.operations; + +import fj.data.Either; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.runners.MockitoJUnitRunner; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.dao.jsongraph.TitanDao; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate; +import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class ToscaOperationFacadeTest { + + @InjectMocks + private ToscaOperationFacade testInstance; + + @Mock + private TitanDao titanDaoMock; + + @Mock + private TopologyTemplateOperation topologyTemplateOperationMock; + + @Before + public void setUp() throws Exception { + testInstance = new ToscaOperationFacade(); + MockitoAnnotations.initMocks(this); + } + + + @SuppressWarnings("unchecked") + @Test + public void fetchMetaDataByResourceType() throws Exception { + ArgumentCaptor<Map> criteriaCapture = ArgumentCaptor.forClass(Map.class); + ComponentParametersView dataFilter = new ComponentParametersView(); + List<GraphVertex> mockVertices = getMockVertices(2); + Either<List<GraphVertex>, TitanOperationStatus> returnedVertices = Either.left(mockVertices); + + when(titanDaoMock.getByCriteria(Mockito.eq(null), criteriaCapture.capture(), Mockito.eq(JsonParseFlagEnum.ParseMetadata))).thenReturn(returnedVertices); + when(topologyTemplateOperationMock.getToscaElement(mockVertices.get(0), dataFilter)).thenReturn(Either.left(getResourceToscaElement("0"))); + when(topologyTemplateOperationMock.getToscaElement(mockVertices.get(1), dataFilter)).thenReturn(Either.left(getResourceToscaElement("1"))); + Either<List<Component>, StorageOperationStatus> fetchedComponents = testInstance.fetchMetaDataByResourceType(ResourceTypeEnum.VF.getValue(), dataFilter); + + verifyCriteriaForHighestVersionAndVfResourceType(criteriaCapture); + + assertTrue(fetchedComponents.isLeft()); + List<Component> cmpts = fetchedComponents.left().value(); + assertEquals(2, cmpts.size()); + assertEquals("0", cmpts.get(0).getUniqueId()); + assertEquals("1", cmpts.get(1).getUniqueId()); + } + + private void verifyCriteriaForHighestVersionAndVfResourceType(ArgumentCaptor<Map> criteriaCapture) { + Map<GraphPropertyEnum, Object> criteria = (Map<GraphPropertyEnum, Object>)criteriaCapture.getValue(); + assertEquals(2, criteria.size()); + assertEquals(criteria.get(GraphPropertyEnum.RESOURCE_TYPE), "VF"); + assertEquals(criteria.get(GraphPropertyEnum.IS_HIGHEST_VERSION), true); + } + + @SuppressWarnings("unchecked") + @Test + public void fetchMetaDataByResourceType_failedToGetData() throws Exception { + when(titanDaoMock.getByCriteria(Mockito.eq(null), Mockito.anyMap(), Mockito.eq(JsonParseFlagEnum.ParseMetadata))).thenReturn(Either.right(TitanOperationStatus.GENERAL_ERROR)); + Either<List<Component>, StorageOperationStatus> fetchedComponents = testInstance.fetchMetaDataByResourceType(ResourceTypeEnum.VF.getValue(), new ComponentParametersView()); + assertTrue(fetchedComponents.isRight()); + assertEquals(StorageOperationStatus.GENERAL_ERROR, fetchedComponents.right().value()); + } + + private List<GraphVertex> getMockVertices(int numOfVertices) { + return IntStream.range(0, numOfVertices).mapToObj(i -> getMockVertex()).collect(Collectors.toList()); + } + + private ToscaElement getResourceToscaElement(String id) { + ToscaElement toscaElement = new TopologyTemplate(); + toscaElement.setMetadata(new HashMap<>()); + toscaElement.getMetadata().put(JsonPresentationFields.COMPONENT_TYPE.getPresentation(), "RESOURCE"); + toscaElement.getMetadata().put(JsonPresentationFields.UNIQUE_ID.getPresentation(), id); + return toscaElement; + } + + private GraphVertex getMockVertex() { + GraphVertex graphVertex = new GraphVertex(); + graphVertex.setLabel(VertexTypeEnum.TOPOLOGY_TEMPLATE); + return graphVertex; + } +}
\ No newline at end of file diff --git a/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts index 4c3922264c..3a61371e85 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts +++ b/catalog-ui/src/app/view-models/forms/property-forms/module-property-modal/module-property-model.ts @@ -86,7 +86,8 @@ export class ModulePropertyView extends PropertyFormBaseView { let property = _.find(this.selectedModule.properties, (property) => { return property.uniqueId === this.$scope.property.uniqueId; }); - if (property.value !== this.$scope.property.value) { + + if (!property.readonly && property.value !== this.$scope.property.value) { if (this.component.isResource()) { (<Resource>this.component).updateResourceGroupProperties(this.selectedModule, [this.$scope.property]).then(onSuccess, onFailed); // for now we only update one property at a time } @@ -101,6 +102,8 @@ export class ModulePropertyView extends PropertyFormBaseView { } } else { deferred.resolve(true); + this.$uibModalInstance.close(); + } return deferred.promise; } |