e5367c4e3da07067aa96a11ed9821d2e3616c14e
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / property / PropertyDeclarationOrchestrator.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 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 package org.openecomp.sdc.be.components.property;
21
22 import static org.apache.commons.collections.MapUtils.isNotEmpty;
23
24 import fj.data.Either;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Optional;
29 import java.util.stream.Collectors;
30 import org.apache.commons.collections.CollectionUtils;
31 import org.apache.commons.lang3.tuple.Pair;
32 import org.openecomp.sdc.be.components.property.propertytopolicydeclarators.ComponentInstancePropertyToPolicyDeclarator;
33 import org.openecomp.sdc.be.components.property.propertytopolicydeclarators.ComponentPropertyToPolicyDeclarator;
34 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
35 import org.openecomp.sdc.be.model.Component;
36 import org.openecomp.sdc.be.model.ComponentInstInputsMap;
37 import org.openecomp.sdc.be.model.ComponentInstancePropInput;
38 import org.openecomp.sdc.be.model.InputDefinition;
39 import org.openecomp.sdc.be.model.PolicyDefinition;
40 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
41 import org.openecomp.sdc.common.log.wrappers.Logger;
42
43 @org.springframework.stereotype.Component("propertyDeclarationOrchestrator")
44 public class PropertyDeclarationOrchestrator {
45
46     private static final Logger log = Logger.getLogger(PropertyDeclarationOrchestrator.class);
47     private ComponentInstanceInputPropertyDeclarator componentInstanceInputPropertyDeclarator;
48     private ComponentInstancePropertyDeclarator componentInstancePropertyDeclarator;
49     private PolicyPropertyDeclarator policyPropertyDeclarator;
50     private GroupPropertyDeclarator groupPropertyDeclarator;
51     private ComponentPropertyDeclarator servicePropertyDeclarator;
52     private List<PropertyDeclarator> propertyDeclaratorsToInput;
53     private List<PropertyDeclarator> propertyDeclaratorsToPolicy;
54     private ComponentPropertyToPolicyDeclarator componentPropertyToPolicyDeclarator;
55     private ComponentInstancePropertyToPolicyDeclarator componentInstancePropertyToPolicyDeclarator;
56
57     public PropertyDeclarationOrchestrator(ComponentInstanceInputPropertyDeclarator componentInstanceInputPropertyDeclarator,
58                                            ComponentInstancePropertyDeclarator componentInstancePropertyDeclarator,
59                                            PolicyPropertyDeclarator policyPropertyDeclarator, GroupPropertyDeclarator groupPropertyDeclarator,
60                                            ComponentPropertyDeclarator servicePropertyDeclarator,
61                                            ComponentPropertyToPolicyDeclarator componentPropertyToPolicyDeclarator,
62                                            ComponentInstancePropertyToPolicyDeclarator componentInstancePropertyToPolicyDeclarator) {
63         this.componentInstanceInputPropertyDeclarator = componentInstanceInputPropertyDeclarator;
64         this.componentInstancePropertyDeclarator = componentInstancePropertyDeclarator;
65         this.policyPropertyDeclarator = policyPropertyDeclarator;
66         this.groupPropertyDeclarator = groupPropertyDeclarator;
67         this.servicePropertyDeclarator = servicePropertyDeclarator;
68         this.componentPropertyToPolicyDeclarator = componentPropertyToPolicyDeclarator;
69         this.componentInstancePropertyToPolicyDeclarator = componentInstancePropertyToPolicyDeclarator;
70         propertyDeclaratorsToInput = Arrays
71             .asList(componentInstanceInputPropertyDeclarator, componentInstancePropertyDeclarator, policyPropertyDeclarator, groupPropertyDeclarator,
72                 servicePropertyDeclarator);
73         propertyDeclaratorsToPolicy = Arrays.asList(componentPropertyToPolicyDeclarator, componentInstancePropertyToPolicyDeclarator);
74     }
75
76     public Either<List<InputDefinition>, StorageOperationStatus> declarePropertiesToInputs(Component component,
77                                                                                            ComponentInstInputsMap componentInstInputsMap) {
78         updatePropertiesConstraints(component, componentInstInputsMap);
79         PropertyDeclarator propertyDeclarator = getPropertyDeclarator(componentInstInputsMap);
80         Pair<String, List<ComponentInstancePropInput>> propsToDeclare = componentInstInputsMap.resolvePropertiesToDeclare();
81         return propertyDeclarator.declarePropertiesAsInputs(component, propsToDeclare.getLeft(), propsToDeclare.getRight());
82     }
83
84     private void updatePropertiesConstraints(Component component, ComponentInstInputsMap componentInstInputsMap) {
85         componentInstInputsMap.getComponentInstanceProperties()
86             .forEach((k, v) -> updatePropsConstraints(component.safeGetComponentInstancesProperties(), k, v));
87         componentInstInputsMap.getComponentInstanceInputsMap()
88             .forEach((k, v) -> updatePropsConstraints(component.safeGetComponentInstancesInputs(), k, v));
89         componentInstInputsMap.getGroupProperties().forEach((k, v) -> updatePropsConstraints(component.safeGetPolicyProperties(), k, v));
90         componentInstInputsMap.getPolicyProperties().forEach((k, v) -> updatePropsConstraints(component.safeGetGroupsProperties(), k, v));
91     }
92
93     public Either<List<PolicyDefinition>, StorageOperationStatus> declarePropertiesToPolicies(Component component,
94                                                                                               ComponentInstInputsMap componentInstInputsMap) {
95         PropertyDeclarator propertyDeclarator = getPropertyDeclarator(componentInstInputsMap);
96         Pair<String, List<ComponentInstancePropInput>> propsToDeclare = componentInstInputsMap.resolvePropertiesToDeclare();
97         return propertyDeclarator.declarePropertiesAsPolicies(component, propsToDeclare.getLeft(), propsToDeclare.getRight());
98     }
99
100     public Either<InputDefinition, StorageOperationStatus> declarePropertiesToListInput(Component component,
101                                                                                         ComponentInstInputsMap componentInstInputsMap,
102                                                                                         InputDefinition input) {
103         PropertyDeclarator propertyDeclarator = getPropertyDeclarator(componentInstInputsMap);
104         Pair<String, List<ComponentInstancePropInput>> propsToDeclare = componentInstInputsMap.resolvePropertiesToDeclare();
105         log.debug("#declarePropertiesToInputs: componentId={}, propOwnerId={}", component.getUniqueId(), propsToDeclare.getLeft());
106         return propertyDeclarator.declarePropertiesAsListInput(component, propsToDeclare.getLeft(), propsToDeclare.getRight(), input);
107     }
108
109     private <T extends PropertyDataDefinition> void updatePropsConstraints(Map<String, List<T>> instancesProperties, String ownerId,
110                                                                            List<ComponentInstancePropInput> inputs) {
111         Optional<List<T>> propertiesOpt = instancesProperties.entrySet().stream().filter(e -> e.getKey().equals(ownerId)).map(Map.Entry::getValue)
112             .findFirst();
113         if (propertiesOpt.isPresent()) {
114             Map<String, PropertyDataDefinition> instProps = propertiesOpt.get().stream()
115                 .collect(Collectors.toMap(PropertyDataDefinition::getName, p -> p));
116             inputs.stream().filter(i -> instProps.containsKey(i.getName())).forEach(i -> updatePropConstraints(i, instProps.get(i.getName())));
117         }
118     }
119
120     private void updatePropConstraints(PropertyDataDefinition input, PropertyDataDefinition property) {
121         if (CollectionUtils.isNotEmpty(property.getPropertyConstraints())) {
122             input.setPropertyConstraints(property.getPropertyConstraints());
123         } else if (property.getSchemaProperty() != null && CollectionUtils.isNotEmpty(property.getSchemaProperty().getPropertyConstraints())) {
124             input.setPropertyConstraints(property.getSchemaProperty().getPropertyConstraints());
125         }
126     }
127
128     public StorageOperationStatus unDeclarePropertiesAsInputs(Component component, InputDefinition inputToDelete) {
129         log.debug("#unDeclarePropertiesAsInputs - removing input declaration for input {} on component {}", inputToDelete.getName(),
130             component.getUniqueId());
131         for (PropertyDeclarator propertyDeclarator : propertyDeclaratorsToInput) {
132             StorageOperationStatus storageOperationStatus = propertyDeclarator.unDeclarePropertiesAsInputs(component, inputToDelete);
133             if (StorageOperationStatus.OK != storageOperationStatus) {
134                 log.debug("#unDeclarePropertiesAsInputs - failed to remove input declaration for input {} on component {}. reason {}",
135                     inputToDelete.getName(), component.getUniqueId(), storageOperationStatus);
136                 return storageOperationStatus;
137             }
138         }
139         return StorageOperationStatus.OK;
140     }
141
142     /**
143      * Un declare properties declared as list type input
144      *
145      * @param component
146      * @param inputToDelete
147      * @return
148      */
149     public StorageOperationStatus unDeclarePropertiesAsListInputs(Component component, InputDefinition inputToDelete) {
150         log.debug("#unDeclarePropertiesAsListInputs - removing input declaration for input {} on component {}", inputToDelete.getName(),
151             component.getUniqueId());
152         for (PropertyDeclarator propertyDeclarator : propertyDeclaratorsToInput) {
153             StorageOperationStatus storageOperationStatus = propertyDeclarator.unDeclarePropertiesAsListInputs(component, inputToDelete);
154             if (StorageOperationStatus.OK != storageOperationStatus) {
155                 log.debug("#unDeclarePropertiesAsListInputs - failed to remove input declaration for input {} on component {}. reason {}",
156                     inputToDelete.getName(), component.getUniqueId(), storageOperationStatus);
157                 return storageOperationStatus;
158             }
159         }
160         return StorageOperationStatus.OK;
161     }
162
163     /**
164      * Get properties owner id
165      *
166      * @param componentInstInputsMap
167      * @return
168      */
169     public String getPropOwnerId(ComponentInstInputsMap componentInstInputsMap) {
170         Pair<String, List<ComponentInstancePropInput>> propsToDeclare = componentInstInputsMap.resolvePropertiesToDeclare();
171         return propsToDeclare.getLeft();
172     }
173
174     public StorageOperationStatus unDeclarePropertiesAsPolicies(Component component, PolicyDefinition policyToDelete) {
175         log.debug("#unDeclarePropertiesAsInputs - removing policy declaration for input {} on component {}", policyToDelete.getName(),
176             component.getUniqueId());
177         for (PropertyDeclarator propertyDeclarator : propertyDeclaratorsToPolicy) {
178             StorageOperationStatus storageOperationStatus = propertyDeclarator.unDeclarePropertiesAsPolicies(component, policyToDelete);
179             if (StorageOperationStatus.OK != storageOperationStatus) {
180                 log.debug("#unDeclarePropertiesAsInputs - failed to remove policy declaration for policy {} on component {}. reason {}",
181                     policyToDelete.getName(), component.getUniqueId(), storageOperationStatus);
182                 return storageOperationStatus;
183             }
184         }
185         return StorageOperationStatus.OK;
186     }
187
188     private PropertyDeclarator getPropertyDeclarator(ComponentInstInputsMap componentInstInputsMap) {
189         if (isNotEmpty(componentInstInputsMap.getComponentInstanceInputsMap())) {
190             return componentInstanceInputPropertyDeclarator;
191         }
192         if (isNotEmpty(componentInstInputsMap.getComponentInstanceProperties())) {
193             return componentInstancePropertyDeclarator;
194         }
195         if (isNotEmpty(componentInstInputsMap.getPolicyProperties())) {
196             return policyPropertyDeclarator;
197         }
198         if (isNotEmpty(componentInstInputsMap.getGroupProperties())) {
199             return groupPropertyDeclarator;
200         }
201         if (isNotEmpty(componentInstInputsMap.getServiceProperties())) {
202             return servicePropertyDeclarator;
203         }
204         if (isNotEmpty(componentInstInputsMap.getComponentPropertiesToPolicies())) {
205             return componentPropertyToPolicyDeclarator;
206         }
207         if (isNotEmpty(componentInstInputsMap.getComponentInstancePropertiesToPolicies())) {
208             return componentInstancePropertyToPolicyDeclarator;
209         }
210         throw new IllegalStateException("there are no properties selected for declaration");
211     }
212 }