aboutsummaryrefslogtreecommitdiffstats
path: root/models-tosca/src/main/java/org/onap/policy/models/tosca/utils/ToscaServiceTemplateUtils.java
blob: 6f4b2993f127e7bc029a3f2db43e9213bed80d0c (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
/*-
 * ============LICENSE_START=======================================================
 * Copyright (C) 2020,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.Map.Entry;
import javax.ws.rs.core.Response;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.models.base.PfConceptContainer;
import org.onap.policy.models.base.PfConceptKey;
import org.onap.policy.models.base.PfModelRuntimeException;
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;
import org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate;

/**
 * This utility class provides methods to manage service templates.
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ToscaServiceTemplateUtils {

    /**
     * Add a service template fragment to a service template. All entities in the service template fragment must either
     * a) not exist on the original service template or b) be identical to entities on the original service template.
     *
     * @param originalTemplate the original service template
     * @param fragmentTemplate the fragment being added to the original service template
     * @return JpaToscaServiceTemplate
     */
    public static JpaToscaServiceTemplate addFragment(@NonNull final JpaToscaServiceTemplate originalTemplate,
            @NonNull final JpaToscaServiceTemplate fragmentTemplate) {

        var result = new BeanValidationResult("incoming fragment", fragmentTemplate);

        if (originalTemplate.compareToWithoutEntities(fragmentTemplate) != 0) {
            Validated.addResult(result, "service template",
                            originalTemplate.getKey(),
                            "does not equal existing service template");
        }

        var compositeTemplate = new JpaToscaServiceTemplate(originalTemplate);

        compositeTemplate.setDataTypes(
                addFragmentEntitites(compositeTemplate.getDataTypes(), fragmentTemplate.getDataTypes(), result));
        compositeTemplate.setPolicyTypes(
                addFragmentEntitites(compositeTemplate.getPolicyTypes(), fragmentTemplate.getPolicyTypes(), result));
        compositeTemplate.setNodeTypes(
                addFragmentEntitites(compositeTemplate.getNodeTypes(), fragmentTemplate.getNodeTypes(), result));

        if (originalTemplate.getTopologyTemplate() != null && fragmentTemplate.getTopologyTemplate() != null) {
            if (originalTemplate.getTopologyTemplate()
                    .compareToWithoutEntities(fragmentTemplate.getTopologyTemplate()) == 0) {
                compositeTemplate.getTopologyTemplate()
                        .setPolicies(addFragmentEntitites(compositeTemplate.getTopologyTemplate().getPolicies(),
                                fragmentTemplate.getTopologyTemplate().getPolicies(), result));
                compositeTemplate.getTopologyTemplate()
                    .setNodeTemplates(addFragmentEntitites(compositeTemplate.getTopologyTemplate().getNodeTemplates(),
                        fragmentTemplate.getTopologyTemplate().getNodeTemplates(), result));
            } else {
                Validated.addResult(result, "topology template",
                                originalTemplate.getTopologyTemplate().getKey(),
                                "does not equal existing topology template");
            }
        } else if (fragmentTemplate.getTopologyTemplate() != null) {
            compositeTemplate.setTopologyTemplate(new JpaToscaTopologyTemplate(fragmentTemplate.getTopologyTemplate()));
        }

        if (result.isValid()) {
            result.addResult(compositeTemplate.validate("composite template"));
        }

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

        return compositeTemplate;
    }

    /**
     * Check entities from a fragment container can be added to an original container.
     *
     * @param <E> The type of TOSCA entity
     * @param <J> The type of the JPA TOSCA entity
     * @param <S> The type of container
     *
     * @param compositeContainer the original container
     * @param fragmentContainer the fragment being added to the original container
     * @return the composite container with the result
     */
    private static <E extends ToscaEntity, J extends JpaToscaEntityType<E>, S extends PfConceptContainer<J, E>>
            S addFragmentEntitites(final S compositeContainer, final S fragmentContainer,
                    final BeanValidationResult result) {

        if (compositeContainer == null) {
            return fragmentContainer;
        }

        if (fragmentContainer == null) {
            return compositeContainer;
        }

        var result2 = new BeanValidationResult("incoming fragment", fragmentContainer);
        var originalContainerMap = compositeContainer.getConceptMap();
        var fragmentContainerMap = fragmentContainer.getConceptMap();

        for (Entry<PfConceptKey, J> fragmentEntry : fragmentContainerMap.entrySet()) {
            J containerEntity = originalContainerMap.get(fragmentEntry.getKey());
            if (containerEntity != null && containerEntity.compareTo(fragmentEntry.getValue()) != 0) {
                Validated.addResult(result, "entity", fragmentEntry.getKey(), "does not equal existing entity");
            }
        }

        if (!result2.isClean()) {
            result.addResult(result2);
        }

        originalContainerMap.putAll(fragmentContainerMap);

        return compositeContainer;
    }
}