The below example code does read/load the Drools files configured as part of rules/ folder located under /src/main/resources project path in case of local Windows based development environment i.e. as part of IDE while from application jar in case of Linux/Unix based production environment.
Incorporated the approach to read/load the files using the java.lang.ClassLoader.getResource(String name) method in case of local Windows development environment while used the org.springframework.core.io.support.ResourcePatternUtils.getResourcePatternResolver(ResourceLoader resourceLoader) returned org.springframework.core.io.support.ResourcePatternResolver.getResources(String locationPattern) method to read/load the files from application jar when deployed in Linux based production environment.
NOTE: The above said example will not work if you use the command line to execute the application jar in Windows environment using the below command:
java -jar questionaries-rules-0.0.1-SNAPSHOT.jar
In this case you need to make a call to loadResourcesOfRulesFromJar() method to make it work in Windows or Linux/Unix environment.
You can add the logic to switch between the local development environment and prod environment as per your requirement either by considering OS type along with some configuration mechanism to meet the development and deployment needs.
Drools Configuration
/**
* @author dinesh.lomte
*/
package com.dl.questioneries.rules.api.config;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternUtils;
import com.dl.questioneries.rules.api.exception.SystemException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Configuration
public class DroolsConfiguration {
private final KieServices kieServices = KieServices.Factory.get();
private ResourceLoader resourceLoader;
/**
*
* @param resourceLoader
*/
@Autowired
public DroolsConfiguration(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
/**
*
* @return
* @throws SystemException
*/
@Bean
public KieContainer kieContainer() throws SystemException {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
File[] files =
System.getProperty("os.name").contains("Windows")
? loadResourcesOfRulesFromLocalSystem()
: loadResourcesOfRulesFromJar();
if (files == null || files.length == 0) {
String message = "Failed to load the '.drl' files located under resources specific rules folder.";
log.error(message);
throw new SystemException(
"SYS_ERROR_00001", message, new Exception(message));
}
for (File file : files) {
kieFileSystem.write(ResourceFactory.newFileResource(file));
}
log.info("Loaded the configured rule files successfully.");
KieBuilder Kiebuilder = kieServices.newKieBuilder(kieFileSystem);
Kiebuilder.buildAll();
return kieServices.newKieContainer(
kieServices.getRepository().getDefaultReleaseId());
}
/**
*
* @return
*/
private File[] loadResourcesOfRulesFromJar() {
log.info("Loading the configured rule files from Jar.");
Resource[] resources = null;
List<File> files = new ArrayList<>();
try {
resources = ResourcePatternUtils
.getResourcePatternResolver(resourceLoader)
.getResources("classpath*:rules/*.drl");
InputStream inputStream = null;
File file = null;
for (Resource resource : resources) {
try {
inputStream = resource.getInputStream();
file = File.createTempFile(
resource.getFilename().substring(
0, resource.getFilename().length() - 4),
".drl");
FileUtils.copyInputStreamToFile(inputStream, file);
} finally {
inputStream.close();
}
log.info("'{}'", resource.getFilename());
files.add(file);
}
} catch (IOException ioException) {
String message = new StringBuilder(
"Failed to load the '.drl' files located under resources specific rules folder.")
.append(ioException.getMessage()).toString();
log.error(message, ioException);
throw new SystemException(
"SYS_ERROR_00001", message, ioException);
}
return (File[]) files.toArray(new File[files.size()]);
}
/**
*
* @return
*/
private File[] loadResourcesOfRulesFromLocalSystem() {
log.info("Loading the configured rule files from local system.");
try {
File files = new File(
getClass().getClassLoader().getResource("rules/").getPath());
return files.listFiles();
} catch (Exception exception) {
String message = new StringBuilder(
"Failed to load the '.drl' files located under resources specific rules folder.")
.append(exception.getMessage()).toString();
log.error(message, exception);
throw new SystemException(
"SYS_ERROR_00001", message, exception);
}
}
}
Rest Controller
/**
* @author dinesh.lomte
*/
package com.dl.questioneries.rules.api.controller;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.dl.questioneries.rules.api.model.Question;
@RestController
public class QuestioneriesRulesController {
@Autowired
private KieContainer kieContainer;
/**
*
* @param question
* @return
*/
@PostMapping(path = "/getQuestion",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public Question fetchQuestion(@RequestBody Question question) {
KieSession kieSession = kieContainer.newKieSession();
kieSession.insert(question);
kieSession.fireAllRules(1);
return question;
}
}
BOOT-INF/classes/files
directory. – SudsFileNotFoundException
when I callgetResource("files/")
– Suds