2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019-2020 Nordix Foundation.
5 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.gui.editors.apex.rest.handling;
25 import com.google.gson.Gson;
26 import com.google.gson.GsonBuilder;
27 import com.google.gson.JsonObject;
28 import java.util.ArrayList;
29 import java.util.List;
30 import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
31 import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
32 import org.onap.policy.apex.model.modelapi.ApexApiResult;
33 import org.onap.policy.apex.model.modelapi.ApexApiResult.Result;
34 import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
35 import org.onap.policy.gui.editors.apex.rest.handling.bean.BeanModel;
36 import org.slf4j.ext.XLogger;
37 import org.slf4j.ext.XLoggerFactory;
40 * This class handles commands on Apex models.
42 public class ModelHandler implements RestCommandHandler {
44 // Get a reference to the logger
45 private static final XLogger LOGGER = XLoggerFactory.getXLogger(ModelHandler.class);
47 // Recurring string constants
48 private static final String OK = ": OK";
49 private static final String NOT_OK = ": Not OK";
50 private static final String KEY = "key";
51 private static final String NAME = "name";
52 private static final String VERSION = "version";
53 private static final String UUID = "uuid";
54 private static final String DESCRIPTION = "description";
55 private static final String POLICY_KEY = "policyKey";
56 private static final String APEX_KEY_INFO = "apexKeyInfo";
62 public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
63 final RestCommand command) {
64 if (!RestCommandType.MODEL.equals(commandType)) {
65 return getUnsupportedCommandResultMessage(session, commandType, command);
70 return analyse(session);
72 return validate(session);
74 return getModelKey(session);
76 return listModel(session);
78 return downloadModel(session);
80 return uploadModel(session);
82 return deleteModel(session);
84 return getUnsupportedCommandResultMessage(session, commandType, command);
92 public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
93 final RestCommand command, final String jsonString) {
94 if (!RestCommandType.MODEL.equals(commandType)) {
95 return getUnsupportedCommandResultMessage(session, commandType, command);
100 return loadFromString(session, jsonString);
102 return createModel(session, jsonString);
104 return updateModel(session, jsonString);
106 return getUnsupportedCommandResultMessage(session, commandType, command);
114 public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
115 final RestCommand command, final String name, final String version) {
116 return getUnsupportedCommandResultMessage(session, commandType, command);
120 * Load the model from a JSON string for this session.
122 * @param session the Apex model editing session
123 * @param jsonString the JSON string to be parsed. The returned value(s) will be similar to {@link AxPolicyModel},
124 * with merged {@linkplain AxKeyInfo} for the root object.
125 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
126 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
128 private ApexApiResult loadFromString(final RestSession session, final String jsonString) {
129 LOGGER.entry(jsonString);
133 ApexApiResult result = session.loadFromString(jsonString);
135 session.finishSession(result.isOk());
137 LOGGER.exit("Model/Load" + (result.isOk() ? OK : NOT_OK));
142 * Analyse the model and return analysis results. If successful the analysis results will be available in the
143 * messages in the result.
145 * @param session the Apex model editing session
146 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
147 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
149 private ApexApiResult analyse(final RestSession session) {
152 ApexApiResult result = session.getApexModel().analyse();
154 LOGGER.exit("Model/Analyse" + (result != null && result.isOk() ? OK : NOT_OK));
159 * Validate the model and return validation results. If successful the validation results will be available in the
160 * messages in the result.
162 * @param session the Apex model editing session
163 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
164 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
166 private ApexApiResult validate(final RestSession session) {
169 ApexApiResult result = session.getApexModel().validate();
171 LOGGER.exit("Model/Validate" + (result != null && result.isOk() ? OK : NOT_OK));
176 * Creates the new model model for this session.
178 * @param session the Apex model editing session
179 * @param jsonString the JSON string to be parsed containing the new model. See {@linkplain BeanModel}
180 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
181 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
183 private ApexApiResult createModel(final RestSession session, final String jsonString) {
184 LOGGER.entry(jsonString);
186 final var jsonbean = RestUtils.getJsonParameters(jsonString, BeanModel.class);
190 ApexApiResult result = session.getApexModelEdited().createModel(jsonbean.getName(), jsonbean.getVersion(),
191 jsonbean.getUuid(), jsonbean.getDescription());
193 session.finishSession(result.isOk());
195 LOGGER.exit("Model/Create" + (result.isOk() ? OK : NOT_OK));
200 * Update the model for this session.
202 * @param session the Apex model editing session
203 * @param jsonString the JSON string to be parsed containing the updated model. See {@linkplain BeanModel}
204 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
205 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
207 private ApexApiResult updateModel(final RestSession session, final String jsonString) {
208 LOGGER.entry(jsonString);
210 final var jsonbean = RestUtils.getJsonParameters(jsonString, BeanModel.class);
214 ApexApiResult result = session.getApexModelEdited().updateModel(jsonbean.getName(), jsonbean.getVersion(),
215 jsonbean.getUuid(), jsonbean.getDescription());
217 session.finishSession(result.isOk());
219 LOGGER.exit("Model/Update" + (result.isOk() ? OK : NOT_OK));
224 * Gets the key for the model for this session. If successful the model key will be available in the first message
225 * in the result. See {@linkplain AxKey}
227 * @param session the Apex model editing session
228 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
229 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
231 private ApexApiResult getModelKey(final RestSession session) {
234 ApexApiResult result = session.getApexModel().getModelKey();
236 LOGGER.exit("Model/GetKey" + (result != null && result.isOk() ? OK : NOT_OK));
241 * Retrieve the model for this session. If successful the model will be available in the first message in the
242 * result. The returned value will be similar to a {@link AxPolicyModel}, with merged {@linkplain AxKeyInfo} for the
245 * @param session the Apex model editing session
246 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
247 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
249 private ApexApiResult listModel(final RestSession session) {
252 ApexApiResult result = session.getApexModel().listModel();
254 result = addKeyInfo2Messages(session, result);
256 LOGGER.exit("Model/Get" + (result.isOk() ? OK : NOT_OK));
261 * Download the model for this session as a String.
263 * @param session the Apex model editing session
264 * @return the model represented as a JSON string. See {@linkplain AxPolicyModel}
266 private ApexApiResult downloadModel(final RestSession session) {
269 ApexApiResult result = session.downloadModel();
271 LOGGER.exit("Model/Download" + (result != null && result.isOk() ? OK : NOT_OK));
276 * Upload the model for this session to the configured URL.
278 * @param session the Apex model editing session
279 * @return a result indicating if the upload was successful or not
281 private ApexApiResult uploadModel(final RestSession session) {
284 ApexApiResult result = session.uploadModel();
286 LOGGER.exit("Model/Download" + (result != null && result.isOk() ? OK : NOT_OK));
291 * Delete the model for this session.
293 * @param session the Apex model editing session
294 * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
295 * messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
297 private ApexApiResult deleteModel(final RestSession session) {
302 ApexApiResult result = session.getApexModel().deleteModel();
304 session.finishSession(result.isOk());
306 LOGGER.exit("Model/Delete" + (result.isOk() ? OK : NOT_OK));
311 * The json strings representing the objects listed, stored in result.messages[], does not contain the
312 * AxKeyInformation for that object. This utility method retrieves the AxKeyInfo for each object and adds it to the
313 * json for the object.
315 * @param session the Apex model editing session
316 * @param incomingResult The list result, containing JSON representations of objects stored in its "messages" array
317 * @return The list result, containing JSON augmented representations of objects stored in its "messages" array
319 private ApexApiResult addKeyInfo2Messages(final RestSession session, final ApexApiResult incomingResult) {
320 final ApexApiResult result = new ApexApiResult(incomingResult.getResult());
321 result.setMessages(incomingResult.getMessages());
323 final List<String> messages = incomingResult.getMessages();
324 final List<String> augmentedMessages = new ArrayList<>(messages.size());
326 for (final String message : messages) {
327 augmentedMessages.add(addKeyInfo2Message(session, message));
329 result.setMessages(augmentedMessages);
331 if (messages.size() != augmentedMessages.size()) {
332 result.setResult(Result.OTHER_ERROR);
333 result.addMessage("Failed to add KeyInfo to all results. Results are not complete");
340 * Augment a message with key information.
342 * @param session the Apex model editing session
343 * @param message The message to augment
344 * @return the augmented message
346 private String addKeyInfo2Message(final RestSession session, final String message) {
347 final Gson gson = new GsonBuilder().serializeNulls().enableComplexMapKeySerialization().create();
349 var jsonObject = gson.fromJson(message, JsonObject.class);
350 if (jsonObject == null) {
354 String name = readFieldFromJsonObject(jsonObject, NAME, null);
355 String version = readFieldFromJsonObject(jsonObject, VERSION, null);
357 if (name == null && version == null) {
358 var newJsonObject = getSubJsonObject(jsonObject);
360 if (newJsonObject != null) {
361 jsonObject = newJsonObject;
362 name = readFieldFromJsonObject(jsonObject, NAME, name);
363 version = readFieldFromJsonObject(jsonObject, VERSION, version);
367 if (name == null || version == null || !setUuidAndDescription(session, jsonObject, name, version)) {
368 jsonObject.addProperty(UUID, (String) null);
369 jsonObject.addProperty(DESCRIPTION, (String) null);
372 return gson.toJson(jsonObject);
376 * Get an embedded JSON object for the given JSON object.
378 * @param jsonObject the input JSON object
379 * @return the embedded JSON object
381 private JsonObject getSubJsonObject(JsonObject jsonObject) {
382 if (jsonObject.entrySet() != null && !jsonObject.entrySet().isEmpty()) {
383 return (JsonObject) jsonObject.entrySet().iterator().next().getValue();
390 * Condition a field so its key information can be looked up.
392 * @param jsonObject the object to query
393 * @param fieldTag the tag of the field to condition
394 * @param value the default value of the field to condition
395 * @return field read from the json
397 private String readFieldFromJsonObject(final JsonObject jsonObject, final String fieldTag, final String value) {
398 String lookedupValue = value;
400 if (jsonObject != null && jsonObject.get(KEY) != null && jsonObject.get(KEY).isJsonObject()
401 && jsonObject.getAsJsonObject(KEY).get(fieldTag) != null) {
402 lookedupValue = jsonObject.getAsJsonObject(KEY).get(fieldTag).getAsString();
403 } else if (jsonObject != null && jsonObject.get(POLICY_KEY) != null && jsonObject.get(POLICY_KEY).isJsonObject()
404 && jsonObject.getAsJsonObject(POLICY_KEY).get(fieldTag) != null) {
405 lookedupValue = jsonObject.getAsJsonObject(POLICY_KEY).get(fieldTag).getAsString();
407 return lookedupValue;
411 * Look up the UUID and description in the key information for a concept.
413 * @param session the Apex editor session
414 * @param jsonObject the JSON object to place the fields in
415 * @param name the concept name to look up
416 * @param version the concept version to look up
418 private boolean setUuidAndDescription(final RestSession session, JsonObject jsonObject, String name,
420 // Look up the key information for the name and version
421 JsonObject keyInfoJsonObject = lookupKeyInfo(session, name, version);
422 if (keyInfoJsonObject == null || keyInfoJsonObject.get(APEX_KEY_INFO) != null) {
426 if (keyInfoJsonObject.get(APEX_KEY_INFO).getAsJsonObject().get("UUID") != null) {
427 jsonObject.addProperty(UUID,
428 keyInfoJsonObject.get(APEX_KEY_INFO).getAsJsonObject().get("UUID").getAsString());
430 jsonObject.addProperty(UUID, (String) null);
433 if (keyInfoJsonObject.get(APEX_KEY_INFO).getAsJsonObject().get(DESCRIPTION) != null) {
434 jsonObject.addProperty(DESCRIPTION,
435 keyInfoJsonObject.get(APEX_KEY_INFO).getAsJsonObject().get(DESCRIPTION).getAsString());
437 jsonObject.addProperty(DESCRIPTION, (String) null);
444 * Look up the key information for the given concept name and value.
446 * @param session the Apex editor session
447 * @param name the concept name to look up
448 * @param version the concept version to look up
449 * @return a JSON version of the concept key information
451 private JsonObject lookupKeyInfo(final RestSession session, final String name, final String version) {
452 final ApexApiResult keyInfoResult = session.getApexModel().listKeyInformation(name, version);
453 final List<String> keyInfoMessages = keyInfoResult.getMessages();
455 if (keyInfoResult.isNok() || keyInfoMessages == null || keyInfoMessages.isEmpty()) {
459 final Gson gson = new GsonBuilder().serializeNulls().enableComplexMapKeySerialization().create();
460 final String keyInfoJson = keyInfoMessages.get(0);
461 return gson.fromJson(keyInfoJson, JsonObject.class);