2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2021,2023 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.drools.server.restful;
24 import ch.qos.logback.classic.LoggerContext;
25 import com.google.re2j.Pattern;
26 import java.io.BufferedReader;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.List;
36 import java.util.Properties;
37 import java.util.UUID;
38 import java.util.function.Function;
39 import java.util.function.Supplier;
40 import java.util.stream.Collectors;
41 import javax.ws.rs.Consumes;
42 import javax.ws.rs.DELETE;
43 import javax.ws.rs.DefaultValue;
44 import javax.ws.rs.GET;
45 import javax.ws.rs.POST;
46 import javax.ws.rs.PUT;
47 import javax.ws.rs.Path;
48 import javax.ws.rs.PathParam;
49 import javax.ws.rs.Produces;
50 import javax.ws.rs.QueryParam;
51 import javax.ws.rs.core.MediaType;
52 import javax.ws.rs.core.Response;
53 import javax.ws.rs.core.Response.Status;
54 import lombok.AllArgsConstructor;
57 import lombok.ToString;
58 import org.onap.policy.common.endpoints.event.comm.Topic;
59 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
60 import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
61 import org.onap.policy.common.endpoints.event.comm.TopicSink;
62 import org.onap.policy.common.endpoints.event.comm.TopicSource;
63 import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
64 import org.onap.policy.common.utils.logging.LoggerUtils;
65 import org.onap.policy.drools.controller.DroolsController;
66 import org.onap.policy.drools.properties.DroolsPropertyConstants;
67 import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters;
68 import org.onap.policy.drools.protocol.coders.EventProtocolCoderConstants;
69 import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
70 import org.onap.policy.drools.protocol.coders.ProtocolCoderToolset;
71 import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
72 import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
73 import org.onap.policy.drools.system.PolicyController;
74 import org.onap.policy.drools.system.PolicyControllerConstants;
75 import org.onap.policy.drools.system.PolicyEngineConstants;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
80 * Telemetry JAX-RS Interface to the PDP-D.
84 @Produces({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
85 @Consumes({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
87 public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsApi,
88 PropertiesApi, EnvironmentApi, SwitchesApi, ControllersApi,
91 private static final String OFFER_FAILED = "{}: cannot offer to topic {} because of {}";
92 private static final String CANNOT_PERFORM_OPERATION = "cannot perform operation";
93 private static final String NO_FILTERS = " no filters";
94 private static final String NOT_FOUND = " not found: ";
95 private static final String NOT_FOUND_MSG = " not found";
96 private static final String DOES_NOT_EXIST_MSG = " does not exist";
97 private static final String NOT_ACCEPTABLE_MSG = " not acceptable";
98 private static final String FETCH_POLICY_FAILED = "{}: cannot get policy-controller because of {}";
99 private static final String FETCH_POLICY_BY_NAME_FAILED = "{}: cannot get policy-controller {} because of {}";
100 private static final String FETCH_POLICY_BY_TOPIC_FAILED =
101 "{}: cannot get policy-controller {} topic {} because of {}";
102 private static final String FETCH_DROOLS_FAILED = "{}: cannot get drools-controller {} because of {}";
103 private static final String FETCH_DROOLS_BY_ENTITY_FAILED =
104 "{}: cannot get: drools-controller {}, session {}, query {}, entity {} because of {}";
105 private static final String FETCH_DROOLS_BY_PARAMS_FAILED =
106 "{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}";
107 private static final String FETCH_DROOLS_BY_FACTTYPE_FAILED =
108 "{}: cannot get: drools-controller {}, session {}, factType {}, because of {}";
109 private static final String FETCH_DECODERS_BY_POLICY_FAILED =
110 "{}: cannot get decoders for policy-controller {} because of {}";
111 private static final String FETCH_DECODERS_BY_TOPIC_FAILED =
112 "{}: cannot get decoders for policy-controller {} topic {} because of {}";
113 private static final String FETCH_DECODER_BY_TYPE_FAILED =
114 "{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}";
115 private static final String FETCH_DECODER_BY_FILTER_FAILED =
116 "{}: cannot get decoder filters for policy-controller {} topic {} type {} filters {} because of {}";
117 private static final String FETCH_ENCODER_BY_FILTER_FAILED =
118 "{}: cannot get encoder filters for policy-controller {} because of {}";
120 private static final String SWAGGER = "/swagger/swagger.json";
125 private static final Logger logger = LoggerFactory.getLogger(RestManager.class);
128 * Feed Ports into Resources.
130 private static final List<String> INPUTS = Collections.singletonList("configuration");
135 private static final List<String> SWITCHES = Arrays.asList("activation", "lock");
140 * @return response object
144 @Path("engine/swagger")
145 public Response swagger() {
147 try (InputStream inputStream = getClass().getResourceAsStream(SWAGGER);
148 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
149 String contents = reader.lines()
150 .collect(Collectors.joining(System.lineSeparator()));
151 return Response.status(Response.Status.OK)
154 } catch (IOException e) {
155 logger.error("Cannot read swagger.json {} because of {}", e.getMessage(), e);
156 return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
165 * @return response object
170 public Response engine() {
171 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
177 * @return response object
182 public Response engineShutdown() {
184 PolicyEngineConstants.getManager().shutdown();
185 } catch (final IllegalStateException e) {
186 logger.error("{}: cannot shutdown {} because of {}", this, PolicyEngineConstants.getManager(),
188 return Response.status(Response.Status.BAD_REQUEST).entity(PolicyEngineConstants.getManager()).build();
191 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
197 * @return response object
201 @Path("engine/features")
202 public Response engineFeatures() {
203 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
208 @Path("engine/features/inventory")
209 public Response engineFeaturesInventory() {
210 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatureProviders())
217 * @return response object
221 @Path("engine/features/{featureName}")
222 public Response engineFeature(@PathParam("featureName") String featureName) {
224 return Response.status(Response.Status.OK)
225 .entity(PolicyEngineConstants.getManager().getFeatureProvider(featureName)).build();
226 } catch (final IllegalArgumentException iae) {
227 logger.debug("feature unavailable: {}", featureName, iae);
228 return Response.status(Response.Status.NOT_FOUND).entity(new Error(iae.getMessage())).build();
235 * @return response object
239 @Path("engine/inputs")
240 public Response engineInputs() {
241 return Response.status(Response.Status.OK).entity(INPUTS).build();
247 * @return response object
251 @Path("engine/inputs/configuration")
252 public Response engineUpdate(PdpdConfiguration configuration) {
253 final PolicyController controller = null;
256 success = PolicyEngineConstants.getManager().configure(configuration);
257 } catch (final Exception e) {
259 logger.info("{}: cannot configure {} because of {}", this, PolicyEngineConstants.getManager(),
264 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
267 return Response.status(Response.Status.OK).entity(controller).build();
274 * @return response object
278 @Path("engine/properties")
279 public Response engineProperties() {
280 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getProperties()).build();
286 * @return response object
290 @Path("engine/environment")
291 public Response engineEnvironment() {
292 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getEnvironment()).build();
298 * @return response object
302 @Path("engine/environment/{envProperty}")
303 @Consumes(MediaType.TEXT_PLAIN)
304 public Response engineEnvironmentProperty(@PathParam("envProperty") String envProperty) {
305 return Response.status(Response.Status.OK)
306 .entity(PolicyEngineConstants.getManager().getEnvironmentProperty(envProperty)).build();
312 * @return response object
316 @Path("engine/environment/{envProperty}")
317 @Consumes(MediaType.TEXT_PLAIN)
318 @Produces(MediaType.TEXT_PLAIN)
319 public Response engineEnvironmentAdd(@PathParam("envProperty") String envProperty, String envValue) {
320 final String previousValue = PolicyEngineConstants.getManager().setEnvironmentProperty(envProperty, envValue);
321 return Response.status(Response.Status.OK).entity(previousValue).build();
327 * @return response object
331 @Path("engine/switches")
332 public Response engineSwitches() {
333 return Response.status(Response.Status.OK).entity(SWITCHES).build();
339 * @return response object
343 @Path("engine/switches/activation")
344 public Response engineActivation() {
347 PolicyEngineConstants.getManager().activate();
348 } catch (final Exception e) {
350 logger.info("{}: cannot activate {} because of {}", this, PolicyEngineConstants.getManager(),
355 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
358 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
365 * @return response object
369 @Path("engine/switches/activation")
370 public Response engineDeactivation() {
373 PolicyEngineConstants.getManager().deactivate();
374 } catch (final Exception e) {
376 logger.info("{}: cannot deactivate {} because of {}", this, PolicyEngineConstants.getManager(),
381 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
384 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
391 * @return response object
395 @Path("engine/switches/lock")
396 public Response engineLock() {
397 final boolean success = PolicyEngineConstants.getManager().lock();
399 return Response.status(Status.OK).entity(PolicyEngineConstants.getManager()).build();
401 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
408 * @return response object
412 @Path("engine/switches/lock")
413 public Response engineUnlock() {
414 final boolean success = PolicyEngineConstants.getManager().unlock();
416 return Response.status(Status.OK).entity(PolicyEngineConstants.getManager()).build();
418 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
425 * @return response object
429 @Path("engine/controllers")
430 public Response controllers() {
431 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getPolicyControllerIds())
438 * @return response object
442 @Path("engine/controllers/inventory")
443 public Response controllerInventory() {
444 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getPolicyControllers())
451 * @return response object
455 @Path("engine/controllers")
456 public Response controllerAdd(Properties config) {
457 if (config == null) {
458 return Response.status(Response.Status.BAD_REQUEST).entity(new Error("A configuration must be provided"))
462 final String controllerName = config.getProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME);
463 if (controllerName == null || controllerName.isEmpty()) {
464 return Response.status(Response.Status.BAD_REQUEST)
466 "Configuration must have an entry for " + DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME))
470 PolicyController controller;
472 controller = PolicyControllerConstants.getFactory().get(controllerName);
473 if (controller != null) {
474 return Response.status(Response.Status.NOT_MODIFIED).entity(controller).build();
476 } catch (final IllegalArgumentException e) {
477 logger.trace("OK ", e);
479 } catch (final IllegalStateException e) {
480 logger.info(FETCH_POLICY_FAILED, this, e.getMessage(), e);
481 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(controllerName + NOT_FOUND_MSG))
486 controller = PolicyEngineConstants.getManager().createPolicyController(
487 config.getProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME), config);
488 } catch (IllegalArgumentException | IllegalStateException e) {
489 logger.warn("{}: cannot create policy-controller because of {}", this, e.getMessage(), e);
490 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(e.getMessage())).build();
494 final boolean success = controller.start();
496 logger.info("{}: cannot start {}", this, controller);
497 return Response.status(Response.Status.PARTIAL_CONTENT)
498 .entity(new Error(controllerName + " can't be started")).build();
500 } catch (final IllegalStateException e) {
501 logger.info("{}: cannot start {} because of {}", this, controller, e.getMessage(), e);
502 return Response.status(Response.Status.PARTIAL_CONTENT).entity(controller).build();
505 return Response.status(Response.Status.CREATED).entity(controller).build();
511 * @return response object
515 @Path("engine/controllers/features")
516 public Response controllerFeatures() {
517 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
523 * @return response object
527 @Path("engine/controllers/features/inventory")
528 public Response controllerFeaturesInventory() {
529 return Response.status(Response.Status.OK)
530 .entity(PolicyControllerConstants.getFactory().getFeatureProviders()).build();
536 * @return response object
540 @Path("engine/controllers/features/{featureName}")
541 public Response controllerFeature(@PathParam("featureName") String featureName) {
543 return Response.status(Response.Status.OK)
544 .entity(PolicyControllerConstants.getFactory().getFeatureProvider(featureName))
546 } catch (final IllegalArgumentException iae) {
547 logger.debug("{}: cannot feature {} because of {}", this, featureName, iae.getMessage(), iae);
548 return Response.status(Response.Status.NOT_FOUND).entity(new Error(iae.getMessage())).build();
555 * @return response object
559 @Path("engine/controllers/{controller}")
560 public Response controller(@PathParam("controller") String controllerName) {
562 return catchArgStateGenericEx(
563 () -> Response.status(Response.Status.OK)
564 .entity(PolicyControllerConstants.getFactory().get(controllerName)).build(),
566 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
567 return (controllerName);
574 * @return response object
578 @Path("engine/controllers/{controller}")
579 public Response controllerDelete(@PathParam("controller") String controllerName) {
581 PolicyController controller;
583 controller = PolicyControllerConstants.getFactory().get(controllerName);
584 if (controller == null) {
585 return Response.status(Response.Status.BAD_REQUEST)
586 .entity(new Error(controllerName + DOES_NOT_EXIST_MSG)).build();
588 } catch (final IllegalArgumentException e) {
589 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
590 return Response.status(Response.Status.BAD_REQUEST)
591 .entity(new Error(controllerName + NOT_FOUND + e.getMessage())).build();
592 } catch (final IllegalStateException e) {
593 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
594 return Response.status(Response.Status.NOT_ACCEPTABLE)
595 .entity(new Error(controllerName + NOT_ACCEPTABLE_MSG)).build();
599 PolicyEngineConstants.getManager().removePolicyController(controllerName);
600 } catch (IllegalArgumentException | IllegalStateException e) {
601 logger.debug("{}: cannot remove policy-controller {} because of {}", this, controllerName, e.getMessage(),
603 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new Error(e.getMessage())).build();
606 return Response.status(Response.Status.OK).entity(controller).build();
612 * @return response object
616 @Path("engine/controllers/{controller}/properties")
618 public Response controllerProperties(@PathParam("controller") String controllerName) {
620 return catchArgStateGenericEx(() -> {
621 final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
622 return Response.status(Response.Status.OK).entity(controller.getProperties()).build();
625 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
626 return (controllerName);
633 * @return response object
637 @Path("engine/controllers/{controller}/inputs")
638 public Response controllerInputs(@PathParam("controller") String controllerName) {
639 return Response.status(Response.Status.OK).entity(INPUTS).build();
645 * @return response object
649 @Path("engine/controllers/{controller}/inputs/configuration")
650 public Response controllerUpdate(ControllerConfiguration controllerConfiguration,
651 @PathParam("controller") String controllerName) {
653 if (controllerName == null || controllerName.isEmpty() || controllerConfiguration == null
654 || !controllerName.equals(controllerConfiguration.getName())) {
655 return Response.status(Response.Status.BAD_REQUEST)
656 .entity("A valid or matching controller names must be provided").build();
659 return catchArgStateGenericEx(() -> {
661 PolicyEngineConstants.getManager().updatePolicyController(controllerConfiguration);
662 if (controller == null) {
663 return Response.status(Response.Status.BAD_REQUEST)
664 .entity(new Error(controllerName + DOES_NOT_EXIST_MSG)).build();
667 return Response.status(Response.Status.OK).entity(controller).build();
670 logger.info("{}: cannot update policy-controller {} because of {}", this, controllerName,
672 return (controllerName);
679 * @return response object
683 @Path("engine/controllers/{controller}/switches")
684 public Response controllerSwitches(@PathParam("controller") String controllerName) {
685 return Response.status(Response.Status.OK).entity(SWITCHES).build();
691 * @return response object
695 @Path("engine/controllers/{controller}/switches/lock")
696 public Response controllerLock(@PathParam("controller") String controllerName) {
697 var policyController = PolicyControllerConstants.getFactory().get(controllerName);
698 final boolean success = policyController.lock();
700 return Response.status(Status.OK).entity(policyController).build();
702 return Response.status(Status.NOT_ACCEPTABLE)
703 .entity(new Error("Controller " + controllerName + " cannot be locked")).build();
710 * @return response object
714 @Path("engine/controllers/{controller}/switches/lock")
715 public Response controllerUnlock(@PathParam("controller") String controllerName) {
716 var policyController = PolicyControllerConstants.getFactory().get(controllerName);
717 final boolean success = policyController.unlock();
719 return Response.status(Status.OK).entity(policyController).build();
721 return Response.status(Status.NOT_ACCEPTABLE)
722 .entity(new Error("Controller " + controllerName + " cannot be unlocked")).build();
729 * @return response object
733 @Path("engine/controllers/{controller}/drools")
734 public Response drools(@PathParam("controller") String controllerName) {
736 return catchArgStateGenericEx(() -> {
737 var drools = this.getDroolsController(controllerName);
738 return Response.status(Response.Status.OK).entity(drools).build();
741 logger.debug(FETCH_DROOLS_FAILED, this, controllerName, e.getMessage(), e);
742 return (controllerName);
749 * @return response object
753 @Path("engine/controllers/{controller}/drools/facts")
754 public Response droolsFacts2(@PathParam("controller") String controllerName) {
756 return catchArgStateGenericEx(() -> {
757 final Map<String, Long> sessionCounts = new HashMap<>();
758 var drools = this.getDroolsController(controllerName);
759 for (final String session : drools.getSessionNames()) {
760 sessionCounts.put(session, drools.factCount(session));
762 return sessionCounts;
765 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
766 return controllerName;
773 * @return response object
777 @Path("engine/controllers/{controller}/drools/facts/{session}")
778 public Response droolsFacts1(@PathParam("controller") String controllerName,
779 @PathParam("session") String sessionName) {
781 return catchArgStateGenericEx(() -> {
782 var drools = this.getDroolsController(controllerName);
783 return drools.factClassNames(sessionName);
786 logger.debug(FETCH_DROOLS_FAILED, this, controllerName, e.getMessage(), e);
787 return (controllerName + ":" + sessionName);
794 * @return response object
798 @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
799 public Response droolsFacts(
800 @PathParam("controller") String controllerName,
801 @PathParam("session") String sessionName,
802 @PathParam("factType") String factType,
803 @DefaultValue("false") @QueryParam("count") boolean count) {
805 return catchArgStateGenericEx(() -> {
806 var drools = this.getDroolsController(controllerName);
807 final List<Object> facts = drools.facts(sessionName, factType, false);
808 return (count ? facts.size() : facts);
811 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
812 return (controllerName + ":" + sessionName + ":" + factType);
819 * @return response object
823 @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
824 public Response droolsFacts3(
825 @PathParam("controller") String controllerName,
826 @PathParam("session") String sessionName,
827 @PathParam("query") String queryName,
828 @PathParam("queriedEntity") String queriedEntity,
829 @DefaultValue("false") @QueryParam("count") boolean count) {
831 return catchArgStateGenericEx(() -> {
832 var drools = this.getDroolsController(controllerName);
833 final List<Object> facts = drools.factQuery(sessionName, queryName, queriedEntity, false);
834 return (count ? facts.size() : facts);
837 logger.debug(FETCH_DROOLS_BY_ENTITY_FAILED, this,
838 controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
839 return (controllerName + ":" + sessionName + ":" + queryName + queriedEntity);
846 * @return response object
850 @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
851 public Response droolsFacts4(
852 @PathParam("controller") String controllerName,
853 @PathParam("session") String sessionName,
854 @PathParam("query") String queryName,
855 @PathParam("queriedEntity") String queriedEntity,
856 List<Object> queryParameters) {
858 return catchArgStateGenericEx(() -> {
859 var drools = this.getDroolsController(controllerName);
860 if (queryParameters == null || queryParameters.isEmpty()) {
861 return drools.factQuery(sessionName, queryName, queriedEntity, false);
863 return drools.factQuery(sessionName, queryName, queriedEntity, false, queryParameters.toArray());
867 logger.debug(FETCH_DROOLS_BY_PARAMS_FAILED,
868 this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
869 return (controllerName + ":" + sessionName + ":" + queryName + queriedEntity);
876 * @return response object
880 @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
881 public Response droolsFactsDelete1(
882 @PathParam("controller") String controllerName,
883 @PathParam("session") String sessionName,
884 @PathParam("factType") String factType) {
886 return catchArgStateGenericEx(() -> {
887 var drools = this.getDroolsController(controllerName);
888 return drools.facts(sessionName, factType, true);
891 logger.debug(FETCH_DROOLS_BY_FACTTYPE_FAILED, this,
892 controllerName, sessionName, factType, e.getMessage(), e);
893 return (controllerName + ":" + sessionName + ":" + factType);
900 * @return response object
904 @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
905 public Response droolsFactsDelete(
906 @PathParam("controller") String controllerName,
907 @PathParam("session") String sessionName,
908 @PathParam("query") String queryName,
909 @PathParam("queriedEntity") String queriedEntity) {
911 return catchArgStateGenericEx(() -> {
912 var drools = this.getDroolsController(controllerName);
913 return drools.factQuery(sessionName, queryName, queriedEntity, true);
917 logger.debug(FETCH_DROOLS_BY_PARAMS_FAILED,
918 this, controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
919 return (controllerName + ":" + sessionName + ":" + queryName + queriedEntity);
926 * @return response object
930 @Path("engine/controllers/tools/coders/decoders/filters/rule")
931 public Response rules(String expression) {
932 return Response.status(Status.OK).entity(new JsonProtocolFilter(expression)).build();
938 * @return response object
942 @Path("engine/controllers/{controller}/decoders")
943 public Response decoders(@PathParam("controller") String controllerName) {
945 return catchArgStateGenericEx(() -> {
946 var drools = this.getDroolsController(controllerName);
947 return EventProtocolCoderConstants.getManager().getDecoders(drools.getGroupId(), drools.getArtifactId());
950 logger.debug(FETCH_DECODERS_BY_POLICY_FAILED, this, controllerName,
952 return (controllerName);
959 * @return response object
963 @Path("engine/controllers/{controller}/decoders/filters")
964 public Response decoderFilters(@PathParam("controller") String controllerName) {
966 return catchArgStateGenericEx(() -> {
967 var drools = this.getDroolsController(controllerName);
968 return EventProtocolCoderConstants.getManager()
969 .getDecoderFilters(drools.getGroupId(), drools.getArtifactId());
972 logger.debug(FETCH_DECODERS_BY_POLICY_FAILED, this, controllerName, e.getMessage(), e);
973 return (controllerName);
980 * @return response object
984 @Path("engine/controllers/{controller}/decoders/{topic}")
985 public Response decoder(
986 @PathParam("controller") String controllerName,
987 @PathParam("topic") String topic) {
989 return catchArgStateGenericEx(() -> {
990 var drools = this.getDroolsController(controllerName);
991 return EventProtocolCoderConstants.getManager()
992 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
995 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this, controllerName, topic, e.getMessage(), e);
996 return (controllerName + ":" + topic);
1003 * @return response object
1007 @Path("engine/controllers/{controller}/decoders/{topic}/filters")
1008 public Response decoderFilter2(
1009 @PathParam("controller") String controllerName,
1010 @PathParam("topic") String topic) {
1012 return catchArgStateGenericEx(() -> {
1013 var drools = this.getDroolsController(controllerName);
1014 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1015 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1016 if (decoder == null) {
1017 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(topic + DOES_NOT_EXIST_MSG))
1020 return decoder.getCoders();
1024 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this, controllerName, topic, e.getMessage(), e);
1025 return (controllerName + ":" + topic);
1032 * @return response object
1036 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
1037 public Response decoderFilter1(
1038 @PathParam("controller") String controllerName,
1039 @PathParam("topic") String topic,
1040 @PathParam("factType") String factClass) {
1042 return catchArgStateGenericEx(() -> {
1043 var drools = this.getDroolsController(controllerName);
1044 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1045 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1046 final CoderFilters filters = decoder.getCoder(factClass);
1047 if (filters == null) {
1048 return Response.status(Response.Status.BAD_REQUEST)
1049 .entity(new Error(topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1055 logger.debug(FETCH_DECODER_BY_TYPE_FAILED, this,
1056 controllerName, topic, factClass, e.getMessage(), e);
1057 return (controllerName + ":" + topic + ":" + factClass);
1064 * @return response object
1068 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
1069 public Response decoderFilter(
1070 JsonProtocolFilter configFilters,
1071 @PathParam("controller") String controllerName,
1072 @PathParam("topic") String topic,
1073 @PathParam("factType") String factClass) {
1075 if (configFilters == null) {
1076 return Response.status(Response.Status.BAD_REQUEST).entity(new Error("Configuration Filters not provided"))
1080 return catchArgStateGenericEx(() -> {
1081 var drools = this.getDroolsController(controllerName);
1082 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1083 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1084 final CoderFilters filters = decoder.getCoder(factClass);
1085 if (filters == null) {
1086 return Response.status(Response.Status.BAD_REQUEST)
1087 .entity(new Error(topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1089 filters.setFilter(configFilters);
1093 logger.debug(FETCH_DECODER_BY_FILTER_FAILED,
1094 this, controllerName, topic, factClass, configFilters, e.getMessage(), e);
1095 return (controllerName + ":" + topic + ":" + factClass);
1102 * @return response object
1106 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule")
1107 public Response decoderFilterRules(
1108 @PathParam("controller") String controllerName,
1109 @PathParam("topic") String topic,
1110 @PathParam("factType") String factClass) {
1112 return catchArgStateGenericEx(() -> {
1113 var drools = this.getDroolsController(controllerName);
1114 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1115 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1117 final CoderFilters filters = decoder.getCoder(factClass);
1118 if (filters == null) {
1119 return Response.status(Response.Status.BAD_REQUEST)
1120 .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1123 final JsonProtocolFilter filter = filters.getFilter();
1124 if (filter == null) {
1125 return Response.status(Response.Status.BAD_REQUEST)
1126 .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
1129 return filter.getRule();
1132 logger.debug(FETCH_DECODER_BY_TYPE_FAILED, this,
1133 controllerName, topic, factClass, e.getMessage(), e);
1134 return (controllerName + ":" + topic + ":" + factClass);
1141 * @return response object
1145 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule")
1146 public Response decoderFilterRuleDelete(
1147 @PathParam("controller") String controllerName,
1148 @PathParam("topic") String topic,
1149 @PathParam("factType") String factClass) {
1151 return catchArgStateGenericEx(() -> {
1152 var drools = this.getDroolsController(controllerName);
1153 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1154 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1156 final CoderFilters filters = decoder.getCoder(factClass);
1157 if (filters == null) {
1158 return Response.status(Response.Status.BAD_REQUEST)
1159 .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1162 final JsonProtocolFilter filter = filters.getFilter();
1163 if (filter == null) {
1164 return Response.status(Response.Status.BAD_REQUEST)
1165 .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
1168 filter.setRule(null);
1169 return filter.getRule();
1172 logger.debug(FETCH_DECODER_BY_TYPE_FAILED,
1173 this, controllerName, topic, factClass, e.getMessage(), e);
1174 return (controllerName + ":" + topic + ":" + factClass);
1181 * @return response object
1185 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule")
1186 public Response decoderFilterRule(
1187 @PathParam("controller") String controllerName,
1188 @PathParam("topic") String topic,
1189 @PathParam("factType") String factClass,
1192 return catchArgStateGenericEx(() -> decoderFilterRule2(controllerName, topic, factClass, rule), e -> {
1193 logger.debug("{}: cannot access decoder filter rules for policy-controller {} "
1194 + "topic {} type {} because of {}",
1195 this, controllerName, topic, factClass, e.getMessage(), e);
1196 return (controllerName + ":" + topic + ":" + factClass);
1200 private Object decoderFilterRule2(String controllerName, String topic, String factClass, String rule) {
1201 var drools = this.getDroolsController(controllerName);
1202 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1203 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1205 final CoderFilters filters = decoder.getCoder(factClass);
1206 if (filters == null) {
1207 return Response.status(Response.Status.BAD_REQUEST)
1208 .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1211 final JsonProtocolFilter filter = filters.getFilter();
1212 if (filter == null) {
1213 return Response.status(Response.Status.BAD_REQUEST)
1214 .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
1217 if (rule == null || rule.isEmpty()) {
1218 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(controllerName + ":" + topic + ":"
1219 + factClass + " no filter rule provided")).build();
1222 filter.setRule(rule);
1223 return filter.getRule();
1229 * @return response object
1233 @Path("engine/controllers/{controller}/decoders/{topic}")
1234 @Consumes(MediaType.TEXT_PLAIN)
1235 public Response decode(
1236 @PathParam("controller") String controllerName,
1237 @PathParam("topic") String topic,
1240 if (!checkValidNameInput(controllerName)) {
1241 return Response.status(Response.Status.NOT_ACCEPTABLE)
1242 .entity(new Error("controllerName contains whitespaces " + NOT_ACCEPTABLE_MSG)).build();
1245 if (!checkValidNameInput(topic)) {
1246 return Response.status(Response.Status.NOT_ACCEPTABLE)
1247 .entity(new Error("topic contains whitespaces " + NOT_ACCEPTABLE_MSG)).build();
1250 PolicyController policyController;
1252 policyController = PolicyControllerConstants.getFactory().get(controllerName);
1253 } catch (final IllegalArgumentException e) {
1254 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this,
1255 controllerName, topic, e.getMessage(), e);
1256 return Response.status(Response.Status.NOT_FOUND)
1257 .entity(new Error(controllerName + ":" + topic + ":" + NOT_FOUND_MSG)).build();
1258 } catch (final IllegalStateException e) {
1259 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this,
1260 controllerName, topic, e.getMessage(), e);
1261 return Response.status(Response.Status.NOT_ACCEPTABLE)
1262 .entity(new Error(controllerName + ":" + topic + ":" + NOT_ACCEPTABLE_MSG)).build();
1265 var result = new CodingResult();
1266 result.setDecoding(false);
1267 result.setEncoding(false);
1268 result.setJsonEncoding(null);
1272 event = EventProtocolCoderConstants.getManager().decode(policyController.getDrools().getGroupId(),
1273 policyController.getDrools().getArtifactId(), topic, json);
1274 result.setDecoding(true);
1275 } catch (final Exception e) {
1276 logger.debug(FETCH_POLICY_BY_TOPIC_FAILED, this, controllerName, topic,
1278 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(e.getMessage())).build();
1282 result.setJsonEncoding(EventProtocolCoderConstants.getManager().encode(topic, event));
1283 result.setEncoding(true);
1284 } catch (final Exception e) {
1285 // continue so to propagate decoding results ..
1286 logger.debug("{}: cannot encode for policy-controller {} topic {} because of {}", this, controllerName,
1287 topic, e.getMessage(), e);
1290 return Response.status(Response.Status.OK).entity(result).build();
1296 * @return response object
1300 @Path("engine/controllers/{controller}/encoders")
1301 public Response encoderFilters(@PathParam("controller") String controllerName) {
1303 return catchArgStateGenericEx(() -> {
1304 final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
1305 var drools = controller.getDrools();
1306 return EventProtocolCoderConstants.getManager()
1307 .getEncoderFilters(drools.getGroupId(), drools.getArtifactId());
1310 logger.debug(FETCH_ENCODER_BY_FILTER_FAILED, this, controllerName,
1312 return (controllerName);
1318 @Path("engine/topics")
1319 public Response topics() {
1320 return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager()).build();
1325 @Path("engine/topics/switches")
1326 public Response topicSwitches() {
1327 return Response.status(Response.Status.OK).entity(SWITCHES).build();
1333 * @return response object
1337 @Path("engine/topics/switches/lock")
1338 public Response topicsLock() {
1339 final boolean success = TopicEndpointManager.getManager().lock();
1341 return Response.status(Status.OK).entity(TopicEndpointManager.getManager()).build();
1343 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
1350 * @return response object
1354 @Path("engine/topics/switches/lock")
1355 public Response topicsUnlock() {
1356 final boolean success = TopicEndpointManager.getManager().unlock();
1358 return Response.status(Status.OK).entity(TopicEndpointManager.getManager()).build();
1360 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
1367 * @return response object
1371 @Path("engine/topics/sources")
1372 public Response sources() {
1373 return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager().getTopicSources()).build();
1379 * @return response object
1383 @Path("engine/topics/sinks")
1384 public Response sinks() {
1385 return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager().getTopicSinks()).build();
1389 * GET sources of a communication type.
1393 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}")
1394 public Response commSources(
1395 @PathParam("comm") String comm) {
1396 if (!checkValidNameInput(comm)) {
1398 .status(Response.Status.NOT_ACCEPTABLE)
1399 .entity(new Error("source communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG))
1403 List<TopicSource> sources = new ArrayList<>();
1404 var status = Status.OK;
1405 switch (CommInfrastructure.valueOf(comm.toUpperCase())) {
1407 sources.addAll(TopicEndpointManager.getManager().getUebTopicSources());
1410 sources.addAll(TopicEndpointManager.getManager().getDmaapTopicSources());
1413 sources.addAll(TopicEndpointManager.getManager().getNoopTopicSources());
1416 status = Status.BAD_REQUEST;
1417 logger.debug("Invalid communication mechanism");
1420 return Response.status(status).entity(sources).build();
1424 * GET sinks of a communication type.
1428 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}")
1429 public Response commSinks(
1430 @PathParam("comm") String comm) {
1431 if (!checkValidNameInput(comm)) {
1433 .status(Response.Status.NOT_ACCEPTABLE)
1434 .entity(new Error("sink communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG))
1438 List<TopicSink> sinks = new ArrayList<>();
1439 var status = Status.OK;
1440 switch (CommInfrastructure.valueOf(comm.toUpperCase())) {
1442 sinks.addAll(TopicEndpointManager.getManager().getUebTopicSinks());
1445 sinks.addAll(TopicEndpointManager.getManager().getDmaapTopicSinks());
1448 sinks.addAll(TopicEndpointManager.getManager().getNoopTopicSinks());
1451 status = Status.BAD_REQUEST;
1452 logger.debug("Invalid communication mechanism");
1455 return Response.status(status).entity(sinks).build();
1463 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}")
1464 public Response sourceTopic(
1465 @PathParam("comm") String comm,
1466 @PathParam("topic") String topic) {
1468 .status(Response.Status.OK)
1469 .entity(TopicEndpointManager.getManager()
1470 .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic))
1479 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}/{topic}")
1480 public Response sinkTopic(
1481 @PathParam("comm") String comm,
1482 @PathParam("topic") String topic) {
1484 .status(Response.Status.OK)
1485 .entity(TopicEndpointManager.getManager()
1486 .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic))
1491 * GET a source events.
1495 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}/events")
1496 public Response sourceEvents(
1497 @PathParam("comm") String comm,
1498 @PathParam("topic") String topic) {
1499 return Response.status(Status.OK)
1500 .entity(Arrays.asList(TopicEndpointManager.getManager()
1501 .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic)
1502 .getRecentEvents()))
1507 * GET a sink events.
1511 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}/{topic}/events")
1512 public Response sinkEvents(
1513 @PathParam("comm") String comm,
1514 @PathParam("topic") String topic) {
1515 return Response.status(Status.OK)
1516 .entity(Arrays.asList(TopicEndpointManager.getManager()
1517 .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic)
1518 .getRecentEvents()))
1523 * GET source topic switches.
1527 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}/switches")
1528 public Response commSourceTopicSwitches(
1529 @PathParam("comm") String comm,
1530 @PathParam("topic") String topic) {
1531 return Response.status(Response.Status.OK).entity(SWITCHES).build();
1535 * GET sink topic switches.
1539 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}/{topic}/switches")
1540 public Response commSinkTopicSwitches(
1541 @PathParam("comm") String comm,
1542 @PathParam("topic") String topic) {
1543 return Response.status(Response.Status.OK).entity(SWITCHES).build();
1547 * PUTs a lock on a topic.
1551 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}/switches/lock")
1552 public Response commSourceTopicLock(
1553 @PathParam("comm") String comm,
1554 @PathParam("topic") String topic) {
1556 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1557 return getResponse(topic, source.lock(), source);
1561 * DELETEs the lock on a topic.
1565 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}/switches/lock")
1566 public Response commSourceTopicUnlock(
1567 @PathParam("comm") String comm,
1568 @PathParam("topic") String topic) {
1570 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1571 return getResponse(topic, source.unlock(), source);
1575 * Starts a topic source.
1579 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}/switches/activation")
1580 public Response commSourceTopicActivation(
1581 @PathParam("comm") String comm,
1582 @PathParam("topic") String topic) {
1584 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1585 return getResponse(topic, source.start(), source);
1589 * Stops a topic source.
1593 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}/switches/activation")
1594 public Response commSourceTopicDeactivation(
1595 @PathParam("comm") String comm,
1596 @PathParam("topic") String topic) {
1598 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1599 return getResponse(topic, source.stop(), source);
1603 * PUTs a lock on a topic.
1607 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}/{topic}/switches/lock")
1608 public Response commSinkTopicLock(
1609 @PathParam("comm") String comm,
1610 @PathParam("topic") String topic) {
1612 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1613 return getResponse(topic, sink.lock(), sink);
1617 * DELETEs the lock on a topic.
1621 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}/{topic}/switches/lock")
1622 public Response commSinkTopicUnlock(
1623 @PathParam("comm") String comm,
1624 @PathParam("topic") String topic) {
1626 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1627 return getResponse(topic, sink.unlock(), sink);
1631 * Starts a topic sink.
1635 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}/{topic}/switches/activation")
1636 public Response commSinkTopicActivation(
1637 @PathParam("comm") String comm,
1638 @PathParam("topic") String topic) {
1640 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1641 return getResponse(topic, sink.start(), sink);
1645 * Stops a topic sink.
1649 @Path("engine/topics/sinks/{comm: ueb|dmaap|noop}/{topic}/switches/activation")
1650 public Response commSinkTopicDeactivation(
1651 @PathParam("comm") String comm,
1652 @PathParam("topic") String topic) {
1654 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1655 return getResponse(topic, sink.stop(), sink);
1658 private Response getResponse(String topicName, boolean success, Topic topic) {
1660 return Response.status(Status.OK).entity(topic).build();
1662 return Response.status(Status.NOT_ACCEPTABLE).entity(makeTopicOperError(topicName)).build();
1666 private Error makeTopicOperError(String topic) {
1667 return new Error("cannot perform operation on " + topic);
1671 * Offers an event to a topic in a communication infrastructure.
1673 * @return response object
1677 @Path("engine/topics/sources/{comm: ueb|dmaap|noop}/{topic}/events")
1678 @Consumes(MediaType.TEXT_PLAIN)
1679 public Response commEventOffer(
1680 @PathParam("comm") String comm,
1681 @PathParam("topic") String topic,
1684 return catchArgStateGenericEx(() -> {
1685 var source = TopicEndpointManager.getManager()
1686 .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1687 if (source.offer(json)) {
1688 return Arrays.asList(source.getRecentEvents());
1690 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error("Failure to inject event over " + topic))
1695 logger.debug(OFFER_FAILED, this, topic, e.getMessage(), e);
1703 * @return response object
1707 @Path("engine/tools/uuid")
1708 @Produces(MediaType.TEXT_PLAIN)
1709 public Response uuid() {
1710 return Response.status(Status.OK).entity(UUID.randomUUID().toString()).build();
1716 * @return response object
1720 @Path("engine/tools/loggers")
1721 public Response loggers() {
1722 final List<String> names = new ArrayList<>();
1723 if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
1724 logger.warn("The SLF4J logger factory is not configured for logback");
1725 return Response.status(Status.INTERNAL_SERVER_ERROR).entity(names).build();
1728 final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
1729 for (final Logger lgr : context.getLoggerList()) {
1730 names.add(lgr.getName());
1733 return Response.status(Status.OK).entity(names).build();
1739 * @return response object
1743 @Path("engine/tools/loggers/{logger}")
1744 @Produces(MediaType.TEXT_PLAIN)
1745 public Response loggerName1(@PathParam("logger") String loggerName) {
1746 if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
1747 logger.warn("The SLF4J logger factory is not configured for logback");
1748 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
1751 final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
1752 var lgr = context.getLogger(loggerName);
1754 return Response.status(Status.NOT_FOUND).build();
1757 final String loggerLevel = (lgr.getLevel() != null) ? lgr.getLevel().toString() : "";
1758 return Response.status(Status.OK).entity(loggerLevel).build();
1764 * @return response object
1768 @Path("engine/tools/loggers/{logger}/{level}")
1769 @Produces(MediaType.TEXT_PLAIN)
1770 @Consumes(MediaType.TEXT_PLAIN)
1771 public Response loggerName(@PathParam("logger") String loggerName, @PathParam("level") String loggerLevel) {
1775 if (!checkValidNameInput(loggerName)) {
1776 return Response.status(Response.Status.NOT_ACCEPTABLE)
1777 .entity(new Error("logger name: " + NOT_ACCEPTABLE_MSG))
1780 if (!Pattern.matches("^[a-zA-Z]{3,5}$", loggerLevel)) {
1781 return Response.status(Response.Status.NOT_ACCEPTABLE)
1782 .entity(new Error("logger level: " + NOT_ACCEPTABLE_MSG))
1785 newLevel = LoggerUtils.setLevel(loggerName, loggerLevel);
1786 } catch (final IllegalArgumentException e) {
1787 logger.warn("{}: invalid operation for logger {} and level {}", this, loggerName, loggerLevel, e);
1788 return Response.status(Status.NOT_FOUND).build();
1789 } catch (final IllegalStateException e) {
1790 logger.warn("{}: logging framework unavailable for {} / {}", this, loggerName, loggerLevel, e);
1791 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
1794 return Response.status(Status.OK).entity(newLevel
1800 * gets the underlying drools controller from the named policy controller.
1802 * @param controllerName the policy controller name
1803 * @return the underlying drools controller
1804 * @throws IllegalArgumentException if an invalid controller name has been passed in
1806 protected DroolsController getDroolsController(String controllerName) {
1807 final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
1808 if (controller == null) {
1809 throw new IllegalArgumentException(controllerName + DOES_NOT_EXIST_MSG);
1812 var drools = controller.getDrools();
1813 if (drools == null) {
1814 throw new IllegalArgumentException(controllerName + " has no drools configuration");
1821 * Invokes a function and returns the generated response, catching illegal argument,
1822 * illegal state, and generic runtime exceptions.
1824 * @param responder function that will generate a response. If it returns a "Response"
1825 * object, then that object is returned as-is. Otherwise, this method will
1826 * return an "OK" Response, using the function's return value as the "entity"
1827 * @param errorMsg function that will generate an error message prefix to be included
1828 * in responses generated as a result of catching an exception
1829 * @return a response
1831 private Response catchArgStateGenericEx(Supplier<Object> responder, Function<Exception, String> errorMsg) {
1833 Object result = responder.get();
1834 if (result instanceof Response) {
1835 return (Response) result;
1838 return Response.status(Response.Status.OK).entity(result).build();
1840 } catch (final IllegalArgumentException e) {
1841 return Response.status(Response.Status.NOT_FOUND).entity(new Error(errorMsg.apply(e) + NOT_FOUND_MSG))
1844 } catch (final IllegalStateException e) {
1845 return Response.status(Response.Status.NOT_ACCEPTABLE)
1846 .entity(new Error(errorMsg.apply(e) + NOT_ACCEPTABLE_MSG)).build();
1848 } catch (final RuntimeException e) {
1850 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new Error(e.getMessage())).build();
1854 public static boolean checkValidNameInput(String test) {
1855 return Pattern.matches("\\S+", test);
1859 * Helper classes for aggregation of results
1863 * Coding/Encoding Results Aggregation Helper class.
1867 public static class CodingResult {
1869 * serialized output.
1872 private String jsonEncoding;
1877 private Boolean encoding;
1882 private Boolean decoding;
1886 * Generic Error Reporting class.
1889 public static class Error {
1892 public String getError() {
1896 public void setError(String msg) {