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