0bacb2473cc6d64b85caf025874c67b50359d09e
[policy/gui.git] /
1 /*
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
8  *
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.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.policy.gui.editors.apex.rest.handling.converter.tosca;
21
22 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.ENGINE_SERVICE_PARAMETERS;
23 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.POLICIES;
24 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.POLICY_TYPE_IMPL;
25 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.PROPERTIES;
26 import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.TOPOLOGY_TEMPLATE;
27
28 import com.google.gson.JsonElement;
29 import com.google.gson.JsonObject;
30 import java.util.Map.Entry;
31 import java.util.Optional;
32 import lombok.Getter;
33 import org.onap.policy.common.utils.coder.CoderException;
34 import org.onap.policy.common.utils.coder.StandardCoder;
35 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
36 import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.exception.PolicyToscaConverterException;
37
38 /**
39  * Handles the conversion from policy JSON to policy YAML.
40  */
41 public class PolicyToscaConverter {
42
43     private final StandardCoder standardCoder;
44     private final YamlJsonTranslator yamlJsonTranslator;
45
46     /**
47      * Creates a policy tosca converter.
48      *
49      * @param standardCoder the encoder that will handle JSON conversions
50      * @param yamlJsonTranslator the translator that will handle YAML conversions
51      */
52     public PolicyToscaConverter(final StandardCoder standardCoder, final YamlJsonTranslator yamlJsonTranslator) {
53         this.standardCoder = standardCoder;
54         this.yamlJsonTranslator = yamlJsonTranslator;
55     }
56
57     /**
58      * Converts the policy model to TOSCA, by merging the 3 given JSON models.
59      *
60      * @param policyModelJsonString the policy model JSON
61      * @param apexConfigJsonString the apex config JSON
62      * @param toscaTemplateJsonString the base TOSCA template in JSON format
63      * @return the merged policy model in YAML format
64      * @throws PolicyToscaConverterException when a JSON string could not be parsed to JsonObject or the resulting JSON
65      *     could not be parsed to YAML.
66      */
67     public Optional<String> convert(final String policyModelJsonString, final String apexConfigJsonString,
68                                     final String toscaTemplateJsonString) throws PolicyToscaConverterException {
69         final JsonObject apexConfigJson = decodeToJson(apexConfigJsonString);
70         final JsonObject policyModelJson = decodeToJson(policyModelJsonString);
71         final JsonObject toscaTemplateJson = decodeToJson(toscaTemplateJsonString);
72
73         final JsonObject toscaPolicyProperties = readTopologyTemplateAsJsonObject(toscaTemplateJson);
74         final JsonObject toscaPolicy = readToscaPolicyAsJsonObject(toscaPolicyProperties);
75         final JsonObject toscaProperties = readPolicyPropertiesAsJsonObject(toscaPolicy);
76
77         for (final Entry<String, JsonElement> entry : apexConfigJson.entrySet()) {
78             if (ENGINE_SERVICE_PARAMETERS.getKey().equals(entry.getKey())) {
79                 final JsonObject engineServiceParameters = readEngineServiceParametersAsJsonObject(entry.getValue());
80                 engineServiceParameters.add(POLICY_TYPE_IMPL.getKey(), policyModelJson);
81             }
82             toscaProperties.add(entry.getKey(), entry.getValue());
83         }
84         return Optional.ofNullable(convertToYaml(toscaTemplateJson));
85     }
86
87     private JsonObject readTopologyTemplateAsJsonObject(final JsonObject toscaTemplateJson)
88         throws PolicyToscaConverterException {
89
90         try {
91             return toscaTemplateJson.get(TOPOLOGY_TEMPLATE.getKey()).getAsJsonObject();
92         } catch (final Exception e) {
93             throw new PolicyToscaConverterException(
94                 String.format("Could not read the '%s' entry in the Tosca Template", TOPOLOGY_TEMPLATE.getKey()), e);
95         }
96     }
97
98     private JsonObject readEngineServiceParametersAsJsonObject(final JsonElement engineServiceParametersEntry)
99         throws PolicyToscaConverterException {
100
101         try {
102             return engineServiceParametersEntry.getAsJsonObject();
103         } catch (final Exception e) {
104             throw new PolicyToscaConverterException(
105                 String.format("Could not read the '%s' in the Apex Config", ENGINE_SERVICE_PARAMETERS.getKey()), e);
106         }
107     }
108
109     private JsonObject readToscaPolicyAsJsonObject(final JsonObject toscaPolicyProperties)
110         throws PolicyToscaConverterException {
111
112         try {
113             return toscaPolicyProperties.get(POLICIES.getKey()).getAsJsonArray().get(0).getAsJsonObject();
114         } catch (final Exception e) {
115             throw new PolicyToscaConverterException(
116                 String.format("Could not read the first policy in the '%s' entry under '%s'",
117                     POLICIES.getKey(), TOPOLOGY_TEMPLATE.getKey()), e);
118         }
119     }
120
121     private JsonObject readPolicyPropertiesAsJsonObject(final JsonObject toscaPolicy)
122         throws PolicyToscaConverterException {
123
124         try {
125             final String policyObjectKey = toscaPolicy.keySet().iterator().next();
126             final JsonObject policyEntry = toscaPolicy.get(policyObjectKey).getAsJsonObject();
127             return policyEntry.get(PROPERTIES.getKey()).getAsJsonObject();
128         } catch (final Exception e) {
129             throw new PolicyToscaConverterException(
130                 String.format("Could not read the policy '%s' entry", PROPERTIES.getKey()), e);
131         }
132     }
133
134     private String convertToYaml(final JsonObject jsonObject) throws PolicyToscaConverterException {
135         try {
136             return yamlJsonTranslator.toYaml(jsonObject);
137         } catch (final Exception e) {
138             throw new PolicyToscaConverterException(
139                 String.format("Could not convert JSON Object to YAML:%n%s", jsonObject.toString()), e);
140         }
141     }
142
143     private JsonObject decodeToJson(final String jsonString) throws PolicyToscaConverterException {
144         try {
145             return standardCoder.decode(jsonString, JsonObject.class);
146         } catch (final CoderException e) {
147             throw new PolicyToscaConverterException(
148                 String.format("Could not convert JSON string to JSON:%n%s", jsonString), e);
149         }
150     }
151
152     @Getter
153     public enum ToscaKey {
154         TOPOLOGY_TEMPLATE("topology_template"),
155         TOSCA_DEFINITIONS_VERSION("tosca_definitions_version"),
156         PROPERTIES("properties"),
157         ENGINE_SERVICE_PARAMETERS("engineServiceParameters"),
158         POLICY_TYPE_IMPL("policy_type_impl"),
159         POLICIES("policies");
160
161         private final String key;
162
163         ToscaKey(final String key) {
164             this.key = key;
165         }
166     }
167
168 }