2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
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.serialization;
23 import com.google.gson.JsonArray;
24 import com.google.gson.JsonElement;
25 import com.google.gson.JsonObject;
27 import java.util.Iterator;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.Map.Entry;
31 import javax.ws.rs.core.Response;
33 import org.onap.policy.models.base.PfConceptKey;
34 import org.onap.policy.models.base.PfModelRuntimeException;
35 import org.onap.policy.models.base.PfReferenceKey;
36 import org.onap.policy.models.tosca.simple.concepts.JpaToscaConstraint;
37 import org.onap.policy.models.tosca.simple.concepts.JpaToscaConstraintLogical.Operation;
38 import org.onap.policy.models.tosca.simple.concepts.JpaToscaConstraintLogicalString;
39 import org.onap.policy.models.tosca.simple.concepts.JpaToscaConstraintValidValues;
40 import org.onap.policy.models.tosca.simple.concepts.JpaToscaEntrySchema;
41 import org.onap.policy.models.tosca.simple.concepts.JpaToscaProperty;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
47 * GSON type adapter for TOSCA properties.
49 * @author Chenfei Gao (cgao@research.att.com)
51 public class ToscaPropertiesJsonAdapter {
53 private static final Logger LOGGER = LoggerFactory.getLogger(ToscaPropertiesJsonAdapter.class);
55 private static final String DESCRIPTION = "description";
56 private static final String REQUIRED = "required";
57 private static final String DEFAULT = "default";
58 private static final String TYPE = "type";
59 private static final String ENTRY_SCHEMA = "entry_schema";
60 private static final String CONSTRAINTS = "constraints";
61 private static final String EQUAL = "equal";
62 private static final String VALID_VALUES = "valid_values";
63 private static final String DEFAULT_VERSION = "1.0.0";
66 * Deserializes the properties.
68 * @param propertiesElement the properties in JsonElement
70 * @return deserialized ToscaProperty list
72 public List<JpaToscaProperty> deserializeProperties(JsonElement propertiesElement) {
74 final JsonObject propertiesMapObject = propertiesElement.getAsJsonObject();
75 List<JpaToscaProperty> properties = new LinkedList<>();
77 for (Entry<String, JsonElement> entry : propertiesMapObject.entrySet()) {
78 final String propertyEntryKey = entry.getKey();
79 final JsonElement propertyEntryVal = entry.getValue();
81 // Set property: key and type
82 JpaToscaProperty property = new JpaToscaProperty(
83 new PfReferenceKey(new PfConceptKey(), propertyEntryKey),
84 new PfConceptKey(propertyEntryVal.getAsJsonObject().get(TYPE).getAsString(), DEFAULT_VERSION));
86 // Set property: description
87 JsonObject propertyJsonObject = propertyEntryVal.getAsJsonObject();
88 if (propertyJsonObject.has(DESCRIPTION)) {
89 property.setDescription(propertyJsonObject.get(DESCRIPTION).getAsString());
92 // Set property: required
93 if (propertyJsonObject.has(REQUIRED)) {
94 property.setRequired(propertyJsonObject.get(REQUIRED).getAsBoolean());
97 // Set property: default
98 if (propertyJsonObject.has(DEFAULT)) {
99 property.setDefaultValue(propertyJsonObject.get(DEFAULT).getAsString());
102 // Set property: entry_schema
103 if (propertyJsonObject.has(ENTRY_SCHEMA)) {
104 checkEntrySchemaCompatibility(property.getType().getName());
105 property.setEntrySchema(deserializeEntrySchema(propertyJsonObject.get(ENTRY_SCHEMA)));
106 property.getEntrySchema().getKey().setParentConceptKey(property.getType());
107 property.getEntrySchema().getType().setVersion(property.getType().getVersion());
110 // Set property: constraints
111 if (propertyJsonObject.has(CONSTRAINTS)) {
112 property.setConstraints(deserializeConstraints(propertyJsonObject.get(CONSTRAINTS)));
113 for (JpaToscaConstraint c : property.getConstraints()) {
114 c.getKey().setParentConceptKey(property.getType());
118 // Add property to properties list
119 properties.add(property);
126 * Serializes the properties.
128 * @param properties the list of ToscaProperty
130 * @return serialized JsonElement
132 public JsonElement serializeProperties(List<JpaToscaProperty> properties) {
134 JsonObject propertiesJsonObject = new JsonObject();
136 for (JpaToscaProperty property : properties) {
137 JsonObject propertyValJsonObject = new JsonObject();
140 propertyValJsonObject.addProperty(TYPE, property.getType().getName());
143 if (property.getDescription() != null) {
144 propertyValJsonObject.addProperty(DESCRIPTION, property.getDescription());
148 propertyValJsonObject.addProperty(REQUIRED, property.isRequired());
151 if (property.getDefaultValue() != null) {
152 propertyValJsonObject.addProperty(DEFAULT, property.getDefaultValue());
156 if (property.getConstraints() != null) {
157 propertyValJsonObject.add(CONSTRAINTS, serializeConstraints(property.getConstraints()));
161 if (property.getEntrySchema() != null) {
162 propertyValJsonObject.add(ENTRY_SCHEMA, serializeEntrySchema(property.getEntrySchema()));
165 propertiesJsonObject.add(property.getKey().getLocalName(), propertyValJsonObject);
168 return propertiesJsonObject;
171 private JsonElement serializeConstraints(List<JpaToscaConstraint> constraints) {
173 JsonArray constraintsValJsonArray = new JsonArray();
175 for (JpaToscaConstraint c : constraints) {
176 JsonObject constraintJsonObject = new JsonObject();
178 // Check which type of constraint it is
179 // TODO: here we only support valid_values and equal
180 if (c instanceof JpaToscaConstraintValidValues) {
181 JsonArray validValuesJsonArray = new JsonArray();
182 for (String validValue : ((JpaToscaConstraintValidValues)c).getValidValues()) {
183 validValuesJsonArray.add(validValue);
185 constraintJsonObject.add(VALID_VALUES, validValuesJsonArray);
186 } else if (c instanceof JpaToscaConstraintLogicalString) {
187 constraintJsonObject.addProperty(EQUAL, ((JpaToscaConstraintLogicalString)c).getCompareToString());
189 String errorMessage = "constraint is neither valid_values nor equal";
190 LOGGER.debug(errorMessage);
191 throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage);
194 constraintsValJsonArray.add(constraintJsonObject);
197 return constraintsValJsonArray;
200 private JsonElement serializeEntrySchema(JpaToscaEntrySchema entrySchema) {
202 JsonObject entrySchemaValJsonObject = new JsonObject();
205 entrySchemaValJsonObject.addProperty(TYPE, entrySchema.getType().getName());
208 if (entrySchema.getDescription() != null) {
209 entrySchemaValJsonObject.addProperty(DESCRIPTION, entrySchema.getDescription());
213 if (entrySchema.getConstraints() != null) {
214 entrySchemaValJsonObject.add(CONSTRAINTS, serializeConstraints(entrySchema.getConstraints()));
217 return entrySchemaValJsonObject;
220 private JpaToscaEntrySchema deserializeEntrySchema(JsonElement entrySchemaElement) {
222 JsonObject entrySchemaJsonObject = entrySchemaElement.getAsJsonObject();
224 // Set entry_schema: key and type
225 JpaToscaEntrySchema entrySchema = new JpaToscaEntrySchema(
226 new PfReferenceKey(new PfConceptKey(), ENTRY_SCHEMA),
227 new PfConceptKey(entrySchemaJsonObject.get(TYPE).getAsString(), DEFAULT_VERSION));
229 // Set entry_schema: description
230 if (entrySchemaJsonObject.has(DESCRIPTION)) {
231 entrySchema.setDescription(entrySchemaJsonObject.get(DESCRIPTION).getAsString());
234 // Set entry_schema: constraints
235 if (entrySchemaJsonObject.has(CONSTRAINTS)) {
236 entrySchema.setConstraints(deserializeConstraints(entrySchemaJsonObject.get(CONSTRAINTS)));
237 for (JpaToscaConstraint c : entrySchema.getConstraints()) {
238 c.getKey().setParentConceptKey(entrySchema.getType());
245 private List<JpaToscaConstraint> deserializeConstraints(JsonElement constraintsElement) {
247 JsonArray constraintsJsonArray = constraintsElement.getAsJsonArray();
248 List<JpaToscaConstraint> constraints = new LinkedList<>();
250 for (Iterator<JsonElement> constraintsIter = constraintsJsonArray.iterator(); constraintsIter.hasNext(); ) {
251 JsonObject constraintJsonObject = constraintsIter.next().getAsJsonObject();
252 // Check which type of constraint it is
253 // TODO: here we only check 'valid_values' and 'equal'
254 if (constraintJsonObject.get(VALID_VALUES) != null) {
255 List<String> validValues = new LinkedList<>();
256 for (Iterator<JsonElement> validValuesIter = constraintJsonObject.get(VALID_VALUES).getAsJsonArray()
257 .iterator(); validValuesIter.hasNext(); ) {
258 validValues.add(validValuesIter.next().getAsString());
260 JpaToscaConstraint constraint = new JpaToscaConstraintValidValues(
261 new PfReferenceKey(new PfConceptKey(), VALID_VALUES), validValues);
262 constraints.add(constraint);
263 } else if (constraintJsonObject.get(EQUAL) != null) {
264 JpaToscaConstraint constraint = new JpaToscaConstraintLogicalString(new PfReferenceKey(
265 new PfConceptKey(), EQUAL), Operation.EQ, constraintJsonObject.get(EQUAL).getAsString());
266 constraints.add(constraint);
268 String errorMessage = "specified constraint is neither valid_values nor equal";
269 LOGGER.debug(errorMessage);
270 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);
277 private void checkEntrySchemaCompatibility(String type) {
278 if (!("list".equalsIgnoreCase(type)) && !("map".equalsIgnoreCase(type))) {
279 String errorMessage = "entry schema can only be specified for list or map property";
280 LOGGER.debug(errorMessage);
281 throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, errorMessage);