diff --git a/pom.xml b/pom.xml index 3b4b5f847c..3f8eeb6264 100644 --- a/pom.xml +++ b/pom.xml @@ -212,6 +212,7 @@ spring-data-gemfire cucumber mybatis + spring-drools diff --git a/spring-drools/pom.xml b/spring-drools/pom.xml new file mode 100644 index 0000000000..8afdae0d84 --- /dev/null +++ b/spring-drools/pom.xml @@ -0,0 +1,130 @@ + + + 4.0.0 + + com.baeldung + spring-drools + 1.0.0-SNAPSHOT + + 1.1.1.RELEASE + 4.0-alpha6 + 7.0.0.CR1 + 3.13 + 2.19.1 + + + + + io.spring.platform + platform-bom + ${spring-boot-version} + pom + import + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-actuator + + + org.apache.httpcomponents + httpcore + ${http-component-version} + + + + org.kie + kie-ci + ${drools-version} + + + org.drools + drools-decisiontables + ${drools-version} + + + + org.drools + drools-core + ${drools-version} + + + org.drools + drools-compiler + ${drools-version} + + + org.apache.poi + poi + ${apache-poi-version} + + + + org.apache.poi + poi-ooxml + ${apache-poi-version} + + + org.kie + kie-spring + 6.4.0.Final + + + org.springframework + spring-tx + + + org.springframework + spring-beans + + + org.springframework + spring-core + + + org.springframework + spring-context + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire-plugin-version} + + + **/*IntegrationTest.java + + + + + + \ No newline at end of file diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/Application.java b/spring-drools/src/main/java/com/baeldung/spring/drools/Application.java new file mode 100644 index 0000000000..8f5b915f88 --- /dev/null +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/Application.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.drools; + + +import com.baeldung.spring.drools.model.Applicant; +import com.baeldung.spring.drools.model.Product; +import com.baeldung.spring.drools.model.SuggestedRole; +import com.baeldung.spring.drools.service.ApplicantService; +import com.baeldung.spring.drools.service.ProductService; +import org.kie.api.KieServices; +import org.kie.api.runtime.KieContainer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(DroolConfiguration.class) +public class Application { + + public static void main(String[] args) { + ApplicationContext ctx = SpringApplication.run(Application.class, args); + ApplicantService applicantService=(ApplicantService)ctx.getBean("applicantService"); + applicantService.suggestARoleForApplicant(new Applicant("Baljeet",37,1200000.0,8),new SuggestedRole()); + + ProductService productService=(ProductService)ctx.getBean("productService"); + Product returnedProduct=productService.applyLabelToProduct(new Product("Microwave","Book")); + } + +} diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/DroolConfiguration.java b/spring-drools/src/main/java/com/baeldung/spring/drools/DroolConfiguration.java new file mode 100644 index 0000000000..7a5e833ed5 --- /dev/null +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/DroolConfiguration.java @@ -0,0 +1,83 @@ +package com.baeldung.spring.drools; + +import com.baeldung.spring.drools.service.ApplicantService; +import com.baeldung.spring.drools.service.ProductService; +import org.kie.api.KieBase; +import org.kie.api.KieServices; +import org.kie.api.builder.*; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieSession; +import org.kie.internal.io.ResourceFactory; +import org.kie.spring.KModuleBeanFactoryPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.io.support.ResourcePatternResolver; + +import java.io.IOException; + +@Configuration +public class DroolConfiguration { + + private static final String RULES_PATH = "com/baeldung/spring/drools/rules/"; + + @Bean + public KieFileSystem kieFileSystem() throws IOException { + KieFileSystem kieFileSystem = getKieServices().newKieFileSystem(); + for (Resource file : getRuleFiles()) { + kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + file.getFilename(), "UTF-8")); + } + return kieFileSystem; + } + + private Resource[] getRuleFiles() throws IOException { + ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); + return resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "**/*.*"); + } + + @Bean + public KieContainer kieContainer() throws IOException { + final KieRepository kieRepository = getKieServices().getRepository(); + + kieRepository.addKieModule(new KieModule() { + public ReleaseId getReleaseId() { + return kieRepository.getDefaultReleaseId(); + } + }); + + KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem()); + kieBuilder.buildAll(); + + return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId()); + } + + private KieServices getKieServices() { + return KieServices.Factory.get(); + } + + @Bean + public KieBase kieBase() throws IOException { + return kieContainer().getKieBase(); + } + + @Bean + public KieSession kieSession() throws IOException { + return kieContainer().newKieSession(); + } + + @Bean + public ApplicantService getApplicantService(){ + return new ApplicantService(); + } + + @Bean + public ProductService getProductService(KieContainer kieContainer){ + return new ProductService(); + } + + @Bean + public KModuleBeanFactoryPostProcessor kiePostProcessor() { + return new KModuleBeanFactoryPostProcessor(); + } +} \ No newline at end of file diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/model/Applicant.java b/spring-drools/src/main/java/com/baeldung/spring/drools/model/Applicant.java new file mode 100644 index 0000000000..f28d0fcab7 --- /dev/null +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/model/Applicant.java @@ -0,0 +1,48 @@ +package com.baeldung.spring.drools.model; + +public class Applicant { + + private String name; + private int age; + private double currentSalary; + private int experienceInYears; + + public Applicant(String name, int age, Double currentSalary, int experienceInYears) { + this.name = name; + this.age = age; + this.currentSalary = currentSalary; + this.experienceInYears = experienceInYears; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Double getCurrentSalary() { + return currentSalary; + } + + public void setCurrentSalary(Double currentSalary) { + this.currentSalary = currentSalary; + } + + public int getExperienceInYears() { + return experienceInYears; + } + + public void setExperienceInYears(int experienceInYears) { + this.experienceInYears = experienceInYears; + } +} diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/model/Product.java b/spring-drools/src/main/java/com/baeldung/spring/drools/model/Product.java new file mode 100644 index 0000000000..a861df5834 --- /dev/null +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/model/Product.java @@ -0,0 +1,38 @@ +package com.baeldung.spring.drools.model; + +public class Product { + private String name; + private String type; + + private String label; + + public Product(String name, String type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + +} diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/model/SuggestedRole.java b/spring-drools/src/main/java/com/baeldung/spring/drools/model/SuggestedRole.java new file mode 100644 index 0000000000..1ace5aa4ae --- /dev/null +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/model/SuggestedRole.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.drools.model; + +public class SuggestedRole { + + private String role; + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } +} diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/service/ApplicantService.java b/spring-drools/src/main/java/com/baeldung/spring/drools/service/ApplicantService.java new file mode 100644 index 0000000000..f78ffe668b --- /dev/null +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/service/ApplicantService.java @@ -0,0 +1,25 @@ +package com.baeldung.spring.drools.service; + +import com.baeldung.spring.drools.model.Applicant; +import com.baeldung.spring.drools.model.SuggestedRole; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ApplicantService { + + @Autowired + private KieContainer kieContainer; + + public SuggestedRole suggestARoleForApplicant(Applicant applicant,SuggestedRole suggestedRole){ + KieSession kieSession = kieContainer.newKieSession(); + kieSession.insert(applicant); + kieSession.setGlobal("suggestedRole",suggestedRole); + kieSession.fireAllRules(); + System.out.println(suggestedRole.getRole()); + return suggestedRole; + + } +} diff --git a/spring-drools/src/main/java/com/baeldung/spring/drools/service/ProductService.java b/spring-drools/src/main/java/com/baeldung/spring/drools/service/ProductService.java new file mode 100644 index 0000000000..21ca9c9730 --- /dev/null +++ b/spring-drools/src/main/java/com/baeldung/spring/drools/service/ProductService.java @@ -0,0 +1,24 @@ +package com.baeldung.spring.drools.service; + +import com.baeldung.spring.drools.model.Product; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ProductService { + + @Autowired + private KieContainer kieContainer; + + public Product applyLabelToProduct(Product product){ + KieSession kieSession = kieContainer.newKieSession(); + kieSession.insert(product); + kieSession.fireAllRules(); + System.out.println(product.getLabel()); + return product; + + } + +} diff --git a/spring-drools/src/main/resources/com/baeldung/spring/drools/rules/Product_rules.xls b/spring-drools/src/main/resources/com/baeldung/spring/drools/rules/Product_rules.xls new file mode 100644 index 0000000000..24caaf2470 Binary files /dev/null and b/spring-drools/src/main/resources/com/baeldung/spring/drools/rules/Product_rules.xls differ diff --git a/spring-drools/src/main/resources/com/baeldung/spring/drools/rules/SuggestApplicant.drl b/spring-drools/src/main/resources/com/baeldung/spring/drools/rules/SuggestApplicant.drl new file mode 100644 index 0000000000..baaf29d0b4 --- /dev/null +++ b/spring-drools/src/main/resources/com/baeldung/spring/drools/rules/SuggestApplicant.drl @@ -0,0 +1,31 @@ +package com.baeldung.spring.drools.rules; + +import com.baeldung.spring.drools.model.Applicant; + +global com.baeldung.spring.drools.model.SuggestedRole suggestedRole; + +dialect "mvel" + +rule "Suggest Manager Role" + when + Applicant(experienceInYears > 10) + Applicant(currentSalary > 1000000 && currentSalary <= 2500000) + then + suggestedRole.setRole("Manager"); +end + +rule "Suggest Senior developer Role" + when + Applicant(experienceInYears > 5 && experienceInYears <= 10) + Applicant(currentSalary > 500000 && currentSalary <= 1500000) + then + suggestedRole.setRole("Senior developer"); +end + +rule "Suggest Developer Role" + when + Applicant(experienceInYears > 0 && experienceInYears <= 5) + Applicant(currentSalary > 200000 && currentSalary <= 1000000) + then + suggestedRole.setRole("Developer"); +end diff --git a/spring-drools/src/test/java/com/baeldung/spring/drools/service/ApplicantServiceIntegrationTest.java b/spring-drools/src/test/java/com/baeldung/spring/drools/service/ApplicantServiceIntegrationTest.java new file mode 100644 index 0000000000..d7e7634c00 --- /dev/null +++ b/spring-drools/src/test/java/com/baeldung/spring/drools/service/ApplicantServiceIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.drools.service; + +import com.baeldung.spring.drools.Application; +import com.baeldung.spring.drools.DroolConfiguration; +import com.baeldung.spring.drools.model.Applicant; +import com.baeldung.spring.drools.model.SuggestedRole; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static junit.framework.Assert.assertNull; +import static junit.framework.TestCase.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {DroolConfiguration.class}) +public class ApplicantServiceIntegrationTest { + + @Autowired + ApplicantService applicantService; + + @Test + public void whenCriteriaMatching_ThenSuggestManagerRole(){ + Applicant applicant=new Applicant("Davis",37,1600000.0,11); + SuggestedRole suggestedRole=new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant,suggestedRole); + assertEquals("Manager",suggestedRole.getRole()); + } + + @Test + public void whenCriteriaMatching_ThenSuggestSeniorDeveloperRole(){ + Applicant applicant=new Applicant("John",37,1200000.0,8); + SuggestedRole suggestedRole=new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant,suggestedRole); + assertEquals("Senior developer",suggestedRole.getRole()); + } + @Test + public void whenCriteriaMatching_ThenSuggestDeveloperRole(){ + Applicant applicant=new Applicant("Davis",37,800000.0,3); + SuggestedRole suggestedRole=new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant,suggestedRole); + assertEquals("Developer",suggestedRole.getRole()); + } + @Test + public void whenCriteriaNotMatching_ThenNoRole(){ + Applicant applicant=new Applicant("John",37,1200000.0,5); + SuggestedRole suggestedRole=new SuggestedRole(); + applicantService.suggestARoleForApplicant(applicant,suggestedRole); + assertNull(suggestedRole.getRole()); + } +} diff --git a/spring-drools/src/test/java/com/baeldung/spring/drools/service/ProductServiceIntegrationTest.java b/spring-drools/src/test/java/com/baeldung/spring/drools/service/ProductServiceIntegrationTest.java new file mode 100644 index 0000000000..7a442e48fd --- /dev/null +++ b/spring-drools/src/test/java/com/baeldung/spring/drools/service/ProductServiceIntegrationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.drools.service; + +import com.baeldung.spring.drools.Application; +import com.baeldung.spring.drools.DroolConfiguration; +import com.baeldung.spring.drools.model.Product; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static junit.framework.TestCase.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {DroolConfiguration.class}) +public class ProductServiceIntegrationTest { + + @Autowired + ProductService productService; + + @Test + public void whenProductTypeElectronic_ThenLabelBarcode(){ + Product product=new Product("Microwave","Electronic"); + product=productService.applyLabelToProduct(product); + assertEquals("BarCode",product.getLabel()); + } + + @Test + public void whenProductTypeBook_ThenLabelIsbn(){ + Product product=new Product("AutoBiography","Book"); + product=productService.applyLabelToProduct(product); + assertEquals("ISBN",product.getLabel()); + } +}