51dcf098733c0f5eb627410f23353421220b0381
[policy/apex-pdp.git] / client / client-editor / src / main / java / org / onap / policy / apex / client / editor / rest / handling / ApexEditorRestResource.java
1 /*-
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.client.editor.rest.handling;
23
24 import java.io.IOException;
25
26 import javax.ws.rs.Consumes;
27 import javax.ws.rs.DELETE;
28 import javax.ws.rs.GET;
29 import javax.ws.rs.POST;
30 import javax.ws.rs.PUT;
31 import javax.ws.rs.Path;
32 import javax.ws.rs.PathParam;
33 import javax.ws.rs.Produces;
34 import javax.ws.rs.QueryParam;
35 import javax.ws.rs.core.MediaType;
36
37 import org.onap.policy.apex.model.modelapi.ApexApiResult;
38 import org.onap.policy.apex.model.modelapi.ApexApiResult.Result;
39 import org.onap.policy.common.utils.resources.TextFileUtils;
40 import org.slf4j.ext.XLogger;
41 import org.slf4j.ext.XLoggerFactory;
42
43 /**
44  * The class represents the root resource exposed at the base URL<br> The url to access this resource would be in the
45  * form {@code <baseURL>/rest/<session>/....} <br> For example: a PUT request to the following URL
46  * {@code http://localhost:8080/apex/rest/109/ContextSchema/Update}, with a JSON string payload containing the new
47  * {@code Schema} in the body, can be explained as: <ul> <li>The server or servlet is running at the base URL
48  * {@code http://localhost:8080/apex} <li>This resource {@code ApexRestEditorResource} is used because the path
49  * {@code rest/109} matches the {@code Path} filter specification for this Resource ({@code @Path("rest/{session}")}),
50  * where the {@code int} path parameter {@code session} is assigned the {@code int} value {@code 109} <li>The path
51  * {@code ContextSchema/Update} redirects this call to the method {@link #updateContextSchema(String)}, which should be
52  * a {@link javax.ws.rs.PUT}, with a single String in the body/payload which gets mapped to the single String parameter
53  * for the method. <li>So, in summary, the REST request updates a {@code ContextSchema} as specified in the payload for
54  * {@code session} number {@code 109} </ul>
55  *
56  * <b>Note:</b> An allocated {@code Session} identifier must be included in (almost) all requests. Models for different
57  * {@code Session} identifiers are completely isolated from one another.
58  *
59  * <b>Note:</b> To create a new {@code Session}, and have a new session ID allocated use {@link javax.ws.rs.GET} request
60  * to {@code <baseURL>/rest/-1/Session/Create} (for example: {@code http://localhost:8080/apex/rest/-1/Session/Create} )
61  *
62  */
63 @Path("editor/{session}")
64 @Produces({MediaType.APPLICATION_JSON})
65 @Consumes({MediaType.APPLICATION_JSON})
66
67 public class ApexEditorRestResource implements RestCommandHandler {
68     // Get a reference to the logger
69     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditorRestResource.class);
70
71     // Location of the periodi event template
72     private static final String PERIODIC_EVENT_TEMPLATE = "src/main/resources/templates/PeriodicEventTemplate.json";
73
74     // Recurring string constants
75     private static final String NAME = "name";
76     private static final String VERSION = "version";
77     private static final String REST_COMMAND_NOT_RECOGNISED = "REST command not recognised";
78     private static final String OK = ": OK";
79     private static final String NOT_OK = ": Not OK";
80     private static final String SESSION_CREATE = "Session/Create";
81     private static final String SESSION_CREATE_NOT_OK = "Session/Create: Not OK";
82
83     // The session handler for sessions on the Apex editor
84     private static final RestSessionHandler SESSION_HANDLER = new RestSessionHandler();
85
86     // Handlers for the various parts of an Apex model
87     //@formatter:off
88     private static final ModelHandler         MODEL_HANDLER          = new ModelHandler();
89     private static final KeyInfoHandler       KEY_INFO_HANDLER       = new KeyInfoHandler();
90     private static final ContextSchemaHandler CONTEXT_SCHEMA_HANDLER = new ContextSchemaHandler();
91     private static final ContextAlbumHandler  CONTEXT_ALBUM_HANDLER  = new ContextAlbumHandler();
92     private static final EventHandler         EVENT_HANDLER          = new EventHandler();
93     private static final TaskHandler          TASK_HANDLER           = new TaskHandler();
94     private static final PolicyHandler        POLICY_HANDLER         = new PolicyHandler();
95     //@formatter:on
96
97     // The ID of this session. This gets injected from the URL.
98     @PathParam("session")
99     private int sessionId = -1;
100
101     /**
102      * Creates a new session. Always call this method with sessionID -1, whereby a new sessionID will be allocated. If
103      * successful the new sessionID will be available in the first message in the result.
104      *
105      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
106      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}. This includes the session id
107      *         for this session.
108      */
109     @GET
110     @Path("Session/Create")
111     public ApexApiResult createSession() {
112         if (sessionId != -1) {
113             return new ApexApiResult(Result.FAILED, "Session ID must be set to -1 to create sessions: " + sessionId);
114         }
115
116         ApexApiResult result = new ApexApiResult();
117         SESSION_HANDLER.createSession(result);
118         return result;
119     }
120
121     /**
122      * Load the model from a JSON string for this session.
123      *
124      * @param jsonString the JSON string to be parsed. The returned value(s) will be similar to {@code AxPolicyModel},
125      *        with merged {@code AxKeyInfo} for the root object.
126      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
127      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
128      */
129     @PUT
130     @Path("/Model/Load")
131     public ApexApiResult loadFromString(final String jsonString) {
132         return processRestCommand(RestCommandType.MODEL, RestCommand.LOAD, jsonString);
133     }
134
135     /**
136      * Analyse the model and return analysis results. If successful the analysis results will be available in the
137      * messages in the result.
138      *
139      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
140      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
141      */
142     @GET
143     @Path("Model/Analyse")
144     public ApexApiResult analyse() {
145         return processRestCommand(RestCommandType.MODEL, RestCommand.ANALYSE);
146     }
147
148     /**
149      * Validate the model and return validation results. If successful the validation results will be available in the
150      * messages in the result.
151      *
152      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
153      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
154      */
155     @GET
156     @Path("Model/Validate")
157     public ApexApiResult validate() {
158         return processRestCommand(RestCommandType.MODEL, RestCommand.VALIDATE);
159     }
160
161     /**
162      * Creates the new model model for this session.
163      *
164      * @param jsonString the JSON string to be parsed containing the new model. See {@code BeanModel}
165      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
166      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
167      */
168     @POST
169     @Path("Model/Create")
170     public ApexApiResult createModel(final String jsonString) {
171         return processRestCommand(RestCommandType.MODEL, RestCommand.CREATE, jsonString);
172     }
173
174     /**
175      * Update the model for this session.
176      *
177      * @param jsonString the JSON string to be parsed containing the updated model. See {@code BeanModel}
178      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
179      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
180      */
181     @PUT
182     @Path("Model/Update")
183     public ApexApiResult updateModel(final String jsonString) {
184         return processRestCommand(RestCommandType.MODEL, RestCommand.UPDATE, jsonString);
185     }
186
187     /**
188      * Gets the key for the model for this session. If successful the model key will be available in the first message
189      * in the result. See {@code AxKey}
190      *
191      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
192      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
193      */
194     @GET
195     @Path("Model/GetKey")
196     public ApexApiResult getModelKey() {
197         return processRestCommand(RestCommandType.MODEL, RestCommand.GET_KEY);
198     }
199
200     /**
201      * Retrieve the model for this session. If successful the model will be available in the first message in the
202      * result. The returned value will be similar to a {@code AxPolicyModel}, with merged {@code AxKeyInfo} for the root
203      * object.
204      *
205      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
206      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
207      */
208     @GET
209     @Path("Model/Get")
210     public ApexApiResult listModel() {
211         return processRestCommand(RestCommandType.MODEL, RestCommand.LIST);
212     }
213
214     /**
215      * Download the model for this session as a String.
216      *
217      * @return the model represented as a JSON string. See {@code AxPolicyModel}
218      */
219     @GET
220     @Path("Model/Download")
221     public String downloadModel() {
222         ApexApiResult result = processRestCommand(RestCommandType.MODEL, RestCommand.DOWNLOAD);
223         if (result != null && result.isOk()) {
224             return result.getMessage();
225         } else {
226             return null;
227         }
228     }
229
230     /**
231      * Delete the model for this session.
232      *
233      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
234      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
235      */
236     @DELETE
237     @Path("Model/Delete")
238     public ApexApiResult deleteModel() {
239         return processRestCommand(RestCommandType.MODEL, RestCommand.DELETE);
240     }
241
242     /**
243      * List key information with the given key names/versions. If successful the result(s) will be available in the
244      * result messages. See {@code AxKeyInfo}
245      *
246      * @param name the name to search for. If null or empty, then all names will be queried
247      * @param version the version to search for. If null then all versions will be searched for.
248      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
249      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
250      */
251     @GET
252     @Path("KeyInformation/Get")
253     public ApexApiResult listKeyInformation(@QueryParam(NAME) final String name,
254             @QueryParam(VERSION) final String version) {
255         return processRestCommand(RestCommandType.KEY_INFO, RestCommand.LIST, name, version);
256     }
257
258     /**
259      * Creates a context schema with the information in the JSON string passed.
260      *
261      * @param jsonString the JSON string to be parsed. See {@code BeanContextSchema}
262      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
263      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
264      */
265     @POST
266     @Path("ContextSchema/Create")
267     public ApexApiResult createContextSchema(final String jsonString) {
268         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.CREATE, jsonString);
269     }
270
271     /**
272      * Update a context schema with the information in the JSON string passed.
273      *
274      * @param jsonString the JSON string to be parsed. See {@code BeanContextSchema}
275      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
276      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
277      */
278     @PUT
279     @Path("ContextSchema/Update")
280     public ApexApiResult updateContextSchema(final String jsonString) {
281         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.UPDATE, jsonString);
282     }
283
284     /**
285      * List context schemas with the given key names/versions. If successful the result(s) will be available in the
286      * result messages. The returned value(s) will be similar to {@code AxContextSchema}, with merged {@code AxKeyInfo}
287      * for the root object.
288      *
289      * @param name the name to search for. If null or empty, then all names will be queried
290      * @param version the version to search for. If null then all versions will be searched for.
291      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
292      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
293      */
294     @GET
295     @Path("ContextSchema/Get")
296     public ApexApiResult listContextSchemas(@QueryParam(NAME) final String name,
297             @QueryParam(VERSION) final String version) {
298         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.LIST, name, version);
299     }
300
301     /**
302      * Delete context schemas with the given key names/versions.
303      *
304      * @param name the name to search for. If null or empty, then all names will be queried
305      * @param version the version to search for. If null then all versions will be searched for.
306      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
307      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
308      */
309     @DELETE
310     @Path("ContextSchema/Delete")
311     public ApexApiResult deleteContextSchema(@QueryParam(NAME) final String name,
312             @QueryParam(VERSION) final String version) {
313         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.DELETE, name, version);
314     }
315
316     /**
317      * Validate context schemas with the given key names/versions. The result(s) will be available in the result
318      * messages.
319      *
320      * @param name the name to search for. If null or empty, then all names will be queried
321      * @param version the version to search for. If null then all versions will be searched for.
322      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
323      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
324      */
325     @GET
326     @Path("Validate/ContextSchema")
327     public ApexApiResult validateContextSchemas(@QueryParam(NAME) final String name,
328             @QueryParam(VERSION) final String version) {
329         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.VALIDATE, name, version);
330     }
331
332     /**
333      * Creates a context album with the information in the JSON string passed.
334      *
335      * @param jsonString the JSON string to be parsed. See {@code BeanContextAlbum}
336      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
337      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
338      */
339     @POST
340     @Path("ContextAlbum/Create")
341     public ApexApiResult createContextAlbum(final String jsonString) {
342         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.CREATE, jsonString);
343     }
344
345     /**
346      * Update a context album with the information in the JSON string passed.
347      *
348      * @param jsonString the JSON string to be parsed. See {@code BeanContextAlbum}
349      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
350      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
351      */
352     @PUT
353     @Path("ContextAlbum/Update")
354     public ApexApiResult updateContextAlbum(final String jsonString) {
355         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.UPDATE, jsonString);
356     }
357
358     /**
359      * List context albums with the given key names/versions. If successful the result(s) will be available in the
360      * result messages. The returned value(s) will be similar to {@code AxContextAlbum}, with merged {@code AxKeyInfo}
361      * for the root object.
362      *
363      * @param name the name to search for. If null or empty, then all names will be queried
364      * @param version the version to search for. If null then all versions will be searched for.
365      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
366      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
367      */
368     @GET
369     @Path("ContextAlbum/Get")
370     public ApexApiResult listContextAlbums(@QueryParam(NAME) final String name,
371             @QueryParam(VERSION) final String version) {
372         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.LIST, name, version);
373     }
374
375     /**
376      * Delete context albums with the given key names/versions.
377      *
378      * @param name the name to search for. If null or empty, then all names will be queried
379      * @param version the version to search for. If null then all versions will be searched for.
380      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
381      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
382      */
383     @DELETE
384     @Path("ContextAlbum/Delete")
385     public ApexApiResult deleteContextAlbum(@QueryParam(NAME) final String name,
386             @QueryParam(VERSION) final String version) {
387         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.DELETE, name, version);
388     }
389
390     /**
391      * Validate context albums with the given key names/versions. The result(s) will be available in the result
392      * messages.
393      *
394      * @param name the name to search for. If null or empty, then all names will be queried
395      * @param version the version to search for. If null then all versions will be searched for.
396      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
397      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
398      */
399     @GET
400     @Path("Validate/ContextAlbum")
401     public ApexApiResult validateContextAlbums(@QueryParam(NAME) final String name,
402             @QueryParam(VERSION) final String version) {
403         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.VALIDATE, name, version);
404     }
405
406     /**
407      * Creates an event with the information in the JSON string passed.
408      *
409      * @param jsonString the JSON string to be parsed. See {@code BeanEvent}
410      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
411      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
412      */
413     @POST
414     @Path("Event/Create")
415     public ApexApiResult createEvent(final String jsonString) {
416         return processRestCommand(RestCommandType.EVENT, RestCommand.CREATE, jsonString);
417     }
418
419     /**
420      * Update an event with the information in the JSON string passed.
421      *
422      * @param jsonString the JSON string to be parsed. See {@code BeanEvent}
423      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
424      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
425      */
426     @PUT
427     @Path("Event/Update")
428     public ApexApiResult updateEvent(final String jsonString) {
429         return processRestCommand(RestCommandType.EVENT, RestCommand.UPDATE, jsonString);
430     }
431
432     /**
433      * List events with the given key names/versions. If successful the result(s) will be available in the result
434      * messages. The returned value(s) will be similar to {@code AxEvent}, with merged {@code AxKeyInfo} for the root
435      * object.
436      *
437      * @param name the name to search for. If null or empty, then all names will be queried
438      * @param version the version to search for. If null then all versions will be searched for.
439      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
440      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
441      */
442     @GET
443     @Path("Event/Get")
444     public ApexApiResult listEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
445         return processRestCommand(RestCommandType.EVENT, RestCommand.LIST, name, version);
446     }
447
448     /**
449      * Delete events with the given key names/versions.
450      *
451      * @param name the name to search for. If null or empty, then all names will be queried
452      * @param version the version to search for. If null then all versions will be searched for.
453      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
454      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
455      */
456     @DELETE
457     @Path("Event/Delete")
458     public ApexApiResult deleteEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
459         return processRestCommand(RestCommandType.EVENT, RestCommand.DELETE, name, version);
460     }
461
462     /**
463      * Validate events with the given key names/versions. The result(s) will be available in the result messages.
464      *
465      * @param name the name to search for. If null or empty, then all names will be queried
466      * @param version the version to search for. If null then all versions will be searched for.
467      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
468      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
469      */
470     @GET
471     @Path("Validate/Event")
472     public ApexApiResult validateEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
473         return processRestCommand(RestCommandType.EVENT, RestCommand.VALIDATE, name, version);
474     }
475
476     /**
477      * Creates a task with the information in the JSON string passed.
478      *
479      * @param jsonString the JSON string to be parsed. See {@code BeanTask}
480      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
481      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
482      */
483     @POST
484     @Path("Task/Create")
485     public ApexApiResult createTask(final String jsonString) {
486         return processRestCommand(RestCommandType.TASK, RestCommand.CREATE, jsonString);
487     }
488
489     /**
490      * Update a task with the information in the JSON string passed.
491      *
492      * @param jsonString the JSON string to be parsed. See {@code BeanTask}
493      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
494      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
495      */
496     @PUT
497     @Path("Task/Update")
498     public ApexApiResult updateTask(final String jsonString) {
499         return processRestCommand(RestCommandType.TASK, RestCommand.UPDATE, jsonString);
500     }
501
502     /**
503      * List tasks with the given key names/versions. If successful the result(s) will be available in the result
504      * messages. The returned value(s) will be similar to {@code AxTask}, with merged {@code AxKeyInfo} for the root
505      * object.
506      *
507      * @param name the name to search for. If null or empty, then all names will be queried
508      * @param version the version to search for. If null then all versions will be searched for.
509      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
510      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
511      */
512     @GET
513     @Path("Task/Get")
514     public ApexApiResult listTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
515         return processRestCommand(RestCommandType.TASK, RestCommand.LIST, name, version);
516     }
517
518     /**
519      * Delete tasks with the given key names/versions.
520      *
521      * @param name the name to search for. If null or empty, then all names will be queried
522      * @param version the version to search for. If null then all versions will be searched for.
523      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
524      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
525      */
526     @DELETE
527     @Path("Task/Delete")
528     public ApexApiResult deleteTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
529         return processRestCommand(RestCommandType.TASK, RestCommand.DELETE, name, version);
530     }
531
532     /**
533      * Validate tasks with the given key names/versions. The result(s) will be available in the result messages.
534      *
535      * @param name the name to search for. If null or empty, then all names will be queried
536      * @param version the version to search for. If null then all versions will be searched for.
537      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
538      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
539      */
540     @GET
541     @Path("Validate/Task")
542     public ApexApiResult validateTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
543         return processRestCommand(RestCommandType.TASK, RestCommand.VALIDATE, name, version);
544     }
545
546     // CHECKSTYLE:OFF: MethodLength
547     /**
548      * Creates a policy with the information in the JSON string passed.
549      *
550      * @param jsonString the JSON string to be parsed See {@code BeanPolicy}
551      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
552      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
553      */
554     @POST
555     @Path("Policy/Create")
556     public ApexApiResult createPolicy(final String jsonString) {
557         return processRestCommand(RestCommandType.POLICY, RestCommand.CREATE, jsonString);
558     }
559
560     /**
561      * Update a policy with the information in the JSON string passed.
562      *
563      * @param firstStatePeriodic indicates if periodic event should be created and added to model
564      * @param jsonString the JSON string to be parsed. See {@code BeanPolicy}
565      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
566      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
567      */
568     @PUT
569     @Path("Policy/Update")
570     public ApexApiResult updatePolicy(@QueryParam("firstStatePeriodic") final boolean firstStatePeriodic,
571             final String jsonString) {
572
573         ApexApiResult result = processRestCommand(RestCommandType.POLICY, RestCommand.UPDATE, jsonString);
574         if (result != null && result.isOk() && firstStatePeriodic) {
575             result = createPeriodicEvent();
576         }
577         return result;
578     }
579
580     /**
581      * List policies with the given key names/versions. If successful the result(s) will be available in the result
582      * messages. The returned value(s) will be similar to {@code AxPolicy}, with merged {@code AxKeyInfo} for the root
583      * object.
584      *
585      * @param name the name to search for. If null or empty, then all names will be queried
586      * @param version the version to search for. If null then all versions will be searched for.
587      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
588      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
589      */
590     @GET
591     @Path("Policy/Get")
592     public ApexApiResult listPolicy(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
593         return processRestCommand(RestCommandType.POLICY, RestCommand.LIST, name, version);
594     }
595
596     /**
597      * Delete policies with the given key names/versions.
598      *
599      * @param name the name to search for. If null or empty, then all names will be queried
600      * @param version the version to search for. If null then all versions will be searched for.
601      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
602      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
603      */
604     @DELETE
605     @Path("Policy/Delete")
606     public ApexApiResult deletePolicy(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
607         return processRestCommand(RestCommandType.POLICY, RestCommand.DELETE, name, version);
608     }
609
610     /**
611      * This method routes REST commands that take no parameters to their caller.
612      *
613      * @param commandType the type of REST command to process
614      * @param command the REST command to process
615      * @return the result of the REST command
616      */
617     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command) {
618         LOGGER.entry(commandType);
619         try {
620             ApexApiResult result = new ApexApiResult();
621             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
622             if (session == null) {
623                 return result;
624             }
625             result = executeRestCommand(session, commandType, command);
626             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
627             return result;
628         } catch (final Exception e) {
629             LOGGER.catching(e);
630             LOGGER.exit(SESSION_CREATE_NOT_OK);
631             throw e;
632         }
633     }
634
635     /**
636      * This method routes REST commands that take a JSON string to their caller.
637      *
638      * @param commandType the type of REST command to process
639      * @param command the REST command to process
640      * @param jsonString the JSON string received in the REST request
641      * @return the result of the REST command
642      */
643     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command,
644             final String jsonString) {
645         LOGGER.entry(commandType, jsonString);
646         try {
647             ApexApiResult result = new ApexApiResult();
648             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
649             if (session == null) {
650                 return result;
651             }
652             result = executeRestCommand(session, commandType, command, jsonString);
653             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
654             return result;
655         } catch (final Exception e) {
656             LOGGER.catching(e);
657             LOGGER.exit(SESSION_CREATE_NOT_OK);
658             throw e;
659         }
660     }
661
662     /**
663      * This method routes REST commands that take a name and version to their caller.
664      *
665      * @param commandType the type of REST command to process
666      * @param command the REST command to process
667      * @param name the name received in the REST request
668      * @param version the name received in the REST request
669      * @return the result of the REST command
670      */
671     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command,
672             final String name, final String version) {
673         LOGGER.entry(commandType, name, version);
674         try {
675             ApexApiResult result = new ApexApiResult();
676             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
677             if (session == null) {
678                 return result;
679             }
680             result = executeRestCommand(session, commandType, command, name, version);
681             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
682             return result;
683         } catch (final Exception e) {
684             LOGGER.catching(e);
685             LOGGER.exit(SESSION_CREATE_NOT_OK);
686             throw e;
687         }
688     }
689
690     /**
691      * This method invokes callers to run REST commands that take no parameters.
692      *
693      * @param session the Apex editor session
694      * @param commandType the type of REST command to process
695      * @param command the REST command to process
696      * @return the result of the REST command
697      */
698     @Override
699     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
700             final RestCommand command) {
701         switch (commandType) {
702             case MODEL:
703                 return MODEL_HANDLER.executeRestCommand(session, commandType, command);
704             case KEY_INFO:
705                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command);
706             case CONTEXT_SCHEMA:
707                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command);
708             case CONTEXT_ALBUM:
709                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command);
710             case EVENT:
711                 return EVENT_HANDLER.executeRestCommand(session, commandType, command);
712             case TASK:
713                 return TASK_HANDLER.executeRestCommand(session, commandType, command);
714             case POLICY:
715                 return POLICY_HANDLER.executeRestCommand(session, commandType, command);
716             default:
717                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
718         }
719     }
720
721     /**
722      * This method invokes callers to run REST commands that take a JSON string.
723      *
724      * @param session the Apex editor session
725      * @param commandType the type of REST command to process
726      * @param command the REST command to process
727      * @param jsonString the JSON string received in the REST request
728      * @return the result of the REST command
729      */
730     @Override
731     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
732             final RestCommand command, final String jsonString) {
733         switch (commandType) {
734             case MODEL:
735                 return MODEL_HANDLER.executeRestCommand(session, commandType, command, jsonString);
736             case KEY_INFO:
737                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command, jsonString);
738             case CONTEXT_SCHEMA:
739                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command, jsonString);
740             case CONTEXT_ALBUM:
741                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command, jsonString);
742             case EVENT:
743                 return EVENT_HANDLER.executeRestCommand(session, commandType, command, jsonString);
744             case TASK:
745                 return TASK_HANDLER.executeRestCommand(session, commandType, command, jsonString);
746             case POLICY:
747                 return POLICY_HANDLER.executeRestCommand(session, commandType, command, jsonString);
748             default:
749                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
750         }
751     }
752
753     /**
754      * This method invokes callers to run REST commands that take a name and version.
755      *
756      * @param session the Apex editor session
757      * @param commandType the type of REST command to process
758      * @param command the REST command to process
759      * @param name the name received in the REST request
760      * @param version the name received in the REST request
761      * @return the result of the REST command
762      */
763     @Override
764     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
765             final RestCommand command, final String name, final String version) {
766         switch (commandType) {
767             case MODEL:
768                 return MODEL_HANDLER.executeRestCommand(session, commandType, command, name, version);
769             case KEY_INFO:
770                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command, name, version);
771             case CONTEXT_SCHEMA:
772                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command, name, version);
773             case CONTEXT_ALBUM:
774                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command, name, version);
775             case EVENT:
776                 return EVENT_HANDLER.executeRestCommand(session, commandType, command, name, version);
777             case TASK:
778                 return TASK_HANDLER.executeRestCommand(session, commandType, command, name, version);
779             case POLICY:
780                 return POLICY_HANDLER.executeRestCommand(session, commandType, command, name, version);
781             default:
782                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
783         }
784     }
785
786     /**
787      * Create a periodic event from the periodic event template.
788      */
789     private ApexApiResult createPeriodicEvent() {
790         String periodicEventJsonString;
791         try {
792             periodicEventJsonString = TextFileUtils.getTextFileAsString(PERIODIC_EVENT_TEMPLATE);
793         } catch (IOException ioException) {
794             String message = "read of periodic event tempalte from " + PERIODIC_EVENT_TEMPLATE + "failed: "
795                     + ioException.getMessage();
796             LOGGER.debug(message, ioException);
797             return new ApexApiResult(Result.FAILED, message);
798         }
799
800         return processRestCommand(RestCommandType.EVENT, RestCommand.CREATE, periodicEventJsonString);
801     }
802
803     /*
804      * This method is used only for testing and is used to cause an exception on calls from unit test to test exception
805      * handling.
806      */
807     protected static int createCorruptSession() {
808         final ApexEditorRestResource apexEditorRestResource = new ApexEditorRestResource();
809         final ApexApiResult result = apexEditorRestResource.createSession();
810         final int corruptSessionId = Integer.parseInt(result.getMessages().get(0));
811
812         SESSION_HANDLER.setCorruptSession(corruptSessionId);
813
814         return corruptSessionId;
815     }
816
817 }