Search code examples
springconfigurationmulticorespring-data-solr

How do i configure multiple cores on embedded solr with raw spring-data-solr


I would like to add another core to my Solr 5.5.0 embedded server environment. "In my world" i create an embedded server and let spring-data load the core configurations. But with my solution it seems that all data go into the default core "collection1". So far i couldn't find an example beside spring-boot. But that is not an option.

My configuration looks like this so far:

@Import({
    AppctxSolrEmbedded.class,
    AppctxSolrHttp.class
})
@EnableSolrRepositories(value = "de.my.application.*.repository", multicoreSupport = true)
@Configuration
public class AppctxSolr {

    public @Bean SolrTemplate solrTemplate(
            @Named("solrClient") SolrClient solrClient) {
        return new SolrTemplate(solrClient, "collection1");
    }

    public @Bean SolrTemplate operatorSolrTemplate(
            @Named("solrClient") SolrClient solrClient) {
        return new SolrTemplate(solrClient, "operator1");
    }
}

@Dev @Qual @RemoteDev
@Configuration
public class AppctxSolrEmbedded {

    @Bean
    public EmbeddedSolrServerFactoryBean solrClient(
            @Value("${solr.server}") String solrHome) {
        EmbeddedSolrServerFactoryBean factory = new EmbeddedSolrServerFactoryBean();
        factory.setSolrHome(solrHome);
        return factory;
    }
}

@Prod
@Configuration
public class AppctxSolrHttp {

    @Bean
    public HttpSolrClientFactoryBean solrClient(
            @Value("${solr.server}") String baseURL) {
        HttpSolrClientFactoryBean factory = new HttpSolrClientFactoryBean();
        factory.setUrl(baseURL);
        return factory;
    }
}

Solution

  • Here is how I would do it

    @Configuration
    @EnableSolrRepositories(multicoreSupport = true)
    public class MulticoreSolrConfiguration {
    
      @Autowired
      private SolrClient solrClient;
    
      @Bean
      public SolrOperations solrTemplate() throws ParserConfigurationException, SAXException, IOException {
        return new SolrTemplate(this.solrClient);
      }
    
      @Bean
      public MulticoreSolrClientFactory multicoreSolrClientFactory()
          throws ParserConfigurationException, SAXException, IOException {
        return new MulticoreSolrClientFactory(this.solrClient, "operator1", "collection1");
      }
    
      @Bean(name = "operatorSolrClient")
      public SolrClient operatorSolrClient() throws IOException, SAXException, ParserConfigurationException {
        return this.multicoreSolrClientFactory().getSolrClient("operator1");
      }
    
      @Bean(name = "operatorSolrTemplate")
      public SolrTemplate operatorSolrTemplate() throws IOException, SAXException, ParserConfigurationException {
        return new SolrTemplate(this.operatorSolrClient());
      }
    }
    
      @Bean(name = "collectionSolrClient")
      public SolrClient collectionSolrClient() throws IOException, SAXException, ParserConfigurationException {
        return this.multicoreSolrClientFactory().getSolrClient("collection1");
      }
    
      @Bean(name = "collectionSolrTemplate")
      public SolrTemplate collectionSolrTemplate() throws IOException, SAXException, ParserConfigurationException {
        return new SolrTemplate(this.collectionSolrClient());
      }
    }
    

    And then instead of AppctxSolrEmbedded and AppctxSolrHttp, you can do something like this

    @Configuration
    class SolrConfiguration {
    
      private final SolrProperties solrProperties; // Has details about solr host, port, directory .....
    
      @Autowired
      public SolrConfiguration(final SolrProperties solrProperties) {
        this.solrProperties = solrProperties;
      }
    
      @Bean
      SolrClient solrClient() {
        final SolrClient solrClient;
        if (this.solrProperties.isEmbedded()) {
          solrClient = createEmbeddedSolrClient();
        } else {
          solrClient = createStandaloneSolrClient();
        }
    
        return solrClient;
      }
    
      private SolrClient createEmbeddedSolrClient() {
        final String solrConfigurationFolder = this.solrProperties.getSolr().getHome();
    
        final EmbeddedSolrServerFactoryBean factoryBean = new EmbeddedSolrServerFactoryBean();
        factoryBean.setSolrHome(solrConfigurationFolder);
    
        return factoryBean.getSolrClient();
      }
    
      private SolrClient createStandaloneSolrClient() {
        final String solrUrl = this.solrProperties.getHost();
    
        return new HttpSolrClient(solrUrl);
      }
    }  
    

    As you can see I am creating embeddedsolrclient or standaloneclient based on some properties set. You can change it to do based on profile(Autowire Environment and check for profile)