Merge branch 'eugenp:master' into master
This commit is contained in:
commit
d3c8cc8a34
4
docker/dockerfile-with-git/.gitmodules
vendored
Normal file
4
docker/dockerfile-with-git/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "project"]
|
||||
path = project
|
||||
url = https://github.com/eugenp/tutorials.git
|
||||
branch = master
|
13
docker/dockerfile-with-git/Dockerfile
Normal file
13
docker/dockerfile-with-git/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
ADD . /project/
|
||||
ADD /build/ /project/
|
||||
ADD /output/project.jar /project/
|
||||
|
||||
ADD ssh-private-key /root/.ssh/id_rsa
|
||||
RUN git clone git@github.com:eugenp/tutorials.git
|
||||
|
||||
ARG username=$GIT_USERNAME
|
||||
ARG password=$GIT_PASSWORD
|
||||
RUN git clone https://username:password@github.com:eugenp/tutorials.git
|
||||
|
||||
VOLUME /build/ /project/
|
||||
|
@ -0,0 +1,14 @@
|
||||
spring:
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
path: /h2-console
|
||||
console.settings.trace: false
|
||||
spring.h2.console.settings.web-allow-others: false
|
||||
datasource:
|
||||
url: jdbc:h2:mem:mydb
|
||||
username: sa
|
||||
password: password
|
||||
driverClassName: org.h2.Driver
|
||||
jpa:
|
||||
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
|
35
rule-engines/evrete/pom.xml
Normal file
35
rule-engines/evrete/pom.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.evrete</groupId>
|
||||
<artifactId>evrete</artifactId>
|
||||
<version>1.0</version>
|
||||
<name>evrete</name>
|
||||
|
||||
<properties>
|
||||
<evrete.version>2.1.04</evrete.version>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>rule-engines</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- Core library -->
|
||||
<dependency>
|
||||
<groupId>org.evrete</groupId>
|
||||
<artifactId>evrete-core</artifactId>
|
||||
<version>${evrete.version}</version>
|
||||
</dependency>
|
||||
<!-- Annotated Java classes -->
|
||||
<dependency>
|
||||
<groupId>org.evrete</groupId>
|
||||
<artifactId>evrete-dsl-java</artifactId>
|
||||
<version>${evrete.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,47 @@
|
||||
package com.baeldung.evrete.introduction;
|
||||
|
||||
import com.baeldung.evrete.introduction.model.Customer;
|
||||
import com.baeldung.evrete.introduction.model.Invoice;
|
||||
import org.evrete.KnowledgeService;
|
||||
import org.evrete.api.Knowledge;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
public class IntroductionAJR {
|
||||
public static void main(String[] args) throws IOException {
|
||||
ClassLoader classLoader = IntroductionAJR.class.getClassLoader();
|
||||
KnowledgeService service = new KnowledgeService();
|
||||
URL rulesetUrl = classLoader.getResource("rules/SalesRuleset.java");
|
||||
Knowledge knowledge = service.newKnowledge(
|
||||
"JAVA-SOURCE",
|
||||
rulesetUrl
|
||||
);
|
||||
|
||||
List<Customer> customers = Arrays.asList(
|
||||
new Customer("Customer A"),
|
||||
new Customer("Customer B"),
|
||||
new Customer("Customer C")
|
||||
);
|
||||
|
||||
Random random = new Random();
|
||||
Collection<Object> sessionData = new LinkedList<>(customers);
|
||||
for (int i = 0; i < 100_000; i++) {
|
||||
Customer randomCustomer = customers.get(random.nextInt(customers.size()));
|
||||
Invoice invoice = new Invoice(randomCustomer, 100 * random.nextDouble());
|
||||
sessionData.add(invoice);
|
||||
}
|
||||
|
||||
knowledge
|
||||
.newStatelessSession()
|
||||
.insert(sessionData)
|
||||
.fire();
|
||||
|
||||
for (Customer c : customers) {
|
||||
System.out.printf("%s:\t$%,.2f%n", c.getName(), c.getTotal());
|
||||
}
|
||||
|
||||
service.shutdown();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.baeldung.evrete.introduction;
|
||||
|
||||
import org.evrete.KnowledgeService;
|
||||
import org.evrete.api.Knowledge;
|
||||
import com.baeldung.evrete.introduction.model.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class IntroductionInline {
|
||||
public static void main(String[] args) {
|
||||
KnowledgeService service = new KnowledgeService();
|
||||
Knowledge knowledge = service
|
||||
.newKnowledge()
|
||||
.newRule("Clear total sales")
|
||||
.forEach("$c", Customer.class)
|
||||
.execute(ctx -> {
|
||||
Customer c = ctx.get("$c");
|
||||
c.setTotal(0.0);
|
||||
})
|
||||
.newRule("Compute totals")
|
||||
.forEach(
|
||||
"$c", Customer.class,
|
||||
"$i", Invoice.class
|
||||
)
|
||||
.where("$i.customer == $c")
|
||||
.execute(ctx -> {
|
||||
Customer c = ctx.get("$c");
|
||||
Invoice i = ctx.get("$i");
|
||||
c.addToTotal(i.getAmount());
|
||||
});
|
||||
|
||||
|
||||
List<Customer> customers = Arrays.asList(
|
||||
new Customer("Customer A"),
|
||||
new Customer("Customer B"),
|
||||
new Customer("Customer C")
|
||||
);
|
||||
|
||||
Random random = new Random();
|
||||
Collection<Object> sessionData = new LinkedList<>(customers);
|
||||
for (int i = 0; i < 100_000; i++) {
|
||||
Customer randomCustomer = customers.get(random.nextInt(customers.size()));
|
||||
Invoice invoice = new Invoice(randomCustomer, 100 * random.nextDouble());
|
||||
sessionData.add(invoice);
|
||||
}
|
||||
|
||||
knowledge
|
||||
.newStatelessSession()
|
||||
.insert(sessionData)
|
||||
.fire();
|
||||
|
||||
for (Customer c : customers) {
|
||||
System.out.printf("%s:\t$%,.2f%n", c.getName(), c.getTotal());
|
||||
}
|
||||
|
||||
service.shutdown();
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.baeldung.evrete.introduction.model;
|
||||
|
||||
public class Customer {
|
||||
private double total = 0.0;
|
||||
private final String name;
|
||||
|
||||
public Customer(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void addToTotal(double amount) {
|
||||
this.total += amount;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public double getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(double total) {
|
||||
this.total = total;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.baeldung.evrete.introduction.model;
|
||||
|
||||
public class Invoice {
|
||||
private final Customer customer;
|
||||
private final double amount;
|
||||
|
||||
public Invoice(Customer customer, double amount) {
|
||||
this.customer = customer;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Customer getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public double getAmount() {
|
||||
return amount;
|
||||
}
|
||||
}
|
13
rule-engines/evrete/src/main/resources/logback.xml
Normal file
13
rule-engines/evrete/src/main/resources/logback.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
@ -0,0 +1,20 @@
|
||||
package org.abc.author1;
|
||||
|
||||
import com.baeldung.evrete.introduction.model.Customer;
|
||||
import com.baeldung.evrete.introduction.model.Invoice;
|
||||
import org.evrete.dsl.annotation.Rule;
|
||||
import org.evrete.dsl.annotation.Where;
|
||||
|
||||
public class SalesRuleset {
|
||||
|
||||
@Rule
|
||||
public void rule1(Customer $c) {
|
||||
$c.setTotal(0.0);
|
||||
}
|
||||
|
||||
@Rule
|
||||
@Where("$i.customer == $c")
|
||||
public void rule2(Customer $c, Invoice $i) {
|
||||
$c.addToTotal($i.getAmount());
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.baeldung.evrete.introduction;
|
||||
|
||||
import com.baeldung.evrete.introduction.model.Customer;
|
||||
import com.baeldung.evrete.introduction.model.Invoice;
|
||||
import org.evrete.KnowledgeService;
|
||||
import org.evrete.api.Knowledge;
|
||||
import org.evrete.api.RuleSession;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
class IntroductionAJRUnitTest {
|
||||
private static KnowledgeService service;
|
||||
|
||||
@BeforeAll
|
||||
static void setUpClass() {
|
||||
service = new KnowledgeService();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void shutDownClass() {
|
||||
service.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* This test makes sure that each customer's actual total sales is equal to the amount
|
||||
* computed by the rule engine
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"true", "false"})
|
||||
void sessionTotalsTest(String type) throws IOException {
|
||||
boolean stateful = Boolean.parseBoolean(type);
|
||||
ClassLoader classLoader = IntroductionAJR.class.getClassLoader();
|
||||
KnowledgeService service = new KnowledgeService();
|
||||
Knowledge knowledge = service
|
||||
.newKnowledge(
|
||||
"JAVA-SOURCE",
|
||||
classLoader.getResource("rules/SalesRuleset.java")
|
||||
);
|
||||
|
||||
|
||||
List<Customer> customers = Arrays.asList(
|
||||
new Customer("Customer A"),
|
||||
new Customer("Customer B"),
|
||||
new Customer("Customer C")
|
||||
);
|
||||
Collection<Object> sessionData = new LinkedList<>(customers);
|
||||
|
||||
HashMap<Customer, Double> actualTotals = new HashMap<>();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 1_000; i++) {
|
||||
Customer randomCustomer = customers.get(random.nextInt(customers.size()));
|
||||
Invoice invoice = new Invoice(randomCustomer, random.nextInt(100));
|
||||
sessionData.add(invoice);
|
||||
|
||||
Double d = actualTotals.get(randomCustomer);
|
||||
if(d == null) {
|
||||
d = 0.0;
|
||||
}
|
||||
d = d + invoice.getAmount();
|
||||
actualTotals.put(randomCustomer, d);
|
||||
}
|
||||
|
||||
RuleSession<?> session = stateful ? knowledge.newStatefulSession() : knowledge.newStatelessSession();
|
||||
session
|
||||
.insert(sessionData)
|
||||
.fire();
|
||||
|
||||
for(Customer c : customers) {
|
||||
double d1 = c.getTotal();
|
||||
double d2 = actualTotals.get(c);
|
||||
assert d1 == d2;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.baeldung.evrete.introduction;
|
||||
|
||||
import com.baeldung.evrete.introduction.model.Customer;
|
||||
import com.baeldung.evrete.introduction.model.Invoice;
|
||||
import org.evrete.KnowledgeService;
|
||||
import org.evrete.api.Knowledge;
|
||||
import org.evrete.api.RuleSession;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class IntroductionInlineUnitTest {
|
||||
private static KnowledgeService service;
|
||||
|
||||
@BeforeAll
|
||||
static void setUpClass() {
|
||||
service = new KnowledgeService();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void shutDownClass() {
|
||||
service.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* This test makes sure that each customer's actual total sales is equal to the amount
|
||||
* computed by the rule engine
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"true", "false"})
|
||||
void sessionTotalsTest(String type) {
|
||||
boolean stateful = Boolean.parseBoolean(type);
|
||||
Knowledge knowledge = service
|
||||
.newKnowledge()
|
||||
.newRule("Clear customer's total sales")
|
||||
.forEach("$c", Customer.class)
|
||||
.execute(ctx -> {
|
||||
Customer c = ctx.get("$c");
|
||||
c.setTotal(0.0);
|
||||
})
|
||||
.newRule("Compute totals")
|
||||
.forEach(
|
||||
"$c", Customer.class,
|
||||
"$i", Invoice.class
|
||||
)
|
||||
.where("$i.customer == $c")
|
||||
.execute(ctx -> {
|
||||
Customer c = ctx.get("$c");
|
||||
Invoice i = ctx.get("$i");
|
||||
c.addToTotal(i.getAmount());
|
||||
});
|
||||
|
||||
|
||||
List<Customer> customers = Arrays.asList(
|
||||
new Customer("Customer A"),
|
||||
new Customer("Customer B"),
|
||||
new Customer("Customer C")
|
||||
);
|
||||
Collection<Object> sessionData = new LinkedList<>(customers);
|
||||
|
||||
HashMap<Customer, Double> actualTotals = new HashMap<>();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 1_000; i++) {
|
||||
Customer randomCustomer = customers.get(random.nextInt(customers.size()));
|
||||
Invoice invoice = new Invoice(randomCustomer, random.nextInt(100));
|
||||
sessionData.add(invoice);
|
||||
|
||||
Double d = actualTotals.get(randomCustomer);
|
||||
if(d == null) {
|
||||
d = 0.0;
|
||||
}
|
||||
d = d + invoice.getAmount();
|
||||
actualTotals.put(randomCustomer, d);
|
||||
}
|
||||
|
||||
RuleSession<?> session = stateful ? knowledge.newStatefulSession() : knowledge.newStatelessSession();
|
||||
session
|
||||
.insert(sessionData)
|
||||
.fire();
|
||||
|
||||
for(Customer c : customers) {
|
||||
double d1 = c.getTotal();
|
||||
double d2 = actualTotals.get(c);
|
||||
assert d1 == d2;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
|
||||
<modules>
|
||||
<module>easy-rules</module>
|
||||
<module>evrete</module>
|
||||
<module>openl-tablets</module>
|
||||
<module>rulebook</module>
|
||||
<!-- <module>jess</module> --> <!-- requires dependencies which are not publicly available -->
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<artifactId>spring-web-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<artifactId>spring-web-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.baeldung.parallel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class FirstParallelUnitTest {
|
||||
|
||||
@Test
|
||||
public void first() throws Exception{
|
||||
System.out.println("FirstParallelUnitTest first() start => " + Thread.currentThread().getName());
|
||||
Thread.sleep(500);
|
||||
System.out.println("FirstParallelUnitTest first() end => " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void second() throws Exception{
|
||||
System.out.println("FirstParallelUnitTest second() start => " + Thread.currentThread().getName());
|
||||
Thread.sleep(500);
|
||||
System.out.println("FirstParallelUnitTest second() end => " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.baeldung.parallel;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.ResourceLock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ParallelResourceLockUnitTest {
|
||||
|
||||
private List<String> resources;
|
||||
|
||||
@BeforeEach
|
||||
void before() {
|
||||
resources = new ArrayList<>();
|
||||
resources.add("test");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void after() {
|
||||
resources.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = "resources")
|
||||
public void first() throws Exception {
|
||||
System.out.println("ParallelResourceLockUnitTest first() start => " + Thread.currentThread().getName());
|
||||
resources.add("first");
|
||||
System.out.println(resources);
|
||||
Thread.sleep(500);
|
||||
System.out.println("ParallelResourceLockUnitTest first() end => " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ResourceLock(value = "resources")
|
||||
public void second() throws Exception {
|
||||
System.out.println("ParallelResourceLockUnitTest second() start => " + Thread.currentThread().getName());
|
||||
resources.add("second");
|
||||
System.out.println(resources);
|
||||
Thread.sleep(500);
|
||||
System.out.println("ParallelResourceLockUnitTest second() end => " + Thread.currentThread().getName());
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.baeldung.parallel;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SecondParallelUnitTest {
|
||||
|
||||
@Test
|
||||
public void first() throws Exception{
|
||||
System.out.println("SecondParallelUnitTest first() start => " + Thread.currentThread().getName());
|
||||
Thread.sleep(500);
|
||||
System.out.println("SecondParallelUnitTest first() end => " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void second() throws Exception{
|
||||
System.out.println("SecondParallelUnitTest second() start => " + Thread.currentThread().getName());
|
||||
Thread.sleep(500);
|
||||
System.out.println("SecondParallelUnitTest second() end => " + Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
junit.jupiter.execution.parallel.enabled = true
|
||||
junit.jupiter.execution.parallel.config.strategy=dynamic
|
||||
junit.jupiter.execution.parallel.mode.default = concurrent
|
||||
junit.jupiter.execution.parallel.mode.classes.default = concurrent
|
@ -15,10 +15,18 @@ public class SimpleXstreamInitializer {
|
||||
}
|
||||
|
||||
public XStream getXstreamJettisonMappedInstance() {
|
||||
return new XStream(new JettisonMappedXmlDriver());
|
||||
XStream xstream = new XStream(new JettisonMappedXmlDriver());
|
||||
xstream.allowTypesByWildcard(new String[]{
|
||||
"com.baeldung.**"
|
||||
});
|
||||
return xstream;
|
||||
}
|
||||
|
||||
public XStream getXstreamJsonHierarchicalInstance() {
|
||||
return new XStream(new JsonHierarchicalStreamDriver());
|
||||
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
|
||||
xstream.allowTypesByWildcard(new String[]{
|
||||
"com.baeldung.**"
|
||||
});
|
||||
return xstream;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user