Sync Integ to Master
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / validation / ComponentValidations.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.components.validation;
22
23 import org.apache.commons.collections.CollectionUtils;
24 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
25 import org.openecomp.sdc.be.dao.api.ActionStatus;
26 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
27 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
28 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
29 import java.util.List;
30 import java.util.Optional;
31 import java.util.Set;
32
33 import org.openecomp.sdc.be.model.Component;
34 import org.openecomp.sdc.be.model.ComponentInstance;
35 import org.openecomp.sdc.be.model.ComponentParametersView;
36 import org.openecomp.sdc.be.model.GroupDefinition;
37 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
38 import org.openecomp.sdc.be.model.operations.StorageException;
39 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
40 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
41 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
42 import org.openecomp.sdc.common.util.ValidationUtils;
43
44 import java.util.HashSet;
45 import java.util.List;
46 import java.util.Set;
47
48 import static java.util.stream.Collectors.toList;
49
50
51 @org.springframework.stereotype.Component
52 public final class ComponentValidations {
53
54     private final ToscaOperationFacade toscaOperationFacade;
55     private final IGraphLockOperation graphLockOperation;
56
57     public ComponentValidations(ToscaOperationFacade toscaOperationFacade, IGraphLockOperation graphLockOperation) {
58         this.toscaOperationFacade = toscaOperationFacade;
59         this.graphLockOperation = graphLockOperation;
60     }
61
62     public static boolean validateComponentInstanceExist(Component component, String instanceId) {
63         return Optional.ofNullable(component.getComponentInstances())
64                        .map(componentInstances -> componentInstances.stream().map(ComponentInstance::getUniqueId).collect(toList()))
65                        .filter(instancesIds -> instancesIds.contains(instanceId))
66                        .isPresent();
67     }
68
69     public static String getNormalizedName(ToscaDataDefinition toscaDataDefinition) {
70         String name = (String) toscaDataDefinition.getToscaPresentationValue(JsonPresentationFields.NAME);
71         return org.openecomp.sdc.common.util.ValidationUtils.normalizeComponentInstanceName(name);
72     }
73
74     /**
75      * The following logic is applied:
76      * For each name new or existing name we look at the normalized name which is used in Tosca representation
77      * @param currentName
78      * @param newName
79      * @param component
80      * @return True is new name can be used in this component, false otherwise
81      */
82     public static boolean validateNameIsUniqueInComponent(String currentName, String newName, Component component) {
83         String normalizedCurrentName = ValidationUtils.normalizeComponentInstanceName(currentName);
84         String normalizedNewName = ValidationUtils.normalizeComponentInstanceName(newName);
85         
86         if (normalizedCurrentName.equals(normalizedNewName)) {
87             return true;    //As it's same entity, still considered unique
88         }
89         List<GroupDefinition> groups = component.getGroups();
90         List<ComponentInstance> componentInstances = component.getComponentInstances();
91         Set<String> existingNames = new HashSet<>();
92         if (CollectionUtils.isNotEmpty(groups)) {
93             List<String> existingGroupNames = groups
94                     .stream()
95                     .map(ComponentValidations::getNormalizedName)
96                     .collect(toList());
97             existingNames.addAll(existingGroupNames);
98         }
99         if (CollectionUtils.isNotEmpty(componentInstances)) {
100             List<String> existingInstanceNames = componentInstances
101                     .stream()
102                     .map(ComponentValidations::getNormalizedName)
103                     .collect(toList());
104             existingNames.addAll(existingInstanceNames);
105         }
106         return !existingNames.contains(normalizedNewName);
107     }
108
109     public Component validateComponentIsCheckedOutByUserAndLockIt(ComponentTypeEnum componentTypeEnum, String componentId, String userId) {
110         Component component = getComponent(componentId, componentTypeEnum);
111
112         if (!ComponentValidationUtils.canWorkOnComponent(component, userId)) {
113             throw new ComponentException(ActionStatus.ILLEGAL_COMPONENT_STATE, component.getName());
114         }
115
116         lockComponent(component);
117
118         return component;
119     }
120
121     private Component getComponent(String componentId, ComponentTypeEnum componentType) {
122         Component component = toscaOperationFacade.getToscaElement(componentId, new ComponentParametersView())
123                 .left()
124                 .on(this::onToscaOperationError);
125
126         if (componentType!=component.getComponentType()) {
127             throw new ComponentException(ActionStatus.INVALID_RESOURCE_TYPE);
128         }
129
130         return component;
131     }
132
133     private void lockComponent(Component component) {
134         StorageOperationStatus lockComponentStatus = graphLockOperation.lockComponent(component.getUniqueId(),
135                 component.getComponentType().getNodeType());
136         if (!StorageOperationStatus.OK.equals(lockComponentStatus)) {
137             throw new StorageException(lockComponentStatus);
138         }
139     }
140
141     private Component onToscaOperationError(StorageOperationStatus storageOperationStatus) {
142         throw new StorageException(storageOperationStatus);
143     }
144
145 }