2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019 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;
32 import java.lang.reflect.Type;
33 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.common.parameters.ParameterGroup;
45 import org.onap.policy.common.parameters.ParameterRuntimeException;
46 import org.slf4j.ext.XLogger;
47 import org.slf4j.ext.XLoggerFactory;
50 * This class deserializes engine service parameters from JSON format. The class produces an
51 * {@link EngineServiceParameters} instance from incoming JSON read from a configuration file in JSON format.
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";
74 public JsonElement serialize(final EngineParameters src, final Type typeOfSrc,
75 final JsonSerializationContext context) {
76 final String returnMessage = "serialization of Apex parameters to Json is not supported";
77 LOGGER.error(returnMessage);
78 throw new ParameterRuntimeException(returnMessage);
85 public EngineParameters deserialize(final JsonElement json, final Type typeOfT,
86 final JsonDeserializationContext context) {
87 final JsonObject engineParametersJsonObject = json.getAsJsonObject();
89 final EngineParameters engineParameters = new EngineParameters();
91 // Deserialise context parameters, they may be a subclass of the ContextParameters class
92 engineParameters.setContextParameters(
93 (ContextParameters) context.deserialize(engineParametersJsonObject, ContextParameters.class));
95 // Context parameter wrangling
96 getContextParameters(engineParametersJsonObject, engineParameters, context);
98 // Executor parameter wrangling
99 getExecutorParameters(engineParametersJsonObject, engineParameters, context);
101 return engineParameters;
105 * Get the context parameters for Apex.
107 * @param engineParametersJsonObject The input JSON
108 * @param engineParameters The output parameters
109 * @param context the JSON context
111 private void getContextParameters(final JsonObject engineParametersJsonObject,
112 final EngineParameters engineParameters, final JsonDeserializationContext context) {
113 final JsonElement contextParametersElement = engineParametersJsonObject.get(CONTEXT_PARAMETERS);
115 // Context parameters are optional so if the element does not exist, just return
116 if (contextParametersElement == null) {
120 // We do this because the JSON parameters may be for a subclass of ContextParameters
121 final ContextParameters contextParameters = (ContextParameters) deserializeParameters(CONTEXT_PARAMETERS,
122 contextParametersElement, context);
124 // We know this will work because if the context parameters was not a Json object, the
125 // previous deserializeParameters() call would not have worked
126 final JsonObject contextParametersObject = engineParametersJsonObject.get(CONTEXT_PARAMETERS).getAsJsonObject();
128 // Now get the distributor, lock manager, and persistence parameters
129 final JsonElement distributorParametersElement = contextParametersObject.get(DISTRIBUTOR_PARAMETERS);
130 if (distributorParametersElement != null) {
131 contextParameters.setDistributorParameters((DistributorParameters) deserializeParameters(
132 DISTRIBUTOR_PARAMETERS, distributorParametersElement, context));
135 final JsonElement lockManagerParametersElement = contextParametersObject.get(LOCK_MANAGER_PARAMETERS);
136 if (lockManagerParametersElement != null) {
137 contextParameters.setLockManagerParameters((LockManagerParameters) deserializeParameters(
138 LOCK_MANAGER_PARAMETERS, lockManagerParametersElement, context));
141 final JsonElement persistorParametersElement = contextParametersObject.get(PERSISTOR_PARAMETERS);
142 if (persistorParametersElement != null) {
143 contextParameters.setPersistorParameters((PersistorParameters) deserializeParameters(PERSISTOR_PARAMETERS,
144 persistorParametersElement, context));
147 // Schema Handler parameter wrangling
148 getSchemaHandlerParameters(contextParametersObject, contextParameters, context);
150 // Get the engine plugin parameters
151 engineParameters.setContextParameters(contextParameters);
155 * Get the executor parameters for Apex.
157 * @param engineParametersJsonObject The input JSON
158 * @param engineParameters The output parameters
159 * @param context the JSON context
161 private void getExecutorParameters(final JsonObject engineParametersJsonObject,
162 final EngineParameters engineParameters, final JsonDeserializationContext context) {
163 final JsonElement executorParametersElement = engineParametersJsonObject.get(EXECUTOR_PARAMETERS);
165 // Executor parameters are mandatory so if the element does not exist throw an exception
166 if (executorParametersElement == null) {
167 final String returnMessage = "no \"" + EXECUTOR_PARAMETERS
168 + "\" entry found in parameters, at least one executor parameter entry must be specified";
169 LOGGER.error(returnMessage);
170 throw new ParameterRuntimeException(returnMessage);
173 // Deserialize the executor parameters
174 final JsonObject executorParametersJsonObject = engineParametersJsonObject.get(EXECUTOR_PARAMETERS)
177 for (final Entry<String, JsonElement> executorEntries : executorParametersJsonObject.entrySet()) {
178 final ExecutorParameters executorParameters = (ExecutorParameters) deserializeParameters(
179 EXECUTOR_PARAMETERS + ':' + executorEntries.getKey(), executorEntries.getValue(), context);
180 engineParameters.getExecutorParameterMap().put(executorEntries.getKey(), executorParameters);
185 * Get the schema parameters for Apex.
187 * @param contextParametersJsonObject The input JSON
188 * @param contextParameters The output parameters
189 * @param context the JSON context
191 private void getSchemaHandlerParameters(final JsonObject contextParametersJsonObject,
192 final ContextParameters contextParameters, final JsonDeserializationContext context) {
193 final JsonElement schemaParametersElement = contextParametersJsonObject.get(SCHEMA_PARAMETERS);
195 // Insert the default Java schema helper
196 contextParameters.getSchemaParameters().getSchemaHelperParameterMap()
197 .put(SchemaParameters.DEFAULT_SCHEMA_FLAVOUR, new JavaSchemaHelperParameters());
199 // Context parameters are optional so if the element does not exist, just return
200 if (schemaParametersElement == null) {
204 // Deserialize the executor parameters
205 final JsonObject schemaHelperParametersJsonObject = contextParametersJsonObject.get(SCHEMA_PARAMETERS)
208 for (final Entry<String, JsonElement> schemaHelperEntries : schemaHelperParametersJsonObject.entrySet()) {
209 contextParameters.getSchemaParameters().getSchemaHelperParameterMap().put(schemaHelperEntries.getKey(),
210 (SchemaHelperParameters) deserializeParameters(
211 SCHEMA_PARAMETERS + ':' + schemaHelperEntries.getKey(),
212 schemaHelperEntries.getValue(), context));
217 * Deserialize a parameter object that's a superclass of the AbstractParameters class.
219 * @param parametersLabel Label to use for error messages
220 * @param parametersElement The JSON object holding the parameters
221 * @param context The GSON context
222 * @return the parameters
223 * @throws ParameterRuntimeException on errors reading the parameters
225 private ParameterGroup deserializeParameters(final String parametersLabel, final JsonElement parametersElement,
226 final JsonDeserializationContext context) {
227 JsonObject parametersObject = null;
229 // Check that the JSON element is a JSON object
230 if (parametersElement.isJsonObject()) {
231 parametersObject = parametersElement.getAsJsonObject();
233 final String returnMessage = "value of \"" + parametersLabel + "\" entry is not a parameter JSON object";
234 LOGGER.error(returnMessage);
235 throw new ParameterRuntimeException(returnMessage);
238 // Get the parameter class name for instantiation in deserialization
239 final JsonElement parameterClassNameElement = parametersObject.get(PARAMETER_CLASS_NAME);
240 if (parameterClassNameElement == null) {
241 final String returnMessage = "could not find field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
243 LOGGER.error(returnMessage);
244 throw new ParameterRuntimeException(returnMessage);
247 // Check the parameter is a JSON primitive
248 if (!parameterClassNameElement.isJsonPrimitive()) {
249 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" of \"" + parametersLabel
250 + "\" entry is not a plain string";
251 LOGGER.error(returnMessage);
252 throw new ParameterRuntimeException(returnMessage);
255 // Check the parameter has a value
256 final String parameterClassName = parameterClassNameElement.getAsString();
257 if (parameterClassName == null || parameterClassName.trim().length() == 0) {
258 final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel
259 + "\" entry is not specified or is blank";
260 LOGGER.error(returnMessage);
261 throw new ParameterRuntimeException(returnMessage);
264 // Deserialize the parameters using GSON
265 ParameterGroup parameters = null;
267 parameters = context.deserialize(parametersObject, Class.forName(parameterClassName));
268 } catch (JsonParseException | ClassNotFoundException e) {
269 final String returnMessage = "failed to deserialize the parameters for \"" + parametersLabel + "\" "
270 + "to parameter class \"" + parameterClassName + "\"\n" + e.getClass().getName() + ": "
272 LOGGER.error(returnMessage, e);
273 throw new ParameterRuntimeException(returnMessage, e);