2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019-2020 Nordix Foundation.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.apex.service.parameters.engineservice;
24 import com.google.gson.JsonDeserializationContext;
25 import com.google.gson.JsonDeserializer;
26 import com.google.gson.JsonElement;
27 import com.google.gson.JsonObject;
28 import com.google.gson.JsonParseException;
29 import com.google.gson.JsonSerializationContext;
30 import com.google.gson.JsonSerializer;
31 import java.lang.reflect.Type;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.Map.Entry;
35 import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
36 import org.onap.policy.apex.context.parameters.ContextParameters;
37 import org.onap.policy.apex.context.parameters.DistributorParameters;
38 import org.onap.policy.apex.context.parameters.LockManagerParameters;
39 import org.onap.policy.apex.context.parameters.PersistorParameters;
40 import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
41 import org.onap.policy.apex.context.parameters.SchemaParameters;
42 import org.onap.policy.apex.core.engine.EngineParameters;
43 import org.onap.policy.apex.core.engine.ExecutorParameters;
44 import org.onap.policy.apex.core.engine.TaskParameters;
45 import org.onap.policy.common.parameters.ParameterGroup;
46 import org.onap.policy.common.parameters.ParameterRuntimeException;
47 import org.onap.policy.common.utils.coder.CoderException;
48 import org.onap.policy.common.utils.coder.StandardCoder;
49 import org.slf4j.ext.XLogger;
50 import org.slf4j.ext.XLoggerFactory;
53 * This class deserializes engine service parameters from JSON format. The class produces an
54 * {@link EngineServiceParameters} instance from incoming JSON read from a configuration file in JSON format.
56 * @author Liam Fallon (liam.fallon@ericsson.com)
58 public class EngineServiceParametersJsonAdapter
59 implements JsonSerializer<EngineParameters>, JsonDeserializer<EngineParameters> {
60 private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineServiceParametersJsonAdapter.class);
62 private static final String PARAMETER_CLASS_NAME = "parameterClassName";
65 private static final String CONTEXT_PARAMETERS = "contextParameters";
66 private static final String DISTRIBUTOR_PARAMETERS = "distributorParameters";
67 private static final String LOCK_MANAGER_PARAMETERS = "lockManagerParameters";
68 private static final String PERSISTOR_PARAMETERS = "persistorParameters";
69 private static final String SCHEMA_PARAMETERS = "schemaParameters";
70 private static final String EXECUTOR_PARAMETERS = "executorParameters";
73 private static StandardCoder standardCoder = new StandardCoder();
79 public JsonElement serialize(final EngineParameters src, final Type typeOfSrc,
80 final JsonSerializationContext context) {
81 final String returnMessage = "serialization of Apex parameters to Json is not supported";
82 LOGGER.error(returnMessage);
83 throw new ParameterRuntimeException(returnMessage);
90 public EngineParameters deserialize(final JsonElement json, final Type typeOfT,
91 final JsonDeserializationContext context) {
92 final JsonObject engineParametersJsonObject = json.getAsJsonObject();
94 final EngineParameters engineParameters = new EngineParameters();
96 // Deserialise context parameters, they may be a subclass of the ContextParameters class
97 engineParameters.setContextParameters(
98 (ContextParameters) context.deserialize(engineParametersJsonObject, ContextParameters.class));
100 // Context parameter wrangling
101 getContextParameters(engineParametersJsonObject, engineParameters, context);
103 // Executor parameter wrangling
104 getExecutorParameters(engineParametersJsonObject, engineParameters, context);
106 // Task parameter wrangling
107 getTaskParametersList(engineParametersJsonObject, engineParameters);
108 return engineParameters;
112 * Method to get the task parameters list for Apex.
114 * @param engineParametersJsonObject The input JSON
115 * @param engineParameters The output parameters
117 private void getTaskParametersList(JsonObject engineParametersJsonObject, EngineParameters engineParameters) {
118 final JsonElement parametersElement = engineParametersJsonObject.get("taskParameters");
120 // configurable parameters are optional so if the element does not exist, just return
121 if (parametersElement == null) {
124 List<TaskParameters> parametersList = new ArrayList<>();
125 parametersElement.getAsJsonArray().forEach(taskParam -> {
126 TaskParameters parameters = null;
128 parameters = standardCoder.decode(standardCoder.encode(taskParam), TaskParameters.class);
129 } catch (CoderException e) {
130 throw new ParameterRuntimeException("Error reading taskParameters from the config json provided.");
132 parametersList.add(parameters);
134 engineParameters.setTaskParameters(parametersList);
138 * Get the context parameters for Apex.
140 * @param engineParametersJsonObject The input JSON
141 * @param engineParameters The output parameters
142 * @param context the JSON context
144 private void getContextParameters(final JsonObject engineParametersJsonObject,
145 final EngineParameters engineParameters, final JsonDeserializationContext context) {
146 final JsonElement contextParametersElement = engineParametersJsonObject.get(CONTEXT_PARAMETERS);
148 // Context parameters are optional so if the element does not exist, just return
149 if (contextParametersElement == null) {
153 // We do this because the JSON parameters may be for a subclass of ContextParameters
154 final ContextParameters contextParameters = (ContextParameters) deserializeParameters(CONTEXT_PARAMETERS,
155 contextParametersElement, context);
157 // We know this will work because if the context parameters was not a Json object, the
158 // previous deserializeParameters() call would not have worked
159 final JsonObject contextParametersObject = engineParametersJsonObject.get(CONTEXT_PARAMETERS).getAsJsonObject();
161 // Now get the distributor, lock manager, and persistence parameters
162 final JsonElement distributorParametersElement = contextParametersObject.get(DISTRIBUTOR_PARAMETERS);
163 if (distributorParametersElement != null) {
164 contextParameters.setDistributorParameters((DistributorParameters) deserializeParameters(
165 DISTRIBUTOR_PARAMETERS, distributorParametersElement, context));
168 final JsonElement lockManagerParametersElement = contextParametersObject.get(LOCK_MANAGER_PARAMETERS);
169 if (lockManagerParametersElement != null) {
170 contextParameters.setLockManagerParameters((LockManagerParameters) deserializeParameters(
171 LOCK_MANAGER_PARAMETERS, lockManagerParametersElement, context));
174 final JsonElement persistorParametersElement = contextParametersObject.get(PERSISTOR_PARAMETERS);
175 if (persistorParametersElement != null) {
176 contextParameters.setPersistorParameters((PersistorParameters) deserializeParameters(PERSISTOR_PARAMETERS,
177 persistorParametersElement, context));
180 // Schema Handler parameter wrangling
181 getSchemaHandlerParameters(contextParametersObject, contextParameters, context);
183 // Get the engine plugin parameters
184 engineParameters.setContextParameters(contextParameters);
188 * Get the executor parameters for Apex.
190 * @param engineParametersJsonObject The input JSON
191 * @param engineParameters The output parameters
192 * @param context the JSON context
194 private void getExecutorParameters(final JsonObject engineParametersJsonObject,
195 final EngineParameters engineParameters, final JsonDeserializationContext context) {
196 final JsonElement executorParametersElement = engineParametersJsonObject.get(EXECUTOR_PARAMETERS);
198 // Executor parameters are mandatory so if the element does not exist throw an exception
199 if (executorParametersElement == null) {
200 final String returnMessage = "no \"" + EXECUTOR_PARAMETERS
201 + "\" entry found in parameters, at least one executor parameter entry must be specified";
202 LOGGER.error(returnMessage);
203 throw new ParameterRuntimeException(returnMessage);
206 // Deserialize the executor parameters
207 final JsonObject executorParametersJsonObject = engineParametersJsonObject.get(EXECUTOR_PARAMETERS)
210 for (final Entry<String, JsonElement> executorEntries : executorParametersJsonObject.entrySet()) {
211 final ExecutorParameters executorParameters = (ExecutorParameters) deserializeParameters(
212 EXECUTOR_PARAMETERS + ':' + executorEntries.getKey(), executorEntries.getValue(), context);
213 engineParameters.getExecutorParameterMap().put(executorEntries.getKey(), executorParameters);
218 * Get the schema parameters for Apex.
220 * @param contextParametersJsonObject The input JSON
221 * @param contextParameters The output parameters
222 * @param context the JSON context
224 private void getSchemaHandlerParameters(final JsonObject contextParametersJsonObject,
225 final ContextParameters contextParameters, final JsonDeserializationContext context) {
226 final JsonElement schemaParametersElement = contextParametersJsonObject.get(SCHEMA_PARAMETERS);
228 // Insert the default Java schema helper
229 contextParameters.getSchemaParameters().getSchemaHelperParameterMap()
230 .put(SchemaParameters.DEFAULT_SCHEMA_FLAVOUR, new JavaSchemaHelperParameters());
232 // Context parameters are optional so if the element does not exist, just return
233 if (schemaParametersElement == null) {
237 // Deserialize the executor parameters
238 final JsonObject schemaHelperParametersJsonObject = contextParametersJsonObject.get(SCHEMA_PARAMETERS)
241 for (final Entry<String, JsonElement> schemaHelperEntries : schemaHelperParametersJsonObject.entrySet()) {
242 contextParameters.getSchemaParameters().getSchemaHelperParameterMap().put(schemaHelperEntries.getKey(),
243 (SchemaHelperParameters) deserializeParameters(
244 SCHEMA_PARAMETERS + ':' + schemaHelperEntries.getKey(),
245 schemaHelperEntries.getValue(), context));
250 * Deserialize a parameter object that's a superclass of the AbstractParameters class.
252 * @param parametersLabel Label to use for error messages
253 * @param parametersElement The JSON object holding the parameters
254 * @param context The GSON context
255 * @return the parameters
256 * @throws ParameterRuntimeException on errors reading the parameters
258 private ParameterGroup deserializeParameters(final String parametersLabel, final JsonElement parametersElement,
259 final JsonDeserializationContext context) {
260 JsonObject parametersObject = null;
262 // Check that the JSON element is a JSON object
263 if (parametersElement.isJsonObject()) {
264 parametersObject = parametersElement.getAsJsonObject();
266 final String returnMessage = "value of \"" + parametersLabel + "\" entry is not a parameter JSON object";
267 LOGGER.error(returnMessage);
268 throw new ParameterRuntimeException(returnMessage);
271 // Get the parameter class name for instantiation in deserialization
272 final JsonElement parameterClassNameElement = parametersObject.get(PARAMETER_CLASS_NAME);
273 if (parameterClassNameElement == null) {
274 final String returnMessage = "could not find field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
276 LOGGER.error(returnMessage);
277 throw new ParameterRuntimeException(returnMessage);
280 // Check the parameter is a JSON primitive
281 if (!parameterClassNameElement.isJsonPrimitive()) {
282 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" of \"" + parametersLabel
283 + "\" entry is not a plain string";
284 LOGGER.error(returnMessage);
285 throw new ParameterRuntimeException(returnMessage);
288 // Check the parameter has a value
289 final String parameterClassName = parameterClassNameElement.getAsString();
290 if (parameterClassName == null || parameterClassName.trim().length() == 0) {
291 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
292 + "\" entry is not specified or is blank";
293 LOGGER.error(returnMessage);
294 throw new ParameterRuntimeException(returnMessage);
297 // Deserialize the parameters using GSON
298 ParameterGroup parameters = null;
300 parameters = context.deserialize(parametersObject, Class.forName(parameterClassName));
301 } catch (JsonParseException | ClassNotFoundException e) {
302 final String returnMessage = "failed to deserialize the parameters for \"" + parametersLabel + "\" "
303 + "to parameter class \"" + parameterClassName + "\"\n" + e.getClass().getName() + ": "
305 LOGGER.error(returnMessage, e);
306 throw new ParameterRuntimeException(returnMessage, e);