/* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jbpm.services.task.assignment.impl.strategy; import java.util.Collection; import java.util.Date; import java.util.Set; import java.util.TreeSet; import org.drools.core.ClassObjectFilter; import org.kie.api.KieServices; import org.kie.api.builder.KieScanner; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.rule.QueryResults; import org.kie.api.task.TaskContext; import org.kie.api.task.model.Task; import org.kie.internal.task.api.assignment.Assignment; import org.kie.internal.task.api.assignment.AssignmentStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BusinessRuleAssignmentStrategy implements AssignmentStrategy { private static final Logger logger = LoggerFactory.getLogger(BusinessRuleAssignmentStrategy.class); private static final String IDENTIFIER = "BusinessRule"; private boolean active = IDENTIFIER.equals(System.getProperty("org.jbpm.task.assignment.strategy")); private String releaseId = System.getProperty("org.jbpm.task.assignment.rules.releaseId"); private String scannerInterval = System.getProperty("org.jbpm.task.assignment.rules.scan"); private KieServices kieServices = KieServices.Factory.get(); private KieContainer kieContainer; private KieScanner kieScanner; public BusinessRuleAssignmentStrategy() { if (active) { if (releaseId == null) { throw new IllegalArgumentException("BusinessRule assignment strategy requires release id to be given via system property 'org.jbpm.task.assignment.rules.releaseId'"); } String[] gav = releaseId.split(":"); logger.debug("Creating KieContainer for {} to be used for task assignments", releaseId); this.kieContainer = kieServices.newKieContainer(kieServices.newReleaseId(gav[0], gav[1], gav[2])); if (scannerInterval != null) { Long pollingInterval = Long.parseLong(scannerInterval); logger.debug("Scanner to be enabled for {} container with polling interval set to {}", kieContainer, pollingInterval); this.kieScanner = this.kieServices.newKieScanner(kieContainer); this.kieScanner.start(pollingInterval); logger.debug("Scanner for container {} started at {}", kieContainer, new Date()); } } } @Override public String getIdentifier() { return IDENTIFIER; } @SuppressWarnings("unchecked") @Override public Assignment apply(Task task, TaskContext context, String excludedUser) { if (!active) { logger.debug("{} strategy is not active", this); return null; } logger.debug("Using rules to assign actual owner to task {}", task); KieSession kieSession = this.kieContainer.newKieSession(); try { context.loadTaskVariables(task); kieSession.insert(task); kieSession.fireAllRules(); Set<Assignment> assignments = new TreeSet<>(); String queryName = System.getProperty("org.jbpm.task.assignment.rules.query"); if (queryName != null) { logger.debug("Query {} is going to be used to retrieve results from working memory", queryName); QueryResults results = kieSession.getQueryResults(queryName); results.forEach(row -> assignments.add((Assignment)row.get("assignment"))); } else { logger.debug("No query defined, retrieving all facts of type Assignment"); Collection<Assignment> results = (Collection<Assignment>) kieSession.getObjects(new ClassObjectFilter(Assignment.class)); assignments.addAll(results); } logger.debug("Rule evaluation completed with selected assignments of {}", assignments); if (assignments.isEmpty()) { logger.debug("No assignments found by BusinessRule strategy"); return null; } Assignment selected = assignments.iterator().next(); logger.debug("Selected assignment is {} for task {}", selected, task); return selected; } finally { kieSession.dispose(); logger.debug("KieSession in BusinessRule disposed"); } } @Override public String toString() { return "BusinessRuleAssignmentStrategy [releaseId=" + releaseId + "]"; } }