ess is a multi-module Elasticsearch-backed service built around two main use cases:
- content search across several dataset indexes
- Reddit-style post submission, voting, and ranked feeds
The runtime lives in ess-app, shared models live in ess-api, and higher-level
integration coverage lives in ess-testing.
Stack: Spring Boot, Elasticsearch, Kibana, Spring Security, Swagger/OpenAPI, Cucumber
Docs: ARCHITECTURE.md · ess-api · ess-app · ess-testing
Prerequisites:
- Docker
- JDK + Maven
docker compose -f microservices/ess/compose.yaml up -dBy default the local stack exposes:
| URL | Description |
|---|---|
| http://localhost:9200 | Elasticsearch |
| http://localhost:5601 | Kibana |
mvn -pl microservices/ess/ess-app spring-boot:runApplication URLs:
| URL | Description |
|---|---|
| http://localhost:8001/swagger-ui/index.html | Swagger UI |
| http://localhost:8001/v3/api-docs | OpenAPI JSON |
Before using the APIs, create the indexes you need through the admin endpoints:
PUT /api/admin/indexes/postsPUT /api/admin/indexes/user-votesPUT /api/admin/indexes/booksPUT /api/admin/indexes/companiesPUT /api/admin/indexes/moviesPUT /api/admin/indexes/musicPUT /api/admin/indexes/people
Practical bootstrap order:
- for search demos: create the content indexes you plan to query
- for post/vote/ranking demos: create
postsanduser-votes
Full endpoint details and payload examples live in ess-app → API Reference.
| Module | Responsibility |
|---|---|
| ess-api | Shared DTOs, enums, validation annotations, API constants |
| ess-app | Spring Boot runtime: controllers, services, Elasticsearch client config, scheduler |
| ess-testing | Cucumber integration tests, downloader utilities, dataset-oriented test support |
| Area | Base path | What it does |
|---|---|---|
| Admin | /api/admin |
Creates Elasticsearch indexes for content, posts, and user votes |
| Search | /api/services/search |
Generic wildcard fan-out search plus dedicated wildcard, fuzzy, interval, and span endpoints |
| Votes | /api/services/user-votes |
Accepts UPVOTE, DOWNVOTE, and NOVOTE, stores one vote doc per (userId, postId) |
| Posts | /api/services/posts |
Creates new post documents with generated IDs and initial ranking fields |
| Post ranking | /api/services/posts/ranking |
Reads ranked feeds: best, new, hot, rising, top, and top/{window} |
Search notes:
SearchService.search()uses Elasticsearchmsearchand fans out wildcard queries across metadata-defined fields- queryable fields are driven by
ess-app/src/main/resources/metadata.json - dedicated search endpoints use explicit query factories for wildcard, fuzzy, interval, and span queries
Ranking notes:
topsorts by denormalizedkarmabestuses the Wilson score lower boundhotuses a Reddit-style time-decayed scorerisingemphasizes recent vote velocitytop/{window}supportsday,week,month, andyear
The repo-local Docker stack is defined in compose.yaml.
Default local behavior:
- Elasticsearch image:
docker.elastic.co/elasticsearch/elasticsearch:9.3.1-arm64 - Kibana image:
docker.elastic.co/kibana/kibana:9.3.1-arm64 - Elasticsearch security: enabled
- Elasticsearch HTTP SSL: disabled
- default Elasticsearch credentials:
- user:
elastic - password:
FverGoe0
- user:
- default Kibana system password:
JgI820Ee
Important application defaults from ess-app/src/main/resources/application.yaml:
- app port:
8001 - Elasticsearch host:
localhost:9200 - SSL to Elasticsearch: disabled by default
- client timeouts and retry/backoff are configured in the custom Elasticsearch transport
- scheduler is enabled by default
To stop the local stack:
docker compose -f microservices/ess/compose.yaml downIf you need different local ports, passwords, or image tags, override the compose environment variables such as:
ES_LOCAL_VERSIONES_LOCAL_PORTKIBANA_LOCAL_PORTES_LOCAL_PASSWORDKIBANA_LOCAL_PASSWORD
Scheduler behavior:
SchedulerJobsruns hourly with cron0 0 * * * *- the job is enabled when
scheduler.enabled=true - it removes
user-votesdocuments older than365days
Error handling behavior:
- validation and malformed-request errors return
400 IOExceptionreturns503- all other unhandled errors return
500
Security note:
- the app currently allows anonymous access to all endpoints
- CSRF is disabled
- HTTP basic support is configured, but no route currently requires authentication
# shared API models and validation
mvn -pl microservices/ess/ess-api test
# Spring Boot application tests
mvn -pl microservices/ess/ess-app test
# Cucumber + Testcontainers integration tests
mvn -pl microservices/ess/ess-testing testSee module-specific docs for more detail: