I'm using elasticsearch and spring in my application. For each index type, I have a document mapping. Using @Document
annotation I have specified the indexName
and type
of index. For eg: @Document(indexName = "myproject", type = "user")
. But for writing unit tests, I would want to create indexes with a different indexName. Hence I want the indexName to be read from a properties file. How to do this in spring?
2
votes
I could not find an elegant solution for this. As a workaround, I just created a test class which extended the user class and specified the indexName for this test class separately.
– coder
2 Answers
0
votes
You can solve this problem by just using SPeL. It allows you to set a expression that Spring will parse at compile time. Hence allowing the Annotations to be processed during the compilation.
@Document(collection = "#{@environment.getProperty('index.access-log')}")
public class AccessLog{
...
}
Before Spring 5.x:
Note that there is no @
in the SPeL.
@Document(collection = "#{environment.getProperty('index.access-log')}")
public class AccessLog{
...
}
Also I found that Spring also supports a much simpler Expression @Document(collection = "${index.access-log}")
but I had mixed results with this.
After setting up the annotation as above you can use either
application.properties
index.access-log=index_access
or application.yaml
index :
access : index_access
-2
votes
Just use ElasticSearchTemplate from your unit tests to create the index with a different name and then use the method "index" or "bulkIndex" to index a document into the new index you just created.
esTemplate.createIndex(newIndexName, loadfromFromFile(settingsFileName));
esTemplate.putMapping(newIndexName, "user", loadfromFromFile(userMappingFileName));
List<IndexQuery> indexes = users.parallelStream().map(user -> {
IndexQuery index = new IndexQuery();
index.setIndexName(newIndexName);
index.setType("user");
index.setObject(user);
index.setId(String.valueOf(user.getId()));
return index;
}).collect(Collectors.toList());
esTemplate.bulkIndex(indexes);
//Load file from src/java/resources or /src/test/resources
public String loadfromFromFile(String fileName) throws IllegalStateException {
StringBuilder buffer = new StringBuilder(2048);
try {
InputStream is = getClass().getResourceAsStream(fileName);
LineNumberReader reader = new LineNumberReader(new InputStreamReader(is));
while (reader.ready()) {
buffer.append(reader.readLine());
buffer.append(' ');
}
} catch (Exception e) {
throw new IllegalStateException("couldn't load file " + fileName, e);
}
return buffer.toString();
}
This should work as its working for me. Same scenario.