Creating a Bonsai Instance¶
Creating a properly configured Bonsai instance is the first step in using the Bonsai rule engine. This guide explains the various configuration options and how to create a Bonsai instance tailored to your needs.
Using the BonsaiBuilder¶
The recommended way to create a Bonsai instance is using the BonsaiBuilder
class. In a production environment, the
properties could come from an external configuration.
Bonsai<Context> bonsai = BonsaiBuilder.builder()
.withBonsaiProperties(
BonsaiProperties.builder()
.maxAllowedVariationsPerKnot(10) // Limit variations per knot
.maxAllowedConditionsPerEdge(10) // Limit conditions per variation
.mutualExclusivitySettingTurnedOn(false)
.build())
.withBonsaiIdGenerator(new UUIDGenerator()) // Custom ID generation strategy, which you can create
.withEdgeStore(new InMemoryEdgeStore()) // Edge storage implementation
.withKeyTreeStore(new InMemoryKeyTreeStore()) // Key-Tree mapping storage
.withKnotStore(new InMemoryKnotStore()) // Knot storage implementation
.build();
Configuration Options¶
BonsaiProperties¶
BonsaiProperties
controls the behavior of the Bonsai instance:
BonsaiProperties properties = BonsaiProperties.builder()
.maxAllowedVariationsPerKnot(10) // Maximum number of variations (edges) per knot
.maxAllowedConditionsPerEdge(10) // Maximum number of conditions per edge
.mutualExclusivitySettingTurnedOn(false) // Whether edge conditions must be mutually exclusive
.build();
Key properties include:
- maxAllowedVariationsPerKnot: Limits the number of outgoing edges from a knot
- maxAllowedConditionsPerEdge: Limits the number of conditions on an edge
- mutualExclusivitySettingTurnedOn: When true, ensures that at most one edge's conditions can match for any given context
ID Generation¶
The BonsaiIdGenerator
determines how IDs are generated for knots and edges:
// Or create a custom ID generator
BonsaiIdGenerator customGenerator = new BonsaiIdGenerator() {
@Override
public String generateId() {
return "custom-" + System.currentTimeMillis();
}
};
Storage Implementations¶
Bonsai requires three storage implementations:
- KnotStore: Stores knot data
- EdgeStore: Stores edge data
- KeyTreeStore: Stores mappings between keys and root knots
In-Memory Storage¶
For development or simple applications, you can use the in-memory implementations:
KnotStore knotStore = new InMemoryKnotStore();
EdgeStore edgeStore = new InMemoryEdgeStore();
KeyTreeStore keyTreeStore = new InMemoryKeyTreeStore();
Custom Storage Implementations¶
For production use, you'll likely want to implement custom storage backends. You should definitely go through the Storage section for more details. Here's an example Redis-based knot store:
// Example Redis-based knot store
public class RedisKnotStore implements KnotStore {
private final RedisClient redisClient;
public RedisKnotStore(RedisClient redisClient) {
this.redisClient = redisClient;
}
@Override
public Knot getKnot(String knotId) {
String json = redisClient.get("knot:" + knotId);
return json != null ? deserialize(json, Knot.class) : null;
}
@Override
public void putKnot(Knot knot) {
redisClient.set("knot:" + knot.getId(), serialize(knot));
}
// Implement other methods...
}
Type Parameters¶
Bonsai is a generic class that can be parameterized with the type of context you'll be using:
// Using the default Context class
Bonsai<Context> bonsai = BonsaiBuilder.builder()
// ... configuration ...
.build();
// Using a custom Context subclass
Bonsai<UserContext> bonsai = BonsaiBuilder.builder()
// ... configuration ...
.build();
Complete Example¶
Here's a complete example of creating a Bonsai instance with custom configuration:
// Create a Bonsai instance with custom configuration
Bonsai<UserContext> bonsai = BonsaiBuilder.builder()
.withBonsaiProperties(
BonsaiProperties.builder()
.maxAllowedVariationsPerKnot(20)
.maxAllowedConditionsPerEdge(15)
.mutualExclusivitySettingTurnedOn(true)
.build())
.withEdgeStore(new RedisEdgeStore(redisClient))
.withKeyTreeStore(new RedisKeyTreeStore(redisClient))
.withKnotStore(new RedisKnotStore(redisClient))
.build();
Best Practices¶
- Choose appropriate limits: Set
maxAllowedVariationsPerKnot
andmaxAllowedConditionsPerEdge
based on your application's needs - Consider mutual exclusivity: Enable
mutualExclusivitySettingTurnedOn
if you want to ensure deterministic behavior - Use meaningful IDs: Consider a custom ID generator that produces readable IDs
- Select the right storage: Use in-memory storage for development and testing, but implement persistent storage for production
- Create a singleton: In most applications, you'll want to create a single Bonsai instance and reuse it