Support Utils Libraries for CL Lab Integration
[policy/drools-pdp.git] / policy-management / src / main / java / org / onap / policy / drools / server / restful / RestManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * policy-management
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.drools.server.restful;
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Properties;
29 import java.util.UUID;
30 import java.util.regex.Pattern;
31
32 import javax.ws.rs.Consumes;
33 import javax.ws.rs.DELETE;
34 import javax.ws.rs.DefaultValue;
35 import javax.ws.rs.GET;
36 import javax.ws.rs.POST;
37 import javax.ws.rs.PUT;
38 import javax.ws.rs.Path;
39 import javax.ws.rs.PathParam;
40 import javax.ws.rs.Produces;
41 import javax.ws.rs.QueryParam;
42 import javax.ws.rs.core.MediaType;
43 import javax.ws.rs.core.Response;
44 import javax.ws.rs.core.Response.Status;
45
46 import org.onap.policy.drools.controller.DroolsController;
47 import org.onap.policy.drools.event.comm.TopicEndpoint;
48 import org.onap.policy.drools.event.comm.TopicSink;
49 import org.onap.policy.drools.event.comm.TopicSource;
50 import org.onap.policy.drools.event.comm.bus.DmaapTopicSink;
51 import org.onap.policy.drools.event.comm.bus.DmaapTopicSource;
52 import org.onap.policy.drools.event.comm.bus.UebTopicSink;
53 import org.onap.policy.drools.event.comm.bus.UebTopicSource;
54 import org.onap.policy.drools.features.PolicyControllerFeatureAPI;
55 import org.onap.policy.drools.features.PolicyEngineFeatureAPI;
56 import org.onap.policy.drools.properties.PolicyProperties;
57 import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
58 import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters;
59 import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
60 import org.onap.policy.drools.protocol.coders.JsonProtocolFilter.FilterRule;
61 import org.onap.policy.drools.protocol.coders.ProtocolCoderToolset;
62 import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
63 import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
64 import org.onap.policy.drools.system.PolicyController;
65 import org.onap.policy.drools.system.PolicyEngine;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69 import ch.qos.logback.classic.LoggerContext;
70 import io.swagger.annotations.Api;
71 import io.swagger.annotations.ApiOperation;
72 import io.swagger.annotations.ApiParam;
73 import io.swagger.annotations.ApiResponse;
74 import io.swagger.annotations.ApiResponses;
75 import io.swagger.annotations.Info;
76 import io.swagger.annotations.SwaggerDefinition;
77 import io.swagger.annotations.Tag;
78
79
80 /**
81  * Telemetry JAX-RS Interface to the PDP-D
82  */
83
84 @Path("/policy/pdp")
85 @Produces(MediaType.APPLICATION_JSON)
86 @Consumes(MediaType.APPLICATION_JSON)
87 @Api
88 @SwaggerDefinition(
89     info = @Info(
90         description = "PDP-D Telemetry Services",
91         version = "v1.0",
92         title = "PDP-D Telemetry"
93     ),
94     consumes = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN},
95     produces = {MediaType.APPLICATION_JSON},
96     schemes = {SwaggerDefinition.Scheme.HTTP},
97     tags = {
98         @Tag(name = "pdp-d-telemetry", description = "Drools PDP Telemetry Operations")
99     }
100 )
101 public class RestManager {
102         /**
103          * Logger
104          */
105         private static Logger logger = LoggerFactory.getLogger(RestManager.class);  
106         
107     @GET
108     @Path("engine")
109     @ApiOperation(
110         value="Retrieves the Engine Operational Status", 
111         notes="Top-level abstraction.  Provides a global view of resources",
112         response=PolicyEngine.class
113     )
114     public Response engine() {          
115         return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
116     }
117     
118     @DELETE
119     @Path("engine")
120     @ApiOperation(
121                 value="Shuts down the Engine", 
122                 notes="Deleting the engine, the top-level abstraction, equivalenty shuts it down",
123                 response=PolicyEngine.class
124     )
125     public Response engineShutdown() { 
126         try {
127                         PolicyEngine.manager.shutdown();
128                 } catch (IllegalStateException e) {
129                         logger.error("{}: cannot shutdown {} because of {}", this, PolicyEngine.manager, e.getMessage(), e);
130                 return Response.status(Response.Status.BAD_REQUEST).
131                                 entity(PolicyEngine.manager).
132                                 build();
133                 }
134         
135                 return Response.status(Response.Status.OK).
136                                 entity(PolicyEngine.manager).
137                                 build();
138     }
139     
140     @GET
141     @Path("engine/features")
142     @ApiOperation(
143                 value="Engine Features", 
144                 notes="Provides the list of loaded features using the PolicyEngineFeatureAPI",
145                 responseContainer="List"
146     )
147     public Response engineFeatures() {
148         return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getFeatures()).build();
149     }
150     
151     @GET
152     @Path("engine/features/inventory")
153     @ApiOperation(
154                 value="Engine Detailed Feature Inventory", 
155                 notes="Provides detailed list of loaded features using the PolicyEngineFeatureAPI",
156                 responseContainer="List",
157                 response=PolicyEngineFeatureAPI.class
158     )
159     public Response engineFeaturesInventory() {
160         return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getFeatureProviders()).build();
161     } 
162     
163     @GET
164     @Path("engine/features/{featureName}")
165     @ApiOperation(
166                 value="Engine Feature", 
167                 notes="Provides Details for a given feature Engine Provider",
168                 response=PolicyEngineFeatureAPI.class
169     )
170     @ApiResponses(value = { 
171                 @ApiResponse(code=404, message = "The feature cannot be found")
172     })
173     public Response engineFeature(@ApiParam(value="Feature Name", required=true)  
174                                   @PathParam("featureName") String featureName) {
175         try {
176                 return Response.status(Response.Status.OK).
177                                 entity(PolicyEngine.manager.getFeatureProvider(featureName)).build();
178         } catch(IllegalArgumentException iae) {
179                 logger.debug("feature unavailable: {}", featureName, iae);
180                 return Response.status(Response.Status.NOT_FOUND).
181                     entity(new Error(iae.getMessage())).build();
182         }
183     }
184     
185     @GET
186     @Path("engine/inputs")
187     @ApiOperation(
188                 value="Engine Input Ports", 
189                 notes="List of input ports",
190                 responseContainer="List"
191     )
192     public Response engineInputs() {    
193                 return Response.status(Response.Status.OK).
194                         entity(Arrays.asList(Inputs.values())).
195                         build();
196     }
197     
198     @POST
199     @Path("engine/inputs/configuration")
200     @ApiOperation(
201                 value="Engine Input Configuration Requests", 
202                 notes="Feeds a configuration request input into the Engine"
203     )
204     @ApiResponses(value={
205         @ApiResponse(code=406, message = "The configuration request cannot be honored") 
206     })
207     public Response engineUpdate(
208                 @ApiParam(value="Configuration to apply", required=true) PdpdConfiguration configuration) {
209         PolicyController controller = null;
210         boolean success = true;
211                 try {
212                         success = PolicyEngine.manager.configure(configuration);
213                 } catch (Exception e) {
214                         success = false;
215                         logger.info("{}: cannot configure {} because of {}", this, PolicyEngine.manager, e.getMessage(), e);
216                 }
217         
218                 if (!success)
219                         return Response.status(Response.Status.NOT_ACCEPTABLE).
220                     entity(new Error("cannot perform operation")).build();
221                 else
222                         return Response.status(Response.Status.OK).entity(controller).build();
223     }
224     
225     @GET
226     @Path("engine/properties")
227     @ApiOperation(
228                 value="Engine Configuration Properties", 
229                 notes="Used for booststrapping the engine",
230                 response=Properties.class
231     )
232     public Response engineProperties() {
233         return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getProperties()).build();
234     }
235     
236     @GET
237     @Path("engine/switches")
238     @ApiOperation(
239                 value="Engine Control Switches", 
240                 notes="List of the Engine Control Switches",
241                 responseContainer="List"
242     )
243     public Response engineSwitches() {          
244                 return Response.status(Response.Status.OK).
245                         entity(Arrays.asList(Switches.values())).
246                         build();
247     }
248     
249     @PUT
250     @Path("engine/switches/activation")
251     @ApiOperation(
252                 value="Switches on the Engine Activation Switch", 
253                 notes="Turns on Activation Switch on the Engine. This order entails that the engine " +
254                       "and controllers are unlocked and started",
255                 response=PolicyEngine.class
256     )
257     public Response engineActivation() {
258         boolean success = true;
259                 try {
260                         PolicyEngine.manager.activate();
261                 } catch (Exception e) {
262                         success = false;
263                         logger.info("{}: cannot activate {} because of {}", this, PolicyEngine.manager, e.getMessage(), e);
264                 }
265         
266                 if (!success)
267                         return Response.status(Response.Status.NOT_ACCEPTABLE).
268                     entity(new Error("cannot perform operation")).build();
269                 else
270                         return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
271     }
272     
273     @DELETE
274     @Path("engine/switches/activation")
275     @ApiOperation(
276                 value="Switches off Engine Activation Switch", 
277                 notes="Turns off the Activation Switch on the Engine. This order entails that the engine " +
278                       "and controllers are locked (with the exception of those resources defined as unmanaged)",
279                 response=PolicyEngine.class
280     )
281     public Response engineDeactivation() {
282         boolean success = true;
283                 try {
284                         PolicyEngine.manager.deactivate();
285                 } catch (Exception e) {
286                         success = false;
287                         logger.info("{}: cannot deactivate {} because of {}", this, PolicyEngine.manager, e.getMessage(), e);
288                 }
289         
290                 if (!success)
291                         return Response.status(Response.Status.NOT_ACCEPTABLE).
292                     entity(new Error("cannot perform operation")).build();
293                 else
294                         return Response.status(Response.Status.OK).entity(PolicyEngine.manager).build();
295     }  
296     
297     @PUT
298     @Path("engine/switches/lock")
299     @ApiOperation(
300                 value="Switches on the Engine Lock Control", 
301                 notes="This switch locks all the engine resources as a whole, except those that are defined unmanaged",
302                 response=PolicyEngine.class
303     )
304     @ApiResponses(value = { 
305                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
306                                                "this request to be fulfilled")
307     })
308     public Response engineLock() {
309         boolean success = PolicyEngine.manager.lock();
310         if (success)
311                 return Response.status(Status.OK).
312                                         entity(PolicyEngine.manager).
313                                         build();
314         else
315                 return Response.status(Status.NOT_ACCEPTABLE).
316                                         entity(new Error("cannot perform operation")).
317                                         build();
318     }
319     
320     @DELETE
321     @Path("engine/switches/lock")
322     @ApiOperation(
323                 value="Switches off the Lock control", 
324                 notes="This switch locks all the engine resources as a whole, except those that are defined unmanaged",
325                 response=PolicyEngine.class
326     )  
327     @ApiResponses(value = { 
328                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
329                                                "this request to be fulfilled")
330     })
331     public Response engineUnlock() {
332         boolean success = PolicyEngine.manager.unlock();
333         if (success)
334                 return Response.status(Status.OK).
335                                         entity(PolicyEngine.manager).
336                                         build();
337         else
338                 return Response.status(Status.NOT_ACCEPTABLE).
339                                         entity(new Error("cannot perform operation")).
340                                         build();
341     }
342     
343     @GET
344     @Path("engine/controllers")
345     @ApiOperation(
346                 value="Lists the Policy Controllers Names", 
347                 notes="Unique Policy Controller Identifiers",
348                 responseContainer="List"
349     )
350     public Response controllers() {
351                 return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getPolicyControllerIds()).build();
352     }
353     
354     @GET
355     @Path("engine/controllers/inventory")
356     @ApiOperation(
357                 value="Lists the Policy Controllers", 
358                 notes="Detailed list of Policy Controllers",
359                 responseContainer="List",
360                 response=PolicyController.class
361     )
362     public Response controllerInventory() {
363                 return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getPolicyControllers()).build();
364     }
365     
366     @POST
367     @Path("engine/controllers")
368     @ApiOperation(
369                 value="Creates and starts a new Policy Controller", 
370                 notes="Controller creation based on properties",
371                 response=PolicyController.class
372     )
373     @ApiResponses(value = { 
374                 @ApiResponse(code=400, message = "Invalid configuration information has been provided"),
375         @ApiResponse(code=304, message = "The controller already exists"),
376         @ApiResponse(code=406, message = "The administrative state of the system prevents it " +
377                                          "from processing this request"),
378         @ApiResponse(code=206, message = "The controller has been created " +
379                                           "but cannot be started"),
380         @ApiResponse(code=201, message = "The controller has been succesfully created and started")
381     })
382     public Response controllerAdd(@ApiParam(value="Configuration Properties to apply", required = true) 
383                                   Properties config) {
384         if (config == null)
385                 return Response.status(Response.Status.BAD_REQUEST).
386                                         entity(new Error("A configuration must be provided")).
387                                         build();
388         
389         String controllerName = config.getProperty(PolicyProperties.PROPERTY_CONTROLLER_NAME);
390         if (controllerName == null || controllerName.isEmpty())
391                 return Response.status(Response.Status.BAD_REQUEST).
392                                         entity(new Error
393                                                                 ("Configuration must have an entry for " + 
394                                                      PolicyProperties.PROPERTY_CONTROLLER_NAME)).
395                                         build();
396         
397         PolicyController controller;
398                 try {
399                         controller = PolicyController.factory.get(controllerName);
400                         if (controller != null)
401                                 return Response.status(Response.Status.NOT_MODIFIED).
402                                                         entity(controller).
403                                                         build();
404                 } catch (IllegalArgumentException e) {
405                         // This is OK
406                 } catch (IllegalStateException e) {
407                         logger.info("{}: cannot get policy-controller because of {}", this, e.getMessage(), e);
408                         return Response.status(Response.Status.NOT_ACCEPTABLE).
409                             entity(new Error(controllerName + " not found")).build();
410                 }
411         
412         try {
413                         controller = PolicyEngine.manager.createPolicyController
414                                         (config.getProperty(PolicyProperties.PROPERTY_CONTROLLER_NAME), config);
415                 } catch (IllegalArgumentException | IllegalStateException e) {
416                         logger.warn("{}: cannot create policy-controller because of {}", this, e.getMessage(), e);
417                 return Response.status(Response.Status.BAD_REQUEST).
418                                                                 entity(new Error(e.getMessage())).
419                                                                 build();
420                 }
421         
422         try {
423                         boolean success = controller.start();
424                         if (!success) {
425                                 logger.info("{}: cannot start {}", this, controller);
426                                 return Response.status(Response.Status.PARTIAL_CONTENT).
427                                        entity(new Error(controllerName + " can't be started")).build();
428                         }
429                 } catch (IllegalStateException e) {
430                         logger.info("{}: cannot start {} because of {}", this, controller, e.getMessage(), e);;
431                         return Response.status(Response.Status.PARTIAL_CONTENT).
432                                    entity(controller).build();
433                 }
434         
435                 return Response.status(Response.Status.CREATED).
436                 entity(controller).
437                 build();
438     }  
439     
440     @GET
441     @Path("engine/controllers/features")
442     @ApiOperation(
443                 value="Lists of Feature Providers Identifiers", 
444                 notes="Unique Policy Controller Identifiers",
445                 responseContainer="List"
446     )
447     public Response controllerFeatures() {
448                 return Response.status(Response.Status.OK).entity(PolicyEngine.manager.getFeatures()).build();
449     }
450     
451     @GET
452     @Path("engine/controllers/features/inventory")
453     @ApiOperation(
454                 value="Detailed Controllers Feature Inventory", 
455                 notes="Provides detailed list of loaded features using the PolicyControllerFeatureAPI",
456                 responseContainer="List",
457                 response=PolicyControllerFeatureAPI.class
458     )    
459     public Response controllerFeaturesInventory() {
460                 return Response.status(Response.Status.OK).
461                                         entity(PolicyController.factory.getFeatureProviders()).
462                         build();
463     }
464     
465     @GET
466     @Path("engine/controllers/features/{featureName}")
467     @ApiOperation(
468                 value="Controller Feature", 
469                 notes="Provides Details for a given Policy Controller feature provider",
470                 response=PolicyControllerFeatureAPI.class
471     )
472     @ApiResponses(value = { 
473                 @ApiResponse(code=404, message = "The feature cannot be found")
474     })    
475     public Response controllerFeature(@ApiParam(value="Feature Name", required=true) 
476                                       @PathParam("featureName") String featureName) {
477         try {
478                 return Response.status(Response.Status.OK).
479                                         entity(PolicyController.factory.getFeatureProvider(featureName)).
480                                         build();
481         } catch(IllegalArgumentException iae) {
482                 logger.debug("{}: cannot feature {} because of {}", this, featureName, iae.getMessage(), iae);
483                 return Response.status(Response.Status.NOT_FOUND).
484                     entity(new Error(iae.getMessage())).build();
485         }
486     }
487
488     @GET
489     @Path("engine/controllers/{controller}")
490     @ApiOperation(
491                 value="Retrieves a Policy Controller", 
492                 notes="A Policy Controller is a concrete drools application abstraction.  " +
493                       "It aggregates networking, drools, and other resources," + 
494                       "as provides operational controls over drools applications",
495                 response=PolicyController.class
496     )
497     @ApiResponses(value = { 
498                 @ApiResponse(code=404, message="The controller cannot be found"),
499                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
500                                                  "this request to be fulfilled")
501     }) 
502     public Response controller(@ApiParam(value="Policy Controller Name", required=true) 
503                                @PathParam("controller") String controllerName) {
504                 try {
505                 return Response.status(Response.Status.OK).
506                                         entity(PolicyController.factory.get(controllerName)).
507                                         build();
508                 } catch (IllegalArgumentException e) {
509                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
510                         return Response.status(Response.Status.NOT_FOUND).
511                             entity(new Error(controllerName + " not found")).
512                             build();
513                 } catch (IllegalStateException e) {
514                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
515                         return Response.status(Response.Status.NOT_ACCEPTABLE).
516                             entity(new Error(controllerName + " not acceptable")).
517                             build();
518                 }
519     }
520     
521     @DELETE
522     @Path("engine/controllers/{controller}")
523     @ApiOperation(
524                 value="Deletes a Policy Controller", 
525                 notes="A Policy Controller is a concrete drools application abstraction.  " +
526                       "It aggregates networking, drools, and other resources," + 
527                       "as provides operational controls over drools applications",
528                 response=PolicyController.class
529     )
530     @ApiResponses(value = { 
531                 @ApiResponse(code=404, message="The controller cannot be found"),
532                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
533                                                 "this request to be fulfilled"),
534                 @ApiResponse(code=500, message="A problem has occurred while deleting the Policy Controller")
535     }) 
536     public Response controllerDelete(@ApiParam(value="Policy Controller Name", required=true) 
537                                      @PathParam("controller") String controllerName) {
538         
539         PolicyController controller;
540         try {
541                 controller =
542                                 PolicyController.factory.get(controllerName);
543                 if (controller == null)
544                         return Response.status(Response.Status.BAD_REQUEST).
545                                                 entity(new Error(controllerName + "  does not exist")).
546                                                 build();
547                 } catch (IllegalArgumentException e) {
548                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
549                         return Response.status(Response.Status.BAD_REQUEST).
550                                                                 entity(new Error(controllerName +  " not found: " + e.getMessage())).
551                                                                 build();
552                 } catch (IllegalStateException e) {
553                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
554                         return Response.status(Response.Status.NOT_ACCEPTABLE).
555                                    entity(new Error(controllerName + " not acceptable")).build();
556                 }
557         
558         try {
559                         PolicyEngine.manager.removePolicyController(controllerName);
560                 } catch (IllegalArgumentException | IllegalStateException e) {
561                         logger.debug("{}: cannot remove policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
562                 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
563                                                                entity(new Error(e.getMessage())).
564                                                                build();
565                 }
566         
567                 return Response.status(Response.Status.OK).
568                 entity(controller).
569                 build();
570     }
571     
572     @GET
573     @Path("engine/controllers/{controller}/properties")
574     @ApiOperation(
575                 value="Retrieves the configuration properties of a Policy Controller", 
576                 notes="Configuration resources used by the controller if Properties format",
577                 response=PolicyController.class
578     )
579     @ApiResponses(value = { 
580                 @ApiResponse(code=404, message="The controller cannot be found"),
581                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
582                                                "this request to be fulfilled")
583     }) 
584     public Response controllerProperties(@ApiParam(value="Policy Controller Name", required=true) 
585                                          @PathParam("controller") String controllerName) {
586                 try {
587                         PolicyController controller = PolicyController.factory.get(controllerName);
588                 return Response.status(Response.Status.OK).
589                                         entity(controller.getProperties()).
590                                         build();
591                 } catch (IllegalArgumentException e) {
592                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
593                         return Response.status(Response.Status.NOT_FOUND).
594                             entity(new Error(controllerName + " not found")).
595                             build();
596                 } catch (IllegalStateException e) {
597                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
598                         return Response.status(Response.Status.NOT_ACCEPTABLE).
599                             entity(new Error(controllerName + " not acceptable")).
600                             build();
601                 }
602     }
603     
604     @GET
605     @Path("engine/controllers/{controller}/inputs")
606     @ApiOperation(
607                 value="Policy Controller Input Ports", 
608                 notes="List of input ports",
609                 responseContainer="List"
610     )
611     public Response controllerInputs() {        
612                 return Response.status(Response.Status.OK).
613                         entity(Arrays.asList(Inputs.values())).
614                         build();
615     }
616     
617     @POST
618     @Path("engine/controllers/{controller}/inputs/configuration")
619     @ApiOperation(
620                 value="Policy Controller Input Configuration Requests", 
621                 notes="Feeds a configuration request input into the given Policy Controller"
622     )
623     @ApiResponses(value={
624         @ApiResponse(code=400, message = "The configuration request is invalid"),
625         @ApiResponse(code=406, message = "The configuration request cannot be honored") 
626     })
627     public Response controllerUpdate(@ApiParam(value="Policy Controller Name", required=true) 
628                                      @PathParam("controller") String controllerName,
629                                      @ApiParam(value="Configuration to apply", required=true)
630                                          ControllerConfiguration controllerConfiguration) {
631         
632         if (controllerName == null || controllerName.isEmpty() || 
633             controllerConfiguration == null || 
634             controllerConfiguration.getName().intern() != controllerName)
635                 return Response.status(Response.Status.BAD_REQUEST).
636                                         entity("A valid or matching controller names must be provided").
637                                         build();
638         
639         PolicyController controller;
640         try {
641                 controller = PolicyEngine.manager.updatePolicyController(controllerConfiguration);
642                 if (controller == null)
643                         return Response.status(Response.Status.BAD_REQUEST).
644                                                 entity(new Error(controllerName + "  does not exist")).
645                                                 build();
646                 } catch (IllegalArgumentException e) {
647                         logger.info("{}: cannot update policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
648                         return Response.status(Response.Status.BAD_REQUEST).
649                                                                 entity(new Error(controllerName +  " not found: " + e.getMessage())).
650                                                                 build();
651                 } catch (Exception e) {
652                         logger.info("{}: cannot update policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
653                         return Response.status(Response.Status.NOT_ACCEPTABLE).
654                                    entity(new Error(controllerName + " not acceptable")).build();
655                 }
656         
657                 return Response.status(Response.Status.OK).
658                 entity(controller).
659                 build();
660     }
661     
662     @GET
663     @Path("engine/controllers/{controller}/switches")
664     @ApiOperation(
665                 value="Policy Controller Switches", 
666                 notes="List of the Policy Controller Switches",
667                 responseContainer="List"
668     )
669     public Response controllerSwitches() {      
670                 return Response.status(Response.Status.OK).
671                         entity(Arrays.asList(Switches.values())).
672                         build();
673     }
674     
675     @PUT
676     @Path("engine/controllers/{controller}/switches/lock")
677     @ApiOperation(
678                 value="Switches on the Policy Controller Lock Control", 
679                 notes="This action on the switch locks the Policy Controller",
680                 response=PolicyController.class
681     )   
682     @ApiResponses(value = { 
683                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
684                                                "this request to be fulfilled")
685     })
686     public Response controllerLock(@ApiParam(value="Policy Controller Name", required=true) 
687                                    @PathParam("controller") String controllerName) {
688         PolicyController policyController = PolicyController.factory.get(controllerName);
689         boolean success = policyController.lock();
690         if (success)
691                 return Response.status(Status.OK).
692                                         entity(policyController).
693                                         build();
694         else
695                 return Response.status(Status.NOT_ACCEPTABLE).
696                                         entity(new Error("Controller " + controllerName + " cannot be locked")).
697                                         build();
698     }  
699     
700     @DELETE
701     @Path("engine/controllers/{controller}/switches/lock")
702     @ApiOperation(
703                 value="Switches off the Policy Controller Lock Control", 
704                 notes="This action on the switch unlocks the Policy Controller",
705                 response=PolicyController.class
706     ) 
707     @ApiResponses(value = { 
708                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
709                                                "this request to be fulfilled")
710     })
711     public Response controllerUnlock(@ApiParam(value="Policy Controller Name", required=true) 
712                                      @PathParam("controller") String controllerName) {
713         PolicyController policyController = PolicyController.factory.get(controllerName);
714         boolean success = policyController.unlock();
715         if (success)
716                 return Response.status(Status.OK).
717                                         entity(policyController).
718                                         build();
719         else
720                 return Response.status(Status.NOT_ACCEPTABLE).
721                                         entity(new Error("Controller " + controllerName + " cannot be unlocked")).
722                                         build();
723     }
724     
725     @GET
726     @Path("engine/controllers/{controller}/drools")
727     @ApiOperation(
728                 value="Retrieves the Drools Controller subcomponent of the Policy Controller", 
729                 notes="The Drools Controller provides an abstraction over the Drools subsystem",
730                 response=DroolsController.class
731     )
732     @ApiResponses(value = { 
733                 @ApiResponse(code=404, message="The controller cannot be found"),
734                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
735                                                "this request to be fulfilled")
736     }) 
737     public Response drools(@ApiParam(value="Policy Controller Name", required=true) 
738                            @PathParam("controller") String controllerName) {
739                 try {
740                         DroolsController drools = getDroolsController(controllerName);                  
741                         return Response.status(Response.Status.OK).
742                                        entity(drools).
743                                        build();
744                 } catch (IllegalArgumentException e) {
745                         logger.debug("{}: cannot get drools-controller {} because of {}", this, controllerName, e.getMessage(), e);
746                         return Response.status(Response.Status.NOT_FOUND).
747                             entity(new Error(controllerName + " not found")).
748                             build();
749                 } catch (IllegalStateException e) {
750                         logger.debug("{}: cannot get drools-controller {} because of {}", this, controllerName, e.getMessage(), e);
751                         return Response.status(Response.Status.NOT_ACCEPTABLE).
752                             entity(new Error(controllerName + " not acceptable")).
753                             build();
754                 }
755     }
756     
757     @GET
758     @Path("engine/controllers/{controller}/drools/facts")
759     @ApiOperation(
760                 value="Retrieves Facts Summary information for a given controller", 
761                 notes="Provides the session names, and a count of fact object in the drools working memory",
762                 responseContainer="Map"
763     )
764     @ApiResponses(value = { 
765                 @ApiResponse(code=404, message="The controller cannot be found"),
766                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
767                                                "this request to be fulfilled")
768     })
769     public Response droolsFacts(@ApiParam(value="Policy Controller Name", required=true) 
770                                 @PathParam("controller") String controllerName) {
771                 try {
772                         Map<String,Long> sessionCounts = new HashMap<>(); 
773                         DroolsController drools = getDroolsController(controllerName);
774                         for (String session : drools.getSessionNames()) {
775                                 sessionCounts.put(session, drools.factCount(session));
776                         }
777                         return Response.status(Response.Status.OK).
778                                        entity(sessionCounts).
779                                        build();
780                 } catch (IllegalArgumentException e) {
781                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
782                         return Response.status(Response.Status.NOT_FOUND).
783                             entity(new Error(controllerName + " not found")).
784                             build();
785                 } catch (IllegalStateException e) {
786                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
787                         return Response.status(Response.Status.NOT_ACCEPTABLE).
788                             entity(new Error(controllerName + " not acceptable")).
789                             build();
790                 }
791     }
792     
793     @GET
794     @Path("engine/controllers/{controller}/drools/facts/{session}")
795     @ApiOperation(
796                 value="Retrieves Fact Types (classnames) for a given controller and its count", 
797                 notes="The fact types are the classnames of the objects inserted in the drools working memory",
798                 responseContainer="Map"
799     )
800     @ApiResponses(value = { 
801                 @ApiResponse(code=404, message="The controller or session cannot be found"),
802                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
803                                                "this request to be fulfilled")
804     })
805     public Response droolsFacts(@ApiParam(value="Policy Controller Name", required=true)
806                                 @PathParam("controller") String controllerName,
807                                 @ApiParam(value="Drools Session Name", required=true)
808                                     @PathParam("session") String sessionName) {
809                 try {
810                         DroolsController drools = getDroolsController(controllerName);
811                         return Response.status(Response.Status.OK).
812                                        entity(drools.factClassNames(sessionName)).
813                                        build();
814                 } catch (IllegalArgumentException e) {
815                         logger.debug("{}: cannot get drools-controller {} because of {}", this, controllerName, e.getMessage(), e);
816                         return Response.status(Response.Status.NOT_FOUND).
817                             entity(new Error("entity not found")).
818                             build();
819                 } catch (IllegalStateException e) {
820                         logger.debug("{}: cannot get drools-controller {} because of {}", this, controllerName, e.getMessage(), e);
821                         return Response.status(Response.Status.NOT_ACCEPTABLE).
822                             entity(new Error(controllerName + ":" + sessionName + " not acceptable")).
823                             build();
824                 }
825     }
826     
827     @GET
828     @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
829     @ApiOperation(
830                 value="Retrieves fact objects of a given type in the drools working memory" +
831                   "for a given controller and session", 
832             notes="The fact types are the classnames of the objects inserted in the drools working memory",
833                 responseContainer="List"
834     )
835     @ApiResponses(value = { 
836                 @ApiResponse(code=404, message="The controller, session, or fact type cannot be found"),
837                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
838                                                "this request to be fulfilled")
839     })
840     public Response droolsFacts(@ApiParam(value="Fact count", required=false)
841                                 @DefaultValue("false") @QueryParam("count") boolean count,
842                                 @ApiParam(value="Policy Controller Name", required=true)
843                                     @PathParam("controller") String controllerName,
844                                 @ApiParam(value="Drools Session Name", required=true)
845                                     @PathParam("session") String sessionName,
846                                 @ApiParam(value="Drools Fact Type", required=true)
847                                     @PathParam("factType") String factType) {
848                 try {
849                         DroolsController drools = getDroolsController(controllerName);
850                         List<Object> facts = drools.facts(sessionName, factType, false);
851                         if (!count)
852                                 return Response.status(Response.Status.OK).entity(facts).build();
853                         else
854                                 return Response.status(Response.Status.OK).entity(facts.size()).build();
855                 } catch (IllegalArgumentException e) {
856                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
857                         return Response.status(Response.Status.NOT_FOUND).
858                             entity(new Error(controllerName + ":" + sessionName + ":" + factType + 
859                                                  " not found")).
860                             build();
861                 } catch (IllegalStateException e) {
862                         logger.debug("{}: cannot get policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
863                         return Response.status(Response.Status.NOT_ACCEPTABLE).
864                             entity(new Error(controllerName + ":" + sessionName + ":" + factType + 
865                                                  " not acceptable")).
866                             build();
867                 }
868     }
869     
870     @DELETE
871     @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
872     @ApiOperation(
873                 value="Deletes all the fact objects of a given type from the drools working memory" +
874                   "for a given controller and session.   The objects retracted from the working " +
875                           "memory are provided in the response.", 
876             notes="The fact types are the classnames of the objects inserted in the drools working memory",
877                 responseContainer="List"
878     )
879     @ApiResponses(value = { 
880                 @ApiResponse(code=404, message="The controller, session, or fact type, cannot be found"),
881                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
882                                                "this request to be fulfilled"),
883                 @ApiResponse(code=500, message="A server error has occurred processing this request")
884     })
885     public Response droolsFactsDelete(@ApiParam(value="Policy Controller Name", required=true)
886                                                                       @PathParam("controller") String controllerName,
887                                                                       @ApiParam(value="Drools Session Name", required=true)
888                                                                       @PathParam("session") String sessionName,
889                                                                       @ApiParam(value="Drools Fact Type", required=true)
890                                                                       @PathParam("factType") String factType) {
891                 try {
892                         DroolsController drools = getDroolsController(controllerName);
893                         List<Object> facts = drools.facts(sessionName, factType, true);
894                         return Response.status(Response.Status.OK).entity(facts).build();
895                 } catch (IllegalArgumentException e) {
896                         logger.debug("{}: cannot get: drools-controller {}, session {}, factType {}, because of {}", 
897                                              this, controllerName, sessionName, factType, e.getMessage(), e);
898                         return Response.status(Response.Status.NOT_FOUND).
899                             entity(new Error(controllerName + ":" + sessionName + ":" + factType + 
900                                                  " not found")).
901                             build();
902                 } catch (IllegalStateException e) {
903                         logger.debug("{}: cannot get: drools-controller {}, session {}, factType {}, because of {}", 
904                                          this, controllerName, sessionName, factType, e.getMessage(), e);
905                         return Response.status(Response.Status.NOT_ACCEPTABLE).
906                             entity(new Error(controllerName + ":" + sessionName + ":" + factType + 
907                                                  " not acceptable")).
908                             build();
909                 } catch (Exception e) {
910                         logger.debug("{}: cannot get: drools-controller {}, session {}, factType {}, because of {}", 
911                                          this, controllerName, sessionName, factType, e.getMessage(), e);
912                         return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
913                                     entity(new Error(e.getMessage())).
914                                     build();                    
915                 }
916     }
917     
918     @GET
919     @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
920     @ApiOperation(
921                 value="Gets all the fact objects returned by a DRL query with no parameters from the drools working memory" +
922                   "for a given controller and session", 
923             notes="The DRL query must be defined in the DRL file",
924                 responseContainer="List"
925     )
926     @ApiResponses(value = { 
927                 @ApiResponse(code=404, message="The controller, session, or query information, cannot be found"),
928                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
929                                                "this request to be fulfilled"),
930                 @ApiResponse(code=500, message="A server error has occurred processing this request")
931     })
932     public Response droolsFacts(@ApiParam(value="Fact count", required=false)
933                                 @DefaultValue("false") @QueryParam("count") boolean count,
934                                 @ApiParam(value="Policy Controller Name", required=true)
935                                 @PathParam("controller") String controllerName,
936                                 @ApiParam(value="Drools Session Name", required=true)
937                                 @PathParam("session") String sessionName,
938                                 @ApiParam(value="Query Name Present in DRL", required=true)
939                                 @PathParam("query") String queryName,
940                                 @ApiParam(value="Query Identifier Present in the DRL Query", required=true)
941                                     @PathParam("queriedEntity") String queriedEntity) {
942                 try {
943                         DroolsController drools = getDroolsController(controllerName);
944                         List<Object> facts = drools.factQuery(sessionName, queryName, queriedEntity, false);
945                         if (!count)
946                                 return Response.status(Response.Status.OK).entity(facts).build();
947                         else
948                                 return Response.status(Response.Status.OK).entity(facts.size()).build();
949                 } catch (IllegalArgumentException e) {
950                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {} because of {}", 
951                                          this, controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
952                         return Response.status(Response.Status.NOT_FOUND).
953                             entity(new Error(controllerName + ":" + sessionName + ":" + queryName + 
954                                                  queriedEntity + " not found")).
955                             build();
956                 } catch (IllegalStateException e) {
957                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {} because of {}", 
958                                      this, controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
959                         return Response.status(Response.Status.NOT_ACCEPTABLE).
960                             entity(new Error(controllerName + ":" + sessionName + ":" + queryName + 
961                                                  queriedEntity + " not acceptable")).
962                             build();
963                 } catch (Exception e) {
964                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {} because of {}", 
965                                      this, controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
966                         return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
967                                     entity(new Error(e.getMessage())).
968                                     build();                    
969                 }
970     }
971     
972     @POST
973     @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
974     @ApiOperation(
975                 value="Gets all the fact objects returned by a DRL query with parameters from the drools working memory" +
976                   "for a given controller and session", 
977             notes="The DRL query with parameters must be defined in the DRL file",
978                 responseContainer="List"
979     )
980     @ApiResponses(value = { 
981                 @ApiResponse(code=404, message="The controller, session, or query information, cannot be found"),
982                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
983                                                "this request to be fulfilled"),
984                 @ApiResponse(code=500, message="A server error has occurred processing this request")
985     })
986     public Response droolsFacts(@ApiParam(value="Policy Controller Name", required=true)
987                                 @PathParam("controller") String controllerName,
988                                 @ApiParam(value="Drools Session Name", required=true)
989                                 @PathParam("session") String sessionName,
990                                 @ApiParam(value="Query Name Present in DRL", required=true)
991                                 @PathParam("query") String queryName,
992                                 @ApiParam(value="Query Identifier Present in the DRL Query", required=true)
993                                     @PathParam("queriedEntity") String queriedEntity,
994                                     @ApiParam(value="Query Parameter Values to pass in the DRL Query", required=false)
995                                 List<Object> queryParameters) {
996                 try {
997                         DroolsController drools = getDroolsController(controllerName);
998                         List<Object> facts;
999                         if (queryParameters == null || queryParameters.isEmpty())
1000                                 facts = drools.factQuery(sessionName, queryName, queriedEntity, false);
1001                         else
1002                                 facts = drools.factQuery(sessionName, queryName, queriedEntity, false, queryParameters.toArray());
1003                         return Response.status(Response.Status.OK).entity(facts).build();
1004                 } catch (IllegalArgumentException e) {
1005                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}", 
1006                                  this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
1007                         return Response.status(Response.Status.NOT_FOUND).
1008                             entity(new Error(controllerName + ":" + sessionName + ":" + queryName + 
1009                                                  queriedEntity + " not found")).
1010                             build();
1011                 } catch (IllegalStateException e) {
1012                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}", 
1013                              this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
1014                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1015                             entity(new Error(controllerName + ":" + sessionName + ":" + queryName + 
1016                                                  queriedEntity + " not acceptable")).
1017                             build();
1018                 } catch (Exception e) {
1019                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}", 
1020                              this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
1021                         return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
1022                                     entity(new Error(e.getMessage())).
1023                                     build();                    
1024                 }
1025     }
1026     
1027     @DELETE
1028     @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
1029     @ApiOperation(
1030                 value="Deletes all the fact objects returned by a DRL query with parameters from the drools working memory" +
1031                   "for a given controller and session", 
1032             notes="The DRL query with parameters must be defined in the DRL file",
1033                 responseContainer="List"
1034     )
1035     @ApiResponses(value = { 
1036                 @ApiResponse(code=404, message="The controller, session, or query information, cannot be found"),
1037                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1038                                                "this request to be fulfilled"),
1039                 @ApiResponse(code=500, message="A server error has occurred processing this request")
1040     })
1041     public Response droolsFactsDelete(@ApiParam(value="Policy Controller Name", required=true)
1042                                                                       @PathParam("controller") String controllerName,
1043                                                                       @ApiParam(value="Drools Session Name", required=true)
1044                                                                       @PathParam("session") String sessionName,
1045                                                                       @ApiParam(value="Query Name Present in DRL", required=true)
1046                                                                       @PathParam("query") String queryName,
1047                                                                       @ApiParam(value="Query Identifier Present in the DRL Query", required=true)
1048                                                                       @PathParam("queriedEntity") String queriedEntity,
1049                                                                       @ApiParam(value="Query Parameter Values to pass in the DRL Query", required=false)
1050                                                                       List<Object> queryParameters) {
1051                 try {
1052                         DroolsController drools = getDroolsController(controllerName);
1053                         List<Object> facts;
1054                         if (queryParameters == null || queryParameters.isEmpty())
1055                                 facts = drools.factQuery(sessionName, queryName, queriedEntity, true);
1056                         else
1057                                 facts = drools.factQuery(sessionName, queryName, queriedEntity, true, queryParameters.toArray());                       
1058                         return Response.status(Response.Status.OK).entity(facts).build();
1059                 } catch (IllegalArgumentException e) {
1060                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}", 
1061                              this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
1062                         return Response.status(Response.Status.NOT_FOUND).
1063                             entity(new Error(controllerName + ":" + sessionName + ":" + queryName + 
1064                                                  queriedEntity + " not found")).
1065                             build();
1066                 } catch (IllegalStateException e) {
1067                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}", 
1068                              this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
1069                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1070                             entity(new Error(controllerName + ":" + sessionName + ":" + queryName + 
1071                                                  queriedEntity + " not acceptable")).
1072                             build();
1073                 } catch (Exception e) {
1074                         logger.debug("{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}", 
1075                              this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
1076                         return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
1077                                     entity(new Error(e.getMessage())).
1078                                     build();                    
1079                 }
1080     }
1081     
1082     @POST
1083     @Path("engine/controllers/tools/coders/decoders/filters/rules/{ruleName}")
1084     @ApiOperation(
1085                 value="Produces a Decoder Rule Filter in a format that the Policy Controller can understand", 
1086                 notes="The result can be used with other APIs to attach a filter to a decoder"
1087     )
1088     public Response rules(@ApiParam(value="Negate regex?", required=true)
1089                           @DefaultValue("false") @QueryParam("negate") boolean negate,
1090                               @ApiParam(value="Rule Name", required=true)
1091                               @PathParam("ruleName") String name,
1092                               @ApiParam(value="Regex expression", required=true)
1093                               String regex) {           
1094         String literalRegex = Pattern.quote(regex);
1095         if (negate)
1096                 literalRegex = "^(?!" + literalRegex + "$).*";
1097         
1098                 return Response.status(Status.OK).
1099                                         entity(new JsonProtocolFilter.FilterRule(name,literalRegex)).
1100                                         build();
1101     }
1102     
1103     @GET
1104     @Path("engine/controllers/{controller}/decoders")
1105     @ApiOperation(
1106                 value="Gets all the decoders used by a controller", 
1107             notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
1108                       "subscribed network topics into specific (fact) objects. " +
1109                       "The deserialized (fact) object will typically be inserted in the drools working " +
1110                       " memory of the controlled drools application.",
1111                 responseContainer="List",
1112                 response=ProtocolCoderToolset.class
1113     )
1114     @ApiResponses(value = { 
1115                 @ApiResponse(code=404, message="The controller cannot be found"),
1116                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1117                                                "this request to be fulfilled")
1118     })
1119     public Response decoders(@ApiParam(value="Policy Controller Name", required=true)
1120                              @PathParam("controller") String controllerName) {
1121                 try {
1122                         DroolsController drools = getDroolsController(controllerName);
1123                         List<ProtocolCoderToolset> decoders = EventProtocolCoder.manager.getDecoders
1124                                                                                                                 (drools.getGroupId(), drools.getArtifactId());                  
1125                         return Response.status(Response.Status.OK).
1126                                        entity(decoders).
1127                                        build();
1128                 } catch (IllegalArgumentException e) {
1129                         logger.debug("{}: cannot get decoders for policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
1130                         return Response.status(Response.Status.NOT_FOUND).
1131                             entity(new Error(controllerName + " not found")).
1132                             build();
1133                 } catch (IllegalStateException e) {
1134                         logger.debug("{}: cannot get decoders for policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
1135                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1136                             entity(new Error(controllerName + " not acceptable")).
1137                             build();
1138                 }
1139     }
1140     
1141     @GET
1142     @Path("engine/controllers/{controller}/decoders/filters")
1143     @ApiOperation(
1144                 value="Gets all the filters used by a controller", 
1145             notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
1146                       "subscribed network topics into specific (fact) objects. " +
1147                       "The deserialized (fact) object will typically be inserted in the drools working " +
1148                       " memory of the controlled drools application." +
1149                   "Acceptance filters are used to filter out undesired network messages for the given controller",
1150                 responseContainer="List",
1151                 response=CoderFilters.class
1152     )
1153     @ApiResponses(value = { 
1154         @ApiResponse(code=404, message="The controller cannot be found"),
1155                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1156                                                "this request to be fulfilled")
1157     })
1158     public Response decoderFilters(@ApiParam(value="Policy Controller Name", required=true)
1159                                    @PathParam("controller") String controllerName) {
1160                 try {
1161                         DroolsController drools = getDroolsController(controllerName);
1162                         List<CoderFilters> filters = EventProtocolCoder.manager.getDecoderFilters
1163                                                                                                                 (drools.getGroupId(), drools.getArtifactId());
1164                         return Response.status(Response.Status.OK).
1165                                     entity(filters).
1166                                     build();
1167                 } catch (IllegalArgumentException e) {
1168                         logger.debug("{}: cannot get decoders for policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
1169                         return Response.status(Response.Status.NOT_FOUND).
1170                             entity(new Error(controllerName + " not found")).
1171                             build();
1172                 } catch (IllegalStateException e) {
1173                         logger.debug("{}: cannot get decoders for policy-controller {} because of {}", this, controllerName, e.getMessage(), e);
1174                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1175                             entity(new Error(controllerName + " not acceptable")).
1176                             build();
1177                 }
1178     }
1179     
1180     @GET
1181     @Path("engine/controllers/{controller}/decoders/{topic}")
1182     @ApiOperation(
1183                 value="Gets all the decoders in use by a controller for a networked topic", 
1184             notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
1185                       "subscribed network topics into specific (fact) objects. " +
1186                       "The deserialized (fact) object will typically be inserted in the drools working " +
1187                       " memory of the controlled drools application.",
1188                 responseContainer="List",
1189                 response=ProtocolCoderToolset.class
1190     )
1191     @ApiResponses(value = { 
1192         @ApiResponse(code=404, message="The controller or topic cannot be found"),
1193                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1194                                                "this request to be fulfilled")
1195     })
1196     public Response decoder(@ApiParam(value="Policy Controller Name", required=true)
1197                             @PathParam("controller") String controllerName,
1198                             @ApiParam(value="Networked Topic Name", required=true)
1199                                 @PathParam("topic") String topic) {
1200                 try {
1201                         DroolsController drools = getDroolsController(controllerName);
1202                         ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1203                                                         (drools.getGroupId(), drools.getArtifactId(), topic);
1204                         return Response.status(Response.Status.OK).
1205                                     entity(decoder).
1206                                     build();
1207                 } catch (IllegalArgumentException e) {
1208                         logger.debug("{}: cannot get decoders for policy-controller {} topic {} because of {}", 
1209                                                 this, controllerName, topic, e.getMessage(), e);
1210                         return Response.status(Response.Status.NOT_FOUND).
1211                             entity(new Error(controllerName + ":" + topic + " not found")).
1212                             build();
1213                 } catch (IllegalStateException e) {
1214                         logger.debug("{}: cannot get decoders for policy-controller {} topic {} because of {}", 
1215                                                 this, controllerName, topic, e.getMessage(), e);
1216                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1217                             entity(new Error(controllerName + ":" + topic + " not acceptable")).
1218                             build();
1219                 }
1220     }    
1221     
1222     @GET
1223     @Path("engine/controllers/{controller}/decoders/{topic}/filters")
1224     @ApiOperation(
1225                 value="Gets all filters attached to decoders for a given networked topic in use by a controller", 
1226             notes="A Policy Controller uses decoders to deserialize incoming network messages from " +
1227                       "subscribed network topics into specific (fact) objects. " +
1228                       "The deserialized (fact) object will typically be inserted in the drools working " +
1229                       " memory of the controlled drools application." +
1230                       "Acceptance filters are used to filter out undesired network messages for the given controller",
1231                 responseContainer="List",
1232                 response=CoderFilters.class
1233     )
1234     @ApiResponses(value = { 
1235         @ApiResponse(code=404, message="The controller or topic cannot be found"),
1236                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1237                                                "this request to be fulfilled")
1238     })
1239     public Response decoderFilter(@ApiParam(value="Policy Controller Name", required=true)
1240                                                               @PathParam("controller") String controllerName,
1241                                                               @ApiParam(value="Networked Topic Name", required=true)
1242                                                               @PathParam("topic") String topic) {
1243                 try {
1244                         DroolsController drools = getDroolsController(controllerName);
1245                         ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1246                                                                                                 (drools.getGroupId(), drools.getArtifactId(), topic);
1247                         if (decoder == null)
1248                         return Response.status(Response.Status.BAD_REQUEST).
1249                                         entity(new Error(topic + "  does not exist")).
1250                                         build();
1251                         else
1252                                 return Response.status(Response.Status.OK).
1253                             entity(decoder.getCoders()).
1254                             build();
1255                 } catch (IllegalArgumentException e) {
1256                         logger.debug("{}: cannot get decoders for policy-controller {} topic {} because of {}", 
1257                                                 this, controllerName, topic, e.getMessage(), e);
1258                         return Response.status(Response.Status.NOT_FOUND).
1259                             entity(new Error(controllerName + ":" + topic + " not found")).
1260                             build();
1261                 } catch (IllegalStateException e) {
1262                         logger.debug("{}: cannot get decoders for policy-controller {} topic {} because of {}", 
1263                                                 this, controllerName, topic, e.getMessage(), e);
1264                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1265                             entity(new Error(controllerName + ":" + topic + " not acceptable")).
1266                             build();
1267                 }
1268     }
1269     
1270     @GET
1271     @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
1272     @ApiOperation(
1273                 value="Gets all filters attached to decoders for a given subscribed networked topic " +
1274                   "and fact type", 
1275             notes="Decoders are associated with networked topics. A Policy Controller manages " +
1276                       "multiple topics and therefore its attached decoders. " + 
1277                       "A Policy Controller uses filters to further specify the fact mapping.  " +
1278                       "Filters are applied on a per fact type (classname).",
1279                 responseContainer="List",
1280                 response=CoderFilters.class
1281     )
1282     @ApiResponses(value = { 
1283         @ApiResponse(code=404, message="The controller, topic, or fact type cannot be found"),
1284                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1285                                                "this request to be fulfilled")
1286     })
1287     public Response decoderFilter(@ApiParam(value="Policy Controller Name", required=true)
1288                                   @PathParam("controller") String controllerName,
1289                                   @ApiParam(value="Networked Topic Name", required=true)
1290                                       @PathParam("topic") String topic,
1291                                       @ApiParam(value="Fact Type", required=true)
1292                                       @PathParam("factType") String factClass) {
1293                 try {
1294                         DroolsController drools = getDroolsController(controllerName);
1295                 ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1296                                                                                         (drools.getGroupId(), drools.getArtifactId(), topic);
1297                         CoderFilters filters = decoder.getCoder(factClass);
1298                         if (filters == null)
1299                         return Response.status(Response.Status.BAD_REQUEST).
1300                                         entity(new Error(topic + ":" + factClass + "  does not exist")).
1301                                         build();
1302                         else
1303                                 return Response.status(Response.Status.OK).
1304                         entity(filters).
1305                         build();
1306                 } catch (IllegalArgumentException e) {
1307                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}", 
1308                                                 this, controllerName, topic, factClass, e.getMessage(), e);
1309                         return Response.status(Response.Status.NOT_FOUND).
1310                             entity(new Error(controllerName + ":" + topic + ":" + 
1311                                                          factClass + " not found")).
1312                             build();
1313                 } catch (IllegalStateException e) {
1314                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}", 
1315                                                 this, controllerName, topic, factClass, e.getMessage(), e);
1316                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1317                             entity(new Error(controllerName + ":" + topic + ":" + 
1318                                                          factClass + " not acceptable")).
1319                             build();
1320                 }
1321     }
1322     
1323     @PUT
1324     @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
1325     @ApiOperation(
1326                 value="Attaches filters to the decoder for a given networked topic " +
1327                   "and fact type", 
1328             notes="Decoders are associated with networked topics. A Policy Controller manages " +
1329                       "multiple topics and therefore its attached decoders. " + 
1330                       "A Policy Controller uses filters to further specify the fact mapping.  " +
1331                       "Filters are applied on a per fact type (classname).",
1332                 responseContainer="List",
1333                 response=CoderFilters.class
1334     )
1335     @ApiResponses(value = { 
1336         @ApiResponse(code=404, message="The controller, topic, fact type, cannot be found, " +
1337                                        "or a filter has not been provided"),
1338                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1339                                                "this request to be fulfilled")
1340     })
1341     public Response decoderFilter(@ApiParam(value="Policy Controller Name", required=true)
1342                                                               @PathParam("controller") String controllerName,
1343                                                               @ApiParam(value="Topic Name", required=true)
1344                                                               @PathParam("topic") String topic,
1345                                                               @ApiParam(value="Fact Type", required=true)
1346                                                               @PathParam("factType") String factClass,
1347                                                               @ApiParam(value="Configuration Filter", required=true)
1348                                       JsonProtocolFilter configFilters) {
1349         
1350         if (configFilters == null) {
1351                 return Response.status(Response.Status.BAD_REQUEST).
1352                                         entity(new Error("Configuration Filters not provided")).
1353                                         build();
1354         }
1355         
1356                 try {
1357                         DroolsController drools = getDroolsController(controllerName);
1358                 ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1359                                                                                         (drools.getGroupId(), drools.getArtifactId(), topic);
1360                 CoderFilters filters = decoder.getCoder(factClass);
1361                         if (filters == null)
1362                         return Response.status(Response.Status.BAD_REQUEST).
1363                                         entity(new Error(topic + ":" + factClass + "  does not exist")).
1364                                         build();
1365                         filters.setFilter(configFilters);
1366                         return Response.status(Response.Status.OK).
1367                                     entity(filters).
1368                                     build();
1369                 } catch (IllegalArgumentException e) {
1370                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} filters {} because of {}", 
1371                                                 this, controllerName, topic, factClass, configFilters, e.getMessage(), e);
1372                         return Response.status(Response.Status.NOT_FOUND).
1373                             entity(new Error(controllerName + ":" + topic + ":" + 
1374                                                          factClass + " not found")).
1375                             build();
1376                 } catch (IllegalStateException e) {
1377                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} filters {} because of {}", 
1378                                                 this, controllerName, topic, factClass, configFilters, e.getMessage(), e);
1379                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1380                             entity(new Error(controllerName + ":" + topic + ":" + 
1381                                                          factClass + " not acceptable")).
1382                             build();
1383                 }
1384     }
1385     
1386     @GET
1387     @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules")
1388     @ApiOperation(
1389                 value="Gets the filter rules attached to a topic decoder of a controller", 
1390             notes="Decoders are associated with networked topics. A Policy Controller manages " +
1391                       "multiple topics and therefore its attached decoders. " + 
1392                       "A Policy Controller uses filters to further specify the fact mapping.  " +
1393                       "Filters are applied on a per fact type and are composed of field matching rules. ",
1394                 responseContainer="List",
1395                 response=FilterRule.class
1396     )
1397     @ApiResponses(value = { 
1398         @ApiResponse(code=404, message="The controller, topic, or fact type cannot be found"),
1399                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1400                                                "this request to be fulfilled")
1401     })
1402     public Response decoderFilterRules(@ApiParam(value="Policy Controller Name", required=true)
1403                                                                            @PathParam("controller") String controllerName,
1404                                                                            @ApiParam(value="Topic Name", required=true)
1405                                                                            @PathParam("topic") String topic,
1406                                                                            @ApiParam(value="Fact Type", required=true)
1407                                                                            @PathParam("factType") String factClass) {
1408                 try {
1409                         DroolsController drools = getDroolsController(controllerName);
1410                 ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1411                                                                                         (drools.getGroupId(), drools.getArtifactId(), topic);
1412                 
1413                 CoderFilters filters = decoder.getCoder(factClass);
1414                         if (filters == null)
1415                         return Response.status(Response.Status.BAD_REQUEST).
1416                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  does not exist")).
1417                                         build();
1418                         
1419                         JsonProtocolFilter filter = filters.getFilter();
1420                         if (filter == null)
1421                         return Response.status(Response.Status.BAD_REQUEST).
1422                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  no filters")).
1423                                         build();
1424                         
1425                         return Response.status(Response.Status.OK).
1426                                     entity(filter.getRules()).
1427                                     build();
1428                 } catch (IllegalArgumentException e) {
1429                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}", 
1430                                                 this, controllerName, topic, factClass, e.getMessage(), e);
1431                         return Response.status(Response.Status.NOT_FOUND).
1432                             entity(new Error(controllerName + ":" + topic + ":" + 
1433                                                          factClass + " not found")).
1434                             build();
1435                 } catch (IllegalStateException e) {
1436                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}", 
1437                                         this, controllerName, topic, factClass, e.getMessage(), e);
1438                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1439                             entity(new Error(controllerName + ":" + topic + ":" + 
1440                                                          factClass + " not acceptable")).
1441                             build();
1442                 }
1443     }
1444     
1445     @GET
1446     @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules/{ruleName}")
1447     @ApiOperation(
1448                 value="Gets a filter rule by name attached to a topic decoder of a controller", 
1449             notes="Decoders are associated with networked topics. A Policy Controller manages " +
1450                       "multiple topics and therefore its attached decoders. " + 
1451                       "A Policy Controller uses filters to further specify the fact mapping.  " +
1452                       "Filters are applied on a per fact type and are composed of field matching rules. ",
1453                 responseContainer="List",
1454                 response=FilterRule.class
1455     )
1456     @ApiResponses(value = { 
1457         @ApiResponse(code=404, message="The controller, topic, fact type, or rule name cannot be found"),
1458                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1459                                                "this request to be fulfilled")
1460     })
1461     public Response decoderFilterRules(@ApiParam(value="Policy Controller Name", required=true)
1462                                                                            @PathParam("controller") String controllerName,
1463                                                                            @ApiParam(value="Topic Name", required=true)
1464                                                                            @PathParam("topic") String topic,
1465                                                                            @ApiParam(value="Fact Type", required=true)
1466                                                                            @PathParam("factType") String factClass,
1467                                                                            @ApiParam(value="Rule Name", required=true)
1468                                            @PathParam("ruleName") String ruleName) {
1469                 try {
1470                         DroolsController drools = getDroolsController(controllerName);
1471                 ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1472                                                                                         (drools.getGroupId(), drools.getArtifactId(), topic);
1473                 
1474                 CoderFilters filters = decoder.getCoder(factClass);
1475                         if (filters == null)
1476                         return Response.status(Response.Status.BAD_REQUEST).
1477                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  does not exist")).
1478                                         build();
1479                         
1480                         JsonProtocolFilter filter = filters.getFilter();
1481                         if (filter == null)
1482                         return Response.status(Response.Status.BAD_REQUEST).
1483                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  no filters")).
1484                                         build();
1485                         
1486                         return Response.status(Response.Status.OK).
1487                                     entity(filter.getRules(ruleName)).
1488                                     build();
1489                 } catch (IllegalArgumentException e) {
1490                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", 
1491                                                 this, controllerName, topic, factClass, ruleName, e.getMessage(), e);
1492                         return Response.status(Response.Status.NOT_FOUND).
1493                             entity(new Error(controllerName + ":" + topic + ":" + 
1494                                                          factClass + ": " + ruleName + " not found")).
1495                             build();
1496                 } catch (IllegalStateException e) {
1497                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", 
1498                                                 this, controllerName, topic, factClass, ruleName, e.getMessage(), e);
1499                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1500                             entity(new Error(controllerName + ":" + topic + ":" + 
1501                                                          factClass + ":" + ruleName + " not acceptable")).
1502                             build();
1503                 }
1504     }
1505     
1506     @DELETE
1507     @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules/{ruleName}")
1508     @ApiOperation(
1509                 value="Deletes a filter rule by name attached to a topic decoder of a controller", 
1510             notes="Decoders are associated with networked topics. A Policy Controller manages " +
1511                       "multiple topics and therefore its attached decoders. " + 
1512                       "A Policy Controller uses filters to further specify the fact mapping.  " +
1513                       "Filters are applied on a per fact type and are composed of field matching rules. ",
1514                 responseContainer="List",
1515                 response=FilterRule.class
1516     )
1517     @ApiResponses(value = { 
1518         @ApiResponse(code=404, message="The controller, topic, fact type, or rule name cannot be found"),
1519                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1520                                                "this request to be fulfilled")
1521     })
1522     public Response decoderFilterRuleDelete(@ApiParam(value="Policy Controller Name", required=true)
1523                                                                                     @PathParam("controller") String controllerName,
1524                                                                                     @ApiParam(value="Topic Name", required=true)
1525                                                                                     @PathParam("topic") String topic,
1526                                                                                     @ApiParam(value="Fact Type", required=true)
1527                                                                                     @PathParam("factType") String factClass,
1528                                                                                     @ApiParam(value="Rule Name", required=true)
1529                                                                                 @PathParam("ruleName") String ruleName,
1530                                                                                 @ApiParam(value="Filter Rule", required=true)
1531                                                     FilterRule rule) {
1532                 
1533                 try {
1534                         DroolsController drools = getDroolsController(controllerName);
1535                 ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1536                                                                                         (drools.getGroupId(), drools.getArtifactId(), topic);
1537                 
1538                 CoderFilters filters = decoder.getCoder(factClass);
1539                         if (filters == null)
1540                         return Response.status(Response.Status.BAD_REQUEST).
1541                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  does not exist")).
1542                                         build();
1543                         
1544                         JsonProtocolFilter filter = filters.getFilter();
1545                         if (filter == null)
1546                         return Response.status(Response.Status.BAD_REQUEST).
1547                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  no filters")).
1548                                         build();
1549                         
1550                         if (rule == null) {
1551                                 filter.deleteRules(ruleName);
1552                                 return Response.status(Response.Status.OK).
1553                             entity(filter.getRules()).
1554                             build();            
1555                         }
1556                         
1557                         if (rule.getName() == null || !rule.getName().equals(ruleName))
1558                         return Response.status(Response.Status.BAD_REQUEST).
1559                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + ":" + ruleName + 
1560                                                                  " rule name request inconsistencies (" + rule.getName() + ")")).
1561                                         build();
1562                         
1563                         filter.deleteRule(ruleName, rule.getRegex());
1564                         return Response.status(Response.Status.OK).
1565                                     entity(filter.getRules()).
1566                                     build();
1567                 } catch (IllegalArgumentException e) {
1568                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", 
1569                                                 this, controllerName, topic, factClass, ruleName, e.getMessage(), e);
1570                         return Response.status(Response.Status.NOT_FOUND).
1571                             entity(new Error(controllerName + ":" + topic + ":" + 
1572                                                          factClass + ": " + ruleName + " not found")).
1573                             build();
1574                 } catch (IllegalStateException e) {
1575                         logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", 
1576                                                 this, controllerName, topic, factClass, ruleName, e.getMessage(), e);
1577                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1578                             entity(new Error(controllerName + ":" + topic + ":" + 
1579                                                          factClass + ":" + ruleName + " not acceptable")).
1580                             build();
1581                 }
1582     }
1583     
1584     @PUT
1585     @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules")
1586     @ApiOperation(
1587                 value="Places a new filter rule in a topic decoder", 
1588             notes="Decoders are associated with networked topics. A Policy Controller manages " +
1589                       "multiple topics and therefore its attached decoders. " + 
1590                       "A Policy Controller uses filters to further specify the fact mapping.  " +
1591                       "Filters are applied on a per fact type and are composed of field matching rules. ",
1592                 responseContainer="List",
1593                 response=FilterRule.class
1594     )
1595     @ApiResponses(value = { 
1596         @ApiResponse(code=404, message="The controller, topic, or fact type cannot be found"),
1597                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1598                                                "this request to be fulfilled")
1599     })
1600     public Response decoderFilterRule(@ApiParam(value="Policy Controller Name", required=true)
1601                                                                           @PathParam("controller") String controllerName,
1602                                                                           @ApiParam(value="Topic Name", required=true)
1603                                                                           @PathParam("topic") String topic,
1604                                                                           @ApiParam(value="Fact Type", required=true)
1605                                                                           @PathParam("factType") String factClass,
1606                                                                           @ApiParam(value="Rule Name", required=true)
1607                                                                           @PathParam("ruleName") String ruleName,
1608                                                                           @ApiParam(value="Filter Rule", required=true)
1609                                                                           FilterRule rule) {
1610                 
1611                 try {
1612                         DroolsController drools = getDroolsController(controllerName);
1613                 ProtocolCoderToolset decoder = EventProtocolCoder.manager.getDecoders
1614                                                                                         (drools.getGroupId(), drools.getArtifactId(), topic);
1615                 
1616                 CoderFilters filters = decoder.getCoder(factClass);
1617                         if (filters == null)
1618                         return Response.status(Response.Status.BAD_REQUEST).
1619                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  does not exist")).
1620                                         build();
1621                         
1622                         JsonProtocolFilter filter = filters.getFilter();
1623                         if (filter == null)
1624                         return Response.status(Response.Status.BAD_REQUEST).
1625                                         entity(new Error(controllerName + ":" + topic + ":" + factClass + "  no filters")).
1626                                         build();
1627                         
1628                         if (rule.getName() == null)
1629                         return Response.status(Response.Status.BAD_REQUEST).
1630                                         entity(new Error(controllerName + ":" + topic + ":" + factClass +  
1631                                                                  " rule name request inconsistencies (" + rule.getName() + ")")).
1632                                         build();
1633                         
1634                         filter.addRule(rule.getName(), rule.getRegex());
1635                         return Response.status(Response.Status.OK).
1636                                     entity(filter.getRules()).
1637                                     build();
1638                 } catch (IllegalArgumentException e) {
1639                         logger.debug("{}: cannot access decoder filter rules for policy-controller {} topic {} type {} rule {} because of {}", 
1640                                                 this, controllerName, topic, factClass, ruleName, e.getMessage(), e);
1641                         return Response.status(Response.Status.NOT_FOUND).
1642                             entity(new Error(controllerName + ":" + topic + ":" + 
1643                                                          factClass + " not found")).
1644                             build();
1645                 } catch (IllegalStateException e) {
1646                         logger.debug("{}: cannot access decoder filter rules for policy-controller {} topic {} type {} rule {} because of {}", 
1647                                                 this, controllerName, topic, factClass, ruleName, e.getMessage(), e);
1648                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1649                             entity(new Error(controllerName + ":" + topic + ":" + 
1650                                                          factClass + " not acceptable")).
1651                             build();
1652                 }
1653     }
1654     
1655     @POST
1656     @Path("engine/controllers/{controller}/decoders/{topic}")
1657     @Consumes(MediaType.TEXT_PLAIN)
1658     @ApiOperation(
1659                 value="Decodes a string into a fact object, and encodes it back into a string", 
1660             notes="Tests the decode/encode functions of a controller",
1661                 response=CodingResult.class
1662     )
1663     @ApiResponses(value = { 
1664         @ApiResponse(code=400, message="Bad input has been provided"),
1665         @ApiResponse(code=404, message="The controller cannot be found"),
1666                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1667                                                "this request to be fulfilled")
1668     })
1669     public Response decode(@ApiParam(value="Policy Controller Name", required=true)
1670                            @PathParam("controller") String controllerName,
1671                            @ApiParam(value="Topic Name", required=true)
1672                                            @PathParam("topic") String topic,
1673                                            @ApiParam(value="JSON String to decode", required=true)
1674                                String json) {
1675         
1676         PolicyController policyController;
1677                 try {
1678                         policyController = PolicyController.factory.get(controllerName);
1679                 } catch (IllegalArgumentException e) {
1680                         logger.debug("{}: cannot get decoders for policy-controller {} topic {} because of {}", 
1681                                                 this, controllerName, topic, e.getMessage(), e);
1682                         return Response.status(Response.Status.NOT_FOUND).
1683                             entity(new Error(controllerName + ":" + topic + ":" +
1684                                                          " not found")).
1685                             build();
1686                 } catch (IllegalStateException e) {
1687                         logger.debug("{}: cannot get decoders for policy-controller {} topic {} because of {}", 
1688                                                 this, controllerName, topic, e.getMessage(), e);
1689                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1690                             entity(new Error(controllerName + ":" + topic + ":" + 
1691                                                          " not acceptable")).
1692                             build();
1693                 }
1694         
1695         CodingResult result = new CodingResult();
1696                 result.decoding = false;
1697                 result.encoding = false;
1698                 result.jsonEncoding = null;
1699
1700                 Object event;
1701         try {
1702                 event = EventProtocolCoder.manager.decode
1703                                         (policyController.getDrools().getGroupId(), 
1704                                          policyController.getDrools().getArtifactId(), 
1705                                          topic, 
1706                                          json);
1707                 result.decoding = true;
1708         } catch (Exception e) {
1709                         logger.debug("{}: cannot get policy-controller {} topic {} because of {}", 
1710                                                 this, controllerName, topic, e.getMessage(), e);
1711                 return Response.status(Response.Status.BAD_REQUEST).
1712                                 entity(new Error(e.getMessage())).
1713                                 build();
1714         }
1715         
1716         try {
1717                 result.jsonEncoding = EventProtocolCoder.manager.encode(topic, event);
1718                 result.encoding = true;
1719         } catch (Exception e) {
1720                 // continue so to propagate decoding results ..
1721                         logger.debug("{}: cannot encode for policy-controller {} topic {} because of {}", 
1722                                         this, controllerName, topic, e.getMessage(), e);
1723         } 
1724         
1725                 return Response.status(Response.Status.OK).
1726                 entity(result).
1727                 build();
1728     }
1729     
1730     @GET
1731     @Path("engine/controllers/{controller}/encoders")
1732     @ApiOperation(
1733                 value="Retrieves the encoder filters of a controller", 
1734             notes="The encoders serializes a fact object, typically for network transmission",
1735             responseContainer="List",
1736                 response=CoderFilters.class
1737     )
1738     @ApiResponses(value = { 
1739         @ApiResponse(code=400, message="Bad input has been provided"),
1740                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1741                                                "this request to be fulfilled")
1742     })
1743     public Response encoderFilters(@ApiParam(value="Policy Controller Name", required=true)
1744                                    @PathParam("controller") String controllerName) {    
1745                 List<CoderFilters> encoders;
1746                 try {
1747                         PolicyController controller = PolicyController.factory.get(controllerName);
1748                         DroolsController drools = controller.getDrools();
1749                         encoders = EventProtocolCoder.manager.getEncoderFilters
1750                                                         (drools.getGroupId(), drools.getArtifactId());
1751                 } catch (IllegalArgumentException e) {
1752                         logger.debug("{}: cannot get encoder filters for policy-controller {} because of {}", 
1753                                         this, controllerName, e.getMessage(), e);
1754                         return Response.status(Response.Status.BAD_REQUEST).
1755                                                        entity(new Error(controllerName +  " not found: " + e.getMessage())).
1756                                                        build();
1757                 } catch (IllegalStateException e) {
1758                         logger.debug("{}: cannot get encoder filters for policy-controller {} because of {}", 
1759                                                 this, controllerName, e.getMessage(), e);
1760                         return Response.status(Response.Status.NOT_ACCEPTABLE).
1761                             entity(new Error(controllerName + " is not accepting the request")).build();
1762                 }
1763                 
1764                 return Response.status(Response.Status.OK).
1765                                entity(encoders).
1766                                build();
1767     }
1768     
1769         @GET
1770     @Path("engine/topics")
1771     @ApiOperation(
1772                 value="Retrieves the managed topics", 
1773             notes="Network Topics Aggregation",
1774                 response=TopicEndpoint.class
1775     )
1776     public Response topics() {
1777                 return Response.status(Response.Status.OK).
1778                                         entity(TopicEndpoint.manager).
1779                                         build();
1780     }
1781         
1782     @GET
1783     @Path("engine/topics/switches")
1784     @ApiOperation(
1785                 value="Topics Control Switches", 
1786                 notes="List of the Topic Control Switches",
1787                 responseContainer="List"
1788     )
1789     public Response topicSwitches() {   
1790                 return Response.status(Response.Status.OK).
1791                         entity(Arrays.asList(Switches.values())).
1792                         build();
1793     }
1794     
1795     @PUT
1796     @Path("engine/topics/switches/lock")
1797     @ApiOperation(
1798                 value="Locks all the managed topics", 
1799                 notes="The operation affects all managed sources and sinks",
1800                 response=TopicEndpoint.class
1801     )
1802     @ApiResponses(value = { 
1803                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1804                                                "this request to be fulfilled")
1805     })
1806     public Response topicsLock() {
1807         boolean success = TopicEndpoint.manager.lock();
1808                 if (success)
1809                         return Response.status(Status.OK).
1810                                                 entity(TopicEndpoint.manager).
1811                                                 build();
1812                 else
1813                         return Response.status(Status.NOT_ACCEPTABLE).
1814                                                 entity(new Error("cannot perform operation")).
1815                                                 build();
1816     }
1817     
1818     @DELETE
1819         @Path("engine/topics/switches/lock")
1820     @ApiOperation(
1821                 value="Unlocks all the managed topics", 
1822                 notes="The operation affects all managed sources and sinks",
1823                 response=TopicEndpoint.class
1824     )
1825     @ApiResponses(value = { 
1826                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
1827                                                "this request to be fulfilled")
1828     })
1829         public Response topicsUnlock() {
1830                 boolean success = TopicEndpoint.manager.unlock();
1831                 if (success)
1832                         return Response.status(Status.OK).
1833                                                 entity(TopicEndpoint.manager).
1834                                                 build();
1835                 else
1836                         return Response.status(Status.NOT_ACCEPTABLE).
1837                                                 entity(new Error("cannot perform operation")).
1838                                                 build();
1839         }
1840     
1841         @GET
1842     @Path("engine/topics/sources")
1843     @ApiOperation(
1844                 value="Retrieves the managed topic sources", 
1845             notes="Network Topic Sources Agregation",
1846             responseContainer="List",
1847                 response=TopicSource.class
1848     )
1849     public Response sources() {
1850         return Response.status(Response.Status.OK).
1851                                 entity(TopicEndpoint.manager.getTopicSources()).
1852                                 build();
1853     }
1854     
1855         @GET
1856     @Path("engine/topics/sinks")
1857     @ApiOperation(
1858                 value="Retrieves the managed topic sinks", 
1859             notes="Network Topic Sinks Agregation",
1860             responseContainer="List",
1861                 response=TopicSink.class
1862     )
1863     public Response sinks() {
1864         return Response.status(Response.Status.OK).
1865                                 entity(TopicEndpoint.manager.getTopicSinks()).
1866                                 build();
1867     }
1868     
1869         @GET
1870     @Path("engine/topics/sources/ueb")
1871     @ApiOperation(
1872                 value="Retrieves the UEB managed topic sources", 
1873             notes="UEB Topic Sources Agregation",
1874             responseContainer="List",
1875                 response=UebTopicSource.class
1876     )
1877     public Response uebSources() {
1878         return Response.status(Response.Status.OK).
1879                                 entity(TopicEndpoint.manager.getUebTopicSources()).
1880                                 build();
1881     }
1882     
1883         @GET
1884     @Path("engine/topics/sinks/ueb")
1885     @ApiOperation(
1886                 value="Retrieves the UEB managed topic sinks", 
1887             notes="UEB Topic Sinks Agregation",
1888             responseContainer="List",
1889                 response=UebTopicSource.class
1890     )
1891     public Response uebSinks() {
1892         return Response.status(Response.Status.OK).
1893                                 entity(TopicEndpoint.manager.getUebTopicSinks()).
1894                                 build();
1895     }
1896     
1897         @GET
1898     @Path("engine/topics/sources/dmaap")
1899     @ApiOperation(
1900                 value="Retrieves the DMaaP managed topic sources", 
1901             notes="DMaaP Topic Sources Agregation",
1902             responseContainer="List",
1903                 response=DmaapTopicSource.class
1904     )
1905     public Response dmaapSources() {
1906         return Response.status(Response.Status.OK).
1907                                 entity(TopicEndpoint.manager.getDmaapTopicSources()).
1908                                 build();
1909     }
1910     
1911         @GET
1912     @Path("engine/topics/sinks/dmaap")
1913     @ApiOperation(
1914                 value="Retrieves the DMaaP managed topic sinks", 
1915             notes="DMaaP Topic Sinks Agregation",
1916             responseContainer="List",
1917                 response=DmaapTopicSink.class
1918     )
1919     public Response dmaapSinks() {
1920         return Response.status(Response.Status.OK).
1921                                 entity(TopicEndpoint.manager.getDmaapTopicSinks()).
1922                                 build();
1923     }
1924     
1925     @GET
1926     @Path("engine/topics/sources/ueb/{topic}")
1927     @ApiOperation(
1928                 value="Retrieves an UEB managed topic source", 
1929             notes="This is an UEB Network Communicaton Endpoint source of messages for the Engine",
1930                 response=UebTopicSource.class
1931     )
1932     public Response uebSourceTopic(@ApiParam(value="Topic Name", required=true)
1933                                    @PathParam("topic") String topic) {
1934         return Response.status(Response.Status.OK).
1935                                 entity(TopicEndpoint.manager.getUebTopicSource(topic)).
1936                                 build();
1937     }
1938     
1939     @GET
1940     @Path("engine/topics/sinks/ueb/{topic}")
1941     @ApiOperation(
1942                 value="Retrieves an UEB managed topic sink", 
1943             notes="This is an UEB Network Communicaton Endpoint destination of messages from the Engine",
1944                 response=UebTopicSink.class
1945     )
1946     public Response uebSinkTopic(@ApiParam(value="Topic Name", required=true) 
1947                                  @PathParam("topic") String topic) {
1948         return Response.status(Response.Status.OK).
1949                                 entity(TopicEndpoint.manager.getUebTopicSink(topic)).
1950                                 build();
1951     }
1952     
1953     @GET
1954     @Path("engine/topics/sources/dmaap/{topic}")
1955     @ApiOperation(
1956                 value="Retrieves a DMaaP managed topic source", 
1957             notes="This is a DMaaP Network Communicaton Endpoint source of messages for the Engine",
1958                 response=DmaapTopicSource.class
1959     )
1960     public Response dmaapSourceTopic(@ApiParam(value="Topic Name", required=true) 
1961                                      @PathParam("topic") String topic) {
1962         return Response.status(Response.Status.OK).
1963                         entity(TopicEndpoint.manager.getDmaapTopicSource(topic)).
1964                         build();
1965     }
1966     
1967     @GET
1968     @Path("engine/topics/sinks/dmaap/{topic}")
1969     @ApiOperation(
1970                 value="Retrieves a DMaaP managed topic sink", 
1971             notes="This is a DMaaP Network Communicaton Endpoint destination of messages from the Engine",
1972                 response=DmaapTopicSink.class
1973     )
1974     public Response dmaapSinkTopic(@ApiParam(value="Topic Name", required=true)
1975                                    @PathParam("topic") String topic) {
1976         return Response.status(Response.Status.OK).
1977                                 entity(TopicEndpoint.manager.getDmaapTopicSink(topic)).
1978                                 build();
1979     }
1980     
1981     @GET
1982     @Path("engine/topics/sources/ueb/{topic}/events")
1983     @ApiOperation(
1984                 value="Retrieves the latest events received by an UEB topic", 
1985             notes="This is a UEB Network Communicaton Endpoint source of messages for the Engine",
1986             responseContainer="List"
1987     )
1988     public Response uebSourceEvents(@ApiParam(value="Topic Name", required=true)
1989                                     @PathParam("topic") String topic) {
1990                 return Response.status(Status.OK).
1991                                 entity(Arrays.asList(TopicEndpoint.manager.getUebTopicSource(topic).getRecentEvents())).
1992                                 build();
1993     }
1994     
1995     @GET
1996     @Path("engine/topics/sinks/ueb/{topic}/events")
1997     @ApiOperation(
1998                 value="Retrieves the latest events sent from a topic", 
1999             notes="This is a UEB Network Communicaton Endpoint sink of messages from the Engine",
2000             responseContainer="List"
2001     )
2002     public Response uebSinkEvents(@ApiParam(value="Topic Name", required=true)
2003                                   @PathParam("topic") String topic) {
2004                 return Response.status(Status.OK).
2005                                         entity(Arrays.asList(TopicEndpoint.manager.getUebTopicSink(topic).getRecentEvents())).
2006                                         build();
2007     }
2008     
2009     @GET
2010     @Path("engine/topics/sources/dmaap/{topic}/events")
2011     @ApiOperation(
2012                 value="Retrieves the latest events received by a DMaaP topic", 
2013             notes="This is a DMaaP Network Communicaton Endpoint source of messages for the Engine",
2014             responseContainer="List"
2015     )
2016     public Response dmaapSourceEvents(@ApiParam(value="Topic Name", required=true)
2017                                       @PathParam("topic") String topic) {       
2018                 return Response.status(Status.OK).
2019                 entity(Arrays.asList(TopicEndpoint.manager.getDmaapTopicSource(topic).getRecentEvents())).
2020                 build();
2021     }
2022     
2023     @GET
2024     @Path("engine/topics/sinks/dmaap/{topic}/events")
2025     @ApiOperation(
2026                 value="Retrieves the latest events send through a DMaaP topic", 
2027             notes="This is a DMaaP Network Communicaton Endpoint destination of messages from the Engine",
2028             responseContainer="List"
2029     )
2030     public Response dmaapSinkEvents(
2031                                     @PathParam("topic") String topic) {         
2032                 return Response.status(Status.OK).
2033                 entity(Arrays.asList(TopicEndpoint.manager.getDmaapTopicSink(topic).getRecentEvents())).
2034                 build();
2035     }
2036     
2037     @GET
2038     @Path("engine/topics/sources/ueb/{topic}/switches")
2039     @ApiOperation(
2040                 value="UEB Topic Control Switches", 
2041                 notes="List of the UEB Topic Control Switches",
2042                 responseContainer="List"
2043     )
2044     public Response uebTopicSwitches() {        
2045                 return Response.status(Response.Status.OK).
2046                         entity(Arrays.asList(Switches.values())).
2047                         build();
2048     }
2049     
2050     @PUT
2051     @Path("engine/topics/sources/ueb/{topic}/switches/lock")
2052     @ApiOperation(
2053                 value="Locks an UEB Source topic", 
2054                 response=UebTopicSource.class
2055     )
2056     @ApiResponses(value = { 
2057                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
2058                                                "this request to be fulfilled")
2059     })
2060     public Response uebTopicLock(@ApiParam(value="Topic Name", required=true)
2061                                  @PathParam("topic") String topic) {
2062         UebTopicSource source = TopicEndpoint.manager.getUebTopicSource(topic);         
2063         boolean success = source.lock();
2064         if (success)
2065                 return Response.status(Status.OK).
2066                                         entity(source).
2067                                         build();
2068         else
2069                 return Response.status(Status.NOT_ACCEPTABLE).
2070                                         entity(new Error("cannot perform operation on " + topic)).
2071                                         build();
2072     }
2073     
2074     @DELETE
2075     @Path("engine/topics/sources/ueb/{topic}/switches/lock")
2076     @ApiOperation(
2077                 value="Unlocks an UEB Source topic", 
2078                 response=UebTopicSource.class
2079     )
2080     @ApiResponses(value = { 
2081                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
2082                                                "this request to be fulfilled")
2083     })
2084     public Response uebTopicUnlock(@ApiParam(value="Topic Name", required=true)
2085                                    @PathParam("topic") String topic) {
2086         UebTopicSource source = TopicEndpoint.manager.getUebTopicSource(topic);         
2087         boolean success = source.unlock();
2088         if (success)
2089                 return Response.status(Status.OK).
2090                                         entity(source).
2091                                         build();
2092         else
2093                 return Response.status(Status.NOT_ACCEPTABLE).
2094                                         entity(new Error("cannot perform operation on " + topic)).
2095                                         build();
2096     }
2097     
2098     @GET
2099     @Path("engine/topics/sources/dmaap/{topic}/switches")
2100     @ApiOperation(
2101                 value="DMaaP Topic Control Switches", 
2102                 notes="List of the DMaaP Topic Control Switches",
2103                 responseContainer="List"
2104     )
2105     public Response dmaapTopicSwitches() {      
2106                 return Response.status(Response.Status.OK).
2107                         entity(Arrays.asList(Switches.values())).
2108                         build();
2109     }
2110     
2111     @PUT
2112     @Path("engine/topics/sources/dmaap/{topic}/switches/lock")
2113     @ApiOperation(
2114                 value="Locks an DMaaP Source topic", 
2115                 response=DmaapTopicSource.class
2116     )
2117     @ApiResponses(value = { 
2118                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
2119                                                "this request to be fulfilled")
2120     })
2121     public Response dmmapTopicLock(@ApiParam(value="Topic Name", required=true)
2122                                    @PathParam("topic") String topic) {
2123         DmaapTopicSource source = TopicEndpoint.manager.getDmaapTopicSource(topic);     
2124         boolean success = source.lock();
2125         if (success)
2126                 return Response.status(Status.OK).
2127                                         entity(source).
2128                                         build();
2129         else
2130                 return Response.status(Status.NOT_ACCEPTABLE).
2131                                         entity(new Error("cannot perform operation on " + topic)).
2132                                         build();
2133     }
2134     
2135     @DELETE
2136     @Path("engine/topics/sources/dmaap/{topic}/switches/lock")
2137     @ApiOperation(
2138                 value="Unlocks an DMaaP Source topic", 
2139                 response=DmaapTopicSource.class
2140     )
2141     @ApiResponses(value = { 
2142                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
2143                                                "this request to be fulfilled")
2144     })
2145     public Response dmaapTopicUnlock(@ApiParam(value="Topic Name", required=true)
2146                                      @PathParam("topic") String topic) {
2147         DmaapTopicSource source = TopicEndpoint.manager.getDmaapTopicSource(topic);     
2148         boolean success = source.unlock();
2149         if (success)
2150                 return Response.status(Status.OK).
2151                                         entity(source).
2152                                         build();
2153         else
2154                 return Response.status(Status.SERVICE_UNAVAILABLE).
2155                                         entity(new Error("cannot perform operation on " + topic)).
2156                                         build();
2157     }
2158     
2159     @PUT
2160     @Path("engine/topics/sources/ueb/{topic}/events")
2161     @Consumes(MediaType.TEXT_PLAIN)
2162     @ApiOperation(
2163                 value="Offers an event to an UEB topic for internal processing by the engine", 
2164                 notes="The offered event is treated as it was incoming from the network",
2165                 responseContainer="List"
2166     )
2167     @ApiResponses(value = { 
2168                 @ApiResponse(code=404, message="The topic information cannot be found"),
2169                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
2170                                                "this request to be fulfilled"),
2171                 @ApiResponse(code=500, message="A server error has occurred processing this request")
2172     })
2173     public Response uebOffer(@ApiParam(value="Topic Name", required=true)
2174                              @PathParam("topic") String topic,
2175                              @ApiParam(value="Network Message", required=true)
2176                                  String json) {
2177         try {
2178                         UebTopicSource uebReader = TopicEndpoint.manager.getUebTopicSource(topic);
2179                         boolean success = uebReader.offer(json);
2180                         if (success)
2181                                 return Response.status(Status.OK).
2182                                                         entity(Arrays.asList(TopicEndpoint.manager.getUebTopicSource(topic).getRecentEvents())).
2183                                                         build();
2184                         else
2185                                 return Response.status(Status.NOT_ACCEPTABLE).
2186                                                         entity(new Error("Failure to inject event over " + topic)).
2187                                                         build();
2188                 } catch (IllegalArgumentException e) {
2189                         logger.debug("{}: cannot offer for encoder ueb topic for {} because of {}", 
2190                                                 this, topic, e.getMessage(), e);
2191                         return Response.status(Response.Status.NOT_FOUND).
2192                             entity(new Error(topic + " not found")).
2193                             build();
2194                 } catch (IllegalStateException e) {
2195                         logger.debug("{}: cannot offer for encoder ueb topic for {} because of {}", 
2196                                                 this, topic, e.getMessage(), e);
2197                         return Response.status(Response.Status.NOT_ACCEPTABLE).
2198                             entity(new Error(topic + " not acceptable due to current state")).
2199                             build();
2200                 } catch (Exception e) {
2201                         logger.debug("{}: cannot offer for encoder ueb topic for {} because of {}", 
2202                                                 this, topic, e.getMessage(), e);
2203                         return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
2204                                     entity(new Error(e.getMessage())).
2205                                     build();                    
2206                 }
2207     }
2208     
2209     @PUT
2210     @Path("engine/topics/sources/dmaap/{topic}/events")
2211     @Consumes(MediaType.TEXT_PLAIN)
2212     @ApiOperation(
2213                 value="Offers an event to a DMaaP topic for internal processing by the engine", 
2214                 notes="The offered event is treated as it was incoming from the network",
2215                 responseContainer="List"
2216     )
2217     @ApiResponses(value = { 
2218                 @ApiResponse(code=404, message="The topic information cannot be found"),
2219                 @ApiResponse(code=406, message="The system is an administrative state that prevents " +
2220                                                "this request to be fulfilled"),
2221                 @ApiResponse(code=500, message="A server error has occurred processing this request")
2222     })
2223     public Response dmaapOffer(@ApiParam(value="Topic Name", required=true)
2224                                @PathParam("topic") String topic,
2225                                @ApiParam(value="Network Message", required=true)
2226                                    String json) {
2227         try {
2228                         DmaapTopicSource dmaapReader = TopicEndpoint.manager.getDmaapTopicSource(topic);
2229                         boolean success = dmaapReader.offer(json);
2230                         if (success)
2231                                 return Response.status(Status.OK).
2232                                                 entity(Arrays.asList(TopicEndpoint.manager.getDmaapTopicSource(topic).getRecentEvents())).
2233                                                 build();
2234                         else
2235                                 return Response.status(Status.NOT_ACCEPTABLE).
2236                                                         entity(new Error("Failure to inject event over " + topic)).
2237                                                         build();
2238                 } catch (IllegalArgumentException e) {
2239                         logger.debug("{}: cannot offer for encoder dmaap topic for {} because of {}", 
2240                                                 this, topic, e.getMessage(), e);
2241                         return Response.status(Response.Status.NOT_FOUND).
2242                             entity(new Error(topic + " not found")).
2243                             build();
2244                 } catch (IllegalStateException e) {
2245                         logger.debug("{}: cannot offer for encoder dmaap topic for {} because of {}", 
2246                                                 this, topic, e.getMessage(), e);
2247                         return Response.status(Response.Status.NOT_ACCEPTABLE).
2248                             entity(new Error(topic + " not acceptable due to current state")).
2249                             build();
2250                 } catch (Exception e) {
2251                         logger.debug("{}: cannot offer for encoder dmaap topic for {} because of {}", 
2252                                                 this, topic, e.getMessage(), e);
2253                         return Response.status(Response.Status.INTERNAL_SERVER_ERROR).
2254                                     entity(new Error(e.getMessage())).
2255                                     build();                    
2256                 }
2257     }
2258     
2259     @GET
2260     @Path("engine/tools/uuid")
2261     @ApiOperation(
2262                 value="Produces an UUID", 
2263                 notes="UUID generation utility"
2264     )
2265     @Produces(MediaType.TEXT_PLAIN)
2266     public Response uuid() {    
2267                 return Response.status(Status.OK).
2268                         entity(UUID.randomUUID().toString()).
2269                         build();
2270     }
2271     
2272     @GET
2273     @Path("engine/tools/loggers")
2274     @ApiOperation(
2275                 value="all active loggers", 
2276             responseContainer="List"
2277     )
2278     @ApiResponses(value = { 
2279                 @ApiResponse(code=500, message="logging misconfiguration")
2280     })
2281     public Response loggers() { 
2282         List<String> names = new ArrayList<String>();
2283         if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
2284                 logger.warn("The SLF4J logger factory is not configured for logback");
2285                 return Response.status(Status.INTERNAL_SERVER_ERROR).
2286                                         entity(names).build();
2287         }
2288                 
2289         LoggerContext context = 
2290                         (LoggerContext) LoggerFactory.getILoggerFactory();
2291         for (Logger logger: context.getLoggerList()) {
2292                 names.add(logger.getName());
2293         }
2294         
2295                 return Response.status(Status.OK).
2296                         entity(names).
2297                         build();
2298     }
2299     
2300     @GET
2301     @Path("engine/tools/loggers/{logger}")
2302     @Produces(MediaType.TEXT_PLAIN)
2303     @ApiOperation(
2304                 value="logging level of a logger"
2305     )
2306     @ApiResponses(value = { 
2307         @ApiResponse(code=500, message="logging misconfiguration"),
2308                 @ApiResponse(code=404, message="logger not found")
2309     })
2310     public Response loggerName(@ApiParam(value="Logger Name", required=true) 
2311                                @PathParam("logger") String loggerName) { 
2312         if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
2313                 logger.warn("The SLF4J logger factory is not configured for logback");
2314                 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
2315         }
2316         
2317         LoggerContext context = 
2318                         (LoggerContext) LoggerFactory.getILoggerFactory();
2319         ch.qos.logback.classic.Logger logger = context.getLogger(loggerName);
2320         if (logger == null) {
2321                 return Response.status(Status.NOT_FOUND).build();
2322         }
2323         
2324         String loggerLevel = (logger.getLevel() != null) ? logger.getLevel().toString() : "";           
2325                 return Response.status(Status.OK).entity(loggerLevel).build();
2326     }
2327     
2328     @PUT
2329     @Path("engine/tools/loggers/{logger}/{level}")
2330     @Produces(MediaType.TEXT_PLAIN)
2331     @Consumes(MediaType.TEXT_PLAIN)
2332     @ApiOperation(
2333                 value="sets the logger level", 
2334                 notes="Please use the SLF4J logger levels"
2335     )
2336     @ApiResponses(value = { 
2337                 @ApiResponse(code=500, message="logging misconfiguration"),
2338                 @ApiResponse(code=404, message="logger not found")
2339     })
2340     public Response loggerName(@ApiParam(value="Logger Name", required=true) 
2341                                @PathParam("logger") String loggerName,
2342                                @ApiParam(value="Logger Level", required=true) 
2343                                @PathParam("level") String loggerLevel) { 
2344         if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
2345                 logger.warn("The SLF4J logger factory is not configured for logback");
2346                 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
2347         }
2348                 
2349         LoggerContext context = 
2350                         (LoggerContext) LoggerFactory.getILoggerFactory();
2351         ch.qos.logback.classic.Logger logger = context.getLogger(loggerName);
2352         if (logger == null) {
2353                 return Response.status(Status.NOT_FOUND).build();
2354         }
2355         
2356         logger.setLevel(ch.qos.logback.classic.Level.toLevel(loggerLevel));
2357                 return Response.status(Status.OK).entity(logger.getLevel().toString()).build();
2358     }
2359     
2360     /**
2361      * gets the underlying drools controller from the named policy controller
2362      * @param controllerName the policy controller name
2363      * @return the underlying drools controller
2364      * @throws IllegalArgumentException if an invalid controller name has been passed in
2365      */
2366     protected DroolsController getDroolsController(String controllerName) {
2367                 PolicyController controller = PolicyController.factory.get(controllerName);
2368         if (controller == null)
2369                 throw new IllegalArgumentException(controllerName + "  does not exist");
2370
2371                 DroolsController drools = controller.getDrools();
2372         if (drools == null)
2373                 throw new IllegalArgumentException(controllerName + "  has no drools configuration");
2374         
2375         return drools;
2376     }
2377     
2378     /*
2379      * Helper classes for aggregation of results
2380      */
2381         
2382         @Override
2383         public String toString() {
2384                 StringBuilder builder = new StringBuilder();
2385                 builder.append("rest-telemetry-api []");
2386                 return builder.toString();
2387         }
2388
2389         /**
2390          * Coding/Encoding Results Aggregation Helper class 
2391          */
2392         public static class CodingResult {
2393                 /**
2394                  * serialized output
2395                  */
2396                 
2397                 public String jsonEncoding;
2398                 /**
2399                  * encoding result
2400                  */
2401                 
2402                 public Boolean encoding;
2403                 
2404                 /**
2405                  * decoding result
2406                  */
2407                 public Boolean decoding;
2408         }
2409         
2410         /**
2411          * Generic Error Reporting class 
2412          */
2413         public static class Error {
2414                 public String error;
2415
2416                 public Error(String error) {
2417                         this.error = error;
2418                 }
2419         }
2420         
2421         /**
2422          * Feed Ports into Resources
2423          */
2424         public enum Inputs {
2425                 configuration,
2426         }
2427         
2428         /**
2429          * Resource Toggles
2430          */
2431         public enum Switches {
2432                 activation,
2433                 lock,
2434         }
2435 }
2436