2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.models.tosca.simple.concepts;
23 import java.util.Collections;
24 import java.util.LinkedHashMap;
25 import java.util.List;
27 import javax.persistence.CascadeType;
28 import javax.persistence.Column;
29 import javax.persistence.ElementCollection;
30 import javax.persistence.Entity;
31 import javax.persistence.FetchType;
32 import javax.persistence.Inheritance;
33 import javax.persistence.InheritanceType;
34 import javax.persistence.JoinColumn;
35 import javax.persistence.JoinColumns;
36 import javax.persistence.Lob;
37 import javax.persistence.OneToOne;
38 import javax.persistence.Table;
39 import javax.ws.rs.core.Response;
41 import lombok.EqualsAndHashCode;
42 import lombok.NonNull;
43 import org.apache.commons.lang3.ObjectUtils;
44 import org.apache.commons.lang3.StringUtils;
45 import org.onap.policy.common.utils.coder.CoderException;
46 import org.onap.policy.common.utils.coder.StandardCoder;
47 import org.onap.policy.models.base.PfAuthorative;
48 import org.onap.policy.models.base.PfConcept;
49 import org.onap.policy.models.base.PfConceptKey;
50 import org.onap.policy.models.base.PfKey;
51 import org.onap.policy.models.base.PfModelRuntimeException;
52 import org.onap.policy.models.base.PfUtils;
53 import org.onap.policy.models.base.PfValidationMessage;
54 import org.onap.policy.models.base.PfValidationResult;
55 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
56 import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityAssignment;
57 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
60 * Class to represent the node template in TOSCA definition.
63 @Table(name = "ToscaNodeTemplate")
64 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
66 @EqualsAndHashCode(callSuper = false)
67 public class JpaToscaNodeTemplate extends JpaToscaEntityType<ToscaNodeTemplate>
68 implements PfAuthorative<ToscaNodeTemplate> {
69 private static final long serialVersionUID = 1675770231921107988L;
71 private static final StandardCoder STANDARD_CODER = new StandardCoder();
78 private Map<String, String> properties;
81 @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
82 @JoinColumns({@JoinColumn(name = "requirementsName", referencedColumnName = "name"),
83 @JoinColumn(name = "requirementsVersion", referencedColumnName = "version")})
84 private JpaToscaRequirements requirements;
86 @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
87 @JoinColumns({@JoinColumn(name = "capabilitiesName", referencedColumnName = "name"),
88 @JoinColumn(name = "capabilitiesVersion", referencedColumnName = "version")})
89 private JpaToscaCapabilityAssignments capabilities;
93 * The Default Constructor creates a {@link JpaToscaNodeTemplate} object with a null key.
95 public JpaToscaNodeTemplate() {
96 this(new PfConceptKey());
100 * The Key Constructor creates a {@link JpaToscaNodeTemplate} object with the given concept key.
104 public JpaToscaNodeTemplate(@NonNull final PfConceptKey key) {
111 * @param copyConcept the concept to copy from
113 public JpaToscaNodeTemplate(final JpaToscaNodeTemplate copyConcept) {
115 this.type = copyConcept.type;
116 this.properties = PfUtils.mapMap(copyConcept.properties, String::new);
118 (copyConcept.requirements != null ? new JpaToscaRequirements(copyConcept.requirements) : null);
120 (copyConcept.capabilities != null ? new JpaToscaCapabilityAssignments(copyConcept.capabilities) : null);
124 * The Key Constructor creates a {@link JpaToscaParameter} object with the given concept key.
127 * @param type the node template type
129 public JpaToscaNodeTemplate(@NonNull final PfConceptKey key, final String type) {
135 * Authorative constructor.
137 * @param authorativeConcept the authorative concept to copy from
139 public JpaToscaNodeTemplate(final ToscaNodeTemplate authorativeConcept) {
140 this.fromAuthorative(authorativeConcept);
144 public ToscaNodeTemplate toAuthorative() {
145 ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate();
146 super.setToscaEntity(toscaNodeTemplate);
147 super.toAuthorative();
149 toscaNodeTemplate.setType(type);
151 toscaNodeTemplate.setProperties(PfUtils.mapMap(properties, property -> {
153 return STANDARD_CODER.decode(property, Object.class);
154 } catch (CoderException ce) {
155 String errorMessage = "error decoding property JSON value read from database: " + property;
156 throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
160 if (requirements != null) {
161 toscaNodeTemplate.setRequirements(requirements.toAuthorative());
164 if (capabilities != null) {
165 toscaNodeTemplate.setCapabilities(new LinkedHashMap<>());
166 List<Map<String, ToscaCapabilityAssignment>> capabilityAssignmentMapList = capabilities.toAuthorative();
167 for (Map<String, ToscaCapabilityAssignment> capabilityAssignmentMap : capabilityAssignmentMapList) {
168 toscaNodeTemplate.getCapabilities().putAll(capabilityAssignmentMap);
172 return toscaNodeTemplate;
176 public void fromAuthorative(ToscaNodeTemplate toscaNodeTemplate) {
177 super.fromAuthorative(toscaNodeTemplate);
179 type = toscaNodeTemplate.getType();
181 properties = PfUtils.mapMap(toscaNodeTemplate.getProperties(), property -> {
183 return STANDARD_CODER.encode(property);
184 } catch (CoderException ce) {
185 String errorMessage = "error encoding property JSON value for database: " + property;
186 throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
190 if (toscaNodeTemplate.getRequirements() != null) {
191 requirements = new JpaToscaRequirements();
192 requirements.fromAuthorative(toscaNodeTemplate.getRequirements());
195 if (toscaNodeTemplate.getCapabilities() != null) {
196 capabilities = new JpaToscaCapabilityAssignments();
197 capabilities.fromAuthorative(Collections.singletonList(toscaNodeTemplate.getCapabilities()));
202 public List<PfKey> getKeys() {
203 final List<PfKey> keyList = super.getKeys();
205 if (requirements != null) {
206 keyList.addAll(requirements.getKeys());
209 if (capabilities != null) {
210 keyList.addAll(capabilities.getKeys());
217 public void clean() {
222 properties = PfUtils.mapMap(properties, String::trim);
224 if (requirements != null) {
225 requirements.clean();
228 if (capabilities != null) {
229 capabilities.clean();
234 public PfValidationResult validate(final PfValidationResult resultIn) {
235 PfValidationResult result = super.validate(resultIn);
237 if (StringUtils.isBlank(type)) {
238 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
239 "node template type may not be null"));
242 if (properties != null) {
243 result.append(validateProperties(new PfValidationResult()));
246 if (requirements != null) {
247 result.append(requirements.validate(result));
250 if (capabilities != null) {
251 result.append(validateProperties(capabilities.validate(result)));
258 * Validate the properties.
260 * @param resultIn The result of validations up to now
261 * @return the validation result
263 private PfValidationResult validateProperties(final PfValidationResult resultIn) {
264 PfValidationResult result = resultIn;
266 for (String property : properties.values()) {
267 if (property == null) {
268 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
269 "topology template property may not be null "));
276 public int compareTo(final PfConcept otherConcept) {
277 if (otherConcept == null) {
280 if (this == otherConcept) {
283 if (getClass() != otherConcept.getClass()) {
284 return getClass().getName().compareTo(otherConcept.getClass().getName());
287 final JpaToscaNodeTemplate other = (JpaToscaNodeTemplate) otherConcept;
288 int result = super.compareTo(other);
293 result = type.compareTo(other.type);
298 result = PfUtils.compareMaps(properties, other.properties);
303 result = ObjectUtils.compare(requirements, other.requirements);
308 return ObjectUtils.compare(capabilities, other.capabilities);