Sample Rules
Author:
Fluent Commerce
Changed on:
23 Oct 2023
Overview
The Rules SDK Maven archetype will generate 2 sample Rules into the Project.
- DemoSendArbitraryEvent
- DemoAddAttributeToOrder
Key points
- DemoSendArbitraryEvent
- DemoAddAttributeToOrder
DemoSendArbitraryEvent
This simple demonstrates one of the most fundamental actions for building orchestrated business logic. This simply sends an , based on the `eventName`
supplied as a parameter to the .
Sending Events from inside a is how the execution of logic can move from one to another, and provides the capability to build in complex branching and flow logic into your workflows.
1package com.acme.rule;
2
3import com.fluentretail.rubix.event.Event;
4import com.fluentretail.rubix.rule.meta.EventInfo;
5import com.fluentretail.rubix.rule.meta.ParamString;
6import com.fluentretail.rubix.rule.meta.RuleInfo;
7import com.fluentretail.rubix.v2.context.Context;
8import com.fluentretail.rubix.v2.rule.Rule;
9import com.fluentretail.rubix.v2.util.RuleUtils;
10
11import static com.fluentcommerce.util.Constants.*;
12
13@RuleInfo(
14 name = "DemoSendArbitraryEvent",
15 /*
16 * The description is how the Rule appears in the editor. Placeholders (like
17 * "{eventName}" here) represent parameters and are substituted with form
18 * fields in the editor. Every defined parameter must appear in the description
19 * and every placeholder in the description must have a corresponding @Param
20 * defined.
21 */
22 description = "Send an event called {" + EVENT_NAME_PARAMETER_NAME + "} for the target entity",
23 /*
24 * Define what types of events can trigger this Rule. This is used for
25 * workflow validation and filtering Rules in the editor.
26 */
27 accepts = {
28 @EventInfo(entityType = "ORDER"),
29 @EventInfo(entityType = "FULFILMENT"),
30 @EventInfo(entityType = "ARTICLE")
31 },
32 /*
33 * Define the event this Rule will produce. In this case the eventName comes
34 * from the parameter of the same name. The entity type/subtype/status defaults
35 * to the same value as the current event (e.g. type:ARTICLE -> type:ARTICLE).
36 */
37 produces = {
38 @EventInfo(eventName = "{" + EVENT_NAME_PARAMETER_NAME + "}")
39 }
40)
41@ParamString(name = EVENT_NAME_PARAMETER_NAME, description = "The name of event to be triggered")
42public class DemoSendArbitraryEvent implements Rule {
43
44 @Override
45 public void run(Context context) {
46
47 RuleUtils.validateAllRuleParameterValuesExist(context, EVENT_NAME_PARAMETER_NAME);
48
49 Event event = context.getEvent();
50 Event newEvent = event.toBuilder().name(context.getProp(EVENT_NAME_PARAMETER_NAME)).build();
51
52 context.action().sendEvent(newEvent);
53 }
54}
DemoAddAttributeToOrder
This demonstrates another fundamental aspect of the Fluent Platform. As the executes on the , it may require additional information or data to be attached, or stored alongside it.
All Fluent Entities are extendable by means of the Attributes field. Attributes are a simple structure that defines a Name (or key), a Type, and a Value.
This demonstrates adding a new to the for which it applies.
This also demonstrates the use of the `accepts`
parameter in the `@RuleInfo`
annotation. Since the logic within the can only apply to an , the `accepts`
parameter ensures this is only available to Workflows.
1package com.acme.rule;
2
3import com.fluentretail.rubix.foundation.graphql.type.AttributeInput;
4import com.fluentretail.rubix.foundation.graphql.com.fluentcommerce.mutations.UpdateOrderMutation;
5import com.fluentretail.rubix.foundation.graphql.type.UpdateOrderInput;
6import com.fluentretail.rubix.rule.meta.EventInfo;
7import com.fluentretail.rubix.rule.meta.ParamString;
8import com.fluentretail.rubix.rule.meta.RuleInfo;
9import com.fluentretail.rubix.v2.context.Context;
10import com.fluentretail.rubix.v2.rule.Rule;
11import com.fluentretail.rubix.v2.util.RuleUtils;
12import lombok.extern.slf4j.Slf4j;
13
14import java.util.Collections;
15
16import static com.fluentcommerce.util.Constants.*;
17
18/**
19 * You can add attributes to most Entities. They're simply a key-value pair
20 * for some data that doesn't quite fit into the defined model, typically
21 * business-specific values such as adding a customer loyalty card number
22 * to Orders made by that customer.
23 */
24@RuleInfo(
25 name = "DemoAddAttributeToOrder",
26 /*
27 * The description is how the Rule appears in the editor. Placeholders (like
28 * "{name}" and "{value}" here) represent parameters and are substituted with form
29 * fields in the editor. Every defined parameter must appear in the description
30 * and every placeholder in the description must have a corresponding @Param
31 * defined.
32 */
33 description = "Adds an attribute named {" + ATTRIBUTE_NAME_PARAMETER_NAME + "} with value {"
34 + ATTRIBUTE_VALUE_PARAMETER_NAME + "} and type {" + ATTRIBUTE_TYPE_PARAMETER_NAME + "} to the Order entity",
35 /*
36 * For this example we're restricting the Rule to apply only to Order actions.
37 * Accepts is an array, so we could add additional Entity types by adding more
38 * @EventInfo annotations. Accepts is used to validate workflows when they are
39 * updated and also to filter the Rule list in the editor.
40 */
41 accepts = {
42 @EventInfo(entityType = "ORDER")
43 }
44)
45/*
46 * This Rule takes three String parameters, one for the name of the attribute, another for the value and another for the value's type.
47 * Parameterising allows the Rule to be re-usable in different ways, for example this Rule could be used multiple times to assign
48 * several different attributes to an Entity.
49*/
50@ParamString(name = ATTRIBUTE_NAME_PARAMETER_NAME, description = "Name of the attribute to assign")
51@ParamString(name = ATTRIBUTE_VALUE_PARAMETER_NAME, description = "Value of the attribute to assign")
52@ParamString(name = ATTRIBUTE_TYPE_PARAMETER_NAME, description = "Type of the attribute to assign")
53public class DemoAddAttributeToOrder implements Rule {
54
55 @Override
56 public void run(Context context) {
57
58 RuleUtils.validateAllRuleParameterValuesExist(context, ATTRIBUTE_NAME_PARAMETER_NAME, ATTRIBUTE_VALUE_PARAMETER_NAME, ATTRIBUTE_TYPE_PARAMETER_NAME);
59
60 AttributeInput attributeInput = AttributeInput.builder()
61 .name(context.getProp(ATTRIBUTE_NAME_PARAMETER_NAME))
62 .type(context.getProp(ATTRIBUTE_TYPE_PARAMETER_NAME))
63 .value(context.getProp(ATTRIBUTE_VALUE_PARAMETER_NAME))
64 .build();
65
66 UpdateOrderInput updateOrderInput = UpdateOrderInput.builder()
67 .id(context.getEntity().getId())
68 .attributes(Collections.singletonList(attributeInput))
69 .build();
70
71 UpdateOrderMutation mutation = UpdateOrderMutation.builder()
72 .input(updateOrderInput)
73 .build();
74
75 context.action().mutation(mutation);
76 }
77}