2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. 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.apex.service.parameters.engineservice;
23 import com.google.gson.JsonDeserializationContext;
24 import com.google.gson.JsonDeserializer;
25 import com.google.gson.JsonElement;
26 import com.google.gson.JsonObject;
27 import com.google.gson.JsonParseException;
28 import com.google.gson.JsonSerializationContext;
29 import com.google.gson.JsonSerializer;
31 import java.lang.reflect.Type;
32 import java.util.Map.Entry;
34 import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
35 import org.onap.policy.apex.context.parameters.ContextParameters;
36 import org.onap.policy.apex.context.parameters.DistributorParameters;
37 import org.onap.policy.apex.context.parameters.LockManagerParameters;
38 import org.onap.policy.apex.context.parameters.PersistorParameters;
39 import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
40 import org.onap.policy.apex.context.parameters.SchemaParameters;
41 import org.onap.policy.apex.core.engine.EngineParameters;
42 import org.onap.policy.apex.core.engine.ExecutorParameters;
43 import org.onap.policy.common.parameters.ParameterGroup;
44 import org.onap.policy.common.parameters.ParameterRuntimeException;
45 import org.slf4j.ext.XLogger;
46 import org.slf4j.ext.XLoggerFactory;
49 * This class deserializes engine service parameters from JSON format. The class produces an
50 * {@link EngineServiceParameters} instance from incoming JSON read from a configuration file in JSON format.
52 * @author Liam Fallon (liam.fallon@ericsson.com)
54 public class EngineServiceParametersJsonAdapter
55 implements JsonSerializer<EngineParameters>, JsonDeserializer<EngineParameters> {
56 private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineServiceParametersJsonAdapter.class);
58 private static final String PARAMETER_CLASS_NAME = "parameterClassName";
61 private static final String CONTEXT_PARAMETERS = "contextParameters";
62 private static final String DISTRIBUTOR_PARAMETERS = "distributorParameters";
63 private static final String LOCK_MANAGER_PARAMETERS = "lockManagerParameters";
64 private static final String PERSISTOR_PARAMETERS = "persistorParameters";
65 private static final String SCHEMA_PARAMETERS = "schemaParameters";
66 private static final String EXECUTOR_PARAMETERS = "executorParameters";
73 public JsonElement serialize(final EngineParameters src, final Type typeOfSrc,
74 final JsonSerializationContext context) {
75 final String returnMessage = "serialization of Apex parameters to Json is not supported";
76 LOGGER.error(returnMessage);
77 throw new ParameterRuntimeException(returnMessage);
84 public EngineParameters deserialize(final JsonElement json, final Type typeOfT,
85 final JsonDeserializationContext context) {
86 final JsonObject engineParametersJsonObject = json.getAsJsonObject();
88 final EngineParameters engineParameters = new EngineParameters();
90 // Deserialise context parameters, they may be a subclass of the ContextParameters class
91 engineParameters.setContextParameters(
92 (ContextParameters) context.deserialize(engineParametersJsonObject, ContextParameters.class));
94 // Context parameter wrangling
95 getContextParameters(engineParametersJsonObject, engineParameters, context);
97 // Executor parameter wrangling
98 getExecutorParameters(engineParametersJsonObject, engineParameters, context);
100 return engineParameters;
104 * Get the context parameters for Apex.
106 * @param engineParametersJsonObject The input JSON
107 * @param engineParameters The output parameters
108 * @param context the JSON context
110 private void getContextParameters(final JsonObject engineParametersJsonObject,
111 final EngineParameters engineParameters, final JsonDeserializationContext context) {
112 final JsonElement contextParametersElement = engineParametersJsonObject.get(CONTEXT_PARAMETERS);
114 // Context parameters are optional so if the element does not exist, just return
115 if (contextParametersElement == null) {
119 // We do this because the JSON parameters may be for a subclass of ContextParameters
120 final ContextParameters contextParameters = (ContextParameters) deserializeParameters(CONTEXT_PARAMETERS,
121 contextParametersElement, context);
123 // We know this will work because if the context parameters was not a Json object, the
124 // previous deserializeParameters() call would not have worked
125 final JsonObject contextParametersObject = engineParametersJsonObject.get(CONTEXT_PARAMETERS).getAsJsonObject();
127 // Now get the distributor, lock manager, and persistence parameters
128 final JsonElement distributorParametersElement = contextParametersObject.get(DISTRIBUTOR_PARAMETERS);
129 if (distributorParametersElement != null) {
130 contextParameters.setDistributorParameters((DistributorParameters) deserializeParameters(
131 DISTRIBUTOR_PARAMETERS, distributorParametersElement, context));
134 final JsonElement lockManagerParametersElement = contextParametersObject.get(LOCK_MANAGER_PARAMETERS);
135 if (lockManagerParametersElement != null) {
136 contextParameters.setLockManagerParameters((LockManagerParameters) deserializeParameters(
137 LOCK_MANAGER_PARAMETERS, lockManagerParametersElement, context));
140 final JsonElement persistorParametersElement = contextParametersObject.get(PERSISTOR_PARAMETERS);
141 if (persistorParametersElement != null) {
142 contextParameters.setPersistorParameters((PersistorParameters) deserializeParameters(PERSISTOR_PARAMETERS,
143 persistorParametersElement, context));
146 // Schema Handler parameter wrangling
147 getSchemaHandlerParameters(contextParametersObject, contextParameters, context);
149 // Get the engine plugin parameters
150 engineParameters.setContextParameters(contextParameters);
154 * Get the executor parameters for Apex.
156 * @param engineParametersJsonObject The input JSON
157 * @param engineParameters The output parameters
158 * @param context the JSON context
160 private void getExecutorParameters(final JsonObject engineParametersJsonObject,
161 final EngineParameters engineParameters, final JsonDeserializationContext context) {
162 final JsonElement executorParametersElement = engineParametersJsonObject.get(EXECUTOR_PARAMETERS);
164 // Executor parameters are mandatory so if the element does not exist throw an exception
165 if (executorParametersElement == null) {
166 final String returnMessage = "no \"" + EXECUTOR_PARAMETERS
167 + "\" entry found in parameters, at least one executor parameter entry must be specified";
168 LOGGER.error(returnMessage);
169 throw new ParameterRuntimeException(returnMessage);
172 // Deserialize the executor parameters
173 final JsonObject executorParametersJsonObject = engineParametersJsonObject.get(EXECUTOR_PARAMETERS)
176 for (final Entry<String, JsonElement> executorEntries : executorParametersJsonObject.entrySet()) {
177 final ExecutorParameters executorParameters = (ExecutorParameters) deserializeParameters(
178 EXECUTOR_PARAMETERS + ':' + executorEntries.getKey(), executorEntries.getValue(), context);
179 engineParameters.getExecutorParameterMap().put(executorEntries.getKey(), executorParameters);
184 * Get the schema parameters for Apex.
186 * @param contextParametersJsonObject The input JSON
187 * @param contextParameters The output parameters
188 * @param context the JSON context
190 private void getSchemaHandlerParameters(final JsonObject contextParametersJsonObject,
191 final ContextParameters contextParameters, final JsonDeserializationContext context) {
192 final JsonElement schemaParametersElement = contextParametersJsonObject.get(SCHEMA_PARAMETERS);
194 // Insert the default Java schema helper
195 contextParameters.getSchemaParameters().getSchemaHelperParameterMap()
196 .put(SchemaParameters.DEFAULT_SCHEMA_FLAVOUR, new JavaSchemaHelperParameters());
198 // Context parameters are optional so if the element does not exist, just return
199 if (schemaParametersElement == null) {
203 // Deserialize the executor parameters
204 final JsonObject schemaHelperParametersJsonObject = contextParametersJsonObject.get(SCHEMA_PARAMETERS)
207 for (final Entry<String, JsonElement> schemaHelperEntries : schemaHelperParametersJsonObject.entrySet()) {
208 contextParameters.getSchemaParameters().getSchemaHelperParameterMap().put(schemaHelperEntries.getKey(),
209 (SchemaHelperParameters) deserializeParameters(
210 SCHEMA_PARAMETERS + ':' + schemaHelperEntries.getKey(),
211 schemaHelperEntries.getValue(), context));
216 * Deserialize a parameter object that's a superclass of the AbstractParameters class.
218 * @param parametersLabel Label to use for error messages
219 * @param parametersElement The JSON object holding the parameters
220 * @param context The GSON context
221 * @return the parameters
222 * @throws ParameterRuntimeException on errors reading the parameters
224 private ParameterGroup deserializeParameters(final String parametersLabel, final JsonElement parametersElement,
225 final JsonDeserializationContext context) {
226 JsonObject parametersObject = null;
228 // Check that the JSON element is a JSON object
229 if (parametersElement.isJsonObject()) {
230 parametersObject = parametersElement.getAsJsonObject();
232 final String returnMessage = "value of \"" + parametersLabel + "\" entry is not a parameter JSON object";
233 LOGGER.error(returnMessage);
234 throw new ParameterRuntimeException(returnMessage);
237 // Get the parameter class name for instantiation in deserialization
238 final JsonElement parameterClassNameElement = parametersObject.get(PARAMETER_CLASS_NAME);
239 if (parameterClassNameElement == null) {
240 final String returnMessage = "could not find field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
242 LOGGER.error(returnMessage);
243 throw new ParameterRuntimeException(returnMessage);
246 // Check the parameter is a JSON primitive
247 if (!parameterClassNameElement.isJsonPrimitive()) {
248 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" of \"" + parametersLabel
249 + "\" entry is not a plain string";
250 LOGGER.error(returnMessage);
251 throw new ParameterRuntimeException(returnMessage);
254 // Check the parameter has a value
255 final String parameterClassName = parameterClassNameElement.getAsString();
256 if (parameterClassName == null || parameterClassName.trim().length() == 0) {
257 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
258 + "\" entry is not specified or is blank";
259 LOGGER.error(returnMessage);
260 throw new ParameterRuntimeException(returnMessage);
263 // Deserialize the parameters using GSON
264 ParameterGroup parameters = null;
266 parameters = context.deserialize(parametersObject, Class.forName(parameterClassName));
267 } catch (JsonParseException | ClassNotFoundException e) {
268 final String returnMessage = "failed to deserialize the parameters for \"" + parametersLabel + "\" "
269 + "to parameter class \"" + parameterClassName + "\"\n" + e.getClass().getCanonicalName()
270 + ": " + e.getMessage();
271 LOGGER.error(returnMessage, e);
272 throw new ParameterRuntimeException(returnMessage, e);