Skip to content

Commit 6edb835

Browse files
authored
DATAES-990 - Index creation fails with Authentication object cannot be null on startup.
Only do a SpEL resolution if there is a SpEL expressin in the index name; resolve ExpressionDependencies. Original PR: #565
1 parent 6a6ead5 commit 6edb835

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
import org.springframework.data.mapping.PropertyHandler;
3232
import org.springframework.data.mapping.model.BasicPersistentEntity;
3333
import org.springframework.data.mapping.model.PersistentPropertyAccessorFactory;
34+
import org.springframework.data.spel.EvaluationContextProvider;
35+
import org.springframework.data.spel.ExpressionDependencies;
36+
import org.springframework.data.util.Lazy;
3437
import org.springframework.data.util.TypeInformation;
3538
import org.springframework.expression.EvaluationContext;
3639
import org.springframework.expression.Expression;
@@ -74,7 +77,10 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
7477
private @Nullable VersionType versionType;
7578
private boolean createIndexAndMapping;
7679
private final Map<String, ElasticsearchPersistentProperty> fieldNamePropertyCache = new ConcurrentHashMap<>();
80+
81+
private EvaluationContextProvider evaluationContextProvider = EvaluationContextProvider.DEFAULT;;
7782
private final ConcurrentHashMap<String, Expression> indexNameExpressions = new ConcurrentHashMap<>();
83+
private final Lazy<EvaluationContext> indexNameEvaluationContext = Lazy.of(this::getIndexNameEvaluationContext);
7884

7985
public SimpleElasticsearchPersistentEntity(TypeInformation<T> typeInformation) {
8086

@@ -302,12 +308,20 @@ public ElasticsearchPersistentProperty getSeqNoPrimaryTermProperty() {
302308
return seqNoPrimaryTermProperty;
303309
}
304310

311+
@Nullable
305312
@Override
306313
public ElasticsearchPersistentProperty getJoinFieldProperty() {
307314
return joinFieldProperty;
308315
}
309316

310317
// region SpEL handling
318+
319+
@Override
320+
public void setEvaluationContextProvider(EvaluationContextProvider provider) {
321+
super.setEvaluationContextProvider(provider);
322+
this.evaluationContextProvider = provider;
323+
}
324+
311325
/**
312326
* resolves all the names in the IndexCoordinates object. If a name cannot be resolved, the original name is returned.
313327
*
@@ -316,14 +330,12 @@ public ElasticsearchPersistentProperty getJoinFieldProperty() {
316330
*/
317331
private IndexCoordinates resolve(IndexCoordinates indexCoordinates) {
318332

319-
EvaluationContext context = getEvaluationContext(null);
320-
321333
String[] indexNames = indexCoordinates.getIndexNames();
322334
String[] resolvedNames = new String[indexNames.length];
323335

324336
for (int i = 0; i < indexNames.length; i++) {
325337
String indexName = indexNames[i];
326-
resolvedNames[i] = resolve(context, indexName);
338+
resolvedNames[i] = resolve(indexName);
327339
}
328340

329341
return IndexCoordinates.of(resolvedNames);
@@ -332,22 +344,49 @@ private IndexCoordinates resolve(IndexCoordinates indexCoordinates) {
332344
/**
333345
* tries to resolve the given name. If this is not successful, the original value is returned
334346
*
335-
* @param context SpEL evaluation context
336347
* @param name name to resolve
337348
* @return the resolved name or the input name if it cannot be resolved
338349
*/
339-
private String resolve(EvaluationContext context, String name) {
350+
private String resolve(String name) {
340351

341352
Assert.notNull(name, "name must not be null");
342353

343-
Expression expression = indexNameExpressions.computeIfAbsent(name, s -> {
344-
Expression expr = PARSER.parseExpression(name, ParserContext.TEMPLATE_EXPRESSION);
354+
Expression expression = getExpressionForIndexName(name);
355+
356+
String resolvedName = expression != null ? expression.getValue(indexNameEvaluationContext.get(), String.class) : null;
357+
return resolvedName != null ? resolvedName : name;
358+
}
359+
360+
/**
361+
* returns an {@link Expression} for #name if name contains a {@link ParserContext#TEMPLATE_EXPRESSION} otherwise
362+
* returns {@literal null}.
363+
*
364+
* @param name the name to get the expression for
365+
* @return Expression may be null
366+
*/
367+
@Nullable
368+
private Expression getExpressionForIndexName(String name) {
369+
return indexNameExpressions.computeIfAbsent(name, s -> {
370+
Expression expr = PARSER.parseExpression(s, ParserContext.TEMPLATE_EXPRESSION);
345371
return expr instanceof LiteralExpression ? null : expr;
346372
});
373+
}
347374

348-
String resolvedName = expression != null ? expression.getValue(context, String.class) : null;
349-
return resolvedName != null ? resolvedName : name;
375+
/**
376+
* build the {@link EvaluationContext} considering {@link ExpressionDependencies} from the name returned by
377+
* {@link #getIndexName()}.
378+
*
379+
* @return EvaluationContext
380+
*/
381+
private EvaluationContext getIndexNameEvaluationContext() {
382+
383+
Expression expression = getExpressionForIndexName(getIndexName());
384+
ExpressionDependencies expressionDependencies = expression != null ? ExpressionDependencies.discover(expression)
385+
: ExpressionDependencies.none();
386+
387+
return evaluationContextProvider.getEvaluationContext(null, expressionDependencies);
350388
}
389+
351390
// endregion
352391

353392
@Override
@@ -363,5 +402,4 @@ public Document getDefaultSettings() {
363402
.put("index.refresh_interval", getRefreshInterval()).put("index.store.type", getIndexStoreType()).map();
364403
return Document.from(map);
365404
}
366-
367405
}

0 commit comments

Comments
 (0)