diff options
author | Jorge Hernandez <jh1730@att.com> | 2017-05-04 09:27:34 -0500 |
---|---|---|
committer | Jorge Hernandez <jh1730@att.com> | 2017-05-04 09:45:56 -0500 |
commit | 4b780cfa3125e30acbd055e260bacf58d33c353e (patch) | |
tree | 8e69ce49abf8fb51a5ea9df66b5ce15336ceb44a /policy-management | |
parent | 3273b61a5dca60033be9fac302be82a761232401 (diff) |
[POLICY-11] New REST APIs to obtain facts info
The following REST APIs have been added, shown by example:
GET policy/pdp/engine/controllers/<controller-name>/drools :
drools information for controller named <controller-name>
For brevity in URL description, assume:
DROOLS-REL-PATH=policy/pdp/engine/controllers/<controller-name>/drools
GET ${DROOLS-REL-PATH}/<session-name>[?count=true]
fact classes and count for <session-name> in controller <name>
GET ${DROOLS-REL-PATH}/<session-name>/<classname>
all fact objects of class <classname> for session <session-name>
GET ${DROOLS-REL-PATH}/<session-name>/<query-name>/<query-id>
all fact objects returned by drools query named <query-name>
for the identifier <query-id>
(need corresponding query definition in drl is necessary)
Change-Id: I2f62931f54a65eec4ef80472ad1af05f30ed83ba
Signed-off-by: Jorge Hernandez <jh1730@att.com>
Diffstat (limited to 'policy-management')
5 files changed, 395 insertions, 38 deletions
diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java index 72f8e0b2..0904d438 100644 --- a/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java +++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/DroolsController.java @@ -21,6 +21,7 @@ package org.openecomp.policy.drools.controller; import java.util.List; +import java.util.Map; import org.openecomp.policy.drools.event.comm.TopicSink; import org.openecomp.policy.drools.properties.Lockable; @@ -65,14 +66,20 @@ public interface DroolsController extends Startable, Lockable { * @return version */ public String getVersion(); - /** * return the policy session names * * @return policy session */ - public List<String> getSessionNames(); + public List<String> getSessionNames(); + + /** + * return the policy full session names + * + * @return policy session + */ + public List<String> getCanonicalSessionNames(); /** * offers an event to this controller for processing @@ -152,7 +159,40 @@ public interface DroolsController extends Startable, Lockable { List<TopicCoderFilterConfiguration> decoderConfigurations, List<TopicCoderFilterConfiguration> encoderConfigurations) throws IllegalArgumentException, LinkageError, Exception; + + /** + * gets the classnames of facts as well as the current count + * @param sessionName the session name + * @return map of class to count + */ + public Map<String,Integer> factClassNames(String sessionName) throws IllegalArgumentException; + + /** + * gets the count of facts for a given session + * @param sessionName the session name + * @return the fact count + * @throws IllegalArgumentException + */ + public long factCount(String sessionName) throws IllegalArgumentException; + /** + * gets all the facts of a given class for a given session + * + * @param sessionName the session identifier + * @param className the class type + * @return the list of facts returned by the query + */ + public List<Object> facts(String sessionName, String className); + + /** + * gets the facts associated with a query for a give session for a given queried entity + * + * @param sessionName the session + * @param queryName the query identifier + * @param queriedEntity the queried entity + * @return list of facts returned by the query + */ + public List<Object> factQuery(String sessionName, String queryName, String queriedEntity); /** * halts and permanently releases all resources @@ -165,6 +205,4 @@ public interface DroolsController extends Startable, Lockable { */ public static final DroolsControllerFactory factory = new IndexedDroolsControllerFactory(); - - } diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java index 76bc5151..62ad6843 100644 --- a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java +++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/MavenDroolsController.java @@ -21,10 +21,17 @@ package org.openecomp.policy.drools.controller.internal; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.commons.collections4.queue.CircularFifoQueue; - +import org.drools.core.ClassObjectFilter; +import org.kie.api.runtime.KieSession; +import org.kie.api.runtime.rule.FactHandle; +import org.kie.api.runtime.rule.QueryResults; +import org.kie.api.runtime.rule.QueryResultsRow; import org.openecomp.policy.common.logging.eelf.MessageCodes; import org.openecomp.policy.common.logging.flexlogger.FlexLogger; import org.openecomp.policy.common.logging.flexlogger.Logger; @@ -40,6 +47,7 @@ import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomJacksonCoder; import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration.PotentialCoderFilter; import org.openecomp.policy.drools.utils.ReflectionUtil; + import com.fasterxml.jackson.annotation.JsonIgnore; /** @@ -647,23 +655,194 @@ public class MavenDroolsController implements DroolsController { return this.locked; } + /** + * gets the policy container + * @return the underlying container + */ + @JsonIgnore + protected PolicyContainer getContainer() { + return this.policyContainer; + } + + /** + * {@inheritDoc} + */ @Override public List<String> getSessionNames() { + return getSessionNames(true); + } + + /** + * {@inheritDoc} + */ + @Override + public List<String> getCanonicalSessionNames() { + return getSessionNames(false); + } + + /** + * get session names + * @param abbreviated true for the short form, otherwise the long form + * @return session names + */ + protected List<String> getSessionNames(boolean abbreviated) { List<String> sessionNames = new ArrayList<String>(); try { for (PolicySession session: this.policyContainer.getPolicySessions()) { - sessionNames.add(session.getFullName()); + if (abbreviated) + sessionNames.add(session.getName()); + else + sessionNames.add(session.getFullName()); } } catch (Exception e) { - logger.warn(MessageCodes.EXCEPTION_ERROR, e, - "Can't retrieve POLICY-CORE sessions: " + e.getMessage(), - this.toString()); + logger.warn("Can't retrieve CORE sessions: " + e.getMessage(), e); sessionNames.add(e.getMessage()); } return sessionNames; } /** + * provides the underlying core layer container sessions + * + * @return the attached Policy Container + */ + protected List<PolicySession> getSessions() { + List<PolicySession> sessions = new ArrayList<PolicySession>(); + sessions.addAll(this.policyContainer.getPolicySessions()); + return sessions; + } + + /** + * provides the underlying core layer container session with name sessionName + * + * @param sessionName session name + * @return the attached Policy Container + * @throws IllegalArgumentException when an invalid session name is provided + * @throws IllegalStateException when the drools controller is in an invalid state + */ + protected PolicySession getSession(String sessionName) { + if (sessionName == null || sessionName.isEmpty()) + throw new IllegalArgumentException("A Session Name must be provided"); + + List<PolicySession> sessions = this.getSessions(); + for (PolicySession session : sessions) { + if (sessionName.equals(session.getName()) || sessionName.equals(session.getName())) + return session; + } + + throw new IllegalArgumentException("Invalid Session Name: " + sessionName); + } + + /** + * {@inheritDoc} + */ + @Override + public Map<String,Integer> factClassNames(String sessionName) throws IllegalArgumentException { + if (sessionName == null || sessionName.isEmpty()) + throw new IllegalArgumentException("Invalid Session Name: " + sessionName); + + // List<String> classNames = new ArrayList<>(); + Map<String,Integer> classNames = new HashMap<>(); + + PolicySession session = getSession(sessionName); + KieSession kieSession = session.getKieSession(); + + Collection<FactHandle> facts = session.getKieSession().getFactHandles(); + for (FactHandle fact : facts) { + try { + String className = kieSession.getObject(fact).getClass().getName(); + if (classNames.containsKey(className)) + classNames.put(className, classNames.get(className) + 1); + else + classNames.put(className, 1); + } catch (Exception e) { + if (logger.isInfoEnabled()) + logger.info("Object cannot be retrieved from fact: " + fact); + } + } + + return classNames; + } + + /** + * {@inheritDoc} + */ + @Override + public long factCount(String sessionName) throws IllegalArgumentException { + if (sessionName == null || sessionName.isEmpty()) + throw new IllegalArgumentException("Invalid Session Name: " + sessionName); + + PolicySession session = getSession(sessionName); + return session.getKieSession().getFactCount(); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Object> facts(String sessionName, String className) { + if (sessionName == null || sessionName.isEmpty()) + throw new IllegalArgumentException("Invalid Session Name: " + sessionName); + + if (className == null || className.isEmpty()) + throw new IllegalArgumentException("Invalid Class Name: " + className); + + Class<?> factClass = + ReflectionUtil.fetchClass(this.policyContainer.getClassLoader(), className); + if (factClass == null) + throw new IllegalArgumentException("Class cannot be fetched in model's classloader: " + className); + + PolicySession session = getSession(sessionName); + KieSession kieSession = session.getKieSession(); + + List<Object> factObjects = new ArrayList<>(); + + Collection<FactHandle> factHandles = kieSession.getFactHandles(new ClassObjectFilter(factClass)); + for (FactHandle factHandle : factHandles) { + try { + factObjects.add(kieSession.getObject(factHandle)); + } catch (Exception e) { + if (logger.isInfoEnabled()) + logger.info("Object cannot be retrieved from fact: " + factHandle); + } + } + + return factObjects; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Object> factQuery(String sessionName, String queryName, String queriedEntity) { + if (sessionName == null || sessionName.isEmpty()) + throw new IllegalArgumentException("Invalid Session Name: " + sessionName); + + if (queryName == null || queryName.isEmpty()) + throw new IllegalArgumentException("Invalid Query Name: " + queryName); + + if (queriedEntity == null || queriedEntity.isEmpty()) + throw new IllegalArgumentException("Invalid Queried Entity: " + queriedEntity); + + PolicySession session = getSession(sessionName); + KieSession kieSession = session.getKieSession(); + + List<Object> factObjects = new ArrayList<>(); + + QueryResults queryResults = kieSession.getQueryResults(queryName); + for (QueryResultsRow row : queryResults) { + try { + factObjects.add(row.get(queriedEntity)); + } catch (Exception e) { + if (logger.isInfoEnabled()) + logger.info("Object cannot be retrieved from fact: " + row); + } + } + + return factObjects; + } + + /** * {@inheritDoc} */ @Override diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java index f0c0f474..ac07bb7d 100644 --- a/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java +++ b/policy-management/src/main/java/org/openecomp/policy/drools/controller/internal/NullDroolsController.java @@ -21,7 +21,9 @@ package org.openecomp.policy.drools.controller.internal; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.openecomp.policy.drools.controller.DroolsController; import org.openecomp.policy.drools.event.comm.TopicSink; @@ -31,16 +33,6 @@ import org.openecomp.policy.drools.protocol.coders.TopicCoderFilterConfiguration * no-op Drools Controller */ public class NullDroolsController implements DroolsController { - - /** - * empty cached events - */ - protected static final String[] emptyRecentEvents = new String[0]; - - /** - * empty session names - */ - protected static final List<String> emptySessionNames = new ArrayList<String>(); /** * {@inheritDoc} @@ -128,7 +120,7 @@ public class NullDroolsController implements DroolsController { @Override public String getVersion() { return NO_VERSION; - } + } /** * {@inheritDoc} @@ -142,6 +134,14 @@ public class NullDroolsController implements DroolsController { * {@inheritDoc} */ @Override + public List<String> getCanonicalSessionNames() { + return new ArrayList<String>(); + } + + /** + * {@inheritDoc} + */ + @Override public boolean offer(String topic, String event) { return false; } @@ -160,7 +160,7 @@ public class NullDroolsController implements DroolsController { */ @Override public Object[] getRecentSourceEvents() { - return NullDroolsController.emptyRecentEvents; + return new String[0]; } /** @@ -168,7 +168,7 @@ public class NullDroolsController implements DroolsController { */ @Override public String[] getRecentSinkEvents() { - return NullDroolsController.emptyRecentEvents; + return new String[0]; } /** @@ -216,4 +216,36 @@ public class NullDroolsController implements DroolsController { throw new IllegalArgumentException(this.getClass().getCanonicalName() + " invoked"); } + /** + * {@inheritDoc} + */ + @Override + public Map<String, Integer> factClassNames(String sessionName) throws IllegalArgumentException { + return new HashMap<String,Integer>(); + } + + /** + * {@inheritDoc} + */ + @Override + public long factCount(String sessionName) throws IllegalArgumentException { + return 0; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Object> facts(String sessionName, String className) { + return new ArrayList<Object>(); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Object> factQuery(String sessionName, String queryName, String queriedEntity) { + return new ArrayList<Object>(); + } + } diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java index 8f8a4ba7..d82b3724 100644 --- a/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java +++ b/policy-management/src/main/java/org/openecomp/policy/drools/protocol/coders/EventProtocolCoder.java @@ -1075,7 +1075,7 @@ abstract class GenericEventProtocolCoder { * @throws UnsupportedOperationException if the operation cannot be performed */ public String encode(String topic, Object encodedClass) - throws IllegalArgumentException, IllegalArgumentException, UnsupportedOperationException { + throws IllegalArgumentException, IllegalStateException, UnsupportedOperationException { if (encodedClass == null) { throw new IllegalArgumentException("Invalid encoded class"); @@ -1090,11 +1090,20 @@ abstract class GenericEventProtocolCoder { encodedClass); List<DroolsController> droolsControllers = droolsCreators(topic, encodedClass); + + if (droolsControllers.isEmpty()) { + if (logger.isWarnEnabled()) + logger.warn("No Drool Controllers for: " + topic + ":" + + encodedClass.getClass().getCanonicalName() + ":" + + droolsControllers + " IN " + this); + throw new IllegalArgumentException("Invalid Topic: " + topic); + } + if (droolsControllers.size() > 1) { - // unexpected - logger.warn("MULTIPLE DROOLS CONTROLLERS FOUND for: " + topic + ":" + - encodedClass.getClass().getCanonicalName() + ":" + - droolsControllers + " IN " + this); + if (logger.isWarnEnabled()) + logger.warn("MULTIPLE DROOLS CONTROLLERS FOUND for: " + topic + ":" + + encodedClass.getClass().getCanonicalName() + ":" + + droolsControllers + " IN " + this); // continue } @@ -1376,8 +1385,16 @@ abstract class GenericEventProtocolCoder { } List<DroolsController> droolsControllers = droolsCreators(topic, fact); + + if (droolsControllers.isEmpty()) { + if (logger.isWarnEnabled()) + logger.warn("No Drool Controllers for: " + topic + ":" + + fact.getClass().getCanonicalName() + ":" + + droolsControllers + " IN " + this); + throw new IllegalArgumentException("Invalid Topic: " + topic); + } + if (droolsControllers.size() > 1) { - // unexpected logger.warn("MULTIPLE DROOLS CONTROLLERS FOUND for: " + topic + ":" + fact.getClass().getCanonicalName() + ":" + droolsControllers + " IN " + this); diff --git a/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java b/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java index 48e6313a..cb5d3688 100644 --- a/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java +++ b/policy-management/src/main/java/org/openecomp/policy/drools/server/restful/RestManager.java @@ -405,16 +405,94 @@ public class RestManager { build(); } - public DroolsController getDroolsController(String controllerName) throws IllegalArgumentException { - PolicyController controller = PolicyController.factory.get(controllerName); - if (controller == null) - throw new IllegalArgumentException(controllerName + " does not exist"); - - DroolsController drools = controller.getDrools(); - if (drools == null) - throw new IllegalArgumentException(controllerName + " has no drools configuration"); - - return drools; + @GET + @Path("engine/controllers/{controllerName}/drools") + @Produces(MediaType.APPLICATION_JSON) + public Response drools(@PathParam("controllerName") String controllerName) { + try { + DroolsController drools = getDroolsController(controllerName); + return Response.status(Response.Status.OK). + entity(drools). + build(); + } catch (IllegalArgumentException | IllegalStateException e) { + logger.warn(MessageCodes.EXCEPTION_ERROR, e, + controllerName, this.toString()); + return Response.status(Response.Status.BAD_REQUEST). + entity(new Error(e.getMessage())). + build(); + } + } + + @GET + @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}") + @Produces(MediaType.APPLICATION_JSON) + public Response droolsFacts(@DefaultValue("false") @QueryParam("count") boolean count, + @PathParam("controllerName") String controllerName, + @PathParam("sessionName") String sessionName) { + try { + DroolsController drools = getDroolsController(controllerName); + if (!count) + return Response.status(Response.Status.OK). + entity(drools.factClassNames(sessionName)). + build(); + else + return Response.status(Response.Status.OK). + entity(new Long(drools.factCount(sessionName))). + build(); + } catch (IllegalArgumentException | IllegalStateException e) { + logger.warn(MessageCodes.EXCEPTION_ERROR, e, + controllerName, this.toString()); + return Response.status(Response.Status.BAD_REQUEST). + entity(new Error(e.getMessage())). + build(); + } + } + + @GET + @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}/{className}") + @Produces(MediaType.APPLICATION_JSON) + public Response droolsFacts(@DefaultValue("false") @QueryParam("count") boolean count, + @PathParam("controllerName") String controllerName, + @PathParam("sessionName") String sessionName, + @PathParam("className") String className) { + try { + DroolsController drools = getDroolsController(controllerName); + List<Object> facts = drools.facts(sessionName, className); + if (!count) + return Response.status(Response.Status.OK).entity(facts).build(); + else + return Response.status(Response.Status.OK).entity(facts.size()).build(); + } catch (IllegalArgumentException | IllegalStateException e) { + logger.warn(MessageCodes.EXCEPTION_ERROR, e, + controllerName, this.toString()); + return Response.status(Response.Status.BAD_REQUEST). + entity(new Error(e.getMessage())). + build(); + } + } + + @GET + @Path("engine/controllers/{controllerName}/drools/facts/{sessionName}/{queryName}/{queriedEntity}") + @Produces(MediaType.APPLICATION_JSON) + public Response droolsFacts(@DefaultValue("false") @QueryParam("count") boolean count, + @PathParam("controllerName") String controllerName, + @PathParam("sessionName") String sessionName, + @PathParam("queryName") String queryName, + @PathParam("queriedEntity") String queriedEntity) { + try { + DroolsController drools = getDroolsController(controllerName); + List<Object> facts = drools.factQuery(sessionName, queryName, queriedEntity); + if (!count) + return Response.status(Response.Status.OK).entity(facts).build(); + else + return Response.status(Response.Status.OK).entity(facts.size()).build(); + } catch (IllegalArgumentException | IllegalStateException e) { + logger.warn(MessageCodes.EXCEPTION_ERROR, e, + controllerName, this.toString()); + return Response.status(Response.Status.BAD_REQUEST). + entity(new Error(e.getMessage())). + build(); + } } @GET @@ -1134,6 +1212,19 @@ public class RestManager { build(); } + + protected DroolsController getDroolsController(String controllerName) throws IllegalArgumentException { + PolicyController controller = PolicyController.factory.get(controllerName); + if (controller == null) + throw new IllegalArgumentException(controllerName + " does not exist"); + + DroolsController drools = controller.getDrools(); + if (drools == null) + throw new IllegalArgumentException(controllerName + " has no drools configuration"); + + return drools; + } + /* * Helper classes for aggregation of results */ |