Rules and patterns for implementing an Elasticsearch DataSource module in Lutece 8. DataSource/DataObject interfaces, CDI auto-discovery, @ConfigProperty injection, batch processing, two-daemon indexing, incremental updates via CDI events. Based on the elasticdata-forms module pattern.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Rules and patterns for implementing an Elasticsearch DataSource module in Lutece 8. DataSource/DataObject interfaces, CDI auto-discovery, @ConfigProperty injection, batch processing, two-daemon indexing, incremental updates via CDI events. Based on the elasticdata-forms module pattern.
Lutece 8 ElasticData DataSource Module
Before implementing a DataSource, consult ~/.lutece-references/lutece-form-module-elasticdata-forms/ — the reference implementation. The framework plugin is at ~/.lutece-references/lutece-elk-plugin-elasticdata/ and the HTTP client library at ~/.lutece-references/lutece-elk-library-elastic/.
Architecture Overview
library-elastic (HTTP/JSON wrapper around Elasticsearch REST API)
↑ used by
plugin-elasticdata (framework — already deployed)
↓ auto-discovers via CDI
module-myentity-elasticdata (@ApplicationScoped DataSource)
↓ produces
MyEntityDataObject (extends AbstractDataObject)
↓ indexed by two daemons
FullIndexingDaemon (daily, bulk reindex)
IncrementalIndexingDaemon (every 3s, processes IndexerAction queue)
Incremental path:
Entity CRUD → CDI event fired
↓ observed by
MyEntityIndexerEventListener (@ObservesAsync)
↓ calls
DataSourceIncrementalService.addTask(dataSourceId, entityId, taskType)
↓ queues in DB → daemon processes
A module provides a DataSource implementation. The plugin-elasticdata framework handles Elasticsearch communication, daemon scheduling, batch processing, and action queue management.
CDI auto-discovery — any @ApplicationScoped class implementing DataSource is automatically registered:
IndexerAction.TASK_CREATE (1) — Index new document (also used for updates)
IndexerAction.TASK_MODIFY (2) — Partial update
IndexerAction.TASK_DELETE (3) — Delete by query
The IncrementalIndexingDaemon runs every 3 seconds and processes the queue. It handles conflict resolution automatically (e.g., CREATE followed by DELETE = task removed).
Step 5 — Elasticsearch Mappings
Provide custom mappings via @ConfigProperty or override getMappings():
TIMESTAMP_AND_LOCATION_MAPPINGS — timestamp + geo_point for spatial data
Use custom mappings when you need keyword fields for aggregations, specific analyzers, or nested objects.
Step 6 — Configuration Properties
# elasticdata-myentity.properties (MicroProfile Config)
# DataSource identity (injected via @ConfigProperty)
elasticdata-myentity.dataSource.id=MyEntityDataSource
elasticdata-myentity.dataSource.name=My Entity Data Source
elasticdata-myentity.dataSource.targetIndexName=myentity
elasticdata-myentity.dataSource.mappings={"mappings":{"properties":{"timestamp":{"type":"date","format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"}}}}
The Elasticsearch server connection is configured at the plugin-elasticdata level (not in your module):
# Already in plugin-elasticdata config (do NOT duplicate)
elasticdata.elastic_server.url=http://localhost:9200
elasticdata.elastic_server.login=
elasticdata.elastic_server.pwd=
elasticdata.bulk_batch_size=10000
Step 7 — plugin.xml
<plug-in><name>myentity-elasticdata</name><class>fr.paris.lutece.portal.service.plugin.PluginDefaultImplementation</class><version>1.0.0-SNAPSHOT</version><description>ElasticData module for MyEntity plugin</description><core-version-dependency><min-core-version>8.0.0</min-core-version></core-version-dependency><db-pool-required>0</db-pool-required></plug-in>
No daemons or admin features needed — the plugin-elasticdata framework provides them.
IDataSourceExternalAttributesProvider (Advanced)
Enrich data objects from other modules with additional attributes:
Process IndexerAction queue (create/update/delete)
Transaction safety: Incremental indexing wraps ES operations + DB task removal in a single transaction. If ES fails, the task remains in queue for retry.