Use ValidationResult for models v2.0
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / concepts / JpaToscaNodeTemplate.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 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.simple.concepts;
23
24 import java.util.Collections;
25 import java.util.LinkedHashMap;
26 import java.util.List;
27 import java.util.Map;
28 import javax.persistence.CascadeType;
29 import javax.persistence.Column;
30 import javax.persistence.ElementCollection;
31 import javax.persistence.Entity;
32 import javax.persistence.FetchType;
33 import javax.persistence.Inheritance;
34 import javax.persistence.InheritanceType;
35 import javax.persistence.JoinColumn;
36 import javax.persistence.JoinColumns;
37 import javax.persistence.Lob;
38 import javax.persistence.OneToOne;
39 import javax.persistence.Table;
40 import javax.ws.rs.core.Response;
41 import lombok.Data;
42 import lombok.EqualsAndHashCode;
43 import lombok.NonNull;
44 import org.apache.commons.lang3.ObjectUtils;
45 import org.onap.policy.common.parameters.BeanValidationResult;
46 import org.onap.policy.common.utils.coder.CoderException;
47 import org.onap.policy.common.utils.coder.StandardCoder;
48 import org.onap.policy.models.base.PfAuthorative;
49 import org.onap.policy.models.base.PfConcept;
50 import org.onap.policy.models.base.PfConceptKey;
51 import org.onap.policy.models.base.PfKey;
52 import org.onap.policy.models.base.PfModelRuntimeException;
53 import org.onap.policy.models.base.PfUtils;
54 import org.onap.policy.models.base.Validated;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityAssignment;
56 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
57
58 /**
59  * Class to represent the node template in TOSCA definition.
60  */
61 @Entity
62 @Table(name = "ToscaNodeTemplate")
63 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
64 @Data
65 @EqualsAndHashCode(callSuper = false)
66 public class JpaToscaNodeTemplate extends JpaToscaEntityType<ToscaNodeTemplate>
67         implements PfAuthorative<ToscaNodeTemplate> {
68     private static final long serialVersionUID = 1675770231921107988L;
69
70     private static final StandardCoder STANDARD_CODER = new StandardCoder();
71
72     @Column
73     private String type;
74
75     @ElementCollection
76     @Lob
77     private Map<String, String> properties;
78
79     // formatter:off
80     @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
81     @JoinColumns({@JoinColumn(name = "requirementsName", referencedColumnName = "name"),
82         @JoinColumn(name = "requirementsVersion", referencedColumnName = "version")})
83     private JpaToscaRequirements requirements;
84
85     @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
86     @JoinColumns({@JoinColumn(name = "capabilitiesName", referencedColumnName = "name"),
87         @JoinColumn(name = "capabilitiesVersion", referencedColumnName = "version")})
88     private JpaToscaCapabilityAssignments capabilities;
89     // @formatter:on
90
91     /**
92      * The Default Constructor creates a {@link JpaToscaNodeTemplate} object with a null key.
93      */
94     public JpaToscaNodeTemplate() {
95         this(new PfConceptKey());
96     }
97
98     /**
99      * The Key Constructor creates a {@link JpaToscaNodeTemplate} object with the given concept key.
100      *
101      * @param key the key
102      */
103     public JpaToscaNodeTemplate(@NonNull final PfConceptKey key) {
104         this(key, null);
105     }
106
107     /**
108      * Copy constructor.
109      *
110      * @param copyConcept the concept to copy from
111      */
112     public JpaToscaNodeTemplate(final JpaToscaNodeTemplate copyConcept) {
113         super(copyConcept);
114         this.type = copyConcept.type;
115         this.properties = PfUtils.mapMap(copyConcept.properties, String::new);
116         this.requirements =
117                 (copyConcept.requirements != null ? new JpaToscaRequirements(copyConcept.requirements) : null);
118         this.capabilities =
119                 (copyConcept.capabilities != null ? new JpaToscaCapabilityAssignments(copyConcept.capabilities) : null);
120     }
121
122     /**
123      * The Key Constructor creates a {@link JpaToscaParameter} object with the given concept key.
124      *
125      * @param key the key
126      * @param type the node template type
127      */
128     public JpaToscaNodeTemplate(@NonNull final PfConceptKey key, final String type) {
129         super(key);
130         this.type = type;
131     }
132
133     /**
134      * Authorative constructor.
135      *
136      * @param authorativeConcept the authorative concept to copy from
137      */
138     public JpaToscaNodeTemplate(final ToscaNodeTemplate authorativeConcept) {
139         this.fromAuthorative(authorativeConcept);
140     }
141
142     @Override
143     public ToscaNodeTemplate toAuthorative() {
144         ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate();
145         super.setToscaEntity(toscaNodeTemplate);
146         super.toAuthorative();
147
148         toscaNodeTemplate.setType(type);
149
150         toscaNodeTemplate.setProperties(PfUtils.mapMap(properties, property -> {
151             try {
152                 return STANDARD_CODER.decode(property, Object.class);
153             } catch (CoderException ce) {
154                 String errorMessage = "error decoding property JSON value read from database: " + property;
155                 throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
156             }
157         }));
158
159         if (requirements != null) {
160             toscaNodeTemplate.setRequirements(requirements.toAuthorative());
161         }
162
163         if (capabilities != null) {
164             toscaNodeTemplate.setCapabilities(new LinkedHashMap<>());
165             List<Map<String, ToscaCapabilityAssignment>> capabilityAssignmentMapList = capabilities.toAuthorative();
166             for (Map<String, ToscaCapabilityAssignment> capabilityAssignmentMap : capabilityAssignmentMapList) {
167                 toscaNodeTemplate.getCapabilities().putAll(capabilityAssignmentMap);
168             }
169         }
170
171         return toscaNodeTemplate;
172     }
173
174     @Override
175     public void fromAuthorative(ToscaNodeTemplate toscaNodeTemplate) {
176         super.fromAuthorative(toscaNodeTemplate);
177
178         type = toscaNodeTemplate.getType();
179
180         properties = PfUtils.mapMap(toscaNodeTemplate.getProperties(), property -> {
181             try {
182                 return STANDARD_CODER.encode(property);
183             } catch (CoderException ce) {
184                 String errorMessage = "error encoding property JSON value for database: " + property;
185                 throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
186             }
187         });
188
189         if (toscaNodeTemplate.getRequirements() != null) {
190             requirements = new JpaToscaRequirements();
191             requirements.fromAuthorative(toscaNodeTemplate.getRequirements());
192         }
193
194         if (toscaNodeTemplate.getCapabilities() != null) {
195             capabilities = new JpaToscaCapabilityAssignments();
196             capabilities.fromAuthorative(Collections.singletonList(toscaNodeTemplate.getCapabilities()));
197         }
198     }
199
200     @Override
201     public List<PfKey> getKeys() {
202         final List<PfKey> keyList = super.getKeys();
203
204         if (requirements != null) {
205             keyList.addAll(requirements.getKeys());
206         }
207
208         if (capabilities != null) {
209             keyList.addAll(capabilities.getKeys());
210         }
211
212         return keyList;
213     }
214
215     @Override
216     public void clean() {
217         super.clean();
218
219         type = type.trim();
220
221         properties = PfUtils.mapMap(properties, String::trim);
222
223         if (requirements != null) {
224             requirements.clean();
225         }
226
227         if (capabilities != null) {
228             capabilities.clean();
229         }
230     }
231
232     @Override
233     public BeanValidationResult validate(String fieldName) {
234         BeanValidationResult result = super.validate(fieldName);
235
236         result.addResult(validateNotBlank("type", type, true));
237
238         validateMap(result, "properties", properties, Validated::validateEntryValueNotNull);
239         validateOptional(result, "requirements", requirements);
240         validateOptional(result, "capabilities", capabilities);
241
242         return result;
243     }
244
245     @Override
246     public int compareTo(final PfConcept otherConcept) {
247         if (otherConcept == null) {
248             return -1;
249         }
250         if (this == otherConcept) {
251             return 0;
252         }
253         if (getClass() != otherConcept.getClass()) {
254             return getClass().getName().compareTo(otherConcept.getClass().getName());
255         }
256
257         final JpaToscaNodeTemplate other = (JpaToscaNodeTemplate) otherConcept;
258         int result = super.compareTo(other);
259         if (result != 0) {
260             return result;
261         }
262
263         result = type.compareTo(other.type);
264         if (result != 0) {
265             return result;
266         }
267
268         result = PfUtils.compareMaps(properties, other.properties);
269         if (result != 0) {
270             return result;
271         }
272
273         result = ObjectUtils.compare(requirements, other.requirements);
274         if (result != 0) {
275             return result;
276         }
277
278         return ObjectUtils.compare(capabilities, other.capabilities);
279     }
280 }