Use ValidationResult for models v2.0
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / utils / ToscaUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019-2020 Nordix Foundation.
4  *  Modifications Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.models.tosca.utils;
23
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.Set;
27 import java.util.function.Function;
28 import javax.ws.rs.core.Response;
29 import lombok.NonNull;
30 import org.apache.commons.collections4.CollectionUtils;
31 import org.onap.policy.common.parameters.BeanValidationResult;
32 import org.onap.policy.common.parameters.ObjectValidationResult;
33 import org.onap.policy.common.parameters.ValidationStatus;
34 import org.onap.policy.models.base.PfConcept;
35 import org.onap.policy.models.base.PfConceptContainer;
36 import org.onap.policy.models.base.PfConceptKey;
37 import org.onap.policy.models.base.PfKey;
38 import org.onap.policy.models.base.PfModelRuntimeException;
39 import org.onap.policy.models.base.PfNameVersion;
40 import org.onap.policy.models.base.Validated;
41 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
42 import org.onap.policy.models.tosca.simple.concepts.JpaToscaEntityType;
43 import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;
44
45 /**
46  * Utility class for TOSCA concepts.
47  *
48  * @author Liam Fallon (liam.fallon@est.tech)
49  */
50 public final class ToscaUtils {
51     private static final String ROOT_KEY_NAME_SUFFIX = ".Root";
52
53     // @formatter:off
54     private static final Set<PfConceptKey> PREDEFINED_TOSCA_DATA_TYPES = Set.of(
55             new PfConceptKey("string",                       PfKey.NULL_KEY_VERSION),
56             new PfConceptKey("integer",                      PfKey.NULL_KEY_VERSION),
57             new PfConceptKey("float",                        PfKey.NULL_KEY_VERSION),
58             new PfConceptKey("boolean",                      PfKey.NULL_KEY_VERSION),
59             new PfConceptKey("timestamp",                    PfKey.NULL_KEY_VERSION),
60             new PfConceptKey("null",                         PfKey.NULL_KEY_VERSION),
61             new PfConceptKey("list",                         PfKey.NULL_KEY_VERSION),
62             new PfConceptKey("map",                          PfKey.NULL_KEY_VERSION),
63             new PfConceptKey("object",                       PfKey.NULL_KEY_VERSION),
64             new PfConceptKey("scalar-unit.size",             PfKey.NULL_KEY_VERSION),
65             new PfConceptKey("scalar-unit.time",             PfKey.NULL_KEY_VERSION),
66             new PfConceptKey("scalar-unit.frequency",        PfKey.NULL_KEY_VERSION),
67             new PfConceptKey("tosca.datatypes.TimeInterval", PfKey.NULL_KEY_VERSION)
68         );
69     // @formatter:on
70
71     /**
72      * Private constructor to prevent subclassing.
73      */
74     private ToscaUtils() {
75         // Private constructor to prevent subclassing
76     }
77
78     /**
79      * Get the predefined policy types.
80      *
81      * @return the predefined policy types
82      */
83     public static Collection<PfConceptKey> getPredefinedDataTypes() {
84         return PREDEFINED_TOSCA_DATA_TYPES;
85     }
86
87     /**
88      * Assert that data types have been specified correctly.
89      *
90      * @param serviceTemplate the service template containing data types to be checked
91      */
92     public static void assertDataTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
93         assertExist(serviceTemplate, ToscaUtils::checkDataTypesExist);
94     }
95
96     /**
97      * Assert that policy types have been specified correctly.
98      *
99      * @param serviceTemplate the service template containing policy types to be checked
100      */
101     public static void assertPolicyTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
102         assertExist(serviceTemplate, ToscaUtils::checkPolicyTypesExist);
103     }
104
105     /**
106      * Assert that policies have been specified correctly.
107      *
108      * @param serviceTemplate the service template containing policy types to be checked
109      */
110     public static void assertPoliciesExist(final JpaToscaServiceTemplate serviceTemplate) {
111         assertExist(serviceTemplate, ToscaUtils::checkPoliciesExist);
112     }
113
114     /**
115      * Check that data types have been specified correctly.
116      *
117      * @param serviceTemplate the service template containing data types to be checked
118      */
119     public static boolean doDataTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
120         return doExist(serviceTemplate, ToscaUtils::checkDataTypesExist);
121     }
122
123     /**
124      * Check that policy types have been specified correctly.
125      *
126      * @param serviceTemplate the service template containing policy types to be checked
127      */
128     public static boolean doPolicyTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
129         return doExist(serviceTemplate, ToscaUtils::checkPolicyTypesExist);
130     }
131
132     /**
133      * Check that policies have been specified correctly.
134      *
135      * @param serviceTemplate the service template containing policy types to be checked
136      */
137     public static boolean doPoliciesExist(final JpaToscaServiceTemplate serviceTemplate) {
138
139         return doExist(serviceTemplate, ToscaUtils::checkPoliciesExist);
140     }
141
142     /**
143      * Assert that something have been specified correctly.
144      *
145      * @param serviceTemplate the service template containing policy types to be checked
146      */
147     public static void assertExist(final JpaToscaServiceTemplate serviceTemplate,
148         final Function<JpaToscaServiceTemplate, String> checkerFunction) {
149         String message = checkerFunction.apply(serviceTemplate);
150         if (message != null) {
151             throw new PfModelRuntimeException(Response.Status.NOT_FOUND, message);
152         }
153     }
154
155     /**
156      * Check that something have been specified correctly.
157      *
158      * @param serviceTemplate the service template containing policy types to be checked
159      */
160     public static boolean doExist(final JpaToscaServiceTemplate serviceTemplate,
161         final Function<JpaToscaServiceTemplate, String> checkerFunction) {
162         return checkerFunction.apply(serviceTemplate) == null;
163     }
164
165     /**
166      * Check if data types have been specified correctly.
167      */
168     public static String checkDataTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
169         if (serviceTemplate.getDataTypes() == null) {
170             return "no data types specified on service template";
171         }
172
173         if (serviceTemplate.getDataTypes().getConceptMap().isEmpty()) {
174             return "list of data types specified on service template is empty";
175         }
176
177         return null;
178     }
179
180     /**
181      * Check if policy types have been specified correctly.
182      */
183     public static String checkPolicyTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
184         if (serviceTemplate.getPolicyTypes() == null) {
185             return "no policy types specified on service template";
186         }
187
188         if (serviceTemplate.getPolicyTypes().getConceptMap().isEmpty()) {
189             return "list of policy types specified on service template is empty";
190         }
191
192         return null;
193     }
194
195     /**
196      * Check if policies have been specified correctly.
197      */
198     public static String checkPoliciesExist(final JpaToscaServiceTemplate serviceTemplate) {
199         if (serviceTemplate.getTopologyTemplate() == null) {
200             return "topology template not specified on service template";
201         }
202
203         if (serviceTemplate.getTopologyTemplate().getPolicies() == null) {
204             return "no policies specified on topology template of service template";
205         }
206
207         if (serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().isEmpty()) {
208             return "list of policies specified on topology template of service template is empty";
209         }
210
211         return null;
212     }
213
214     /**
215      * getLatestPolicyTypeVersion Find all the ancestors of an entity type.
216      *
217      * @param entityTypes the set of entity types that exist
218      * @param entityType the entity type for which to get the parents
219      * @param result the result of the ancestor search with any warnings or errors
220      * @return the entity set containing the ancestors of the incoming entity
221      */
222     public static Collection<JpaToscaEntityType<ToscaEntity>> getEntityTypeAncestors(
223         @NonNull PfConceptContainer<? extends PfConcept, ? extends PfNameVersion> entityTypes,
224         @NonNull JpaToscaEntityType<?> entityType, @NonNull final BeanValidationResult result) {
225
226         PfConceptKey parentEntityTypeKey = entityType.getDerivedFrom();
227         if (parentEntityTypeKey == null || parentEntityTypeKey.getName().endsWith(ROOT_KEY_NAME_SUFFIX)) {
228             return CollectionUtils.emptyCollection();
229         }
230
231         if (entityType.getKey().equals(parentEntityTypeKey)) {
232             result.addResult(new ObjectValidationResult("entity type", entityType.getKey().getId(),
233                             ValidationStatus.INVALID, "ancestor of itself"));
234             throw new PfModelRuntimeException(Response.Status.CONFLICT, result.getResult());
235         }
236
237         @SuppressWarnings("unchecked")
238         Set<JpaToscaEntityType<ToscaEntity>> ancestorEntitySet = (Set<JpaToscaEntityType<ToscaEntity>>) entityTypes
239             .getAll(parentEntityTypeKey.getName(), parentEntityTypeKey.getVersion());
240         Set<JpaToscaEntityType<ToscaEntity>> ancestorEntitySetToReturn = new HashSet<>(ancestorEntitySet);
241         if (ancestorEntitySet.isEmpty()) {
242             result.addResult(new ObjectValidationResult("parent", parentEntityTypeKey.getId(),
243                             ValidationStatus.INVALID, Validated.NOT_FOUND));
244         } else {
245             for (JpaToscaEntityType<?> filteredEntityType : ancestorEntitySet) {
246                 ancestorEntitySetToReturn.addAll(getEntityTypeAncestors(entityTypes, filteredEntityType, result));
247             }
248         }
249         return ancestorEntitySetToReturn;
250     }
251
252     /**
253      * Get the entity tree from a concept container for a given entity key.
254      *
255      * @param entityTypes the concept container containing entity types
256      * @param entityName the name of the entity
257      * @param entityVersion the version of the entity
258      */
259     public static void getEntityTree(
260         @NonNull final PfConceptContainer<? extends PfConcept, ? extends PfNameVersion> entityTypes,
261         final String entityName, final String entityVersion) {
262
263         BeanValidationResult result = new BeanValidationResult("entity", entityName);
264
265         @SuppressWarnings("unchecked")
266         Set<JpaToscaEntityType<?>> filteredEntitySet =
267             (Set<JpaToscaEntityType<?>>) entityTypes.getAllNamesAndVersions(entityName, entityVersion);
268         Set<JpaToscaEntityType<?>> filteredEntitySetToReturn = new HashSet<>(filteredEntitySet);
269         for (JpaToscaEntityType<?> filteredEntityType : filteredEntitySet) {
270             filteredEntitySetToReturn
271                 .addAll(ToscaUtils.getEntityTypeAncestors(entityTypes, filteredEntityType, result));
272         }
273
274         if (!result.isValid()) {
275             throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, result.getResult());
276         }
277
278         entityTypes.getConceptMap().entrySet()
279             .removeIf(entityEntry -> !filteredEntitySetToReturn.contains(entityEntry.getValue()));
280     }
281 }