2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2021, 2023-2024 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 jakarta.ws.rs.Consumes;
27 import jakarta.ws.rs.DELETE;
28 import jakarta.ws.rs.DefaultValue;
29 import jakarta.ws.rs.GET;
30 import jakarta.ws.rs.POST;
31 import jakarta.ws.rs.PUT;
32 import jakarta.ws.rs.Path;
33 import jakarta.ws.rs.PathParam;
34 import jakarta.ws.rs.Produces;
35 import jakarta.ws.rs.QueryParam;
36 import jakarta.ws.rs.core.MediaType;
37 import jakarta.ws.rs.core.Response;
38 import jakarta.ws.rs.core.Response.Status;
39 import java.io.BufferedReader;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.InputStreamReader;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Collections;
46 import java.util.HashMap;
47 import java.util.List;
49 import java.util.Objects;
50 import java.util.Properties;
51 import java.util.UUID;
52 import java.util.function.Function;
53 import java.util.function.Supplier;
54 import java.util.stream.Collectors;
55 import lombok.AllArgsConstructor;
58 import lombok.ToString;
59 import org.onap.policy.common.endpoints.event.comm.Topic;
60 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
61 import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
62 import org.onap.policy.common.endpoints.event.comm.TopicSink;
63 import org.onap.policy.common.endpoints.event.comm.TopicSource;
64 import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
65 import org.onap.policy.common.utils.logging.LoggerUtils;
66 import org.onap.policy.drools.controller.DroolsController;
67 import org.onap.policy.drools.properties.DroolsPropertyConstants;
68 import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters;
69 import org.onap.policy.drools.protocol.coders.EventProtocolCoderConstants;
70 import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
71 import org.onap.policy.drools.protocol.coders.ProtocolCoderToolset;
72 import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
73 import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
74 import org.onap.policy.drools.system.PolicyController;
75 import org.onap.policy.drools.system.PolicyControllerConstants;
76 import org.onap.policy.drools.system.PolicyEngineConstants;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
81 * Telemetry JAX-RS Interface to the PDP-D.
85 @Produces({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
86 @Consumes({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
88 public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsApi,
89 PropertiesApi, EnvironmentApi, SwitchesApi, ControllersApi,
92 private static final String OFFER_FAILED = "{}: cannot offer to topic {} because of {}";
93 private static final String CANNOT_PERFORM_OPERATION = "cannot perform operation";
94 private static final String NO_FILTERS = " no filters";
95 private static final String NOT_FOUND = " not found: ";
96 private static final String NOT_FOUND_MSG = " not found";
97 private static final String DOES_NOT_EXIST_MSG = " does not exist";
98 private static final String NOT_ACCEPTABLE_MSG = " not acceptable";
99 private static final String FETCH_POLICY_FAILED = "{}: cannot get policy-controller because of {}";
100 private static final String FETCH_POLICY_BY_NAME_FAILED = "{}: cannot get policy-controller {} because of {}";
101 private static final String FETCH_POLICY_BY_TOPIC_FAILED =
102 "{}: cannot get policy-controller {} topic {} because of {}";
103 private static final String FETCH_DROOLS_FAILED = "{}: cannot get drools-controller {} because of {}";
104 private static final String FETCH_DROOLS_BY_ENTITY_FAILED =
105 "{}: cannot get: drools-controller {}, session {}, query {}, entity {} because of {}";
106 private static final String FETCH_DROOLS_BY_PARAMS_FAILED =
107 "{}: cannot get: drools-controller {}, session {}, query {}, entity {}, params {} because of {}";
108 private static final String FETCH_DROOLS_BY_FACTTYPE_FAILED =
109 "{}: cannot get: drools-controller {}, session {}, factType {}, because of {}";
110 private static final String FETCH_DECODERS_BY_POLICY_FAILED =
111 "{}: cannot get decoders for policy-controller {} because of {}";
112 private static final String FETCH_DECODERS_BY_TOPIC_FAILED =
113 "{}: cannot get decoders for policy-controller {} topic {} because of {}";
114 private static final String FETCH_DECODER_BY_TYPE_FAILED =
115 "{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}";
116 private static final String FETCH_DECODER_BY_FILTER_FAILED =
117 "{}: cannot get decoder filters for policy-controller {} topic {} type {} filters {} because of {}";
118 private static final String FETCH_ENCODER_BY_FILTER_FAILED =
119 "{}: cannot get encoder filters for policy-controller {} because of {}";
121 private static final String SWAGGER = "/swagger/swagger.json";
126 private static final Logger logger = LoggerFactory.getLogger(RestManager.class);
129 * Feed Ports into Resources.
131 private static final List<String> INPUTS = Collections.singletonList("configuration");
136 private static final List<String> SWITCHES = Arrays.asList("activation", "lock");
141 * @return response object
145 @Path("engine/swagger")
146 public Response swagger() {
148 try (InputStream inputStream = getClass().getResourceAsStream(SWAGGER);
149 BufferedReader reader = new BufferedReader(
150 new InputStreamReader(Objects.requireNonNull(inputStream)))) {
151 String contents = reader.lines()
152 .collect(Collectors.joining(System.lineSeparator()));
153 return Response.status(Response.Status.OK)
156 } catch (IOException e) {
157 logger.error("Cannot read swagger.json {} because of {}", e.getMessage(), e);
158 return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
167 * @return response object
172 public Response engine() {
173 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
179 * @return response object
184 public Response engineShutdown() {
186 PolicyEngineConstants.getManager().shutdown();
187 } catch (final IllegalStateException e) {
188 logger.error("{}: cannot shutdown {} because of {}", this, PolicyEngineConstants.getManager(),
190 return Response.status(Response.Status.BAD_REQUEST).entity(PolicyEngineConstants.getManager()).build();
193 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
199 * @return response object
203 @Path("engine/features")
204 public Response engineFeatures() {
205 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
210 @Path("engine/features/inventory")
211 public Response engineFeaturesInventory() {
212 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatureProviders())
219 * @return response object
223 @Path("engine/features/{featureName}")
224 public Response engineFeature(@PathParam("featureName") String featureName) {
226 return Response.status(Response.Status.OK)
227 .entity(PolicyEngineConstants.getManager().getFeatureProvider(featureName)).build();
228 } catch (final IllegalArgumentException iae) {
229 logger.debug("feature unavailable: {}", featureName, iae);
230 return Response.status(Response.Status.NOT_FOUND).entity(new Error(iae.getMessage())).build();
237 * @return response object
241 @Path("engine/inputs")
242 public Response engineInputs() {
243 return Response.status(Response.Status.OK).entity(INPUTS).build();
249 * @return response object
253 @Path("engine/inputs/configuration")
254 public Response engineUpdate(PdpdConfiguration configuration) {
255 final PolicyController controller = null;
258 success = PolicyEngineConstants.getManager().configure(configuration);
259 } catch (final Exception e) {
261 logger.info("{}: cannot configure {} because of {}", this, PolicyEngineConstants.getManager(),
266 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
269 return Response.status(Response.Status.OK).entity(controller).build();
276 * @return response object
280 @Path("engine/properties")
281 public Response engineProperties() {
282 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getProperties()).build();
288 * @return response object
292 @Path("engine/environment")
293 public Response engineEnvironment() {
294 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getEnvironment()).build();
300 * @return response object
304 @Path("engine/environment/{envProperty}")
305 @Consumes(MediaType.TEXT_PLAIN)
306 public Response engineEnvironmentProperty(@PathParam("envProperty") String envProperty) {
307 return Response.status(Response.Status.OK)
308 .entity(PolicyEngineConstants.getManager().getEnvironmentProperty(envProperty)).build();
314 * @return response object
318 @Path("engine/environment/{envProperty}")
319 @Consumes(MediaType.TEXT_PLAIN)
320 @Produces(MediaType.TEXT_PLAIN)
321 public Response engineEnvironmentAdd(@PathParam("envProperty") String envProperty, String envValue) {
322 final String previousValue = PolicyEngineConstants.getManager().setEnvironmentProperty(envProperty, envValue);
323 return Response.status(Response.Status.OK).entity(previousValue).build();
329 * @return response object
333 @Path("engine/switches")
334 public Response engineSwitches() {
335 return Response.status(Response.Status.OK).entity(SWITCHES).build();
341 * @return response object
345 @Path("engine/switches/activation")
346 public Response engineActivation() {
349 PolicyEngineConstants.getManager().activate();
350 } catch (final Exception e) {
352 logger.info("{}: cannot activate {} because of {}", this, PolicyEngineConstants.getManager(),
357 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
360 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
367 * @return response object
371 @Path("engine/switches/activation")
372 public Response engineDeactivation() {
375 PolicyEngineConstants.getManager().deactivate();
376 } catch (final Exception e) {
378 logger.info("{}: cannot deactivate {} because of {}", this, PolicyEngineConstants.getManager(),
383 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
386 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
393 * @return response object
397 @Path("engine/switches/lock")
398 public Response engineLock() {
399 final boolean success = PolicyEngineConstants.getManager().lock();
401 return Response.status(Status.OK).entity(PolicyEngineConstants.getManager()).build();
403 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
410 * @return response object
414 @Path("engine/switches/lock")
415 public Response engineUnlock() {
416 final boolean success = PolicyEngineConstants.getManager().unlock();
418 return Response.status(Status.OK).entity(PolicyEngineConstants.getManager()).build();
420 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
427 * @return response object
431 @Path("engine/controllers")
432 public Response controllers() {
433 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getPolicyControllerIds())
440 * @return response object
444 @Path("engine/controllers/inventory")
445 public Response controllerInventory() {
446 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getPolicyControllers())
453 * @return response object
457 @Path("engine/controllers")
458 public Response controllerAdd(Properties config) {
459 if (config == null) {
460 return Response.status(Response.Status.BAD_REQUEST).entity(new Error("A configuration must be provided"))
464 final String controllerName = config.getProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME);
465 if (controllerName == null || controllerName.isEmpty()) {
466 return Response.status(Response.Status.BAD_REQUEST)
468 "Configuration must have an entry for " + DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME))
472 PolicyController controller;
474 controller = PolicyControllerConstants.getFactory().get(controllerName);
475 if (controller != null) {
476 return Response.status(Response.Status.NOT_MODIFIED).entity(controller).build();
478 } catch (final IllegalArgumentException e) {
479 logger.trace("OK ", e);
481 } catch (final IllegalStateException e) {
482 logger.info(FETCH_POLICY_FAILED, this, e.getMessage(), e);
483 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(controllerName + NOT_FOUND_MSG))
488 controller = PolicyEngineConstants.getManager().createPolicyController(
489 config.getProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME), config);
490 } catch (IllegalArgumentException | IllegalStateException e) {
491 logger.warn("{}: cannot create policy-controller because of {}", this, e.getMessage(), e);
492 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(e.getMessage())).build();
496 final boolean success = controller.start();
498 logger.info("{}: cannot start {}", this, controller);
499 return Response.status(Response.Status.PARTIAL_CONTENT)
500 .entity(new Error(controllerName + " can't be started")).build();
502 } catch (final IllegalStateException e) {
503 logger.info("{}: cannot start {} because of {}", this, controller, e.getMessage(), e);
504 return Response.status(Response.Status.PARTIAL_CONTENT).entity(controller).build();
507 return Response.status(Response.Status.CREATED).entity(controller).build();
513 * @return response object
517 @Path("engine/controllers/features")
518 public Response controllerFeatures() {
519 return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
525 * @return response object
529 @Path("engine/controllers/features/inventory")
530 public Response controllerFeaturesInventory() {
531 return Response.status(Response.Status.OK)
532 .entity(PolicyControllerConstants.getFactory().getFeatureProviders()).build();
538 * @return response object
542 @Path("engine/controllers/features/{featureName}")
543 public Response controllerFeature(@PathParam("featureName") String featureName) {
545 return Response.status(Response.Status.OK)
546 .entity(PolicyControllerConstants.getFactory().getFeatureProvider(featureName))
548 } catch (final IllegalArgumentException iae) {
549 logger.debug("{}: cannot feature {} because of {}", this, featureName, iae.getMessage(), iae);
550 return Response.status(Response.Status.NOT_FOUND).entity(new Error(iae.getMessage())).build();
557 * @return response object
561 @Path("engine/controllers/{controller}")
562 public Response controller(@PathParam("controller") String controllerName) {
564 return catchArgStateGenericEx(
565 () -> Response.status(Response.Status.OK)
566 .entity(PolicyControllerConstants.getFactory().get(controllerName)).build(),
568 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
569 return (controllerName);
576 * @return response object
580 @Path("engine/controllers/{controller}")
581 public Response controllerDelete(@PathParam("controller") String controllerName) {
583 PolicyController controller;
585 controller = PolicyControllerConstants.getFactory().get(controllerName);
586 if (controller == null) {
587 return Response.status(Response.Status.BAD_REQUEST)
588 .entity(new Error(controllerName + DOES_NOT_EXIST_MSG)).build();
590 } catch (final IllegalArgumentException e) {
591 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
592 return Response.status(Response.Status.BAD_REQUEST)
593 .entity(new Error(controllerName + NOT_FOUND + e.getMessage())).build();
594 } catch (final IllegalStateException e) {
595 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
596 return Response.status(Response.Status.NOT_ACCEPTABLE)
597 .entity(new Error(controllerName + NOT_ACCEPTABLE_MSG)).build();
601 PolicyEngineConstants.getManager().removePolicyController(controllerName);
602 } catch (IllegalArgumentException | IllegalStateException e) {
603 logger.debug("{}: cannot remove policy-controller {} because of {}", this, controllerName, e.getMessage(),
605 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new Error(e.getMessage())).build();
608 return Response.status(Response.Status.OK).entity(controller).build();
614 * @return response object
618 @Path("engine/controllers/{controller}/properties")
620 public Response controllerProperties(@PathParam("controller") String controllerName) {
622 return catchArgStateGenericEx(() -> {
623 final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
624 return Response.status(Response.Status.OK).entity(controller.getProperties()).build();
627 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
628 return (controllerName);
635 * @return response object
639 @Path("engine/controllers/{controller}/inputs")
640 public Response controllerInputs(@PathParam("controller") String controllerName) {
641 return Response.status(Response.Status.OK).entity(INPUTS).build();
647 * @return response object
651 @Path("engine/controllers/{controller}/inputs/configuration")
652 public Response controllerUpdate(ControllerConfiguration controllerConfiguration,
653 @PathParam("controller") String controllerName) {
655 if (controllerName == null || controllerName.isEmpty() || controllerConfiguration == null
656 || !controllerName.equals(controllerConfiguration.getName())) {
657 return Response.status(Response.Status.BAD_REQUEST)
658 .entity("A valid or matching controller names must be provided").build();
661 return catchArgStateGenericEx(() -> {
663 PolicyEngineConstants.getManager().updatePolicyController(controllerConfiguration);
664 if (controller == null) {
665 return Response.status(Response.Status.BAD_REQUEST)
666 .entity(new Error(controllerName + DOES_NOT_EXIST_MSG)).build();
669 return Response.status(Response.Status.OK).entity(controller).build();
672 logger.info("{}: cannot update policy-controller {} because of {}", this, controllerName,
674 return (controllerName);
681 * @return response object
685 @Path("engine/controllers/{controller}/switches")
686 public Response controllerSwitches(@PathParam("controller") String controllerName) {
687 return Response.status(Response.Status.OK).entity(SWITCHES).build();
693 * @return response object
697 @Path("engine/controllers/{controller}/switches/lock")
698 public Response controllerLock(@PathParam("controller") String controllerName) {
699 var policyController = PolicyControllerConstants.getFactory().get(controllerName);
700 final boolean success = policyController.lock();
702 return Response.status(Status.OK).entity(policyController).build();
704 return Response.status(Status.NOT_ACCEPTABLE)
705 .entity(new Error("Controller " + controllerName + " cannot be locked")).build();
712 * @return response object
716 @Path("engine/controllers/{controller}/switches/lock")
717 public Response controllerUnlock(@PathParam("controller") String controllerName) {
718 var policyController = PolicyControllerConstants.getFactory().get(controllerName);
719 final boolean success = policyController.unlock();
721 return Response.status(Status.OK).entity(policyController).build();
723 return Response.status(Status.NOT_ACCEPTABLE)
724 .entity(new Error("Controller " + controllerName + " cannot be unlocked")).build();
731 * @return response object
735 @Path("engine/controllers/{controller}/drools")
736 public Response drools(@PathParam("controller") String controllerName) {
738 return catchArgStateGenericEx(() -> {
739 var drools = this.getDroolsController(controllerName);
740 return Response.status(Response.Status.OK).entity(drools).build();
743 logger.debug(FETCH_DROOLS_FAILED, this, controllerName, e.getMessage(), e);
744 return (controllerName);
751 * @return response object
755 @Path("engine/controllers/{controller}/drools/facts")
756 public Response droolsFacts2(@PathParam("controller") String controllerName) {
758 return catchArgStateGenericEx(() -> {
759 final Map<String, Long> sessionCounts = new HashMap<>();
760 var drools = this.getDroolsController(controllerName);
761 for (final String session : drools.getSessionNames()) {
762 sessionCounts.put(session, drools.factCount(session));
764 return sessionCounts;
767 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
768 return controllerName;
775 * @return response object
779 @Path("engine/controllers/{controller}/drools/facts/{session}")
780 public Response droolsFacts1(@PathParam("controller") String controllerName,
781 @PathParam("session") String sessionName) {
783 return catchArgStateGenericEx(() -> {
784 var drools = this.getDroolsController(controllerName);
785 return drools.factClassNames(sessionName);
788 logger.debug(FETCH_DROOLS_FAILED, this, controllerName, e.getMessage(), e);
789 return (controllerName + ":" + sessionName);
796 * @return response object
800 @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
801 public Response droolsFacts(
802 @PathParam("controller") String controllerName,
803 @PathParam("session") String sessionName,
804 @PathParam("factType") String factType,
805 @DefaultValue("false") @QueryParam("count") boolean count) {
807 return catchArgStateGenericEx(() -> {
808 var drools = this.getDroolsController(controllerName);
809 final List<Object> facts = drools.facts(sessionName, factType, false);
810 return (count ? facts.size() : facts);
813 logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
814 return (controllerName + ":" + sessionName + ":" + factType);
821 * @return response object
825 @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
826 public Response droolsFacts3(
827 @PathParam("controller") String controllerName,
828 @PathParam("session") String sessionName,
829 @PathParam("query") String queryName,
830 @PathParam("queriedEntity") String queriedEntity,
831 @DefaultValue("false") @QueryParam("count") boolean count) {
833 return catchArgStateGenericEx(() -> {
834 var drools = this.getDroolsController(controllerName);
835 final List<Object> facts = drools.factQuery(sessionName, queryName, queriedEntity, false);
836 return (count ? facts.size() : facts);
839 logger.debug(FETCH_DROOLS_BY_ENTITY_FAILED, this,
840 controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
841 return (controllerName + ":" + sessionName + ":" + queryName + queriedEntity);
848 * @return response object
852 @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
853 public Response droolsFacts4(
854 @PathParam("controller") String controllerName,
855 @PathParam("session") String sessionName,
856 @PathParam("query") String queryName,
857 @PathParam("queriedEntity") String queriedEntity,
858 List<Object> queryParameters) {
860 return catchArgStateGenericEx(() -> {
861 var drools = this.getDroolsController(controllerName);
862 if (queryParameters == null || queryParameters.isEmpty()) {
863 return drools.factQuery(sessionName, queryName, queriedEntity, false);
865 return drools.factQuery(sessionName, queryName, queriedEntity, false, queryParameters.toArray());
869 logger.debug(FETCH_DROOLS_BY_PARAMS_FAILED,
870 this, controllerName, sessionName, queryName, queriedEntity, queryParameters, e.getMessage(), e);
871 return (controllerName + ":" + sessionName + ":" + queryName + queriedEntity);
878 * @return response object
882 @Path("engine/controllers/{controller}/drools/facts/{session}/{factType}")
883 public Response droolsFactsDelete1(
884 @PathParam("controller") String controllerName,
885 @PathParam("session") String sessionName,
886 @PathParam("factType") String factType) {
888 return catchArgStateGenericEx(() -> {
889 var drools = this.getDroolsController(controllerName);
890 return drools.facts(sessionName, factType, true);
893 logger.debug(FETCH_DROOLS_BY_FACTTYPE_FAILED, this,
894 controllerName, sessionName, factType, e.getMessage(), e);
895 return (controllerName + ":" + sessionName + ":" + factType);
902 * @return response object
906 @Path("engine/controllers/{controller}/drools/facts/{session}/{query}/{queriedEntity}")
907 public Response droolsFactsDelete(
908 @PathParam("controller") String controllerName,
909 @PathParam("session") String sessionName,
910 @PathParam("query") String queryName,
911 @PathParam("queriedEntity") String queriedEntity) {
913 return catchArgStateGenericEx(() -> {
914 var drools = this.getDroolsController(controllerName);
915 return drools.factQuery(sessionName, queryName, queriedEntity, true);
919 logger.debug(FETCH_DROOLS_BY_PARAMS_FAILED,
920 this, controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
921 return (controllerName + ":" + sessionName + ":" + queryName + queriedEntity);
928 * @return response object
932 @Path("engine/controllers/tools/coders/decoders/filters/rule")
933 public Response rules(String expression) {
934 return Response.status(Status.OK).entity(new JsonProtocolFilter(expression)).build();
940 * @return response object
944 @Path("engine/controllers/{controller}/decoders")
945 public Response decoders(@PathParam("controller") String controllerName) {
947 return catchArgStateGenericEx(() -> {
948 var drools = this.getDroolsController(controllerName);
949 return EventProtocolCoderConstants.getManager().getDecoders(drools.getGroupId(), drools.getArtifactId());
952 logger.debug(FETCH_DECODERS_BY_POLICY_FAILED, this, controllerName,
954 return (controllerName);
961 * @return response object
965 @Path("engine/controllers/{controller}/decoders/filters")
966 public Response decoderFilters(@PathParam("controller") String controllerName) {
968 return catchArgStateGenericEx(() -> {
969 var drools = this.getDroolsController(controllerName);
970 return EventProtocolCoderConstants.getManager()
971 .getDecoderFilters(drools.getGroupId(), drools.getArtifactId());
974 logger.debug(FETCH_DECODERS_BY_POLICY_FAILED, this, controllerName, e.getMessage(), e);
975 return (controllerName);
982 * @return response object
986 @Path("engine/controllers/{controller}/decoders/{topic}")
987 public Response decoder(
988 @PathParam("controller") String controllerName,
989 @PathParam("topic") String topic) {
991 return catchArgStateGenericEx(() -> {
992 var drools = this.getDroolsController(controllerName);
993 return EventProtocolCoderConstants.getManager()
994 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
997 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this, controllerName, topic, e.getMessage(), e);
998 return (controllerName + ":" + topic);
1005 * @return response object
1009 @Path("engine/controllers/{controller}/decoders/{topic}/filters")
1010 public Response decoderFilter2(
1011 @PathParam("controller") String controllerName,
1012 @PathParam("topic") String topic) {
1014 return catchArgStateGenericEx(() -> {
1015 var drools = this.getDroolsController(controllerName);
1016 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1017 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1018 if (decoder == null) {
1019 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(topic + DOES_NOT_EXIST_MSG))
1022 return decoder.getCoders();
1026 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this, controllerName, topic, e.getMessage(), e);
1027 return (controllerName + ":" + topic);
1034 * @return response object
1038 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
1039 public Response decoderFilter1(
1040 @PathParam("controller") String controllerName,
1041 @PathParam("topic") String topic,
1042 @PathParam("factType") String factClass) {
1044 return catchArgStateGenericEx(() -> {
1045 var drools = this.getDroolsController(controllerName);
1046 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1047 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1048 final CoderFilters filters = decoder.getCoder(factClass);
1049 if (filters == null) {
1050 return Response.status(Response.Status.BAD_REQUEST)
1051 .entity(new Error(topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1057 logger.debug(FETCH_DECODER_BY_TYPE_FAILED, this,
1058 controllerName, topic, factClass, e.getMessage(), e);
1059 return (controllerName + ":" + topic + ":" + factClass);
1066 * @return response object
1070 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
1071 public Response decoderFilter(
1072 JsonProtocolFilter configFilters,
1073 @PathParam("controller") String controllerName,
1074 @PathParam("topic") String topic,
1075 @PathParam("factType") String factClass) {
1077 if (configFilters == null) {
1078 return Response.status(Response.Status.BAD_REQUEST).entity(new Error("Configuration Filters not provided"))
1082 return catchArgStateGenericEx(() -> {
1083 var drools = this.getDroolsController(controllerName);
1084 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1085 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1086 final CoderFilters filters = decoder.getCoder(factClass);
1087 if (filters == null) {
1088 return Response.status(Response.Status.BAD_REQUEST)
1089 .entity(new Error(topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1091 filters.setFilter(configFilters);
1095 logger.debug(FETCH_DECODER_BY_FILTER_FAILED,
1096 this, controllerName, topic, factClass, configFilters, e.getMessage(), e);
1097 return (controllerName + ":" + topic + ":" + factClass);
1104 * @return response object
1108 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule")
1109 public Response decoderFilterRules(
1110 @PathParam("controller") String controllerName,
1111 @PathParam("topic") String topic,
1112 @PathParam("factType") String factClass) {
1114 return catchArgStateGenericEx(() -> {
1115 var drools = this.getDroolsController(controllerName);
1116 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1117 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1119 final CoderFilters filters = decoder.getCoder(factClass);
1120 if (filters == null) {
1121 return Response.status(Response.Status.BAD_REQUEST)
1122 .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1125 final JsonProtocolFilter filter = filters.getFilter();
1126 if (filter == null) {
1127 return Response.status(Response.Status.BAD_REQUEST)
1128 .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
1131 return filter.getRule();
1134 logger.debug(FETCH_DECODER_BY_TYPE_FAILED, this,
1135 controllerName, topic, factClass, e.getMessage(), e);
1136 return (controllerName + ":" + topic + ":" + factClass);
1143 * @return response object
1147 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule")
1148 public Response decoderFilterRuleDelete(
1149 @PathParam("controller") String controllerName,
1150 @PathParam("topic") String topic,
1151 @PathParam("factType") String factClass) {
1153 return catchArgStateGenericEx(() -> {
1154 var drools = this.getDroolsController(controllerName);
1155 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1156 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1158 final CoderFilters filters = decoder.getCoder(factClass);
1159 if (filters == null) {
1160 return Response.status(Response.Status.BAD_REQUEST)
1161 .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1164 final JsonProtocolFilter filter = filters.getFilter();
1165 if (filter == null) {
1166 return Response.status(Response.Status.BAD_REQUEST)
1167 .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
1170 filter.setRule(null);
1171 return filter.getRule();
1174 logger.debug(FETCH_DECODER_BY_TYPE_FAILED,
1175 this, controllerName, topic, factClass, e.getMessage(), e);
1176 return (controllerName + ":" + topic + ":" + factClass);
1183 * @return response object
1187 @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule")
1188 public Response decoderFilterRule(
1189 @PathParam("controller") String controllerName,
1190 @PathParam("topic") String topic,
1191 @PathParam("factType") String factClass,
1194 return catchArgStateGenericEx(() -> decoderFilterRule2(controllerName, topic, factClass, rule), e -> {
1195 logger.debug("{}: cannot access decoder filter rules for policy-controller {} "
1196 + "topic {} type {} because of {}",
1197 this, controllerName, topic, factClass, e.getMessage(), e);
1198 return (controllerName + ":" + topic + ":" + factClass);
1202 private Object decoderFilterRule2(String controllerName, String topic, String factClass, String rule) {
1203 var drools = this.getDroolsController(controllerName);
1204 final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
1205 .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
1207 final CoderFilters filters = decoder.getCoder(factClass);
1208 if (filters == null) {
1209 return Response.status(Response.Status.BAD_REQUEST)
1210 .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
1213 final JsonProtocolFilter filter = filters.getFilter();
1214 if (filter == null) {
1215 return Response.status(Response.Status.BAD_REQUEST)
1216 .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
1219 if (rule == null || rule.isEmpty()) {
1220 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(controllerName + ":" + topic + ":"
1221 + factClass + " no filter rule provided")).build();
1224 filter.setRule(rule);
1225 return filter.getRule();
1231 * @return response object
1235 @Path("engine/controllers/{controller}/decoders/{topic}")
1236 @Consumes(MediaType.TEXT_PLAIN)
1237 public Response decode(
1238 @PathParam("controller") String controllerName,
1239 @PathParam("topic") String topic,
1242 if (!checkValidNameInput(controllerName)) {
1243 return Response.status(Response.Status.NOT_ACCEPTABLE)
1244 .entity(new Error("controllerName contains whitespaces " + NOT_ACCEPTABLE_MSG)).build();
1247 if (!checkValidNameInput(topic)) {
1248 return Response.status(Response.Status.NOT_ACCEPTABLE)
1249 .entity(new Error("topic contains whitespaces " + NOT_ACCEPTABLE_MSG)).build();
1252 PolicyController policyController;
1254 policyController = PolicyControllerConstants.getFactory().get(controllerName);
1255 } catch (final IllegalArgumentException e) {
1256 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this,
1257 controllerName, topic, e.getMessage(), e);
1258 return Response.status(Response.Status.NOT_FOUND)
1259 .entity(new Error(controllerName + ":" + topic + ":" + NOT_FOUND_MSG)).build();
1260 } catch (final IllegalStateException e) {
1261 logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this,
1262 controllerName, topic, e.getMessage(), e);
1263 return Response.status(Response.Status.NOT_ACCEPTABLE)
1264 .entity(new Error(controllerName + ":" + topic + ":" + NOT_ACCEPTABLE_MSG)).build();
1267 var result = new CodingResult();
1268 result.setDecoding(false);
1269 result.setEncoding(false);
1270 result.setJsonEncoding(null);
1274 event = EventProtocolCoderConstants.getManager().decode(policyController.getDrools().getGroupId(),
1275 policyController.getDrools().getArtifactId(), topic, json);
1276 result.setDecoding(true);
1277 } catch (final Exception e) {
1278 logger.debug(FETCH_POLICY_BY_TOPIC_FAILED, this, controllerName, topic,
1280 return Response.status(Response.Status.BAD_REQUEST).entity(new Error(e.getMessage())).build();
1284 result.setJsonEncoding(EventProtocolCoderConstants.getManager().encode(topic, event));
1285 result.setEncoding(true);
1286 } catch (final Exception e) {
1287 // continue so to propagate decoding results ..
1288 logger.debug("{}: cannot encode for policy-controller {} topic {} because of {}", this, controllerName,
1289 topic, e.getMessage(), e);
1292 return Response.status(Response.Status.OK).entity(result).build();
1298 * @return response object
1302 @Path("engine/controllers/{controller}/encoders")
1303 public Response encoderFilters(@PathParam("controller") String controllerName) {
1305 return catchArgStateGenericEx(() -> {
1306 final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
1307 var drools = controller.getDrools();
1308 return EventProtocolCoderConstants.getManager()
1309 .getEncoderFilters(drools.getGroupId(), drools.getArtifactId());
1312 logger.debug(FETCH_ENCODER_BY_FILTER_FAILED, this, controllerName,
1314 return (controllerName);
1320 @Path("engine/topics")
1321 public Response topics() {
1322 return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager()).build();
1327 @Path("engine/topics/switches")
1328 public Response topicSwitches() {
1329 return Response.status(Response.Status.OK).entity(SWITCHES).build();
1335 * @return response object
1339 @Path("engine/topics/switches/lock")
1340 public Response topicsLock() {
1341 final boolean success = TopicEndpointManager.getManager().lock();
1343 return Response.status(Status.OK).entity(TopicEndpointManager.getManager()).build();
1345 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
1352 * @return response object
1356 @Path("engine/topics/switches/lock")
1357 public Response topicsUnlock() {
1358 final boolean success = TopicEndpointManager.getManager().unlock();
1360 return Response.status(Status.OK).entity(TopicEndpointManager.getManager()).build();
1362 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
1369 * @return response object
1373 @Path("engine/topics/sources")
1374 public Response sources() {
1375 return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager().getTopicSources()).build();
1381 * @return response object
1385 @Path("engine/topics/sinks")
1386 public Response sinks() {
1387 return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager().getTopicSinks()).build();
1391 * GET sources of a communication type.
1395 @Path("engine/topics/sources/{comm: ueb|kafka|noop}")
1396 public Response commSources(
1397 @PathParam("comm") String comm) {
1398 if (!checkValidNameInput(comm)) {
1400 .status(Response.Status.NOT_ACCEPTABLE)
1401 .entity(new Error("source communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG))
1405 List<TopicSource> sources = new ArrayList<>();
1406 var status = Status.OK;
1407 switch (CommInfrastructure.valueOf(comm.toUpperCase())) {
1409 sources.addAll(TopicEndpointManager.getManager().getUebTopicSources());
1412 sources.addAll(TopicEndpointManager.getManager().getNoopTopicSources());
1415 sources.addAll(TopicEndpointManager.getManager().getKafkaTopicSources());
1418 status = Status.BAD_REQUEST;
1419 logger.debug("Invalid communication mechanism");
1422 return Response.status(status).entity(sources).build();
1426 * GET sinks of a communication type.
1430 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}")
1431 public Response commSinks(
1432 @PathParam("comm") String comm) {
1433 if (!checkValidNameInput(comm)) {
1435 .status(Response.Status.NOT_ACCEPTABLE)
1436 .entity(new Error("sink communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG))
1440 List<TopicSink> sinks = new ArrayList<>();
1441 var status = Status.OK;
1442 switch (CommInfrastructure.valueOf(comm.toUpperCase())) {
1444 sinks.addAll(TopicEndpointManager.getManager().getUebTopicSinks());
1447 sinks.addAll(TopicEndpointManager.getManager().getNoopTopicSinks());
1450 sinks.addAll(TopicEndpointManager.getManager().getKafkaTopicSinks());
1453 status = Status.BAD_REQUEST;
1454 logger.debug("Invalid communication mechanism");
1457 return Response.status(status).entity(sinks).build();
1465 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}")
1466 public Response sourceTopic(
1467 @PathParam("comm") String comm,
1468 @PathParam("topic") String topic) {
1470 .status(Response.Status.OK)
1471 .entity(TopicEndpointManager.getManager()
1472 .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic))
1481 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}/{topic}")
1482 public Response sinkTopic(
1483 @PathParam("comm") String comm,
1484 @PathParam("topic") String topic) {
1486 .status(Response.Status.OK)
1487 .entity(TopicEndpointManager.getManager()
1488 .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic))
1493 * GET a source events.
1497 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}/events")
1498 public Response sourceEvents(
1499 @PathParam("comm") String comm,
1500 @PathParam("topic") String topic) {
1501 return Response.status(Status.OK)
1502 .entity(Arrays.asList(TopicEndpointManager.getManager()
1503 .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic)
1504 .getRecentEvents()))
1509 * GET a sink events.
1513 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}/{topic}/events")
1514 public Response sinkEvents(
1515 @PathParam("comm") String comm,
1516 @PathParam("topic") String topic) {
1517 return Response.status(Status.OK)
1518 .entity(Arrays.asList(TopicEndpointManager.getManager()
1519 .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic)
1520 .getRecentEvents()))
1525 * GET source topic switches.
1529 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}/switches")
1530 public Response commSourceTopicSwitches(
1531 @PathParam("comm") String comm,
1532 @PathParam("topic") String topic) {
1533 return Response.status(Response.Status.OK).entity(SWITCHES).build();
1537 * GET sink topic switches.
1541 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}/{topic}/switches")
1542 public Response commSinkTopicSwitches(
1543 @PathParam("comm") String comm,
1544 @PathParam("topic") String topic) {
1545 return Response.status(Response.Status.OK).entity(SWITCHES).build();
1549 * PUTs a lock on a topic.
1553 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}/switches/lock")
1554 public Response commSourceTopicLock(
1555 @PathParam("comm") String comm,
1556 @PathParam("topic") String topic) {
1558 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1559 return getResponse(topic, source.lock(), source);
1563 * DELETEs the lock on a topic.
1567 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}/switches/lock")
1568 public Response commSourceTopicUnlock(
1569 @PathParam("comm") String comm,
1570 @PathParam("topic") String topic) {
1572 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1573 return getResponse(topic, source.unlock(), source);
1577 * Starts a topic source.
1581 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}/switches/activation")
1582 public Response commSourceTopicActivation(
1583 @PathParam("comm") String comm,
1584 @PathParam("topic") String topic) {
1586 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1587 return getResponse(topic, source.start(), source);
1591 * Stops a topic source.
1595 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}/switches/activation")
1596 public Response commSourceTopicDeactivation(
1597 @PathParam("comm") String comm,
1598 @PathParam("topic") String topic) {
1600 TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1601 return getResponse(topic, source.stop(), source);
1605 * PUTs a lock on a topic.
1609 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}/{topic}/switches/lock")
1610 public Response commSinkTopicLock(
1611 @PathParam("comm") String comm,
1612 @PathParam("topic") String topic) {
1614 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1615 return getResponse(topic, sink.lock(), sink);
1619 * DELETEs the lock on a topic.
1623 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}/{topic}/switches/lock")
1624 public Response commSinkTopicUnlock(
1625 @PathParam("comm") String comm,
1626 @PathParam("topic") String topic) {
1628 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1629 return getResponse(topic, sink.unlock(), sink);
1633 * Starts a topic sink.
1637 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}/{topic}/switches/activation")
1638 public Response commSinkTopicActivation(
1639 @PathParam("comm") String comm,
1640 @PathParam("topic") String topic) {
1642 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1643 return getResponse(topic, sink.start(), sink);
1647 * Stops a topic sink.
1651 @Path("engine/topics/sinks/{comm: ueb|kafka|noop}/{topic}/switches/activation")
1652 public Response commSinkTopicDeactivation(
1653 @PathParam("comm") String comm,
1654 @PathParam("topic") String topic) {
1656 TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1657 return getResponse(topic, sink.stop(), sink);
1660 private Response getResponse(String topicName, boolean success, Topic topic) {
1662 return Response.status(Status.OK).entity(topic).build();
1664 return Response.status(Status.NOT_ACCEPTABLE).entity(makeTopicOperError(topicName)).build();
1668 private Error makeTopicOperError(String topic) {
1669 return new Error("cannot perform operation on " + topic);
1673 * Offers an event to a topic in a communication infrastructure.
1675 * @return response object
1679 @Path("engine/topics/sources/{comm: ueb|kafka|noop}/{topic}/events")
1680 @Consumes(MediaType.TEXT_PLAIN)
1681 public Response commEventOffer(
1682 @PathParam("comm") String comm,
1683 @PathParam("topic") String topic,
1686 return catchArgStateGenericEx(() -> {
1687 var source = TopicEndpointManager.getManager()
1688 .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
1689 if (source.offer(json)) {
1690 return Arrays.asList(source.getRecentEvents());
1692 return Response.status(Status.NOT_ACCEPTABLE).entity(new Error("Failure to inject event over " + topic))
1697 logger.debug(OFFER_FAILED, this, topic, e.getMessage(), e);
1705 * @return response object
1709 @Path("engine/tools/uuid")
1710 @Produces(MediaType.TEXT_PLAIN)
1711 public Response uuid() {
1712 return Response.status(Status.OK).entity(UUID.randomUUID().toString()).build();
1718 * @return response object
1722 @Path("engine/tools/loggers")
1723 public Response loggers() {
1724 final List<String> names = new ArrayList<>();
1725 if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext context)) {
1726 logger.warn("The SLF4J logger factory is not configured for logback");
1727 return Response.status(Status.INTERNAL_SERVER_ERROR).entity(names).build();
1730 for (final Logger lgr : context.getLoggerList()) {
1731 names.add(lgr.getName());
1734 return Response.status(Status.OK).entity(names).build();
1740 * @return response object
1744 @Path("engine/tools/loggers/{logger}")
1745 @Produces(MediaType.TEXT_PLAIN)
1746 public Response loggerName1(@PathParam("logger") String loggerName) {
1747 if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext context)) {
1748 logger.warn("The SLF4J logger factory is not configured for logback");
1749 return Response.status(Status.INTERNAL_SERVER_ERROR).build();
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) {