blob: 8795d2d9d4ab3c3550381ed436ec7d63827b1261 [file] [view]
stormcrawler-opensearch-java
===========================
A collection of resources for [OpenSearch](https://opensearch.org/) built on the
[OpenSearch Java Client 3.x](https://opensearch.org/docs/latest/clients/java/) and
Apache HttpClient 5:
* [IndexerBolt](https://github.com/apache/stormcrawler/blob/master/external/opensearch-java/src/main/java/org/apache/stormcrawler/opensearch/bolt/IndexerBolt.java) for indexing documents crawled with StormCrawler
* [Spouts](https://github.com/apache/stormcrawler/blob/master/external/opensearch-java/src/main/java/org/apache/stormcrawler/opensearch/persistence/AggregationSpout.java) and [StatusUpdaterBolt](https://github.com/apache/stormcrawler/blob/master/external/opensearch-java/src/main/java/org/apache/stormcrawler/opensearch/persistence/StatusUpdaterBolt.java) for persisting URL information in recursive crawls
* [MetricsConsumer](https://github.com/apache/stormcrawler/blob/master/external/opensearch-java/src/main/java/org/apache/stormcrawler/opensearch/metrics/MetricsConsumer.java)
* [StatusMetricsBolt](https://github.com/apache/stormcrawler/blob/master/external/opensearch-java/src/main/java/org/apache/stormcrawler/opensearch/metrics/StatusMetricsBolt.java) for sending the breakdown of URLs per status as metrics and display its evolution over time.
This module is functionally equivalent to the legacy `external/opensearch` module
(which is based on the deprecated `RestHighLevelClient` and HttpClient 4), but
uses the typed `OpenSearchClient` and the `ApacheHttpClient5TransportBuilder`
transport. Unlike the legacy client, the Java Client 3.x no longer ships a
sniffer nor a built-in `BulkProcessor`; this module provides an internal
`AsyncBulkProcessor` that preserves the same semantics (size/count/time based
flushing, back-pressure, listener callbacks).
Getting started
---------------------
Add the dependency to your crawler project:
```xml
<dependency>
<groupId>org.apache.stormcrawler</groupId>
<artifactId>stormcrawler-opensearch-java</artifactId>
<version>${stormcrawler.version}</version>
</dependency>
```
You will of course need to have both Storm and OpenSearch installed. For the
latter, see the [OpenSearch documentation](https://opensearch.org/docs/latest/install-and-configure/install-opensearch/docker/)
for Docker-based setups.
Schemas are automatically created by the bolts on first use; you can override
them by providing your own index definitions before starting the topology.
Configuration and dashboards
---------------------
For a ready-to-use crawler configuration, example Flux topologies, index
initialization scripts and OpenSearch Dashboards exports, refer to the
[`external/opensearch`](../opensearch) module: all of those resources are
compatible with this module and have not been duplicated here.
Differences from the legacy `external/opensearch` module
---------------------
* `opensearch.<bolt>.responseBufferSize` is no longer supported. The legacy
module used the HC4-based low-level REST client and set a heap response
buffer via `HeapBufferedResponseConsumerFactory`. The HC5-based async
transport used here does not expose an equivalent per-request override, so
the key is ignored. A `WARN` is logged at startup if it is found in the
configuration; remove it when migrating.
* `opensearch.<bolt>.sniff` is no longer supported. The legacy module enabled
node auto-discovery by default via the low-level REST client `Sniffer`. The
OpenSearch Java Client 3.x does not ship a sniffer equivalent, so this
feature is dropped. Keep the `addresses` list up to date manually or put a
load balancer in front of the cluster. A `WARN` is logged at startup if the
key is found in the configuration; remove it when migrating.
* Date fields (`nextFetchDate` in the status index and `timestamp` in the
metrics index) are serialized as ISO-8601 strings produced by
`Instant#toString()` (for example `2026-01-01T00:00:00Z`). The legacy module
serializes the same fields through `XContentBuilder#timeField`, which emits
ISO-8601 strings via `ISODateTimeFormat.dateTime()` (for example
`2026-01-01T00:00:00.000Z`). Both representations are accepted by the
default OpenSearch `date` mapping and by the `date_optional_time` /
`strict_date_optional_time` formats used in the example mappings under
`src/test/resources/`. If you run a custom mapping that restricts the field
`format` to `epoch_millis`, update it to accept ISO-8601 (for example
`strict_date_optional_time||epoch_millis`) before writing with this module.