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 java.lang.reflect.Type;
24 import java.util.Map.Entry;
26 import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
27 import org.onap.policy.apex.context.parameters.ContextParameters;
28 import org.onap.policy.apex.context.parameters.DistributorParameters;
29 import org.onap.policy.apex.context.parameters.LockManagerParameters;
30 import org.onap.policy.apex.context.parameters.PersistorParameters;
31 import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
32 import org.onap.policy.apex.context.parameters.SchemaParameters;
33 import org.onap.policy.apex.core.engine.EngineParameters;
34 import org.onap.policy.apex.core.engine.ExecutorParameters;
35 import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
36 import org.onap.policy.apex.service.parameters.ApexParameterRuntimeException;
37 import org.slf4j.ext.XLogger;
38 import org.slf4j.ext.XLoggerFactory;
40 import com.google.gson.JsonDeserializationContext;
41 import com.google.gson.JsonDeserializer;
42 import com.google.gson.JsonElement;
43 import com.google.gson.JsonObject;
44 import com.google.gson.JsonParseException;
45 import com.google.gson.JsonSerializationContext;
46 import com.google.gson.JsonSerializer;
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
53 * @author Liam Fallon (liam.fallon@ericsson.com)
55 public class EngineServiceParametersJSONAdapter
56 implements JsonSerializer<EngineParameters>, JsonDeserializer<EngineParameters> {
57 private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineServiceParametersJSONAdapter.class);
59 private static final String PARAMETER_CLASS_NAME = "parameterClassName";
62 private static final String CONTEXT_PARAMETERS = "contextParameters";
63 private static final String DISTRIBUTOR_PARAMETERS = "distributorParameters";
64 private static final String LOCK_MANAGER_PARAMETERS = "lockManagerParameters";
65 private static final String PERSISTOR_PARAMETERS = "persistorParameters";
66 private static final String SCHEMA_PARAMETERS = "schemaParameters";
67 private static final String EXECUTOR_PARAMETERS = "executorParameters";
73 * @see com.google.gson.JsonSerializer#serialize(java.lang.Object, java.lang.reflect.Type,
74 * com.google.gson.JsonSerializationContext)
77 public JsonElement serialize(final EngineParameters src, final Type typeOfSrc,
78 final JsonSerializationContext context) {
79 final String returnMessage = "serialization of Apex parameters to Json is not supported";
80 LOGGER.error(returnMessage);
81 throw new ApexParameterRuntimeException(returnMessage);
87 * @see com.google.gson.JsonDeserializer#deserialize(com.google.gson.JsonElement,
88 * java.lang.reflect.Type, com.google.gson.JsonDeserializationContext)
91 public EngineParameters deserialize(final JsonElement json, final Type typeOfT,
92 final JsonDeserializationContext context) throws JsonParseException {
93 final JsonObject engineParametersJsonObject = json.getAsJsonObject();
95 final EngineParameters engineParameters = new EngineParameters();
97 // Deserialise context parameters, they may be a subclass of the ContextParameters class
98 engineParameters.setContextParameters(
99 (ContextParameters) context.deserialize(engineParametersJsonObject, ContextParameters.class));
101 // Context parameter wrangling
102 getContextParameters(engineParametersJsonObject, engineParameters, context);
104 // Executor parameter wrangling
105 getExecutorParameters(engineParametersJsonObject, engineParameters, context);
107 return engineParameters;
111 * Get the context parameters for Apex.
113 * @param engineParametersJsonObject The input JSON
114 * @param engineParameters The output parameters
115 * @param context the JSON context
117 private void getContextParameters(final JsonObject engineParametersJsonObject,
118 final EngineParameters engineParameters, final JsonDeserializationContext context) {
119 final JsonElement contextParametersElement = engineParametersJsonObject.get(CONTEXT_PARAMETERS);
121 // Context parameters are optional so if the element does not exist, just return
122 if (contextParametersElement == null) {
126 // We do this because the JSON parameters may be for a subclass of ContextParameters
127 final ContextParameters contextParameters =
128 (ContextParameters) deserializeParameters(CONTEXT_PARAMETERS, contextParametersElement, context);
130 // We know this will work because if the context parameters was not a Json object, the
131 // previous deserializeParameters() call would not have worked
132 final JsonObject contextParametersObject = engineParametersJsonObject.get(CONTEXT_PARAMETERS).getAsJsonObject();
134 // Now get the distributor, lock manager, and persistence parameters
135 final JsonElement distributorParametersElement = contextParametersObject.get(DISTRIBUTOR_PARAMETERS);
136 if (distributorParametersElement != null) {
138 .setDistributorParameters((DistributorParameters) deserializeParameters(DISTRIBUTOR_PARAMETERS,
139 distributorParametersElement, context));
142 final JsonElement lockManagerParametersElement = contextParametersObject.get(LOCK_MANAGER_PARAMETERS);
143 if (lockManagerParametersElement != null) {
145 .setLockManagerParameters((LockManagerParameters) deserializeParameters(LOCK_MANAGER_PARAMETERS,
146 lockManagerParametersElement, context));
149 final JsonElement persistorParametersElement = contextParametersObject.get(PERSISTOR_PARAMETERS);
150 if (persistorParametersElement != null) {
151 contextParameters.setPersistorParameters((PersistorParameters) deserializeParameters(PERSISTOR_PARAMETERS,
152 persistorParametersElement, context));
155 // Schema Handler parameter wrangling
156 getSchemaHandlerParameters(contextParametersObject, contextParameters, context);
158 // Get the engine plugin parameters
159 engineParameters.setContextParameters(contextParameters);
163 * Get the executor parameters for Apex.
165 * @param engineParametersJsonObject The input JSON
166 * @param engineParameters The output parameters
167 * @param context the JSON context
169 private void getExecutorParameters(final JsonObject engineParametersJsonObject,
170 final EngineParameters engineParameters, final JsonDeserializationContext context) {
171 final JsonElement executorParametersElement = engineParametersJsonObject.get(EXECUTOR_PARAMETERS);
173 // Executor parameters are mandatory so if the element does not exist throw an exception
174 if (executorParametersElement == null) {
175 final String returnMessage = "no \"" + EXECUTOR_PARAMETERS
176 + "\" entry found in parameters, at least one executor parameter entry must be specified";
177 LOGGER.error(returnMessage);
178 throw new ApexParameterRuntimeException(returnMessage);
181 // Deserialize the executor parameters
182 final JsonObject executorParametersJsonObject =
183 engineParametersJsonObject.get(EXECUTOR_PARAMETERS).getAsJsonObject();
185 for (final Entry<String, JsonElement> executorEntries : executorParametersJsonObject.entrySet()) {
186 final ExecutorParameters executorParameters =
187 (ExecutorParameters) deserializeParameters(EXECUTOR_PARAMETERS + ':' + executorEntries.getKey(),
188 executorEntries.getValue(), context);
189 engineParameters.getExecutorParameterMap().put(executorEntries.getKey(), executorParameters);
194 * Get the schema parameters for Apex.
196 * @param contextParametersJsonObject The input JSON
197 * @param contextParameters The output parameters
198 * @param context the JSON context
200 private void getSchemaHandlerParameters(final JsonObject contextParametersJsonObject,
201 final ContextParameters contextParameters, final JsonDeserializationContext context) {
202 final JsonElement schemaParametersElement = contextParametersJsonObject.get(SCHEMA_PARAMETERS);
204 // Insert the default Java schema helper
205 contextParameters.getSchemaParameters().getSchemaHelperParameterMap()
206 .put(SchemaParameters.DEFAULT_SCHEMA_FLAVOUR, new JavaSchemaHelperParameters());
208 // Context parameters are optional so if the element does not exist, just return
209 if (schemaParametersElement == null) {
213 // Deserialize the executor parameters
214 final JsonObject schemaHelperParametersJsonObject =
215 contextParametersJsonObject.get(SCHEMA_PARAMETERS).getAsJsonObject();
217 for (final Entry<String, JsonElement> schemaHelperEntries : schemaHelperParametersJsonObject.entrySet()) {
218 contextParameters.getSchemaParameters().getSchemaHelperParameterMap().put(schemaHelperEntries.getKey(),
219 (SchemaHelperParameters) deserializeParameters(
220 SCHEMA_PARAMETERS + ':' + schemaHelperEntries.getKey(), schemaHelperEntries.getValue(),
226 * Deserialize a parameter object that's a superclass of the AbstractParameters class.
228 * @param parametersLabel Label to use for error messages
229 * @param parametersElement The JSON object holding the parameters
230 * @param context The GSON context
231 * @return the parameters
232 * @throws ApexParameterRuntimeException on errors reading the parameters
234 private AbstractParameters deserializeParameters(final String parametersLabel, final JsonElement parametersElement,
235 final JsonDeserializationContext context) throws ApexParameterRuntimeException {
236 JsonObject parametersObject = null;
238 // Check that the JSON element is a JSON object
239 if (parametersElement.isJsonObject()) {
240 parametersObject = parametersElement.getAsJsonObject();
242 final String returnMessage = "value of \"" + parametersLabel + "\" entry is not a parameter JSON object";
243 LOGGER.error(returnMessage);
244 throw new ApexParameterRuntimeException(returnMessage);
247 // Get the parameter class name for instantiation in deserialization
248 final JsonElement parameterClassNameElement = parametersObject.get(PARAMETER_CLASS_NAME);
249 if (parameterClassNameElement == null) {
250 final String returnMessage =
251 "could not find field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel + "\" entry";
252 LOGGER.error(returnMessage);
253 throw new ApexParameterRuntimeException(returnMessage);
256 // Check the parameter is a JSON primitive
257 if (!parameterClassNameElement.isJsonPrimitive()) {
258 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
259 + "\" entry is not a plain string";
260 LOGGER.error(returnMessage);
261 throw new ApexParameterRuntimeException(returnMessage);
264 // Check the parameter has a value
265 final String parameterClassName = parameterClassNameElement.getAsString();
266 if (parameterClassName == null || parameterClassName.trim().length() == 0) {
267 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
268 + "\" entry is not specified or is blank";
269 LOGGER.error(returnMessage);
270 throw new ApexParameterRuntimeException(returnMessage);
273 // Deserialize the parameters using GSON
274 AbstractParameters parameters = null;
276 parameters = context.deserialize(parametersObject, Class.forName(parameterClassName));
277 } catch (JsonParseException | ClassNotFoundException e) {
278 final String returnMessage =
279 "failed to deserialize the parameters for \"" + parametersLabel + "\" " + "to parameter class \""
280 + parameterClassName + "\"\n" + e.getClass().getCanonicalName() + ": " + e.getMessage();
281 LOGGER.error(returnMessage, e);
282 throw new ApexParameterRuntimeException(returnMessage, e);