aboutsummaryrefslogtreecommitdiffstats
path: root/models-tosca/src/main/java/org/onap/policy/models/tosca/utils/ToscaUtils.java
blob: be0d41d9b992b24ab05bcc4584449eb0eab37071 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/*-
 * ============LICENSE_START=======================================================
 *  Copyright (C) 2019-2022 Nordix Foundation.
 *  Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 * ============LICENSE_END=========================================================
 */

package org.onap.policy.models.tosca.utils;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;
import javax.ws.rs.core.Response;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.apache.commons.collections4.CollectionUtils;
import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.common.parameters.ValidationStatus;
import org.onap.policy.models.base.PfConcept;
import org.onap.policy.models.base.PfConceptContainer;
import org.onap.policy.models.base.PfConceptKey;
import org.onap.policy.models.base.PfKey;
import org.onap.policy.models.base.PfModelRuntimeException;
import org.onap.policy.models.base.PfNameVersion;
import org.onap.policy.models.base.Validated;
import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
import org.onap.policy.models.tosca.simple.concepts.JpaToscaEntityType;
import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate;

/**
 * Utility class for TOSCA concepts.
 *
 * @author Liam Fallon (liam.fallon@est.tech)
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ToscaUtils {
    private static final String ROOT_KEY_NAME_SUFFIX = ".Root";

    // @formatter:off
    private static final Set<PfConceptKey> PREDEFINED_TOSCA_DATA_TYPES = Set.of(
            new PfConceptKey("string",                       PfKey.NULL_KEY_VERSION),
            new PfConceptKey("integer",                      PfKey.NULL_KEY_VERSION),
            new PfConceptKey("float",                        PfKey.NULL_KEY_VERSION),
            new PfConceptKey("boolean",                      PfKey.NULL_KEY_VERSION),
            new PfConceptKey("timestamp",                    PfKey.NULL_KEY_VERSION),
            new PfConceptKey("null",                         PfKey.NULL_KEY_VERSION),
            new PfConceptKey("list",                         PfKey.NULL_KEY_VERSION),
            new PfConceptKey("map",                          PfKey.NULL_KEY_VERSION),
            new PfConceptKey("object",                       PfKey.NULL_KEY_VERSION),
            new PfConceptKey("scalar-unit.size",             PfKey.NULL_KEY_VERSION),
            new PfConceptKey("scalar-unit.time",             PfKey.NULL_KEY_VERSION),
            new PfConceptKey("scalar-unit.frequency",        PfKey.NULL_KEY_VERSION),
            new PfConceptKey("tosca.datatypes.TimeInterval", PfKey.NULL_KEY_VERSION)
        );
    // @formatter:on

    /**
     * Get the predefined policy types.
     *
     * @return the predefined policy types
     */
    public static Collection<PfConceptKey> getPredefinedDataTypes() {
        return PREDEFINED_TOSCA_DATA_TYPES;
    }

    /**
     * Assert that data types have been specified correctly.
     *
     * @param serviceTemplate the service template containing data types to be checked
     */
    public static void assertDataTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
        assertExist(serviceTemplate, ToscaUtils::checkDataTypesExist);
    }

    /**
     * Assert that policy types have been specified correctly.
     *
     * @param serviceTemplate the service template containing policy types to be checked
     */
    public static void assertPolicyTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
        assertExist(serviceTemplate, ToscaUtils::checkPolicyTypesExist);
    }

    /**
     * Assert that policies have been specified correctly.
     *
     * @param serviceTemplate the service template containing policy types to be checked
     */
    public static void assertPoliciesExist(final JpaToscaServiceTemplate serviceTemplate) {
        assertExist(serviceTemplate, ToscaUtils::checkPoliciesExist);
    }

    /**
     * Assert that node templates have been specified correctly.
     *
     * @param serviceTemplate the service template containing node templates to be checked
     */
    public static void assertNodeTemplatesExist(final JpaToscaServiceTemplate serviceTemplate) {
        assertExist(serviceTemplate, ToscaUtils::checkNodeTemplateExist);
    }

    /**
     * Check that data types have been specified correctly.
     *
     * @param serviceTemplate the service template containing data types to be checked
     */
    public static boolean doDataTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
        return doExist(serviceTemplate, ToscaUtils::checkDataTypesExist);
    }

    /**
     * Check that policy types have been specified correctly.
     *
     * @param serviceTemplate the service template containing policy types to be checked
     */
    public static boolean doPolicyTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
        return doExist(serviceTemplate, ToscaUtils::checkPolicyTypesExist);
    }

    /**
     * Check that policies have been specified correctly.
     *
     * @param serviceTemplate the service template containing policy types to be checked
     */
    public static boolean doPoliciesExist(final JpaToscaServiceTemplate serviceTemplate) {

        return doExist(serviceTemplate, ToscaUtils::checkPoliciesExist);
    }

    /**
     * Check that tosca node templates have been specified correctly.
     *
     * @param serviceTemplate the service template containing node templates to be checked
     */
    public static boolean doNodeTemplatesExist(final JpaToscaServiceTemplate serviceTemplate) {

        return doExist(serviceTemplate, ToscaUtils::checkNodeTemplateExist);
    }

    /**
     * Assert that something have been specified correctly.
     *
     * @param serviceTemplate the service template containing policy types to be checked
     */
    public static void assertExist(final JpaToscaServiceTemplate serviceTemplate,
            final Function<JpaToscaServiceTemplate, String> checkerFunction) {
        String message = checkerFunction.apply(serviceTemplate);
        if (message != null) {
            throw new PfModelRuntimeException(Response.Status.NOT_FOUND, message);
        }
    }

    /**
     * Check that something have been specified correctly.
     *
     * @param serviceTemplate the service template containing policy types to be checked
     */
    public static boolean doExist(final JpaToscaServiceTemplate serviceTemplate,
            final Function<JpaToscaServiceTemplate, String> checkerFunction) {
        return checkerFunction.apply(serviceTemplate) == null;
    }

    /**
     * Check if data types have been specified correctly.
     */
    public static String checkDataTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
        if (serviceTemplate.getDataTypes() == null) {
            return "no data types specified on service template";
        }

        if (serviceTemplate.getDataTypes().getConceptMap().isEmpty()) {
            return "list of data types specified on service template is empty";
        }

        return null;
    }

    /**
     * Check if policy types have been specified correctly.
     */
    public static String checkPolicyTypesExist(final JpaToscaServiceTemplate serviceTemplate) {
        if (serviceTemplate.getPolicyTypes() == null) {
            return "no policy types specified on service template";
        }

        if (serviceTemplate.getPolicyTypes().getConceptMap().isEmpty()) {
            return "list of policy types specified on service template is empty";
        }

        return null;
    }

    /**
     * Check if policies have been specified correctly.
     */
    public static String checkPoliciesExist(final JpaToscaServiceTemplate serviceTemplate) {
        if (serviceTemplate.getTopologyTemplate() == null) {
            return "topology template not specified on service template";
        }

        if (serviceTemplate.getTopologyTemplate().getPolicies() == null) {
            return "no policies specified on topology template of service template";
        }

        if (serviceTemplate.getTopologyTemplate().getPolicies().getConceptMap().isEmpty()) {
            return "list of policies specified on topology template of service template is empty";
        }

        return null;
    }

    /**
     * Check if node templates have been specified correctly.
     */
    public static String checkNodeTemplateExist(final JpaToscaServiceTemplate serviceTemplate) {
        if (serviceTemplate.getTopologyTemplate().getNodeTemplates() == null) {
            return "node templates not present on the service template";
        }

        if (serviceTemplate.getTopologyTemplate().getNodeTemplates().getConceptMap().isEmpty()) {
            return "no parameters present on the node templates";
        }
        return null;
    }

    /**
     * getLatestPolicyTypeVersion Find all the ancestors of an entity type.
     *
     * @param entityTypes the set of entity types that exist
     * @param entityType the entity type for which to get the parents
     * @param result the result of the ancestor search with any warnings or errors
     * @return the entity set containing the ancestors of the incoming entity
     */
    public static Collection<JpaToscaEntityType<ToscaEntity>> getEntityTypeAncestors(
            @NonNull PfConceptContainer<? extends PfConcept, ? extends PfNameVersion> entityTypes,
            @NonNull JpaToscaEntityType<?> entityType, @NonNull final BeanValidationResult result) {

        PfConceptKey parentEntityTypeKey = entityType.getDerivedFrom();
        if (parentEntityTypeKey == null || parentEntityTypeKey.getName().endsWith(ROOT_KEY_NAME_SUFFIX)) {
            return CollectionUtils.emptyCollection();
        }

        if (entityType.getKey().equals(parentEntityTypeKey)) {
            result.addResult("entity type", entityType.getKey().getId(),
                            ValidationStatus.INVALID, "ancestor of itself");
            throw new PfModelRuntimeException(Response.Status.CONFLICT, result.getResult());
        }

        @SuppressWarnings("unchecked")
        Set<JpaToscaEntityType<ToscaEntity>> ancestorEntitySet = (Set<JpaToscaEntityType<ToscaEntity>>) entityTypes
                .getAll(parentEntityTypeKey.getName(), parentEntityTypeKey.getVersion());
        Set<JpaToscaEntityType<ToscaEntity>> ancestorEntitySetToReturn = new HashSet<>(ancestorEntitySet);
        if (ancestorEntitySet.isEmpty()) {
            result.addResult("parent", parentEntityTypeKey.getId(), ValidationStatus.INVALID, Validated.NOT_FOUND);
        } else {
            for (JpaToscaEntityType<?> filteredEntityType : ancestorEntitySet) {
                ancestorEntitySetToReturn.addAll(getEntityTypeAncestors(entityTypes, filteredEntityType, result));
            }
        }
        return ancestorEntitySetToReturn;
    }

    /**
     * Get the entity tree from a concept container for a given entity key.
     *
     * @param entityTypes the concept container containing entity types
     * @param entityName the name of the entity
     * @param entityVersion the version of the entity
     */
    public static void getEntityTree(
            @NonNull final PfConceptContainer<? extends PfConcept, ? extends PfNameVersion> entityTypes,
            final String entityName, final String entityVersion) {

        var result = new BeanValidationResult("entity", entityName);

        @SuppressWarnings("unchecked")
        Set<JpaToscaEntityType<?>> filteredEntitySet =
                (Set<JpaToscaEntityType<?>>) entityTypes.getAllNamesAndVersions(entityName, entityVersion);
        Set<JpaToscaEntityType<?>> filteredEntitySetToReturn = new HashSet<>(filteredEntitySet);
        for (JpaToscaEntityType<?> filteredEntityType : filteredEntitySet) {
            filteredEntitySetToReturn
                    .addAll(ToscaUtils.getEntityTypeAncestors(entityTypes, filteredEntityType, result));
        }

        if (!result.isValid()) {
            throw new PfModelRuntimeException(Response.Status.NOT_ACCEPTABLE, result.getResult());
        }

        entityTypes.getConceptMap().entrySet()
                .removeIf(entityEntry -> !filteredEntitySetToReturn.contains(entityEntry.getValue()));
    }
}