2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2019-2020 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 * SPDX-License-Identifier: Apache-2.0
21 * ============LICENSE_END=========================================================
24 package org.onap.policy.models.tosca.simple.concepts;
26 import java.util.LinkedHashMap;
27 import java.util.List;
29 import java.util.Map.Entry;
30 import javax.persistence.AttributeOverride;
31 import javax.persistence.AttributeOverrides;
32 import javax.persistence.Column;
33 import javax.persistence.ElementCollection;
34 import javax.persistence.Entity;
35 import javax.persistence.Inheritance;
36 import javax.persistence.InheritanceType;
37 import javax.persistence.Lob;
38 import javax.persistence.Table;
39 import javax.ws.rs.core.Response;
41 import lombok.EqualsAndHashCode;
42 import lombok.NonNull;
43 import org.onap.policy.common.utils.coder.CoderException;
44 import org.onap.policy.common.utils.coder.StandardCoder;
45 import org.onap.policy.common.utils.validation.ParameterValidationUtils;
46 import org.onap.policy.models.base.PfAuthorative;
47 import org.onap.policy.models.base.PfConcept;
48 import org.onap.policy.models.base.PfConceptKey;
49 import org.onap.policy.models.base.PfKey;
50 import org.onap.policy.models.base.PfModelRuntimeException;
51 import org.onap.policy.models.base.PfUtils;
52 import org.onap.policy.models.base.PfValidationMessage;
53 import org.onap.policy.models.base.PfValidationResult;
54 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
58 * Class to represent the policy in TOSCA definition.
60 * @author Chenfei Gao (cgao@research.att.com)
61 * @author Liam Fallon (liam.fallon@est.tech)
64 @Table(name = "ToscaPolicy")
65 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
67 @EqualsAndHashCode(callSuper = true)
68 public class JpaToscaPolicy extends JpaToscaEntityType<ToscaPolicy> implements PfAuthorative<ToscaPolicy> {
69 private static final long serialVersionUID = 3265174757061982805L;
72 private static final String METADATA_POLICY_ID_TAG = "policy-id";
73 private static final String METADATA_POLICY_VERSION_TAG = "policy-version";
75 private static final StandardCoder STANDARD_CODER = new StandardCoder();
80 @AttributeOverride(name = "name",
81 column = @Column(name = "type_name")),
82 @AttributeOverride(name = "version",
83 column = @Column(name = "type_version"))
85 private PfConceptKey type;
89 private Map<String, String> properties;
92 private List<PfConceptKey> targets;
96 * The Default Constructor creates a {@link JpaToscaPolicy} object with a null key.
98 public JpaToscaPolicy() {
99 this(new PfConceptKey());
103 * The Key Constructor creates a {@link JpaToscaPolicy} object with the given concept key.
107 public JpaToscaPolicy(@NonNull final PfConceptKey key) {
108 this(key, new PfConceptKey());
112 * The full Constructor creates a {@link JpaToscaPolicy} object with all mandatory fields.
115 * @param type the type of the policy
117 public JpaToscaPolicy(@NonNull final PfConceptKey key, @NonNull final PfConceptKey type) {
125 * @param copyConcept the concept to copy from
127 public JpaToscaPolicy(@NonNull final JpaToscaPolicy copyConcept) {
129 this.type = new PfConceptKey(copyConcept.type);
130 this.properties = (copyConcept.properties != null ? new LinkedHashMap<>(copyConcept.properties) : null);
131 this.targets = PfUtils.mapList(copyConcept.targets, PfConceptKey::new);
135 * Authorative constructor.
137 * @param authorativeConcept the authorative concept to copy from
139 public JpaToscaPolicy(final ToscaPolicy authorativeConcept) {
140 super(new PfConceptKey());
141 type = new PfConceptKey();
142 this.fromAuthorative(authorativeConcept);
146 public ToscaPolicy toAuthorative() {
147 ToscaPolicy toscaPolicy = new ToscaPolicy();
148 super.setToscaEntity(toscaPolicy);
149 super.toAuthorative();
151 toscaPolicy.setType(type.getName());
153 if (!PfKey.NULL_KEY_VERSION.equals(type.getVersion())) {
154 toscaPolicy.setTypeVersion(type.getVersion());
156 toscaPolicy.setTypeVersion(null);
159 toscaPolicy.setProperties(PfUtils.mapMap(properties, property -> {
161 return STANDARD_CODER.decode(property, Object.class);
162 } catch (CoderException ce) {
163 String errorMessage = "error decoding property JSON value read from database: " + property;
164 throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
172 public void fromAuthorative(@NonNull final ToscaPolicy toscaPolicy) {
173 super.fromAuthorative(toscaPolicy);
175 if (toscaPolicy.getType() != null) {
176 type.setName(toscaPolicy.getType());
178 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
179 "PolicyType type not specified, the type of the PolicyType for this policy must be specified in "
183 if (toscaPolicy.getTypeVersion() != null) {
184 type.setVersion(toscaPolicy.getTypeVersion());
186 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
187 "PolicyType version not specified, the version of the PolicyType for this policy must be specified"
188 + " in the type_version field");
191 properties = PfUtils.mapMap(toscaPolicy.getProperties(), property -> {
193 return STANDARD_CODER.encode(property);
194 } catch (CoderException ce) {
195 String errorMessage = "error encoding property JSON value for database: " + property;
196 throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
200 // Add the property metadata if it doesn't exist already
201 if (toscaPolicy.getMetadata() == null) {
202 setMetadata(new LinkedHashMap<>());
205 // Add the policy name and version fields to the metadata
206 getMetadata().put(METADATA_POLICY_ID_TAG, getKey().getName());
207 getMetadata().put(METADATA_POLICY_VERSION_TAG, getKey().getVersion());
211 public List<PfKey> getKeys() {
212 final List<PfKey> keyList = super.getKeys();
214 keyList.addAll(type.getKeys());
216 if (targets != null) {
217 keyList.addAll(targets);
224 public void clean() {
229 if (targets != null) {
230 for (PfConceptKey target : targets) {
237 public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
238 PfValidationResult result = super.validate(resultIn);
240 if (PfKey.NULL_KEY_VERSION.equals(getKey().getVersion())) {
241 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
242 "key version is a null version"));
245 if (type == null || type.isNullKey()) {
246 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
247 "type is null or a null key"));
249 result = type.validate(result);
252 if (properties != null) {
253 validateProperties(result);
256 if (targets != null) {
257 result = validateTargets(result);
264 * Validate the policy properties.
266 * @param result where to put the validation results
268 private void validateProperties(final PfValidationResult result) {
270 for (Entry<String, String> propertyEntry : properties.entrySet()) {
271 if (!ParameterValidationUtils.validateStringParameter(propertyEntry.getKey())) {
272 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
273 "policy property key may not be null "));
274 } else if (propertyEntry.getValue() == null) {
275 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
276 "policy property value may not be null "));
282 * Validate the policy targets.
284 * @param resultIn The result of validations up to now
285 * @return the validation result
287 private PfValidationResult validateTargets(final PfValidationResult resultIn) {
288 PfValidationResult result = resultIn;
290 for (PfConceptKey target : targets) {
291 if (target == null) {
292 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(), ValidationResult.INVALID,
293 "policy target may not be null "));
295 result = target.validate(result);
302 public int compareTo(final PfConcept otherConcept) {
303 if (otherConcept == null) {
307 if (this == otherConcept) {
311 if (getClass() != otherConcept.getClass()) {
312 return getClass().getName().compareTo(otherConcept.getClass().getName());
315 final JpaToscaPolicy other = (JpaToscaPolicy) otherConcept;
316 int result = super.compareTo(other);
321 result = type.compareTo(other.type);
326 result = PfUtils.compareMaps(properties, other.properties);
331 return PfUtils.compareCollections(targets, other.targets);