fdd310150b8b7ecd59b9b3bd35d8345f5e23821c
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.client.editor.rest.handling;
22
23 import java.io.IOException;
24
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
36 import org.onap.policy.apex.model.modelapi.ApexApiResult;
37 import org.onap.policy.apex.model.modelapi.ApexApiResult.Result;
38 import org.onap.policy.apex.model.utilities.TextFileUtils;
39 import org.slf4j.ext.XLogger;
40 import org.slf4j.ext.XLoggerFactory;
41
42 /**
43  * The class represents the root resource exposed at the base URL<br> The url to access this resource would be in the
44  * form {@code <baseURL>/rest/<session>/....} <br> For example: a PUT request to the following URL
45  * {@code http://localhost:8080/apex/rest/109/ContextSchema/Update}, with a JSON string payload containing the new
46  * {@code Schema} in the body, can be explained as: <ul> <li>The server or servlet is running at the base URL
47  * {@code http://localhost:8080/apex} <li>This resource {@code ApexRestEditorResource} is used because the path
48  * {@code rest/109} matches the {@code Path} filter specification for this Resource ({@code @Path("rest/{session}")}),
49  * where the {@code int} path parameter {@code session} is assigned the {@code int} value {@code 109} <li>The path
50  * {@code ContextSchema/Update} redirects this call to the method {@link #updateContextSchema(String)}, which should be
51  * a {@link javax.ws.rs.PUT}, with a single String in the body/payload which gets mapped to the single String parameter
52  * for the method. <li>So, in summary, the REST request updates a {@code ContextSchema} as specified in the payload for
53  * {@code session} number {@code 109} </ul>
54  *
55  * <b>Note:</b> An allocated {@code Session} identifier must be included in (almost) all requests. Models for different
56  * {@code Session} identifiers are completely isolated from one another.
57  *
58  * <b>Note:</b> To create a new {@code Session}, and have a new session ID allocated use {@link javax.ws.rs.GET} request
59  * to {@code <baseURL>/rest/-1/Session/Create} (for example: {@code http://localhost:8080/apex/rest/-1/Session/Create} )
60  *
61  */
62 @Path("editor/{session}")
63 @Produces(
64     { MediaType.APPLICATION_JSON })
65 @Consumes(
66     { MediaType.APPLICATION_JSON })
67
68 public class ApexEditorRestResource implements RestCommandHandler {
69     // Get a reference to the logger
70     private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditorRestResource.class);
71
72     // Location of the periodi event template
73     private static final String PERIODIC_EVENT_TEMPLATE = "src/main/resources/templates/PeriodicEventTemplate.json";
74
75     // Recurring string constants
76     private static final String NAME = "name";
77     private static final String VERSION = "version";
78     private static final String REST_COMMAND_NOT_RECOGNISED = "REST command not recognised";
79     private static final String OK = ": OK";
80     private static final String NOT_OK = ": Not OK";
81     private static final String SESSION_CREATE = "Session/Create";
82     private static final String SESSION_CREATE_NOT_OK = "Session/Create: Not OK";
83
84     // The session handler for sessions on the Apex editor
85     private static final RestSessionHandler SESSION_HANDLER = new RestSessionHandler();
86
87     // Handlers for the various parts of an Apex model
88     //@formatter:off
89     private static final ModelHandler         MODEL_HANDLER          = new ModelHandler();
90     private static final KeyInfoHandler       KEY_INFO_HANDLER       = new KeyInfoHandler();
91     private static final ContextSchemaHandler CONTEXT_SCHEMA_HANDLER = new ContextSchemaHandler();
92     private static final ContextAlbumHandler  CONTEXT_ALBUM_HANDLER  = new ContextAlbumHandler();
93     private static final EventHandler         EVENT_HANDLER          = new EventHandler();
94     private static final TaskHandler          TASK_HANDLER           = new TaskHandler();
95     private static final PolicyHandler        POLICY_HANDLER         = new PolicyHandler();
96     //@formatter:on
97
98     // The ID of this session. This gets injected from the URL.
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
204      * root 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      * Delete the model for this session.
233      *
234      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
235      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
236      */
237     @DELETE
238     @Path("Model/Delete")
239     public ApexApiResult deleteModel() {
240         return processRestCommand(RestCommandType.MODEL, RestCommand.DELETE);
241     }
242
243     /**
244      * List key information with the given key names/versions. If successful the result(s) will be available in the
245      * result messages. See {@code AxKeyInfo}
246      *
247      * @param name the name to search for. If null or empty, then all names will be queried
248      * @param version the version to search for. If null then all versions will be searched for.
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     @GET
253     @Path("KeyInformation/Get")
254     public ApexApiResult listKeyInformation(@QueryParam(NAME) final String name,
255                     @QueryParam(VERSION) final String version) {
256         return processRestCommand(RestCommandType.KEY_INFO, RestCommand.LIST, name, version);
257     }
258
259     /**
260      * Creates a context schema with the information in the JSON string passed.
261      *
262      * @param jsonString the JSON string to be parsed. See {@code BeanContextSchema}
263      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
264      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
265      */
266     @POST
267     @Path("ContextSchema/Create")
268     public ApexApiResult createContextSchema(final String jsonString) {
269         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.CREATE, jsonString);
270     }
271
272     /**
273      * Update a context schema with the information in the JSON string passed.
274      *
275      * @param jsonString the JSON string to be parsed. See {@code BeanContextSchema}
276      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
277      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
278      */
279     @PUT
280     @Path("ContextSchema/Update")
281     public ApexApiResult updateContextSchema(final String jsonString) {
282         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.UPDATE, jsonString);
283     }
284
285     /**
286      * List context schemas with the given key names/versions. If successful the result(s) will be available in the
287      * result messages. The returned value(s) will be similar to {@code AxContextSchema}, with merged
288      * {@code AxKeyInfo} for the root object.
289      *
290      * @param name the name to search for. If null or empty, then all names will be queried
291      * @param version the version to search for. If null then all versions will be searched for.
292      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
293      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
294      */
295     @GET
296     @Path("ContextSchema/Get")
297     public ApexApiResult listContextSchemas(@QueryParam(NAME) final String name,
298                     @QueryParam(VERSION) final String version) {
299         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.LIST, name, version);
300     }
301
302     /**
303      * Delete context schemas with the given key names/versions.
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     @DELETE
311     @Path("ContextSchema/Delete")
312     public ApexApiResult deleteContextSchema(@QueryParam(NAME) final String name,
313                     @QueryParam(VERSION) final String version) {
314         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.DELETE, name, version);
315     }
316
317     /**
318      * Validate context schemas with the given key names/versions. The result(s) will be available in the result
319      * messages.
320      *
321      * @param name the name to search for. If null or empty, then all names will be queried
322      * @param version the version to search for. If null then all versions will be searched for.
323      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
324      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
325      */
326     @GET
327     @Path("Validate/ContextSchema")
328     public ApexApiResult validateContextSchemas(@QueryParam(NAME) final String name,
329                     @QueryParam(VERSION) final String version) {
330         return processRestCommand(RestCommandType.CONTEXT_SCHEMA, RestCommand.VALIDATE, name, version);
331     }
332
333     /**
334      * Creates a context album with the information in the JSON string passed.
335      *
336      * @param jsonString the JSON string to be parsed. See {@code BeanContextAlbum}
337      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
338      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
339      */
340     @POST
341     @Path("ContextAlbum/Create")
342     public ApexApiResult createContextAlbum(final String jsonString) {
343         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.CREATE, jsonString);
344     }
345
346     /**
347      * Update a context album with the information in the JSON string passed.
348      *
349      * @param jsonString the JSON string to be parsed. See {@code BeanContextAlbum}
350      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
351      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
352      */
353     @PUT
354     @Path("ContextAlbum/Update")
355     public ApexApiResult updateContextAlbum(final String jsonString) {
356         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.UPDATE, jsonString);
357     }
358
359     /**
360      * List context albums with the given key names/versions. If successful the result(s) will be available in the
361      * result messages. The returned value(s) will be similar to {@code AxContextAlbum}, with merged
362      * {@code AxKeyInfo} for the root object.
363      *
364      * @param name the name to search for. If null or empty, then all names will be queried
365      * @param version the version to search for. If null then all versions will be searched for.
366      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
367      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
368      */
369     @GET
370     @Path("ContextAlbum/Get")
371     public ApexApiResult listContextAlbums(@QueryParam(NAME) final String name,
372                     @QueryParam(VERSION) final String version) {
373         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.LIST, name, version);
374     }
375
376     /**
377      * Delete context albums with the given key names/versions.
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     @DELETE
385     @Path("ContextAlbum/Delete")
386     public ApexApiResult deleteContextAlbum(@QueryParam(NAME) final String name,
387                     @QueryParam(VERSION) final String version) {
388         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.DELETE, name, version);
389     }
390
391     /**
392      * Validate context albums with the given key names/versions. The result(s) will be available in the result
393      * messages.
394      *
395      * @param name the name to search for. If null or empty, then all names will be queried
396      * @param version the version to search for. If null then all versions will be searched for.
397      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
398      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
399      */
400     @GET
401     @Path("Validate/ContextAlbum")
402     public ApexApiResult validateContextAlbums(@QueryParam(NAME) final String name,
403                     @QueryParam(VERSION) final String version) {
404         return processRestCommand(RestCommandType.CONTEXT_ALBUM, RestCommand.VALIDATE, name, version);
405     }
406
407     /**
408      * Creates an event with the information in the JSON string passed.
409      *
410      * @param jsonString the JSON string to be parsed. See {@code BeanEvent}
411      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
412      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
413      */
414     @POST
415     @Path("Event/Create")
416     public ApexApiResult createEvent(final String jsonString) {
417         return processRestCommand(RestCommandType.EVENT, RestCommand.CREATE, jsonString);
418     }
419
420     /**
421      * Update an event with the information in the JSON string passed.
422      *
423      * @param jsonString the JSON string to be parsed. See {@code BeanEvent}
424      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
425      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
426      */
427     @PUT
428     @Path("Event/Update")
429     public ApexApiResult updateEvent(final String jsonString) {
430         return processRestCommand(RestCommandType.EVENT, RestCommand.UPDATE, jsonString);
431     }
432
433     /**
434      * List events with the given key names/versions. If successful the result(s) will be available in the result
435      * messages. The returned value(s) will be similar to {@code AxEvent}, with merged {@code AxKeyInfo} for the
436      * root object.
437      *
438      * @param name the name to search for. If null or empty, then all names will be queried
439      * @param version the version to search for. If null then all versions will be searched for.
440      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
441      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
442      */
443     @GET
444     @Path("Event/Get")
445     public ApexApiResult listEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
446         return processRestCommand(RestCommandType.EVENT, RestCommand.LIST, name, version);
447     }
448
449     /**
450      * Delete events with the given key names/versions.
451      *
452      * @param name the name to search for. If null or empty, then all names will be queried
453      * @param version the version to search for. If null then all versions will be searched for.
454      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
455      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
456      */
457     @DELETE
458     @Path("Event/Delete")
459     public ApexApiResult deleteEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
460         return processRestCommand(RestCommandType.EVENT, RestCommand.DELETE, name, version);
461     }
462
463     /**
464      * Validate events with the given key names/versions. The result(s) will be available in the result messages.
465      *
466      * @param name the name to search for. If null or empty, then all names will be queried
467      * @param version the version to search for. If null then all versions will be searched for.
468      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
469      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
470      */
471     @GET
472     @Path("Validate/Event")
473     public ApexApiResult validateEvent(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
474         return processRestCommand(RestCommandType.EVENT, RestCommand.VALIDATE, name, version);
475     }
476
477     /**
478      * Creates a task with the information in the JSON string passed.
479      *
480      * @param jsonString the JSON string to be parsed. See {@code BeanTask}
481      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
482      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
483      */
484     @POST
485     @Path("Task/Create")
486     public ApexApiResult createTask(final String jsonString) {
487         return processRestCommand(RestCommandType.TASK, RestCommand.CREATE, jsonString);
488     }
489
490     /**
491      * Update a task with the information in the JSON string passed.
492      *
493      * @param jsonString the JSON string to be parsed. See {@code BeanTask}
494      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
495      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
496      */
497     @PUT
498     @Path("Task/Update")
499     public ApexApiResult updateTask(final String jsonString) {
500         return processRestCommand(RestCommandType.TASK, RestCommand.UPDATE, jsonString);
501     }
502
503     /**
504      * List tasks with the given key names/versions. If successful the result(s) will be available in the result
505      * messages. The returned value(s) will be similar to {@code AxTask}, with merged {@code AxKeyInfo} for the
506      * root object.
507      *
508      * @param name the name to search for. If null or empty, then all names will be queried
509      * @param version the version to search for. If null then all versions will be searched for.
510      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
511      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
512      */
513     @GET
514     @Path("Task/Get")
515     public ApexApiResult listTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
516         return processRestCommand(RestCommandType.TASK, RestCommand.LIST, name, version);
517     }
518
519     /**
520      * Delete tasks with the given key names/versions.
521      *
522      * @param name the name to search for. If null or empty, then all names will be queried
523      * @param version the version to search for. If null then all versions will be searched for.
524      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
525      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
526      */
527     @DELETE
528     @Path("Task/Delete")
529     public ApexApiResult deleteTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
530         return processRestCommand(RestCommandType.TASK, RestCommand.DELETE, name, version);
531     }
532
533     /**
534      * Validate tasks with the given key names/versions. The result(s) will be available in the result messages.
535      *
536      * @param name the name to search for. If null or empty, then all names will be queried
537      * @param version the version to search for. If null then all versions will be searched for.
538      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
539      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
540      */
541     @GET
542     @Path("Validate/Task")
543     public ApexApiResult validateTask(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
544         return processRestCommand(RestCommandType.TASK, RestCommand.VALIDATE, name, version);
545     }
546
547     // CHECKSTYLE:OFF: MethodLength
548     /**
549      * Creates a policy with the information in the JSON string passed.
550      *
551      * @param jsonString the JSON string to be parsed See {@code BeanPolicy}
552      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
553      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
554      */
555     @POST
556     @Path("Policy/Create")
557     public ApexApiResult createPolicy(final String jsonString) {
558         return processRestCommand(RestCommandType.POLICY, RestCommand.CREATE, jsonString);
559     }
560
561     /**
562      * Update a policy with the information in the JSON string passed.
563      *
564      * @param firstStatePeriodic indicates if periodic event should be created and added to model
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     @PUT
570     @Path("Policy/Update")
571     public ApexApiResult updatePolicy(@QueryParam("firstStatePeriodic") final boolean firstStatePeriodic,
572                     final String jsonString) {
573
574         ApexApiResult result = processRestCommand(RestCommandType.POLICY, RestCommand.UPDATE, jsonString);
575         if (result != null && result.isOk() && firstStatePeriodic) {
576             result = createPeriodicEvent();
577         }
578         return result;
579     }
580
581     /**
582      * List policies with the given key names/versions. If successful the result(s) will be available in the result
583      * messages. The returned value(s) will be similar to {@code AxPolicy}, with merged {@code AxKeyInfo} for the
584      * root object.
585      *
586      * @param name the name to search for. If null or empty, then all names will be queried
587      * @param version the version to search for. If null then all versions will be searched for.
588      * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any
589      *         messages/errors can be retrieved using {@link ApexApiResult#getMessages()}
590      */
591     @GET
592     @Path("Policy/Get")
593     public ApexApiResult listPolicy(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
594         return processRestCommand(RestCommandType.POLICY, RestCommand.LIST, name, version);
595     }
596
597     /**
598      * Delete policies with the given key names/versions.
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     @DELETE
606     @Path("Policy/Delete")
607     public ApexApiResult deletePolicy(@QueryParam(NAME) final String name, @QueryParam(VERSION) final String version) {
608         return processRestCommand(RestCommandType.POLICY, RestCommand.DELETE, name, version);
609     }
610
611     /**
612      * This method routes REST commands that take no parameters to their caller.
613      * 
614      * @param commandType the type of REST command to process
615      * @param command the REST command to process
616      * @return the result of the REST command
617      */
618     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command) {
619         LOGGER.entry(commandType);
620         try {
621             ApexApiResult result = new ApexApiResult();
622             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
623             if (session == null) {
624                 return result;
625             }
626             result = executeRestCommand(session, commandType, command);
627             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
628             return result;
629         } catch (final Exception e) {
630             LOGGER.catching(e);
631             LOGGER.exit(SESSION_CREATE_NOT_OK);
632             throw e;
633         }
634     }
635
636     /**
637      * This method routes REST commands that take a JSON string to their caller.
638      * 
639      * @param commandType the type of REST command to process
640      * @param command the REST command to process
641      * @param jsonString the JSON string received in the REST request
642      * @return the result of the REST command
643      */
644     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command,
645                     final String jsonString) {
646         LOGGER.entry(commandType, jsonString);
647         try {
648             ApexApiResult result = new ApexApiResult();
649             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
650             if (session == null) {
651                 return result;
652             }
653             result = executeRestCommand(session, commandType, command, jsonString);
654             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
655             return result;
656         } catch (final Exception e) {
657             LOGGER.catching(e);
658             LOGGER.exit(SESSION_CREATE_NOT_OK);
659             throw e;
660         }
661     }
662
663     /**
664      * This method routes REST commands that take a name and version to their caller.
665      * 
666      * @param commandType the type of REST command to process
667      * @param command the REST command to process
668      * @param name the name received in the REST request
669      * @param version the name received in the REST request
670      * @return the result of the REST command
671      */
672     private ApexApiResult processRestCommand(final RestCommandType commandType, final RestCommand command,
673                     final String name, final String version) {
674         LOGGER.entry(commandType, name, version);
675         try {
676             ApexApiResult result = new ApexApiResult();
677             RestSession session = SESSION_HANDLER.getSession(sessionId, result);
678             if (session == null) {
679                 return result;
680             }
681             result = executeRestCommand(session, commandType, command, name, version);
682             LOGGER.exit(SESSION_CREATE + (result != null && result.isOk() ? OK : NOT_OK));
683             return result;
684         } catch (final Exception e) {
685             LOGGER.catching(e);
686             LOGGER.exit(SESSION_CREATE_NOT_OK);
687             throw e;
688         }
689     }
690
691     /**
692      * This method invokes callers to run REST commands that take no parameters.
693      *
694      * @param session the Apex editor session
695      * @param commandType the type of REST command to process
696      * @param command the REST command to process
697      * @return the result of the REST command
698      */
699     @Override
700     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
701                     final RestCommand command) {
702         switch (commandType) {
703             case MODEL:
704                 return MODEL_HANDLER.executeRestCommand(session, commandType, command);
705             case KEY_INFO:
706                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command);
707             case CONTEXT_SCHEMA:
708                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command);
709             case CONTEXT_ALBUM:
710                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command);
711             case EVENT:
712                 return EVENT_HANDLER.executeRestCommand(session, commandType, command);
713             case TASK:
714                 return TASK_HANDLER.executeRestCommand(session, commandType, command);
715             case POLICY:
716                 return POLICY_HANDLER.executeRestCommand(session, commandType, command);
717             default:
718                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
719         }
720     }
721
722     /**
723      * This method invokes callers to run REST commands that take a JSON string.
724      * 
725      * @param session the Apex editor session
726      * @param commandType the type of REST command to process
727      * @param command the REST command to process
728      * @param jsonString the JSON string received in the REST request
729      * @return the result of the REST command
730      */
731     @Override
732     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
733                     final RestCommand command, final String jsonString) {
734         switch (commandType) {
735             case MODEL:
736                 return MODEL_HANDLER.executeRestCommand(session, commandType, command, jsonString);
737             case KEY_INFO:
738                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command, jsonString);
739             case CONTEXT_SCHEMA:
740                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command, jsonString);
741             case CONTEXT_ALBUM:
742                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command, jsonString);
743             case EVENT:
744                 return EVENT_HANDLER.executeRestCommand(session, commandType, command, jsonString);
745             case TASK:
746                 return TASK_HANDLER.executeRestCommand(session, commandType, command, jsonString);
747             case POLICY:
748                 return POLICY_HANDLER.executeRestCommand(session, commandType, command, jsonString);
749             default:
750                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
751         }
752     }
753
754     /**
755      * This method invokes callers to run REST commands that take a name and version.
756      * 
757      * @param session the Apex editor session
758      * @param commandType the type of REST command to process
759      * @param command the REST command to process
760      * @param name the name received in the REST request
761      * @param version the name received in the REST request
762      * @return the result of the REST command
763      */
764     @Override
765     public ApexApiResult executeRestCommand(final RestSession session, final RestCommandType commandType,
766                     final RestCommand command, final String name, final String version) {
767         switch (commandType) {
768             case MODEL:
769                 return MODEL_HANDLER.executeRestCommand(session, commandType, command, name, version);
770             case KEY_INFO:
771                 return KEY_INFO_HANDLER.executeRestCommand(session, commandType, command, name, version);
772             case CONTEXT_SCHEMA:
773                 return CONTEXT_SCHEMA_HANDLER.executeRestCommand(session, commandType, command, name, version);
774             case CONTEXT_ALBUM:
775                 return CONTEXT_ALBUM_HANDLER.executeRestCommand(session, commandType, command, name, version);
776             case EVENT:
777                 return EVENT_HANDLER.executeRestCommand(session, commandType, command, name, version);
778             case TASK:
779                 return TASK_HANDLER.executeRestCommand(session, commandType, command, name, version);
780             case POLICY:
781                 return POLICY_HANDLER.executeRestCommand(session, commandType, command, name, version);
782             default:
783                 return new ApexApiResult(Result.FAILED, REST_COMMAND_NOT_RECOGNISED);
784         }
785     }
786
787     /**
788      * Create a periodic event from the periodic event template.
789      */
790     private ApexApiResult createPeriodicEvent() {
791         String periodicEventJsonString;
792         try {
793             periodicEventJsonString = TextFileUtils.getTextFileAsString(PERIODIC_EVENT_TEMPLATE);
794         } catch (IOException ioException) {
795             String message = "read of periodic event tempalte from " + PERIODIC_EVENT_TEMPLATE + "failed: "
796                             + ioException.getMessage();
797             LOGGER.debug(message, ioException);
798             return new ApexApiResult(Result.FAILED, message);
799         }
800
801         return processRestCommand(RestCommandType.EVENT, RestCommand.CREATE, periodicEventJsonString);
802     }
803     
804     /*
805      * This method is used only for testing and is used to cause an exception on calls from unit test to test exception
806      * handling.
807      */
808     protected static int createCorruptSession() {
809         final ApexEditorRestResource apexEditorRestResource = new ApexEditorRestResource();
810         final ApexApiResult result = apexEditorRestResource.createSession();
811         final int corruptSessionId = Integer.parseInt(result.getMessages().get(0));
812
813         SESSION_HANDLER.setCorruptSession(corruptSessionId);
814
815         return corruptSessionId;
816     }
817
818 }