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
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.onap.policy.gui.editors.apex.rest.handling.converter.tosca;
22 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.POLICIES;
23 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.PROPERTIES;
24 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.TOPOLOGY_TEMPLATE;
25 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.TOSCA_DEFINITIONS_VERSION;
26 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.INVALID_ENTRY;
27 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.INVALID_POLICY;
28 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.INVALID_TOSCA_TEMPLATE;
29 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.MISSING_ENTRY;
30 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.MISSING_POLICY;
31 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.ONLY_ONE_POLICY_ALLOWED;
33 import com.google.gson.JsonArray;
34 import com.google.gson.JsonObject;
35 import com.google.gson.JsonPrimitive;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.nio.charset.StandardCharsets;
39 import java.util.HashSet;
40 import java.util.Optional;
42 import java.util.function.Function;
43 import lombok.AllArgsConstructor;
44 import org.apache.commons.io.IOUtils;
45 import org.onap.policy.common.utils.coder.CoderException;
46 import org.onap.policy.common.utils.coder.StandardCoder;
47 import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
52 * Process the TOSCA JSON template file, base for the Policy Model TOSCA conversion.
54 public class ToscaTemplateProcessor {
56 private static final Logger LOGGER = LoggerFactory.getLogger(ToscaTemplateProcessor.class);
58 private final StandardCoder jsonCoder;
60 public ToscaTemplateProcessor(final StandardCoder jsonCoder) {
61 this.jsonCoder = jsonCoder;
65 * Process the TOSCA JSON template file.
67 * @param toscaTemplateInputStream the input stream for the TOSCA JSON template file
68 * @return the result of the processing with the read JSON and its errors.
70 public ProcessedTemplate process(final InputStream toscaTemplateInputStream) throws IOException {
71 final ProcessedTemplate processedTemplate = new ProcessedTemplate();
73 final String templateAsString;
74 try (final InputStream inputStream = toscaTemplateInputStream) {
75 templateAsString = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
78 final Set<String> errorSet = validate(templateAsString);
79 processedTemplate.setContent(templateAsString);
80 processedTemplate.addToErrors(errorSet);
82 return processedTemplate;
85 private Set<String> validate(final String toscaTemplate) {
86 final Set<String> errorSet = new HashSet<>();
87 final JsonObject toscaTemplateJson;
89 toscaTemplateJson = jsonCoder.decode(toscaTemplate, JsonObject.class);
90 } catch (final CoderException e) {
91 LOGGER.debug(INVALID_TOSCA_TEMPLATE.getMessage(), e);
92 errorSet.add(INVALID_TOSCA_TEMPLATE.getMessage());
96 final Optional<JsonPrimitive> toscaDefinitionVersionOpt =
97 readJsonEntry(TOSCA_DEFINITIONS_VERSION, toscaTemplateJson::getAsJsonPrimitive, errorSet);
98 if (toscaDefinitionVersionOpt.isEmpty()) {
102 final Optional<JsonObject> topologyTemplate =
103 readJsonEntry(TOPOLOGY_TEMPLATE, toscaTemplateJson::getAsJsonObject, errorSet);
104 if (topologyTemplate.isEmpty()) {
108 final Optional<JsonArray> policiesOpt =
109 readJsonEntry(POLICIES, topologyTemplate.get()::getAsJsonArray, errorSet);
110 if (policiesOpt.isEmpty()) {
113 final JsonArray policies = policiesOpt.get();
115 if (policies.size() == 0) {
116 errorSet.add(MISSING_POLICY.getMessage());
120 if (policies.size() > 1) {
121 errorSet.add(ONLY_ONE_POLICY_ALLOWED.getMessage());
125 final JsonObject firstPolicy;
127 final JsonObject firstPolicyObj = policies.get(0).getAsJsonObject();
128 firstPolicy = firstPolicyObj.entrySet().iterator().next().getValue().getAsJsonObject();
129 } catch (final Exception e) {
130 final String errorMsg = INVALID_POLICY.getMessage();
131 LOGGER.debug(errorMsg, e);
132 errorSet.add(errorMsg);
136 readJsonEntry(PROPERTIES, firstPolicy::getAsJsonObject, errorSet);
141 private <T> Optional<T> readJsonEntry(final ToscaKey toscaKey,
142 final Function<String, T> jsonFunction, final Set<String> errorSet) {
144 final T json = jsonFunction.apply(toscaKey.getKey());
146 errorSet.add(MISSING_ENTRY.getMessage(toscaKey.getKey()));
148 return Optional.ofNullable(json);
149 } catch (final Exception e) {
150 final String errorMsg = INVALID_ENTRY.getMessage(toscaKey.getKey());
151 LOGGER.debug(errorMsg, e);
152 errorSet.add(errorMsg);
153 return Optional.empty();
159 * Stores the possible error messages for the Tosca template validation process.
162 public enum ErrorMessage {
163 MISSING_ENTRY("Missing '%s' entry"),
164 MISSING_POLICY("No policy was provided in the 'policies' list"),
165 INVALID_POLICY("Invalid policy was provided in the 'policies' list"),
166 ONLY_ONE_POLICY_ALLOWED("Only one policy entry is allowed in the 'policies' list"),
167 INVALID_TOSCA_TEMPLATE("Invalid tosca template provided"),
168 INVALID_ENTRY("Invalid entry '%s' provided"),
169 MISSING_PROPERTIES_ENTRY("Missing properties entry in '%s'");
171 private final String messageFormat;
173 public String getMessage(final String... params) {
174 return String.format(this.messageFormat, params);