Write your first custom Rule using the Fluent Rules SDK (Hello World)
Author:
Lesley Dean
Changed on:
1 July 2024
Key Points
- A step-by-Step guide to creating your first custom Rule to log "Hello World"
Author:
Lesley Dean
Changed on:
1 July 2024
`LogAction`.A `LogAction` creates an `ORCHESTRATION_AUDIT` Event which can be retrieved using the Event API.`rule` folder of your Plugin Project.`src/main/java/com/acme/rule``LogHelloWorld.java``com.fluentretail.rubix.v2.rule.Rule` interface, and implement the `run` method.`run(C context)``@RuleInfo` annotation.`com.fluentretail.rubix.rule.meta.RuleInfo``name` field of the `@RuleInfo` to "LogHelloWorld"`description` field to "Say Hello to the World"`run` method, produce a `LogAction` by accessing the `ActionFactory` on the incoming `context`:`context.action().log();``message` parameter to "Hello World"`detailedMessage` parameter to "This is a log message that says Hello World"`attributes` parameter to an empty ArrayList: `new ArrayList<>()``rule` folder under your `src/test/java`.`src/test/java/com/acme/rule``LogHelloWorldTest.java``private final LogHelloWorld rule = new LogHelloWorld();``private AutoCloseable mocks;``private Context context;``private ActionFactory actionFactory;``setUp` method, annotated with `@Before`:`mocks = MockitoAnnotations.openMocks(this);``when(context.action()).thenReturn(actionFactory);``tearDown` method, annotated with `@After`:`mocks.close();``run_producesHelloWorldLog`:`@Test public void run_producesHelloWorldLog()``run` method: `rule.run(context);``LogAction` was produced with a message equal to "Hello World":`verify(actionFactory, times(1)).log(eq("Hello World"), anyString(), anyList());``rule` folder under your `src/test/java`.`src/test/java/com/acme/rule``LogHelloWorldExecutorTest.java``private static final String ORDER_ID = "123";``private static final String ORDER_REF = "HD_123";``private TestExecutor executor;``private Event event;``setUp` method, annotated with `@Before`:`RubixEntity entity = RubixEntity.builder()`:`.entityType("ORDER")``.id(ORDER_ID)``.ref(ORDER_REF)``.status("BOOKED")``.type("HD")``.flexType("ORDER::HD")``.flexVersion(1)``.build();``event = Event.builder()``.retailerId("1")``.entityId(entity.getId())``.entityRef(entity.getRef())``.entityType(entity.getEntityType())``.name("test-event")``.build();``RuleSet ruleSet = ruleSet(event, ruleInstance(LogHelloWorld.class.getSimpleName()));``executor = TestExecutor.builder()``.rule(LogHelloWorld.class)``.ruleset(ruleSet)``.entity(entity)``.build();``run_producesLogEvent`:`@Test public void run_producesLogEvent()``execute` method:`TestContext testContext = executor.execute(event);``assertEquals(1, testContext.countActionsOfType(TestContext.LogAction.class));`1package com.fluentcommerce.rule;
2
3import com.fluentretail.rubix.rule.meta.RuleInfo;
4import com.fluentretail.rubix.v2.context.Context;
5import com.fluentretail.rubix.v2.rule.Rule;
6
7import java.util.ArrayList;
8
9@RuleInfo(name = "LogHelloWorld", description = "Say Hello to the World")
10public class LogHelloWorld implements Rule {
11 @Override
12 public <C extends Context> void run(C context) {
13 context.action().log("Hello World", "This is a log message that says Hello World", new ArrayList<>());
14 }
15}1package com.fluentcommerce.rule;
2
3import com.fluentretail.rubix.v2.action.ActionFactory;
4import com.fluentretail.rubix.v2.context.Context;
5import org.junit.After;
6import org.junit.Before;
7import org.junit.Test;
8import org.mockito.Mock;
9import org.mockito.MockitoAnnotations;
10
11import static org.mockito.Mockito.*;
12
13public class LogHelloWorldTest {
14
15 private final LogHelloWorld rule = new LogHelloWorld();
16 private AutoCloseable mocks;
17
18 @Mock
19 private Context context;
20
21 @Mock
22 private ActionFactory actionFactory;
23
24 @Before
25 public void setUp() throws Exception {
26 mocks = MockitoAnnotations.openMocks(this);
27
28 when(context.action()).thenReturn(actionFactory);
29 }
30
31 @After
32 public void tearDown() throws Exception {
33 mocks.close();
34 }
35
36 @Test
37 public void run_producesHelloWorldLog() {
38
39 // arrange:
40
41 // act:
42 rule.run(context);
43
44 // assert:
45 verify(actionFactory, times(1)).log(eq("Hello World"), anyString(), anyList());
46 }
47}1package com.fluentcommerce.rule;
2
3import com.fluentretail.api.model.RubixEntity;
4import com.fluentretail.rubix.event.Event;
5import com.fluentretail.rubix.v2.test.TestContext;
6import com.fluentretail.rubix.v2.test.TestExecutor;
7import com.fluentretail.rubix.workflow.RuleSet;
8import org.junit.Before;
9import org.junit.Test;
10
11import static com.fluentretail.rubix.test.TestUtils.ruleInstance;
12import static com.fluentretail.rubix.test.TestUtils.ruleSet;
13import static org.junit.Assert.assertEquals;
14
15public class LogHelloWorldExecutorTest {
16
17 private static final String ORDER_ID = "123";
18 private static final String ORDER_REF = "HD_123";
19
20 private TestExecutor executor;
21
22 private Event event;
23
24 @Before
25 public void setUp() {
26
27 // Setup up an instance of an Orchestrate-able Entity
28 RubixEntity entity = RubixEntity.builder()
29 .entityType("ORDER")
30 .id(ORDER_ID)
31 .ref(ORDER_REF)
32 .status("BOOKED")
33 .type("HD")
34 .flexType("ORDER::HD")
35 .flexVersion(1)
36 .build();
37
38 // Create an Event to trigger the Ruleset
39 event = Event.builder()
40 .retailerId("1")
41 .entityId(entity.getId())
42 .entityRef(entity.getRef())
43 .entityType(entity.getEntityType())
44 .name("test-event")
45 .build();
46
47 // Create an instance of a Ruleset which contains an instance of the Rule configured with the Parameters
48 RuleSet ruleSet = ruleSet(event, ruleInstance(LogHelloWorld.class.getSimpleName()));
49
50 // Set up a TestExecutor to simulate Orchestration Engine
51 executor = TestExecutor.builder()
52 .rule(LogHelloWorld.class)
53 .ruleset(ruleSet)
54 .entity(entity)
55 .build();
56
57 }
58
59 @Test
60 public void run_producesLogEvent() {
61
62 TestContext testContext = executor.execute(event);
63
64 assertEquals(1, testContext.countActionsOfType(TestContext.LogAction.class));
65 }
66}