Set Spring SolrDocument Collection name based on PropertyValue

884 Views Asked by At

I want to set values Spring SolrDocument Collection based on application.yml value.

@Data
@SolrDocument(collection = @Value("${solr.core}"))
public class SearchableProduct {
}
1

There are 1 best solutions below

0
beagle On

Hoi Michela,

Ok, I had the same Problem and I found a solution: SpEL

it is described in details here:Spring Data for Apache Solr

  1. you have to add the EL-expression to the Annotation

    @SolrDocument(collection = "#{@serverSolrContext.getCollectionName()}")
    public class SOLREntity implements Serializable {
         .....
    }
    
  2. you have to provide a the serverSolrContext Bean with the method getCollectionName().

    @Value("${solr.core}")
    private String core;
    
    public String getCollectionName() {
        return core;
    }
    
  3. you have to write in our application.properties the following core entry.

    solr.core=myOwnCoreName
    

    That's it actually, BUT

  4. if you get the following Exception, so as I did:

org.springframework.expression.spel.SpelEvaluationException: EL1057E: No bean resolver registered in the context to resolve access to bean

You have to have the following in your Configuration Bean

    @Configuration
    @EnableSolrRepositories(basePackages = { "de.solr.db" })
    @Profile("default")
    @PropertySource("classpath:application.properties")
    public class ServerSolrContext extends AbstractSolrConfiguration {

        private static final Logger logger = LoggerFactory.getLogger(ServerSolrContext.class);

        @Resource
        private Environment environment;

        @Value("${solr.core}")
        private String core;

        public String getCollectionName() {
            return core;
        }

        @PostConstruct
        public void init() {
            System.out.println(core);
        }

        @Bean
        public SolrClient solrClient() {
            String url = environment.getProperty("solr.server.url");
            String user = environment.getProperty("solr.server.user");
            String password = environment.getProperty("solr.server.password");

            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
                            new UsernamePasswordCredentials(user, password));
            SSLContext sslContext = null;
            try {
                sslContext = ReportConfiguration.getTrustAllContext();
            }
            catch (KeyManagementException | NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

            LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext);
            HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslSocketFactory)
                            .addInterceptorFirst(new PreemptiveAuthInterceptor()).setDefaultCredentialsProvider(credentialsProvider)
                            .build();

            SolrClient client = new HttpSolrClient.Builder().withHttpClient(httpClient).withBaseSolrUrl(url).build();
            return client;
        }

        @Bean
        @ConditionalOnMissingBean(name = "solrTemplate")
        public SolrTemplate solrTemplate(@Qualifier("mySolrTemplate") SolrTemplate solrTemplate) {
            return solrTemplate;
        }


        @Bean("mySolrTemplate")
        public SolrTemplate mySolrTemplate(SolrClient solrClient, SolrConverter solrConverter) {
            return new SolrTemplate(new HttpSolrClientFactory(solrClient), solrConverter); 

        }

        @Override
        public SolrClientFactory solrClientFactory() {
            return new HttpSolrClientFactory(solrClient());
        }

    }

The last 3 Methods are doing the Trick, that cost me a while to find the right solution:

it is here, so actually I was lucky to find this:

Allow PropertyPlaceholders in @SolrDocument solrCoreName