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