Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fd53bdf

Browse files
committed
Add sample codes for Spring and Drools integration
1 parent c6da794 commit fd53bdf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1586
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
*.classpath
3+
*.project
4+
*.iml
5+
**/.settings/
6+
**/target/
7+
**/bin/
8+
**/.idea/

spring-drools/README.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
Drools Demo
2+
===
3+
4+
Course planner application for demonstrating Drools use-cases and configuration. Current configuration assumes a central
5+
rules repository (Drools Workbench) what will contain the rules and can be configured at runtime.
6+
7+
## `drools-demo-facts`
8+
Contains classes that are needed in authoring rules. This artifact is imported into the workbench to be able to
9+
reference fact classes.
10+
11+
## `drools-demo-app`
12+
The actual application for the course planner.
13+
14+
15+
16+
To Be able to use this sample, you need to have a running Drools Workbench on your system. The most compatible container for this is Wildfly. The setup guides for these are found below.
17+
18+
### Setup Wildfly
19+
Download [Wildfly 8](http://download.jboss.org/wildfly/8.2.1.Final/wildfly-8.2.1.Final.zip) (you could also use any version of Wildfly above 8).
20+
21+
1. Extract to desired location. For the purposes of this article, `${WILDFLY_HOME}` will refer to this path.
22+
2. Go to `${WILDFLY_HOME}/bin`
23+
3. Execute `add-user.sh`, select "a) Management User", enter your desired admin username and password then type yes to all questions. When asked to input groups, just leave it blank.
24+
4. Execute `add-user.sh` again, select "b) Application User", enter your desired Drools Workbench admin user, same as before but when asked for groups, type in "analyst,admin"
25+
5. Run wildfly by running `standalone.sh`
26+
27+
### Setup Drools Workbench
28+
Download the [Drools Workbench 6.3.0.Final](http://download.jboss.org/drools/release/6.3.0.Final/kie-drools-wb-6.3.0.Final-wildfly8.war).
29+
This version is chosen to match the version of the project dependency.
30+
31+
1. Go to [Wildfly Manager](http://localhost:9990/console/App.html) and login using your admin account.
32+
2. Go to Deployments select "Add". Then upload the Drools Workbench WAR file. ![Admin](readme-assets/038.png)
33+
3. When the upload is done, the drools application will be in http://localhost:8080/kie-drools-wb-6.3.0.Final-wildfly8
34+
4. Log-in using the Drools Admin user you've created.
35+
36+
### Setup a Drools Project
37+
Before going any further, make sure you install the `drools-demo-facts` artifact.
38+
39+
In the `drools-demo-facts` folder:
40+
41+
```
42+
$ mvn clean install
43+
```
44+
45+
This will create an artifact in your local maven repository (usually located at `~/.m2/repository/com/rmpader/course-suggestion/1.0/course-suggestion-1.0.jar`).
46+
Take note of this location because you will be uploading this particular JAR file in the workbench later. Also, make sure
47+
to remember that each time you change the facts artifact dependency in your project, it is advisable to also upload the new artifact in the workbench.
48+
Lastly, as much as possible, only upload RELEASED versions of your facts artifact. Using SNAPSHOTS are dangerous because
49+
those artifacts could change without notice.
50+
51+
Now setup a Drools Project in the Workbench.
52+
53+
* Log-in as your Drools Administration User in the workbench
54+
55+
![Login](readme-assets/023.png)
56+
57+
* Go to the artifact repository and upload the facts artifact JAR file generated earlier:
58+
59+
![Artifact Page](readme-assets/024.png)
60+
61+
![Upload artifact](readme-assets/025.png)
62+
63+
* In the **Authoring > Administration** page:
64+
65+
![Admin Page](readme-assets/026.png)
66+
67+
* Create a new organizational unit:
68+
69+
![Organizational Unit](readme-assets/027.png)
70+
71+
and a repository for the new Organizational Unit:
72+
73+
![Repo](readme-assets/028.png)
74+
75+
* Go to Project Authoring:
76+
77+
![Authoring](readme-assets/031.png)
78+
79+
* Select the correct Organizational unit and the correct repository:
80+
81+
![Select](readme-assets/041.png)
82+
83+
* Create a project:
84+
85+
![Project](readme-assets/032.png)
86+
87+
* Create a new Drool file (New Item > DRL file) with the contents of `course_suggestion.drl`. The package declaration must stay as what is generated by the workbench:
88+
89+
![DRL File](readme-assets/033.png)
90+
91+
Make sure to click on **Validate** before saving the file you will notice that some errors will pop-up. This is because we haven't added the dependencies for the facts yet.
92+
93+
* Open the Project Editor and go to the dependencies section:
94+
95+
![Project Editor](readme-assets/034.png)
96+
97+
![Deps](readme-assets/035.png)
98+
99+
* Click "Add from repository" and select the uploaded JAR file from the first step. Make sure to click the save button near the search bar afterwards.
100+
101+
![Deps2](readme-assets/036.png)
102+
103+
* Go back to your DRL file and click on validate again. There should be no more error pertaining to unresolved classes.
104+
105+
* Click "Build & Deploy" to rules and get the download link from the Artifact repository.
106+
107+
![Build](readme-assets/037.png)
108+
109+
![Link](readme-assets/042.png)
110+
111+
* The artifact URL will be `{workbench URL} + /maven2/ + value of PATH`. In this case it will be http://localhost:8080/kie-drools-wb-6.3.0.Final-wildfly8/maven2/com/rmpader/course-suggestion/1.0/course-suggestion-1.0.jar
112+
113+
* Find `RulesConfig.java` in `drools-demo-app` and change the URL to the download URL from the previous step
114+
115+
* Update the release ID in `RulesConfig.java` to the correct information of your Drools Project
116+
117+
## How to run
118+
In the `drools-demo-app` folder:
119+
120+
```
121+
$ mvn spring-boot:run
122+
```
123+
124+
125+
## Testing
126+
Use [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) to interact with
127+
the API.
128+
129+
Sample GET request:
130+
http://localhost:8081/course/suggest?math=7&software=10&electronics=5&arts=10&social_studies=7
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import com.rmpader.springdrools.fact.SubjectRating;
2+
3+
global com.rmpader.springdrools.fact.Suggestions suggestions;
4+
5+
rule "Suggest Computer Science"
6+
when
7+
SubjectRating( subject=="math", rating >= 6)
8+
SubjectRating( subject=="software", rating >= 9)
9+
SubjectRating( subject=="electronics", rating >= 3)
10+
then
11+
suggestions.addSuggestedCourseCode("COMP-SCI");
12+
end
13+
14+
rule "Suggest Theoretical Physics"
15+
when
16+
SubjectRating( subject=="math", rating >= 9)
17+
SubjectRating( subject=="physics", rating >= 9)
18+
then
19+
suggestions.addSuggestedCourseCode("THEOR-PHYS");
20+
end
21+
22+
rule "Suggest Theatrical Arts"
23+
when
24+
SubjectRating( subject=="arts", rating >= 9)
25+
SubjectRating( subject=="social_studies", rating >= 6)
26+
then
27+
suggestions.addSuggestedCourseCode("THEAT-ART");
28+
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Drools Demo Application
2+
===
3+
4+
## How to run
5+
In the `drools-demo-app-classpath` folder:
6+
7+
```
8+
$ mvn spring-boot:run
9+
```
10+
11+
12+
## Testing
13+
Use [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) to interact with
14+
the API.
15+
16+
Sample GET request:
17+
18+
* `http://localhost:8081/course/suggest?math=7&software=10&electronics=5&arts=10&social_studies=7`
19+
* Change the values as needed.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.rmpader</groupId>
8+
<artifactId>drools-demo-app-classpath</artifactId>
9+
<version>0.0.1-SNAPSHOT</version>
10+
<packaging>jar</packaging>
11+
12+
<parent>
13+
<groupId>org.springframework.boot</groupId>
14+
<artifactId>spring-boot-starter-parent</artifactId>
15+
<version>1.2.7.RELEASE</version>
16+
<relativePath/>
17+
</parent>
18+
19+
<properties>
20+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
21+
<java.version>1.8</java.version>
22+
<kie.version>6.3.0.Final</kie.version>
23+
</properties>
24+
25+
<dependencies>
26+
<dependency>
27+
<groupId>com.rmpader</groupId>
28+
<artifactId>drools-demo-facts</artifactId>
29+
<version>1.0-SNAPSHOT</version>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.springframework.boot</groupId>
33+
<artifactId>spring-boot-starter-web</artifactId>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.kie</groupId>
37+
<artifactId>kie-ci</artifactId>
38+
<version>${kie.version}</version>
39+
</dependency>
40+
41+
<dependency>
42+
<groupId>org.springframework.boot</groupId>
43+
<artifactId>spring-boot-starter-test</artifactId>
44+
<scope>test</scope>
45+
</dependency>
46+
</dependencies>
47+
48+
<build>
49+
<plugins>
50+
<plugin>
51+
<groupId>org.apache.maven.plugins</groupId>
52+
<artifactId>maven-compiler-plugin</artifactId>
53+
<configuration>
54+
<source>1.8</source>
55+
<target>1.8</target>
56+
</configuration>
57+
</plugin>
58+
<plugin>
59+
<groupId>org.springframework.boot</groupId>
60+
<artifactId>spring-boot-maven-plugin</artifactId>
61+
</plugin>
62+
</plugins>
63+
</build>
64+
65+
</project>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.rmpader.springdrools;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
6+
7+
@SpringBootApplication
8+
@EnableConfigurationProperties()
9+
public class Application {
10+
11+
public static void main(String[] args) {
12+
SpringApplication.run(Application.class, args);
13+
}
14+
15+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.rmpader.springdrools.api.endpoint;
2+
3+
import com.rmpader.springdrools.api.resource.SuggestionResponse;
4+
import com.rmpader.springdrools.service.CourseService;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.web.bind.annotation.RequestMapping;
7+
import org.springframework.web.bind.annotation.RequestMethod;
8+
import org.springframework.web.bind.annotation.RequestParam;
9+
import org.springframework.web.bind.annotation.RestController;
10+
11+
import java.util.Map;
12+
import java.util.stream.Collectors;
13+
14+
/**
15+
* @author RMPader
16+
*/
17+
@RestController
18+
@RequestMapping(value = "/course")
19+
public class CourseEndpoint {
20+
21+
@Autowired
22+
private CourseService courseService;
23+
24+
@RequestMapping(value = "/suggest",
25+
method = RequestMethod.GET)
26+
public SuggestionResponse suggestCourse(@RequestParam Map<String, String> params) {
27+
Map<String, Integer> ratings = params.entrySet()
28+
.stream()
29+
.collect(Collectors.toMap(entry -> entry.getKey(),
30+
entry -> Integer.valueOf(entry.getValue())));
31+
return courseService.suggestCourses(ratings);
32+
}
33+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.rmpader.springdrools.api.resource;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* @author RMPader
8+
*/
9+
public class SuggestionResponse {
10+
11+
private List<String> suggestions = new ArrayList<>();
12+
13+
public List<String> getSuggestions() {
14+
return suggestions;
15+
}
16+
17+
public void addSuggestion(String suggestion) {
18+
suggestions.add(suggestion);
19+
}
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.rmpader.springdrools.config;
2+
3+
import org.kie.api.KieServices;
4+
import org.kie.api.runtime.KieContainer;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
8+
import java.io.IOException;
9+
10+
/**
11+
* @author RMPader
12+
*/
13+
@Configuration
14+
public class RulesConfig {
15+
16+
@Bean
17+
public KieContainer kieContainer() throws IOException {
18+
KieServices ks = KieServices.Factory.get();
19+
return ks.getKieClasspathContainer();
20+
}
21+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.rmpader.springdrools.service;
2+
3+
import com.rmpader.springdrools.api.resource.SuggestionResponse;
4+
import com.rmpader.springdrools.fact.SubjectRating;
5+
import com.rmpader.springdrools.fact.Suggestions;
6+
import org.kie.api.runtime.KieContainer;
7+
import org.kie.api.runtime.StatelessKieSession;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.stereotype.Service;
10+
11+
import java.util.List;
12+
import java.util.Map;
13+
14+
import static java.util.stream.Collectors.toList;
15+
16+
/**
17+
* @author RMPader
18+
*/
19+
@Service
20+
public class CourseService {
21+
22+
@Autowired
23+
private KieContainer kieContainer;
24+
25+
public SuggestionResponse suggestCourses(Map<String, Integer> subjectRating) {
26+
StatelessKieSession courseMatchSession = kieContainer.newStatelessKieSession();
27+
SuggestionResponse response = new SuggestionResponse();
28+
List<Object> facts = subjectRating.entrySet()
29+
.stream()
30+
.map(stringStringEntry -> new SubjectRating(stringStringEntry.getKey(),
31+
stringStringEntry.getValue()))
32+
.collect(toList());
33+
34+
Suggestions suggestions = new Suggestions();
35+
courseMatchSession.setGlobal("suggestions", suggestions);
36+
courseMatchSession.execute(facts);
37+
38+
//TODO: retrieve course name based on course code? Maybe.
39+
suggestions.getSuggestedCourseCodes()
40+
.forEach(response::addSuggestion);
41+
42+
return response;
43+
}
44+
45+
}

0 commit comments

Comments
 (0)