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