diff options
Diffstat (limited to 'policy-core/src/main/java/org/onap/policy/drools/util/KieUtils.java')
-rw-r--r-- | policy-core/src/main/java/org/onap/policy/drools/util/KieUtils.java | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/policy-core/src/main/java/org/onap/policy/drools/util/KieUtils.java b/policy-core/src/main/java/org/onap/policy/drools/util/KieUtils.java index 03a307cf..bd1c6cee 100644 --- a/policy-core/src/main/java/org/onap/policy/drools/util/KieUtils.java +++ b/policy-core/src/main/java/org/onap/policy/drools/util/KieUtils.java @@ -22,14 +22,25 @@ package org.onap.policy.drools.util; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; import lombok.NonNull; +import org.apache.commons.io.IOUtils; import org.drools.compiler.kie.builder.impl.InternalKieModule; import org.drools.compiler.kproject.models.KieModuleModelImpl; +import org.drools.core.impl.KnowledgeBaseImpl; +import org.kie.api.KieBase; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; @@ -41,12 +52,20 @@ import org.kie.api.definition.rule.Rule; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.scanner.KieMavenRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Kie related utilities. */ public class KieUtils { + private static final Logger logger = LoggerFactory.getLogger(KieUtils.class); + + // resource names used by 'resourceToPackages' + private static final String RESOURCE_PREFIX = "src/main/resources/drools"; + private static final String RESOURCE_SUFFIX = ".drl"; + private KieUtils() { // Utility class } @@ -154,4 +173,80 @@ public class KieUtils { } return kieBuilder; } + + /** + * Find all Drools resources matching a specified name, and generate a + * collection of 'KiePackage' instances from those resources. + * + * @param classLoader the class loader to use when finding resources, or + * when building the 'KiePackage' collection + * @param resourceName the resource name, without a leading '/' character + * @return a collection of 'KiePackage' instances, or 'null' in case of + * failure + */ + public static Collection<KiePackage> resourceToPackages(ClassLoader classLoader, String resourceName) { + + // find all resources matching 'resourceName' + Enumeration<URL> resources; + try { + resources = classLoader.getResources(resourceName); + } catch (IOException e) { + logger.error("Exception fetching resources: " + resourceName, e); + return null; + } + if (!resources.hasMoreElements()) { + // no resources found + return null; + } + + // generate a 'KieFileSystem' from these resources + KieServices kieServices = KieServices.Factory.get(); + KieFileSystem kfs = kieServices.newKieFileSystem(); + int index = 1; + while (resources.hasMoreElements()) { + URL url = resources.nextElement(); + try (InputStream is = url.openStream()) { + // convert a resource to a byte array + byte[] drl = IOUtils.toByteArray(is); + + // add a new '.drl' entry to the KieFileSystem + kfs.write(RESOURCE_PREFIX + index++ + RESOURCE_SUFFIX, drl); + } catch (IOException e) { + logger.error("Couldn't read in " + url, e); + return null; + } + } + + // do a build of the 'KieFileSystem' + KieBuilder builder = kieServices.newKieBuilder(kfs, classLoader); + builder.buildAll(); + List<Message> results = builder.getResults().getMessages(); + if (!results.isEmpty()) { + logger.error("Kie build failed:\n" + results); + return null; + } + + // generate a KieContainer, and extract the package list + return kieServices.newKieContainer(builder.getKieModule().getReleaseId(), classLoader) + .getKieBase().getKiePackages(); + } + + /** + * Add a collection of 'KiePackage' instances to the specified 'KieBase'. + * + * @param kieBase the 'KieBase' instance to add the packages to + * @param kiePackages the collection of packages to add + */ + public static void addKiePackages(KieBase kieBase, Collection<KiePackage> kiePackages) { + HashSet<KiePackage> stillNeeded = new HashSet<>(kiePackages); + + // update 'stillNeeded' by removing any packages we already have + stillNeeded.removeAll(kieBase.getKiePackages()); + + if (!stillNeeded.isEmpty()) { + // there are still packages we need to add -- + // this code makes use of an internal class and method + ((KnowledgeBaseImpl)kieBase).addPackages(stillNeeded); + } + } } |