2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
 
   4  *  Modifications Copyright (C) 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.client.editor.rest.handling;
 
  24 import java.io.IOException;
 
  25 import javax.ws.rs.Consumes;
 
  26 import javax.ws.rs.DELETE;
 
  27 import javax.ws.rs.GET;
 
  28 import javax.ws.rs.POST;
 
  29 import javax.ws.rs.PUT;
 
  30 import javax.ws.rs.Path;
 
  31 import javax.ws.rs.PathParam;
 
  32 import javax.ws.rs.Produces;
 
  33 import javax.ws.rs.QueryParam;
 
  34 import javax.ws.rs.core.MediaType;
 
  35 import org.onap.policy.apex.model.modelapi.ApexApiResult;
 
  36 import org.onap.policy.apex.model.modelapi.ApexApiResult.Result;
 
  37 import org.onap.policy.common.utils.resources.TextFileUtils;
 
  38 import org.slf4j.ext.XLogger;
 
  39 import org.slf4j.ext.XLoggerFactory;
 
  42  * The class represents the root resource exposed at the base URL<br> The url to access this resource would be in the
 
  43  * form {@code <baseURL>/rest/<session>/....} <br> For example: a PUT request to the following URL
 
  44  * {@code http://localhost:8080/apex/rest/109/ContextSchema/Update}, with a JSON string payload containing the new
 
  45  * {@code Schema} in the body, can be explained as: <ul> <li>The server or servlet is running at the base URL
 
  46  * {@code http://localhost:8080/apex} <li>This resource {@code ApexRestEditorResource} is used because the path
 
  47  * {@code rest/109} matches the {@code Path} filter specification for this Resource ({@code @Path("rest/{session}")}),
 
  48  * where the {@code int} path parameter {@code session} is assigned the {@code int} value {@code 109} <li>The path
 
  49  * {@code ContextSchema/Update} redirects this call to the method {@link #updateContextSchema(String)}, which should be
 
  50  * a {@link javax.ws.rs.PUT}, with a single String in the body/payload which gets mapped to the single String parameter
 
  51  * for the method. <li>So, in summary, the REST request updates a {@code ContextSchema} as specified in the payload for
 
  52  * {@code session} number {@code 109} </ul>
 
  54  * <b>Note:</b> An allocated {@code Session} identifier must be included in (almost) all requests. Models for different
 
  55  * {@code Session} identifiers are completely isolated from one another.
 
  57  * <b>Note:</b> To create a new {@code Session}, and have a new session ID allocated use {@link javax.ws.rs.GET} request
 
  58  * to {@code <baseURL>/rest/-1/Session/Create} (for example: {@code http://localhost:8080/apex/rest/-1/Session/Create} )
 
  61 @Path("editor/{session}")
 
  62 @Produces({MediaType.APPLICATION_JSON})
 
  63 @Consumes({MediaType.APPLICATION_JSON})
 
  65 public class ApexEditorRestResource implements RestCommandHandler {
 
  66     // Get a reference to the logger
 
  67     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditorRestResource.class);
 
  69     // Location of the periodi event template
 
  70     private static final String PERIODIC_EVENT_TEMPLATE = "src/main/resources/templates/PeriodicEventTemplate.json";
 
  72     // Recurring string constants
 
  73     private static final String NAME = "name";
 
  74     private static final String VERSION = "version";
 
  75     private static final String REST_COMMAND_NOT_RECOGNISED = "REST command not recognised";
 
  76     private static final String OK = ": OK";
 
  77     private static final String NOT_OK = ": Not OK";
 
  78     private static final String SESSION_CREATE = "Session/Create";
 
  79     private static final String SESSION_CREATE_NOT_OK = "Session/Create: Not OK";
 
  81     // The session handler for sessions on the Apex editor
 
  82     private static final RestSessionHandler SESSION_HANDLER = new RestSessionHandler();
 
  84     // Handlers for the various parts of an Apex model
 
  86     private static final ModelHandler         MODEL_HANDLER          = new ModelHandler();
 
  87     private static final KeyInfoHandler       KEY_INFO_HANDLER       = new KeyInfoHandler();
 
  88     private static final ContextSchemaHandler CONTEXT_SCHEMA_HANDLER = new ContextSchemaHandler();
 
  89     private static final ContextAlbumHandler  CONTEXT_ALBUM_HANDLER  = new ContextAlbumHandler();
 
  90     private static final EventHandler         EVENT_HANDLER          = new EventHandler();
 
  91     private static final TaskHandler          TASK_HANDLER           = new TaskHandler();
 
  92     private static final PolicyHandler        POLICY_HANDLER         = new PolicyHandler();
 
  95     // The ID of this session. This gets injected from the URL.
 
  97     private int sessionId = -1;
 
 100      * Creates a new session. Always call this method with sessionID -1, whereby a new sessionID will be allocated. If
 
 101      * successful the new sessionID will be available in the first message in the result.
 
 103      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 104      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}. This includes the session id
 
 108     @Path("Session/Create")
 
 109     public ApexApiResult createSession() {
 
 110         if (sessionId != -1) {
 
 111             return new ApexApiResult(Result.FAILED, "Session ID must be set to -1 to create sessions: " + sessionId);
 
 114         ApexApiResult result = new ApexApiResult();
 
 115         SESSION_HANDLER.createSession(result);
 
 120      * Load the model from a JSON string for this session.
 
 122      * @param jsonString the JSON string to be parsed. The returned value(s) will be similar to {@code AxPolicyModel},
 
 123      *        with merged {@code AxKeyInfo} for the root object.
 
 124      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 125      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 129     public ApexApiResult loadFromString(final String jsonString) {
 
 130         return processRestCommand(RestCommandType.MODEL, RestCommand.LOAD, jsonString);
 
 134      * Analyse the model and return analysis results. If successful the analysis results will be available in the
 
 135      * messages in the result.
 
 137      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 138      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 141     @Path("Model/Analyse")
 
 142     public ApexApiResult analyse() {
 
 143         return processRestCommand(RestCommandType.MODEL, RestCommand.ANALYSE);
 
 147      * Validate the model and return validation results. If successful the validation results will be available in the
 
 148      * messages in the result.
 
 150      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 151      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 154     @Path("Model/Validate")
 
 155     public ApexApiResult validate() {
 
 156         return processRestCommand(RestCommandType.MODEL, RestCommand.VALIDATE);
 
 160      * Creates the new model model for this session.
 
 162      * @param jsonString the JSON string to be parsed containing the new model. See {@code BeanModel}
 
 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()}
 
 167     @Path("Model/Create")
 
 168     public ApexApiResult createModel(final String jsonString) {
 
 169         return processRestCommand(RestCommandType.MODEL, RestCommand.CREATE, jsonString);
 
 173      * Update the model for this session.
 
 175      * @param jsonString the JSON string to be parsed containing the updated model. See {@code BeanModel}
 
 176      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 177      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 180     @Path("Model/Update")
 
 181     public ApexApiResult updateModel(final String jsonString) {
 
 182         return processRestCommand(RestCommandType.MODEL, RestCommand.UPDATE, jsonString);
 
 186      * Gets the key for the model for this session. If successful the model key will be available in the first message
 
 187      * in the result. See {@code AxKey}
 
 189      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 190      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 193     @Path("Model/GetKey")
 
 194     public ApexApiResult getModelKey() {
 
 195         return processRestCommand(RestCommandType.MODEL, RestCommand.GET_KEY);
 
 199      * Retrieve the model for this session. If successful the model will be available in the first message in the
 
 200      * result. The returned value will be similar to a {@code AxPolicyModel}, with merged {@code AxKeyInfo} for the root
 
 203      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 204      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 208     public ApexApiResult listModel() {
 
 209         return processRestCommand(RestCommandType.MODEL, RestCommand.LIST);
 
 213      * Download the model for this session as a String.
 
 215      * @return the model represented as a JSON string. See {@code AxPolicyModel}
 
 218     @Path("Model/Download")
 
 219     public String downloadModel() {
 
 220         ApexApiResult result = processRestCommand(RestCommandType.MODEL, RestCommand.DOWNLOAD);
 
 221         if (result != null && result.isOk()) {
 
 222             return result.getMessage();
 
 229      * Delete the model for this session.
 
 231      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 232      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 235     @Path("Model/Delete")
 
 236     public ApexApiResult deleteModel() {
 
 237         return processRestCommand(RestCommandType.MODEL, RestCommand.DELETE);
 
 241      * List key information with the given key names/versions. If successful the result(s) will be available in the
 
 242      * result messages. See {@code AxKeyInfo}
 
 244      * @param name the name to search for. If null or empty, then all names will be queried
 
 245      * @param version the version to search for. If null then all versions will be searched for.
 
 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()}
 
 250     @Path("KeyInformation/Get")
 
 251     public ApexApiResult listKeyInformation(@QueryParam(NAME) final String name,
 
 252             @QueryParam(VERSION) final String version) {
 
 253         return processRestCommand(RestCommandType.KEY_INFO, RestCommand.LIST, name, version);
 
 257      * Creates a context schema with the information in the JSON string passed.
 
 259      * @param jsonString the JSON string to be parsed. See {@code BeanContextSchema}
 
 260      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 261      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 264     @Path("ContextSchema/Create")
 
 265     public ApexApiResult createContextSchema(final String jsonString) {
 
 266         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.CREATE, jsonString);
 
 270      * Update a context schema with the information in the JSON string passed.
 
 272      * @param jsonString the JSON string to be parsed. See {@code BeanContextSchema}
 
 273      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 274      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 277     @Path("ContextSchema/Update")
 
 278     public ApexApiResult updateContextSchema(final String jsonString) {
 
 279         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.UPDATE, jsonString);
 
 283      * List context schemas with the given key names/versions. If successful the result(s) will be available in the
 
 284      * result messages. The returned value(s) will be similar to {@code AxContextSchema}, with merged {@code AxKeyInfo}
 
 285      * for the root object.
 
 287      * @param name the name to search for. If null or empty, then all names will be queried
 
 288      * @param version the version to search for. If null then all versions will be searched for.
 
 289      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 290      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 293     @Path("ContextSchema/Get")
 
 294     public ApexApiResult listContextSchemas(@QueryParam(NAME) final String name,
 
 295             @QueryParam(VERSION) final String version) {
 
 296         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.LIST, name, version);
 
 300      * Delete context schemas with the given key names/versions.
 
 302      * @param name the name to search for. If null or empty, then all names will be queried
 
 303      * @param version the version to search for. If null then all versions will be searched for.
 
 304      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 305      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 308     @Path("ContextSchema/Delete")
 
 309     public ApexApiResult deleteContextSchema(@QueryParam(NAME) final String name,
 
 310             @QueryParam(VERSION) final String version) {
 
 311         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.DELETE, name, version);
 
 315      * Validate context schemas with the given key names/versions. The result(s) will be available in the result
 
 318      * @param name the name to search for. If null or empty, then all names will be queried
 
 319      * @param version the version to search for. If null then all versions will be searched for.
 
 320      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 321      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 324     @Path("Validate/ContextSchema")
 
 325     public ApexApiResult validateContextSchemas(@QueryParam(NAME) final String name,
 
 326             @QueryParam(VERSION) final String version) {
 
 327         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.VALIDATE, name, version);
 
 331      * Creates a context album with the information in the JSON string passed.
 
 333      * @param jsonString the JSON string to be parsed. See {@code BeanContextAlbum}
 
 334      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 335      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 338     @Path("ContextAlbum/Create")
 
 339     public ApexApiResult createContextAlbum(final String jsonString) {
 
 340         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.CREATE, jsonString);
 
 344      * Update a context album with the information in the JSON string passed.
 
 346      * @param jsonString the JSON string to be parsed. See {@code BeanContextAlbum}
 
 347      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 348      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 351     @Path("ContextAlbum/Update")
 
 352     public ApexApiResult updateContextAlbum(final String jsonString) {
 
 353         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.UPDATE, jsonString);
 
 357      * List context albums with the given key names/versions. If successful the result(s) will be available in the
 
 358      * result messages. The returned value(s) will be similar to {@code AxContextAlbum}, with merged {@code AxKeyInfo}
 
 359      * for the root object.
 
 361      * @param name the name to search for. If null or empty, then all names will be queried
 
 362      * @param version the version to search for. If null then all versions will be searched for.
 
 363      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 364      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 367     @Path("ContextAlbum/Get")
 
 368     public ApexApiResult listContextAlbums(@QueryParam(NAME) final String name,
 
 369             @QueryParam(VERSION) final String version) {
 
 370         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.LIST, name, version);
 
 374      * Delete context albums with the given key names/versions.
 
 376      * @param name the name to search for. If null or empty, then all names will be queried
 
 377      * @param version the version to search for. If null then all versions will be searched for.
 
 378      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 379      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 382     @Path("ContextAlbum/Delete")
 
 383     public ApexApiResult deleteContextAlbum(@QueryParam(NAME) final String name,
 
 384             @QueryParam(VERSION) final String version) {
 
 385         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.DELETE, name, version);
 
 389      * Validate context albums with the given key names/versions. The result(s) will be available in the result
 
 392      * @param name the name to search for. If null or empty, then all names will be queried
 
 393      * @param version the version to search for. If null then all versions will be searched for.
 
 394      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 395      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 398     @Path("Validate/ContextAlbum")
 
 399     public ApexApiResult validateContextAlbums(@QueryParam(NAME) final String name,
 
 400             @QueryParam(VERSION) final String version) {
 
 401         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.VALIDATE, name, version);
 
 405      * Creates an event with the information in the JSON string passed.
 
 407      * @param jsonString the JSON string to be parsed. See {@code BeanEvent}
 
 408      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 409      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 412     @Path("Event/Create")
 
 413     public ApexApiResult createEvent(final String jsonString) {
 
 414         return processRestCommand(RestCommandType.EVENT, RestCommand.CREATE, jsonString);
 
 418      * Update an event with the information in the JSON string passed.
 
 420      * @param jsonString the JSON string to be parsed. See {@code BeanEvent}
 
 421      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 422      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 425     @Path("Event/Update")
 
 426     public ApexApiResult updateEvent(final String jsonString) {
 
 427         return processRestCommand(RestCommandType.EVENT, RestCommand.UPDATE, jsonString);
 
 431      * List events with the given key names/versions. If successful the result(s) will be available in the result
 
 432      * messages. The returned value(s) will be similar to {@code AxEvent}, with merged {@code AxKeyInfo} for the root
 
 435      * @param name the name to search for. If null or empty, then all names will be queried
 
 436      * @param version the version to search for. If null then all versions will be searched for.
 
 437      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 438      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 442     public ApexApiResult listEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 443         return processRestCommand(RestCommandType.EVENT, RestCommand.LIST, name, version);
 
 447      * Delete events with the given key names/versions.
 
 449      * @param name the name to search for. If null or empty, then all names will be queried
 
 450      * @param version the version to search for. If null then all versions will be searched for.
 
 451      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 452      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 455     @Path("Event/Delete")
 
 456     public ApexApiResult deleteEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 457         return processRestCommand(RestCommandType.EVENT, RestCommand.DELETE, name, version);
 
 461      * Validate events with the given key names/versions. The result(s) will be available in the result messages.
 
 463      * @param name the name to search for. If null or empty, then all names will be queried
 
 464      * @param version the version to search for. If null then all versions will be searched for.
 
 465      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 466      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 469     @Path("Validate/Event")
 
 470     public ApexApiResult validateEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 471         return processRestCommand(RestCommandType.EVENT, RestCommand.VALIDATE, name, version);
 
 475      * Creates a task with the information in the JSON string passed.
 
 477      * @param jsonString the JSON string to be parsed. See {@code BeanTask}
 
 478      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 479      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 483     public ApexApiResult createTask(final String jsonString) {
 
 484         return processRestCommand(RestCommandType.TASK, RestCommand.CREATE, jsonString);
 
 488      * Update a task with the information in the JSON string passed.
 
 490      * @param jsonString the JSON string to be parsed. See {@code BeanTask}
 
 491      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 492      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 496     public ApexApiResult updateTask(final String jsonString) {
 
 497         return processRestCommand(RestCommandType.TASK, RestCommand.UPDATE, jsonString);
 
 501      * List tasks with the given key names/versions. If successful the result(s) will be available in the result
 
 502      * messages. The returned value(s) will be similar to {@code AxTask}, with merged {@code AxKeyInfo} for the root
 
 505      * @param name the name to search for. If null or empty, then all names will be queried
 
 506      * @param version the version to search for. If null then all versions will be searched for.
 
 507      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 508      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 512     public ApexApiResult listTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 513         return processRestCommand(RestCommandType.TASK, RestCommand.LIST, name, version);
 
 517      * Delete tasks with the given key names/versions.
 
 519      * @param name the name to search for. If null or empty, then all names will be queried
 
 520      * @param version the version to search for. If null then all versions will be searched for.
 
 521      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 522      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 526     public ApexApiResult deleteTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 527         return processRestCommand(RestCommandType.TASK, RestCommand.DELETE, name, version);
 
 531      * Validate tasks with the given key names/versions. The result(s) will be available in the result messages.
 
 533      * @param name the name to search for. If null or empty, then all names will be queried
 
 534      * @param version the version to search for. If null then all versions will be searched for.
 
 535      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 536      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 539     @Path("Validate/Task")
 
 540     public ApexApiResult validateTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 541         return processRestCommand(RestCommandType.TASK, RestCommand.VALIDATE, name, version);
 
 544     // CHECKSTYLE:OFF: MethodLength
 
 546      * Creates a policy with the information in the JSON string passed.
 
 548      * @param jsonString the JSON string to be parsed See {@code BeanPolicy}
 
 549      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 550      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 553     @Path("Policy/Create")
 
 554     public ApexApiResult createPolicy(final String jsonString) {
 
 555         return processRestCommand(RestCommandType.POLICY, RestCommand.CREATE, jsonString);
 
 559      * Update a policy with the information in the JSON string passed.
 
 561      * @param firstStatePeriodic indicates if periodic event should be created and added to model
 
 562      * @param jsonString the JSON string to be parsed. See {@code BeanPolicy}
 
 563      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 564      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 567     @Path("Policy/Update")
 
 568     public ApexApiResult updatePolicy(@QueryParam("firstStatePeriodic") final boolean firstStatePeriodic,
 
 569             final String jsonString) {
 
 571         ApexApiResult result = processRestCommand(RestCommandType.POLICY, RestCommand.UPDATE, jsonString);
 
 572         if (result != null && result.isOk() && firstStatePeriodic) {
 
 573             result = createPeriodicEvent();
 
 579      * List policies with the given key names/versions. If successful the result(s) will be available in the result
 
 580      * messages. The returned value(s) will be similar to {@code AxPolicy}, with merged {@code AxKeyInfo} for the root
 
 583      * @param name the name to search for. If null or empty, then all names will be queried
 
 584      * @param version the version to search for. If null then all versions will be searched for.
 
 585      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 586      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 590     public ApexApiResult listPolicy(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 591         return processRestCommand(RestCommandType.POLICY, RestCommand.LIST, name, version);
 
 595      * Delete policies with the given key names/versions.
 
 597      * @param name the name to search for. If null or empty, then all names will be queried
 
 598      * @param version the version to search for. If null then all versions will be searched for.
 
 599      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
 
 600      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
 
 603     @Path("Policy/Delete")
 
 604     public ApexApiResult deletePolicy(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
 
 605         return processRestCommand(RestCommandType.POLICY, RestCommand.DELETE, name, version);
 
 609      * This method routes REST commands that take no parameters to their caller.
 
 611      * @param commandType the type of REST command to process
 
 612      * @param command the REST command to process
 
 613      * @return the result of the REST command
 
 615     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command) {
 
 616         LOGGER.entry(commandType);
 
 618             ApexApiResult result = new ApexApiResult();
 
 619             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
 
 620             if (session == null) {
 
 623             result = executeRestCommand(session, commandType, command);
 
 624             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
 
 626         } catch (final Exception e) {
 
 628             LOGGER.exit(SESSION_CREATE_NOT_OK);
 
 634      * This method routes REST commands that take a JSON string to their caller.
 
 636      * @param commandType the type of REST command to process
 
 637      * @param command the REST command to process
 
 638      * @param jsonString the JSON string received in the REST request
 
 639      * @return the result of the REST command
 
 641     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command,
 
 642             final String jsonString) {
 
 643         LOGGER.entry(commandType, jsonString);
 
 645             ApexApiResult result = new ApexApiResult();
 
 646             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
 
 647             if (session == null) {
 
 650             result = executeRestCommand(session, commandType, command, jsonString);
 
 651             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
 
 653         } catch (final Exception e) {
 
 655             LOGGER.exit(SESSION_CREATE_NOT_OK);
 
 661      * This method routes REST commands that take a name and version to their caller.
 
 663      * @param commandType the type of REST command to process
 
 664      * @param command the REST command to process
 
 665      * @param name the name received in the REST request
 
 666      * @param version the name received in the REST request
 
 667      * @return the result of the REST command
 
 669     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command,
 
 670             final String name, final String version) {
 
 671         LOGGER.entry(commandType, name, version);
 
 673             ApexApiResult result = new ApexApiResult();
 
 674             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
 
 675             if (session == null) {
 
 678             result = executeRestCommand(session, commandType, command, name, version);
 
 679             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
 
 681         } catch (final Exception e) {
 
 683             LOGGER.exit(SESSION_CREATE_NOT_OK);
 
 689      * This method invokes callers to run REST commands that take no parameters.
 
 691      * @param session the Apex editor session
 
 692      * @param commandType the type of REST command to process
 
 693      * @param command the REST command to process
 
 694      * @return the result of the REST command
 
 697     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
 
 698             final RestCommand command) {
 
 699         switch (commandType) {
 
 701                 return MODEL_HANDLER.executeRestCommand(session, commandType, command);
 
 703                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command);
 
 705                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command);
 
 707                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command);
 
 709                 return EVENT_HANDLER.executeRestCommand(session, commandType, command);
 
 711                 return TASK_HANDLER.executeRestCommand(session, commandType, command);
 
 713                 return POLICY_HANDLER.executeRestCommand(session, commandType, command);
 
 715                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
 
 720      * This method invokes callers to run REST commands that take a JSON string.
 
 722      * @param session the Apex editor session
 
 723      * @param commandType the type of REST command to process
 
 724      * @param command the REST command to process
 
 725      * @param jsonString the JSON string received in the REST request
 
 726      * @return the result of the REST command
 
 729     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
 
 730             final RestCommand command, final String jsonString) {
 
 731         switch (commandType) {
 
 733                 return MODEL_HANDLER.executeRestCommand(session, commandType, command, jsonString);
 
 735                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command, jsonString);
 
 737                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command, jsonString);
 
 739                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command, jsonString);
 
 741                 return EVENT_HANDLER.executeRestCommand(session, commandType, command, jsonString);
 
 743                 return TASK_HANDLER.executeRestCommand(session, commandType, command, jsonString);
 
 745                 return POLICY_HANDLER.executeRestCommand(session, commandType, command, jsonString);
 
 747                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
 
 752      * This method invokes callers to run REST commands that take a name and version.
 
 754      * @param session the Apex editor session
 
 755      * @param commandType the type of REST command to process
 
 756      * @param command the REST command to process
 
 757      * @param name the name received in the REST request
 
 758      * @param version the name received in the REST request
 
 759      * @return the result of the REST command
 
 762     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
 
 763             final RestCommand command, final String name, final String version) {
 
 764         switch (commandType) {
 
 766                 return MODEL_HANDLER.executeRestCommand(session, commandType, command, name, version);
 
 768                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command, name, version);
 
 770                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command, name, version);
 
 772                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command, name, version);
 
 774                 return EVENT_HANDLER.executeRestCommand(session, commandType, command, name, version);
 
 776                 return TASK_HANDLER.executeRestCommand(session, commandType, command, name, version);
 
 778                 return POLICY_HANDLER.executeRestCommand(session, commandType, command, name, version);
 
 780                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
 
 785      * Create a periodic event from the periodic event template.
 
 787     private ApexApiResult createPeriodicEvent() {
 
 788         String periodicEventJsonString;
 
 790             periodicEventJsonString = TextFileUtils.getTextFileAsString(PERIODIC_EVENT_TEMPLATE);
 
 791         } catch (IOException ioException) {
 
 792             String message = "read of periodic event tempalte from " + PERIODIC_EVENT_TEMPLATE + "failed: "
 
 793                     + ioException.getMessage();
 
 794             LOGGER.debug(message, ioException);
 
 795             return new ApexApiResult(Result.FAILED, message);
 
 798         return processRestCommand(RestCommandType.EVENT, RestCommand.CREATE, periodicEventJsonString);
 
 802      * This method is used only for testing and is used to cause an exception on calls from unit test to test exception
 
 805     protected static int createCorruptSession() {
 
 806         final ApexEditorRestResource apexEditorRestResource = new ApexEditorRestResource();
 
 807         final ApexApiResult result = apexEditorRestResource.createSession();
 
 808         final int corruptSessionId = Integer.parseInt(result.getMessages().get(0));
 
 810         SESSION_HANDLER.setCorruptSession(corruptSessionId);
 
 812         return corruptSessionId;