Developer Guide
This page is the full implementation starter for consumers integrating ConvEngine into a Spring Boot service.
Consumer Extension Map
Click each node to inspect extension timing, file, method and expected session state.
1. Start a Spring Boot project
- pom.xml
- build.gradle.kts
- Application class
Maven dependency
package: project build
XML
<dependency>
<groupId>com.github.salilvnair</groupId>
<artifactId>convengine</artifactId>
<version>1.0.15</version>
</dependency>
Gradle dependency
package: project build
KOTLIN
implementation("com.github.salilvnair:convengine:1.0.15")
Enable ConvEngine
package: com.zapper.demofile: src/main/java/com/acme/demo/DemoApplication.java
JAVA
@SpringBootApplication
@EnableConvEngine(stream = true)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2. Required schema (DDL)
- Postgres
- Oracle
- SQLite
Postgres DDL source
package: src/main/resources/sql
SQL
-- Use full script from:
-- src/main/resources/sql/ddl_postgres.sql
-- (legacy path still available: src/main/resources/sql/ddl.sql)
Oracle DDL source
package: src/main/resources/sql
SQL
-- Use full script from:
-- src/main/resources/sql/ddl_oracle.sql
SQLite DDL source
package: src/main/resources/sql
SQL
-- Use full script from:
-- src/main/resources/sql/ddl_sqlite.sql
Source of truth
Use the dialect-specific DDL file from ConvEngine:
- src/main/resources/sql/ddl_postgres.sql (or legacy src/main/resources/sql/ddl.sql)
- src/main/resources/sql/ddl_oracle.sql
- src/main/resources/sql/ddl_sqlite.sql
3. Minimal DML for FAQ scenario
FAQ DML example
package: db/seed
SQL
insert into ce_intent(intent_code, state_code, enabled)
values ('FAQ', null, true);
insert into ce_intent_classifier(intent_code, pattern, priority, enabled)
values ('FAQ', '(?i).*(office|location|address).*', 10, true);
insert into ce_response(intent_code, state_code, response_type, output_format, exact_text, enabled)
values ('FAQ', null, 'EXACT', 'TEXT', 'Our office is at 123 Tech Park, Silicon Valley.', true);
insert into ce_config(config_key, config_value, enabled)
values ('RESET_COMMAND', 'RESET_SESSION', true);
FAQ seed preview
| Table | Key values |
|---|---|
| ce_intent | intent_code=FAQ |
| ce_intent_classifier | pattern=(?i).*(office|location|address).* |
| ce_response | response_type=EXACT, output_format=TEXT |
| ce_config | RESET_COMMAND=RESET_SESSION |
4. application.yml (full consumer starter)
application.yml
package: src/main/resources
YAML
application.yml tag reference
server + datasource
| Tag | What it controls | Expected values | Default/notes |
|---|---|---|---|
| server.port | HTTP port for your app | integer | 8080 in sample |
| spring.datasource.url | DB connection URL | jdbc URL | Must point to DB with ce_* tables |
| spring.datasource.username | DB username | string | DB user with read/write on ce_* |
| spring.datasource.password | DB password | string | Use secret manager/env var in prod |
convengine.transport.sse
| Tag | What it controls | Expected values | Default/notes |
|---|---|---|---|
| convengine.transport.sse.enabled | Enable SSE endpoints/publishers | true | false | Default true |
| convengine.transport.sse.emitter-timeout-ms | SSE emitter timeout | milliseconds | Default 1800000 (30 min) |
convengine.transport.stomp
| Tag | What it controls | Expected values | Default/notes |
|---|---|---|---|
| convengine.transport.stomp.enabled | Enable STOMP websocket transport | true | false | Default false |
| convengine.transport.stomp.endpoint | WebSocket handshake endpoint | path | Default /ws-convengine |
| convengine.transport.stomp.app-destination-prefix | Client send prefix | path prefix | Default /app |
| convengine.transport.stomp.topic-prefix | Server publish topic prefix | path prefix | Default /topic |
| convengine.transport.stomp.audit-destination-base | Audit topic base path | path | Default /topic/convengine/audit |
| convengine.transport.stomp.allowed-origin-pattern | CORS origin pattern | origin pattern | Default * |
| convengine.transport.stomp.sock-js | SockJS fallback toggle | true | false | Default true |
convengine.transport.stomp.broker
| Tag | What it controls | Expected values | Default/notes |
|---|---|---|---|
| convengine.transport.stomp.broker.mode | Broker mode selection | SIMPLE | RELAY | SIMPLE uses in-memory broker |
| convengine.transport.stomp.broker.relay-destination-prefixes | Relay destinations to enable | list of prefixes | Default [/topic, /queue] |
| convengine.transport.stomp.broker.relay-host | Relay broker host | hostname | Used when mode=RELAY |
| convengine.transport.stomp.broker.relay-port | Relay broker port | integer | Default 61613 |
| convengine.transport.stomp.broker.client-login | Client login to relay | string | Optional |
| convengine.transport.stomp.broker.client-passcode | Client passcode to relay | string | Optional |
| convengine.transport.stomp.broker.system-login | System login to relay | string | Optional |
| convengine.transport.stomp.broker.system-passcode | System passcode to relay | string | Optional |
| convengine.transport.stomp.broker.virtual-host | Relay vhost | string | Optional |
| convengine.transport.stomp.broker.system-heartbeat-send-interval-ms | Outbound heartbeat | milliseconds | Default 10000 |
| convengine.transport.stomp.broker.system-heartbeat-receive-interval-ms | Inbound heartbeat | milliseconds | Default 10000 |
convengine.audit (root)
| Tag | What it controls | Expected values | Default/notes |
|---|---|---|---|
| convengine.audit.enabled | Master audit enable switch | true | false | Default true |
| convengine.audit.persist-meta | Persist `_meta` into `ce_audit.payload_json` | true | false | Default true |
| convengine.audit.level | Audit verbosity | ALL | STANDARD | ERROR_ONLY | NONE | STANDARD suppresses STEP_ENTER/STEP_EXIT |
| convengine.audit.include-stages | Allowlist stages | list of stage patterns | Empty = no allowlist filter |
| convengine.audit.exclude-stages | Blocklist stages | list of stage patterns | Applied after include filter |
convengine.audit.dispatch + rate-limit + persistence
| Tag | What it controls | Expected values | Default/notes |
|---|---|---|---|
| convengine.audit.dispatch.async-enabled | Async listener dispatch | true | false | Default false unless enabled |
| convengine.audit.dispatch.worker-threads | Async worker count | integer >= 1 | Default 2 |
| convengine.audit.dispatch.queue-capacity | Dispatch queue size | integer >= 1 | Default 2000 |
| convengine.audit.dispatch.rejection-policy | Backpressure behavior | CALLER_RUNS | DROP_NEWEST | DROP_OLDEST | ABORT | Default CALLER_RUNS |
| convengine.audit.dispatch.keep-alive-seconds | Thread keep-alive | seconds | Default 60 |
| convengine.audit.rate-limit.enabled | Enable per-window throttling | true | false | Default false |
| convengine.audit.rate-limit.max-events | Events allowed per window | integer | Default 200 |
| convengine.audit.rate-limit.window-ms | Rate-limit window | milliseconds | Default 1000 |
| convengine.audit.rate-limit.per-conversation | Bucket by conversation | true | false | Default true |
| convengine.audit.rate-limit.per-stage | Bucket by stage | true | false | Default true |
| convengine.audit.rate-limit.max-tracked-buckets | Bucket cardinality cap | integer | Default 20000 |
| convengine.audit.persistence.mode | DB persistence mode | IMMEDIATE | DEFERRED_BULK | Default IMMEDIATE |
| convengine.audit.persistence.jdbc-batch-size | Batch insert chunk size | integer | Default 200 |
| convengine.audit.persistence.max-buffered-events | Deferred buffer cap | integer | Default 5000 |
| convengine.audit.persistence.flush-stages | Stages forcing flush | list of stages | Defaults include engine failure stages |
| convengine.audit.persistence.final-step-names | Final steps that flush | list of step names | Default includes PipelineEndGuardStep |
| convengine.audit.persistence.flush-on-stop-outcome | Flush on STOP step outcome | true | false | Default true |
Streaming startup rule
If @EnableConvEngine(stream=true) is set, startup fails when both convengine.transport.sse.enabled=false and convengine.transport.stomp.enabled=false.
5. API entry and session contracts
- API Entry Point
- Session API
ConversationController.message
package: com.github.salilvnair.convengine.api.controllerfile: src/main/java/com/github/salilvnair/convengine/api/controller/ConversationController.java
JAVA
@PostMapping("/message")
public ConversationResponse message(@RequestBody ConversationRequest request) {
EngineContext engineContext = EngineContext
.builder()
.conversationId(request.getConversationId())
.userText(request.getMessage())
.inputParams(request.getInputParams())
.build();
EngineResult result = engine.process(engineContext);
return mapToResponse(result);
}
EngineSession.java (key methods)
package: com.github.salilvnair.convengine.engine.sessionfile: src/main/java/com/github/salilvnair/convengine/engine/session/EngineSession.java
JAVA
// state management
void setIntent(String intent);
void setState(String state);
// extras/input params
Map<String, Object> getInputParams();
void putInputParam(String key, Object value);
// persisted conversation row
CeConversation getConversation();
// stop pipeline with final result
void setFinalResult(EngineResult result);
6. Extension examples
- EngineStepHook
- SET_TASK Action
- Getting Extracted Data
- Interceptors / Transformers
Step hook with enum-safe matching
package: com.zapper.convengine.hooks
JAVA
@Component
public class SchemaHintHook implements EngineStepHook {
@Override
public boolean supports(EngineStep.Name stepName, EngineSession session) {
return EngineStep.Name.SchemaExtractionStep == stepName;
}
@Override
public void beforeStep(EngineStep.Name stepName, EngineSession session) {
session.putInputParam("consumer_hint", "compact");
}
}
SET_TASK via ce_rule
package: consumer DB
SQL
INSERT INTO ce_rule
(phase, intent_code, rule_type, match_pattern, action, action_value, priority, enabled, description)
VALUES
('PIPELINE_RULES', 'REQUEST_TRACKER', 'REGEX', '(?i).*track.*request.*', 'SET_TASK', 'requestTrackerTask:loadStatus', 10, true,
'Invoke consumer task bean');
Consumer task bean
package: com.zapper.convengine.tasks
JAVA
@Component("requestTrackerTask")
public class RequestTrackerTask implements CeRuleTask {
public void loadStatus(EngineSession session, CeRule rule) {
session.putInputParam("requestStatus", "IN_REVIEW");
}
}
Read schema extracted values
package: consumer logic
JAVA
String accountId = (String) session.getInputParams().get("accountId");
Interception chain
package: com.zapper.convengine.ext
JAVA
@Component
public class MyInterceptor implements ContainerDataInterceptor {
@Override
public Map<String, Object> intercept(Map<String, Object> inputParams) {
inputParams.putIfAbsent("channel", "web");
return inputParams;
}
}
@Component
public class MyContainerTransformer implements ContainerDataTransformer {
@Override
public Object transform(Object data, EngineSession session) {
return data;
}
}
@Component
public class MyResponseTransformer implements ResponseTransformer {
@Override
public OutputPayload transform(OutputPayload payload, EngineSession session) {
return payload;
}
}
7. Persistence, audit and streaming tuning
Production sequence
Start with direct HTTP + IMMEDIATE audit. Then enable async dispatch and bounded queue. Move to DEFERRED_BULK only after validating final-step flush behavior for your trace requirements.
High-impact runtime knobs
| Area | Config | Effect |
|---|---|---|
| Audit dispatch | convengine.audit.dispatch.* | Decouples request latency from listener work |
| Queue/backpressure | convengine.audit.dispatch.queue-capacity + rejection-policy | Bounds memory and defines overflow behavior |
| Audit persistence mode | convengine.audit.persistence.mode | IMMEDIATE or DEFERRED_BULK (JDBC batch flush) |
| Stage filtering | convengine.audit.level + include-stages/exclude-stages | Controls emitted/saved stages |
| Broker relay | convengine.transport.stomp.broker.mode=RELAY | Optional external broker for STOMP scaling |
| Stream hard requirement | @EnableConvEngine(stream=true) | Fails startup if both SSE and STOMP are disabled |