Change to enable SDC list type input
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / property / ComponentPropertyDeclarator.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.be.components.property;
18
19 import fj.data.Either;
20 import org.apache.commons.collections.CollectionUtils;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Optional;
25 import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic;
26 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
27 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
28 import org.openecomp.sdc.be.impl.ComponentsUtils;
29 import org.openecomp.sdc.be.model.Component;
30 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
31 import org.openecomp.sdc.be.model.InputDefinition;
32 import org.openecomp.sdc.be.model.PropertyDefinition;
33 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
34 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
35 import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
36
37 @org.springframework.stereotype.Component
38 public class ComponentPropertyDeclarator extends DefaultPropertyDeclarator<Component, PropertyDataDefinition> {
39
40   private ToscaOperationFacade toscaOperationFacade;
41   PropertyBusinessLogic propertyBL;
42
43
44   public ComponentPropertyDeclarator(ComponentsUtils componentsUtils,
45                                      PropertyOperation propertyOperation,
46                                      ToscaOperationFacade toscaOperationFacade,
47                                      PropertyBusinessLogic propertyBL) {
48     super(componentsUtils, propertyOperation);
49     this.toscaOperationFacade = toscaOperationFacade;
50     this.propertyBL = propertyBL;
51   }
52
53   @Override
54   public PropertyDataDefinition createDeclaredProperty(PropertyDataDefinition prop) {
55     return new PropertyDataDefinition(prop);
56   }
57
58   @Override
59   public Either<?, StorageOperationStatus> updatePropertiesValues(Component component,
60                                                            String propertiesOwnerId,
61                                                            List<PropertyDataDefinition> properties) {
62     if(CollectionUtils.isNotEmpty(properties)) {
63       for(PropertyDataDefinition property : properties) {
64         Either<PropertyDefinition, StorageOperationStatus>
65             storageStatus = toscaOperationFacade
66             .updatePropertyOfComponent(component, new PropertyDefinition(property));
67         if(storageStatus.isRight()) {
68           return Either.right(storageStatus.right().value());
69         }
70       }
71     }
72     return Either.left(properties);
73   }
74
75   @Override
76   public Optional<Component> resolvePropertiesOwner(Component component, String propertiesOwnerId) {
77     return Optional.of(component);
78   }
79
80   @Override
81   public void addPropertiesListToInput(PropertyDataDefinition declaredProp,
82                                 InputDefinition input) {
83
84     List<ComponentInstanceProperty> propertiesList = input.getProperties();
85     if(propertiesList == null) {
86       propertiesList = new ArrayList<>(); // adding the property with the new value for UI
87     }
88     propertiesList.add(new ComponentInstanceProperty(declaredProp));
89     input.setProperties(propertiesList);
90   }
91
92   @Override
93   public StorageOperationStatus unDeclarePropertiesAsInputs(Component component,
94                                                             InputDefinition input) {
95     PropertyDefinition propertyDefinition = new PropertyDefinition(input);
96
97     if(propertyBL.isPropertyUsedByOperation(component, propertyDefinition)) {
98       return StorageOperationStatus.DECLARED_INPUT_USED_BY_OPERATION;
99     }
100
101     Optional<PropertyDefinition> propertyToUpdateCandidate =
102         getDeclaredPropertyByInputId(component, input.getUniqueId());
103
104     if(propertyToUpdateCandidate.isPresent()) {
105       PropertyDefinition propertyToUpdate = propertyToUpdateCandidate.get();
106       return unDeclareInput(component, input, propertyToUpdate);
107     }
108
109
110     return StorageOperationStatus.OK;
111   }
112
113   @Override
114   public StorageOperationStatus unDeclarePropertiesAsListInputs(Component component,
115                                                             InputDefinition input) {
116     PropertyDefinition propertyDefinition = new PropertyDefinition(input);
117
118     if(propertyBL.isPropertyUsedByOperation(component, propertyDefinition)) {
119       return StorageOperationStatus.DECLARED_INPUT_USED_BY_OPERATION;
120     }
121
122     Optional<List <PropertyDefinition>> propertyToUpdateCandidate =
123             getDeclaredPropertiesByInputId(component, input.getUniqueId());
124
125     if(propertyToUpdateCandidate.isPresent()) {
126       List<PropertyDefinition> propertiesToUpdate = propertyToUpdateCandidate.get();
127       if (!propertiesToUpdate.isEmpty()) {
128         return unDeclareInputs(component, input, propertiesToUpdate);
129       }
130     }
131
132     return StorageOperationStatus.OK;
133   }
134
135   private StorageOperationStatus unDeclareInputs(Component component,
136                                                  InputDefinition input,
137                                                  List <PropertyDefinition> propertiesToUpdate) {
138     for (PropertyDefinition propertyToUpdate : propertiesToUpdate) {
139       StorageOperationStatus storageOperationStatus = unDeclareInput(component, input, propertyToUpdate);
140       if (StorageOperationStatus.OK != storageOperationStatus) {
141         return storageOperationStatus;
142       }
143     }
144     return StorageOperationStatus.OK;
145   }
146
147   private StorageOperationStatus unDeclareInput(Component component,
148                                                 InputDefinition input,
149                                                 PropertyDefinition propertyToUpdate) {
150     prepareValueBeforeDelete(input, propertyToUpdate, Collections.emptyList());
151     propertyToUpdate.setValue(input.getDefaultValue());
152     Either<PropertyDefinition, StorageOperationStatus> status = toscaOperationFacade
153         .updatePropertyOfComponent(component, propertyToUpdate);
154     if(status.isRight()) {
155       return status.right().value();
156     }
157
158     return StorageOperationStatus.OK;
159   }
160
161   private Optional<PropertyDefinition> getDeclaredPropertyByInputId(Component component, String inputId) {
162     List<PropertyDefinition> properties = component.getProperties();
163
164     if (CollectionUtils.isEmpty(properties)) {
165       return Optional.empty();
166     }
167
168     for (PropertyDefinition propertyDefinition : properties) {
169       List<GetInputValueDataDefinition> getInputValues = propertyDefinition.getGetInputValues();
170       if (CollectionUtils.isEmpty(getInputValues)) {
171         continue;
172       }
173
174       Optional<GetInputValueDataDefinition> getInputCandidate =
175               getInputValues.stream().filter(getInput -> getInput.getInputId().equals(inputId)).findAny();
176
177       if (getInputCandidate.isPresent()) {
178         return Optional.of(propertyDefinition);
179       }
180     }
181
182     return Optional.empty();
183   }
184
185   private Optional<List <PropertyDefinition>> getDeclaredPropertiesByInputId(Component component,
186                                                                     String inputId) {
187     List<PropertyDefinition> properties = component.getProperties();
188     List<PropertyDefinition> propertiesToUpdate = new ArrayList<>();
189
190     if(CollectionUtils.isEmpty(properties)) {
191       return Optional.empty();
192     }
193
194     for(PropertyDefinition propertyDefinition : properties) {
195       List<GetInputValueDataDefinition> getInputValues = propertyDefinition.getGetInputValues();
196       if(CollectionUtils.isEmpty(getInputValues)) {
197         continue;
198       }
199
200       Optional<GetInputValueDataDefinition> getInputCandidate =
201               getInputValues.stream().filter(getInput -> getInput.getInputId().equals(inputId))
202                       .findAny();
203
204       if(getInputCandidate.isPresent()) {
205         propertiesToUpdate.add(propertyDefinition);
206       }
207     }
208
209     return Optional.of(propertiesToUpdate);
210   }
211 }