Improve handling 'empty'/null string in Service fields
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / PolicyExportParserImpl.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.tosca;
21
22 import static org.apache.commons.collections.CollectionUtils.isEmpty;
23 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
24 import static org.apache.commons.collections.MapUtils.isNotEmpty;
25 import static org.apache.commons.lang.StringUtils.isNotEmpty;
26
27 import fj.data.Either;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.function.Supplier;
33 import java.util.stream.Collectors;
34 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
35 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
36 import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType;
37 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
38 import org.openecomp.sdc.be.model.Component;
39 import org.openecomp.sdc.be.model.ComponentInstance;
40 import org.openecomp.sdc.be.model.DataTypeDefinition;
41 import org.openecomp.sdc.be.model.GroupDefinition;
42 import org.openecomp.sdc.be.model.PolicyDefinition;
43 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
44 import org.openecomp.sdc.be.tosca.model.IToscaMetadata;
45 import org.openecomp.sdc.be.tosca.model.ToscaMetadata;
46 import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
47 import org.openecomp.sdc.common.log.wrappers.Logger;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.context.event.EventListener;
50
51 @org.springframework.stereotype.Component
52 public class PolicyExportParserImpl implements PolicyExportParser {
53
54     private static final Logger log = Logger.getLogger(PolicyExportParserImpl.class);
55     private ApplicationDataTypeCache applicationDataTypeCache;
56     private Map<String, DataTypeDefinition> dataTypes;
57     private PropertyConvertor propertyConvertor;
58
59     @Autowired
60     public PolicyExportParserImpl(ApplicationDataTypeCache applicationDataTypeCache, PropertyConvertor propertyConvertor) {
61         this.applicationDataTypeCache = applicationDataTypeCache;
62         this.propertyConvertor = propertyConvertor;
63         this.dataTypes = getDataTypes();
64     }
65
66     private Map<String, DataTypeDefinition> getDataTypes() {
67         Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(null);
68         if (dataTypesEither.isRight()) {
69             log.error("Failed to retrieve all data types {}", dataTypesEither.right().value());
70             throw new SdcResourceNotFoundException();
71         }
72         return dataTypesEither.left().value();
73     }
74
75     @EventListener
76     public void onDataTypesCacheChangedEvent(ApplicationDataTypeCache.DataTypesCacheChangedEvent dataTypesCacheChangedEvent) {
77         dataTypes = dataTypesCacheChangedEvent.getNewData().get(null);
78         log.debug("Data types cache updated.");
79     }
80
81     @Override
82     public Map<String, ToscaPolicyTemplate> getPolicies(Component component) {
83         Map<String, ToscaPolicyTemplate> toscaPolicies = null;
84         Map<String, PolicyDefinition> policies = component.getPolicies();
85         if (isNotEmpty(policies)) {
86             toscaPolicies = policies.values().stream()
87                 .collect(Collectors.toMap(PolicyDefinition::getName, policy -> getToscaPolicyTemplate(policy, component)));
88             log.debug("policies converted");
89         }
90         return toscaPolicies;
91     }
92
93     private ToscaPolicyTemplate getToscaPolicyTemplate(PolicyDefinition policyDefinition, Component component) {
94         String type = policyDefinition.getPolicyTypeName();
95         IToscaMetadata metadata = getToscaPolicyTemplateMetadata(policyDefinition);
96         Map<String, Object> properties = getToscaPolicyTemplateProperties(policyDefinition);
97         List<String> targets = getToscaPolicyTemplateTargets(policyDefinition, component.getComponentInstances(), component.getGroups());
98         return new ToscaPolicyTemplate(type, metadata, properties, targets);
99     }
100
101     private List<String> getToscaPolicyTemplateTargets(PolicyDefinition policyDefinition, List<ComponentInstance> componentInstances,
102                                                        List<GroupDefinition> groups) {
103         Map<PolicyTargetType, List<String>> targets = policyDefinition.getTargets();
104         List<String> targetNames = null;
105         if (targets == null || targets.isEmpty()) {
106             return null;
107         }
108         List<String> componentInstancesTargets = targets.get(PolicyTargetType.COMPONENT_INSTANCES);
109         List<String> groupTargets = targets.get(PolicyTargetType.GROUPS);
110         if (isNotEmpty(componentInstancesTargets) && isNotEmpty(componentInstances)) {
111             // get target names by Id from component instances
112             Map<String, String> targetNamesByIdFromComponentInstances = getTargetNamesByIdFromComponentInstances(componentInstances);
113             targetNames = targetNamesLazyInstantiation(targetNames);
114             addTargetNames(componentInstancesTargets, targetNames, targetNamesByIdFromComponentInstances);
115         }
116         if (isNotEmpty(groupTargets) && isNotEmpty(groups)) {
117             // get target names by id from group definitions
118             Map<String, String> targetNamesByIdFromGroupDefinitions = getTargetNamesByIdFromGroupDefinitions(groups);
119             targetNames = targetNamesLazyInstantiation(targetNames);
120             addTargetNames(groupTargets, targetNames, targetNamesByIdFromGroupDefinitions);
121         }
122         return targetNames;
123     }
124
125     private List<String> targetNamesLazyInstantiation(List<String> targetNames) {
126         if (targetNames == null) {
127             targetNames = new ArrayList<>();
128         }
129         return targetNames;
130     }
131
132     private void addTargetNames(List<String> targets, List<String> targetNames, Map<String, String> targetNamesById) {
133         if (!targetNamesById.isEmpty()) {
134             for (String id : targets) {
135                 String name = targetNamesById.get(id);
136                 if (name != null) {
137                     targetNames.add(name);
138                 }
139             }
140         }
141     }
142
143     private Map<String, String> getTargetNamesByIdFromGroupDefinitions(List<GroupDefinition> groups) {
144         return groups.stream().collect(Collectors.toMap(GroupDefinition::getUniqueId, GroupDefinition::getName));
145     }
146
147     private Map<String, String> getTargetNamesByIdFromComponentInstances(List<ComponentInstance> componentInstances) {
148         return componentInstances.stream().collect(Collectors.toMap(ComponentInstance::getUniqueId, ComponentInstance::getName));
149     }
150
151     private Map<String, Object> getToscaPolicyTemplateProperties(PolicyDefinition policyDefinition) {
152         List<PropertyDataDefinition> tempProperties = policyDefinition.getProperties();
153         if (isEmpty(tempProperties)) {
154             return null;
155         }
156         Map<String, Object> props = new HashMap<>();
157         tempProperties.forEach(input -> propertyConvertor.convertAndAddValue(dataTypes, props, input, getPropertyValue(input)));
158         if (props.isEmpty()) {
159             return null;
160         } else {
161             return props;
162         }
163     }
164
165     private Supplier<String> getPropertyValue(PropertyDataDefinition propertyDataDefinition) {
166         return () -> {
167             if (isNotEmpty(propertyDataDefinition.getValue())) {
168                 return propertyDataDefinition.getValue();
169             } else {
170                 return propertyDataDefinition.getDefaultValue();
171             }
172         };
173     }
174
175     private IToscaMetadata getToscaPolicyTemplateMetadata(PolicyDefinition policyDefinition) {
176         IToscaMetadata metadata = new ToscaMetadata();
177         metadata.setInvariantUUID(policyDefinition.getInvariantUUID());
178         metadata.setUUID(policyDefinition.getPolicyUUID());
179         metadata.setName(policyDefinition.getName());
180         metadata.setVersion(policyDefinition.getVersion());
181         return metadata;
182     }
183 }