I have a Spring Boot application with a working configuration where ElasticsearchCustomConversions
are used. Works fine.
Inside this application I want to create some standalone src/test/java classes where I can test my ElasticsearchRepository
logic. Standalone because starting Spring Boot every time is too time consuming.
I am able to use a ElasticsearchRepository
in a standalone java program like:
public class ExampleRepositoryStandaloneTester {
private static ElasticsearchRepositoryFactory factoryBean;
static {
ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build();
RestHighLevelClient client = RestClients.create(clientConfiguration).rest();
ElasticsearchOperations elasticsearchOperations = new ElasticsearchRestTemplate(client);
factoryBean = new ElasticsearchRepositoryFactory(elasticsearchOperations);
}
public static ProductRepository getProductRepository() {
return factoryBean.getRepository(ProductRepository.class);
}
public static void main(String[] args) {
System.out.println("Product count: " + getProductRepository().count());
}}
The count function is really going to my local docker Elastic instance and prints the Product count. So this works.
But, my model needs ElasticsearchCustomConversions
and I cannot find a way to properly setup the ElasticsearchRepositoryFactory
so that the conversion are configured and used.
Does anyone know how to do this?
Versions are dependency managed through a RedHat fuse version so I cannot (easily) upgrade to newer versions.
The following attempt fails with "No converter found capable of converting from type [java.lang.Boolean] to type [com.my.TrueFalseType]":
public class ExampleCustomConversionsTester {
static class ExampleConfigurator extends AbstractElasticsearchConfiguration {
private RestHighLevelClient client;
public ExampleConfigurator(RestHighLevelClient client) {
ExampleConfigurator.this.client = client;
}
@Override
public RestHighLevelClient elasticsearchClient() {
return client;
}
@Override
public ElasticsearchCustomConversions elasticsearchCustomConversions() {
return new ElasticsearchCustomConversions(Collections.singletonList(new TrueFalseTypeConverter()));
}
@ReadingConverter
static class TrueFalseTypeConverter implements Converter<Boolean, TrueFalseType> {
@Override
public TrueFalseType convert(Boolean value) {
return TrueFalseType.fromValue(value.toString());
}
}
}
static {
ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build();
RestHighLevelClient client = RestClients.create(clientConfiguration).rest();
ExampleConfigurator cfg = new ExampleConfigurator(client);
ElasticsearchOperations elasticsearchOperations = new ElasticsearchRestTemplate(cfg.elasticsearchClient());
MappingElasticsearchConverter elasticsearchConverter = (MappingElasticsearchConverter) elasticsearchOperations.getElasticsearchConverter();
elasticsearchConverter.setConversions(cfg.elasticsearchCustomConversions());
factoryBean = new ElasticsearchRepositoryFactory(cfg.elasticsearchOperations(elasticsearchConverter));
}
private static ElasticsearchRepositoryFactory factoryBean;
public static ProductRepository getProductRepository() {
return factoryBean.getRepository(ProductRepository.class);
}
public static void main(String[] args) {
System.out.println("Product count: " + getProductRepository().count());
Page<Product> page = getProductRepository().findProducts(PageRequest.of(0, 10));
}
}
After you set the conversions with
elasticsearchConverter.setConversions(cfg.elasticsearchCustomConversions());
you need to call
elasticsearchConverter.afterPropertiesSet()
as described in the Javadoc for the setConversions
method. Normally Spring does this, but as you are not using Spring to setup the beans, you need to do this in your code.