JanusGraph / JanusGraph/janusgraph
RestElasticSearchClient.clearStore does not lowercase the store name, so DISCARD_INDEX cannot delete data for mixed-case index names
- Dominant language
- Java
- Stars
- 5.8k
- Forks
- 1.2k
- Avg merge
- 13h 53m
- Merged PRs (30d)
- 6
Description
- Version: `master` (`ac0eb23`)
- Storage Backend: any
- Mixed Index Backend: elasticsearch
- Expected Behavior: `mgmt.updateIndex(index, SchemaAction.DISCARD_INDEX)` on a mixed index deletes the backing Elasticsearch index.
- Current Behavior: for any mixed index whose name contains an uppercase character, it targets an index name that cannot exist, so the data is never deleted.
### Details
Every read and write path derives the Elasticsearch index name through `generateIndexStoreName`, which **lowercases** the store:
https://github.com/JanusGraph/janusgraph/blob/ac0eb2392ddad3d96ab8cde2a5a9a123dbc5d839/janusgraph-es/src/main/java/org/janusgraph/diskstorage/es/ElasticSearchIndex.java#L530-L532
```java
private String generateIndexStoreName(String store){
return indexName + INDEX_NAME_SEPARATOR + store.toLowerCase();
}
```
`clearStore` composes the same name by hand, and does not:
https://github.com/JanusGraph/janusgraph/blob/ac0eb2392ddad3d96ab8cde2a5a9a123dbc5d839/janusgraph-es/src/main/java/org/janusgraph/diskstorage/es/rest/RestElasticSearchClient.java#L390-L395
```java
public void clearStore(String indexName, String storeName) throws IOException {
String name = indexName + "_" + storeName; // no toLowerCase()
if (indexExists(name)) {
performRequest(REQUEST_TYPE_DELETE, REQUEST_SEPARATOR + indexName + "_" + storeName, null);
}
}
```
A mixed index's store name is its JanusGraph index name verbatim (`createMixedIndex` sets `INDEXSTORE_NAME = indexName`), and index names are case-sensitive on the JanusGraph side. So for `mgmt.buildIndex("vertexByName", Vertex.class).buildMixedIndex(...)`:
| | |
|---|---|
| written and queried as | `_vertexbyname` |
| `clearStore` targets | `_vertexByName` |
Since Elasticsearch requires lowercase index names, the second cannot exist. Either `indexExists` returns false and the call silently no-ops, or ES rejects the invalid name and `ManagementSystem` reports the misleading `"Index removal is not supported for this Backend. Index must be removed in the indexing system directly."` Either way the documents remain and the schema is marked `DISCARDED`, so JanusGraph believes the data is gone.
Related, and worth considering separately: because `generateIndexStoreName` lowercases, two mixed indexes differing only in case (`byName` and `byname`) map to the *same* Elasticsearch index and silently share documents. `ManagementSystem.checkIndexName` only enforces uniqueness on the JanusGraph side.
### Steps to Reproduce
1. Create a mixed index with an uppercase character in its name, e.g. `vertexByName`, and index some vertices.
2. `mgmt.updateIndex(mgmt.getGraphIndex("vertexByName"), SchemaAction.DISCARD_INDEX)`, then commit.
3. Observe: the schema status becomes `DISCARDED`, and `GET _cat/indices` still shows `_vertexbyname` with all its documents.
### Suggested Fix
```java
String name = indexName + "_" + storeName.toLowerCase();
```
applied to both the existence check and the delete path. Better still, have `ElasticSearchIndex` pass the already-derived name so the mapping exists in exactly one place.
Contributor guide
Research direction
Start in janusgraph-es/src/main/java/org/janusgraph/diskstorage/es/rest/RestElasticSearchClient.java, focusing on clearStore, and compare it with generateIndexStoreName in ElasticSearchIndex.java. Reproduce the mixed-case vertexByName scenario and verify that DISCARD_INDEX removes the lowercased Elasticsearch index and its documents.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elasticsearch, java
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100