From 72084478e63e33d531e5418e1330d80e1f11ee69 Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Sat, 26 Mar 2016 11:50:55 +0530 Subject: [PATCH 1/6] Fixes DATASOLR-264 - Implemented multicore support in SolrTemplate. --- .../solr/core/MulticoreSolrOperations.java | 431 ++++++++++++++++++ .../data/solr/core/SolrOperations.java | 6 +- .../data/solr/core/SolrTemplate.java | 340 ++++++++++---- .../solr/server/support/SolrClientUtils.java | 25 +- 4 files changed, 715 insertions(+), 87 deletions(-) create mode 100644 src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java diff --git a/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java b/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java new file mode 100644 index 000000000..5b31da05d --- /dev/null +++ b/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java @@ -0,0 +1,431 @@ +package org.springframework.data.solr.core; + +import java.io.Serializable; +import java.util.Collection; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.client.solrj.response.UpdateResponse; +import org.apache.solr.common.SolrInputDocument; +import org.springframework.data.solr.core.query.FacetQuery; +import org.springframework.data.solr.core.query.HighlightQuery; +import org.springframework.data.solr.core.query.Query; +import org.springframework.data.solr.core.query.SolrDataQuery; +import org.springframework.data.solr.core.query.TermsQuery; +import org.springframework.data.solr.core.query.result.Cursor; +import org.springframework.data.solr.core.query.result.FacetPage; +import org.springframework.data.solr.core.query.result.GroupPage; +import org.springframework.data.solr.core.query.result.HighlightPage; +import org.springframework.data.solr.core.query.result.ScoredPage; +import org.springframework.data.solr.core.query.result.StatsPage; +import org.springframework.data.solr.core.query.result.TermsPage; + +/** + * Interface that specifies a set of multicore Solr operations. + * + * @author Venil Noronha + */ +public interface MulticoreSolrOperations { + + /** + * Get the SolrClient instance for the given solr core. + * + * @param coreName + * + * @return + */ + SolrClient getSolrClient(String coreName); + + /** + * Execute ping against the given solr core and return duration in msec. + * + * @param coreName + * + * @return + */ + SolrPingResponse ping(String coreName); + + /** + * Return number of elements found by for given query against the given + * solr core. + * + * @param coreName + * @param query + * + * @return + */ + long count(String coreName, SolrDataQuery query); + + /** + * Return number of elements found by for given query against the given + * solr core. + * + * @param coreName + * @param query + * @param method + * + * @return + */ + long count(String coreName, SolrDataQuery query, RequestMethod method); + + /** + * Execute add operation against the given solr core, which will do either + * insert or update. + * + * @param coreName + * @param obj + * + * @return + */ + UpdateResponse saveBean(String coreName, Object obj); + + /** + * Execute add operation against the given solr core, which will do either + * insert or update with support for commitWithin strategy. + * + * @param coreName + * @param obj + * @param commitWithinMs + * + * @return + */ + UpdateResponse saveBean(String coreName, Object obj, int commitWithinMs); + + /** + * Add a collection of beans to the given solr core, which will do either + * insert or update. + * + * @param coreName + * @param beans + * + * @return + */ + UpdateResponse saveBeans(String coreName, Collection beans); + + /** + * Add a collection of beans to the given solr core, which will do either + * insert or update with support for commitWithin strategy. + * + * @param coreName + * @param beans + * @param commitWithinMs + * + * @return + */ + UpdateResponse saveBeans(String coreName, Collection beans, int commitWithinMs); + + /** + * Add a solrj input document to the given solr core, which will do either + * insert or update. + * + * @param coreName + * @param document + * + * @return + */ + UpdateResponse saveDocument(String coreName, SolrInputDocument document); + + /** + * Add a solrj input document to the given solr core, which will do either + * insert or update with support for commitWithin strategy. + * + * @param coreName + * @param document + * @param commitWithinMs + * + * @return + */ + UpdateResponse saveDocument(String coreName, SolrInputDocument document, int commitWithinMs); + + /** + * Add multiple solrj input documents to the given solr core, which will do + * either insert or update. + * + * @param coreName + * @param documents + * + * @return + */ + UpdateResponse saveDocuments(String coreName, Collection documents); + + /** + * Add multiple solrj input documents to the given solr core, which will do + * either insert or update with support for commitWithin strategy. + * + * @param coreName + * @param documents + * @param commitWithinMs + * + * @return + */ + UpdateResponse saveDocuments(String coreName, Collection documents, int commitWithinMs); + + /** + * Find and delete all objects matching the provided Query from the given + * solr core. + * + * @param coreName + * @param query + * + * @return + */ + UpdateResponse delete(String coreName, SolrDataQuery query); + + /** + * Delete the one object with provided id from the given solr core. + * + * @param coreName + * @param id + * + * @return + */ + UpdateResponse deleteById(String coreName, String id); + + /** + * Delete objects with given ids from the given solr core. + * + * @param coreName + * @param ids + * + * @return + */ + UpdateResponse deleteById(String coreName, Collection ids); + + /** + * Execute the query against the given solr core and return the + * first returned object. + * + * @param coreName + * @param query + * @param clazz + * + * @return the first matching object + */ + T queryForObject(String coreName, Query query, Class clazz); + + /** + * Execute the query against the given solr core and return the + * first returned object. + * + * @param coreName + * @param query + * @param clazz + * @param method + * + * @return the first matching object + */ + T queryForObject(String coreName, Query query, Class clazz, RequestMethod method); + + /** + * Execute the query against the given solr core and return result + * as Page. + * + * @param coreName + * @param query + * @param clazz + * + * @return + */ + ScoredPage queryForPage(String coreName, Query query, Class clazz); + + /** + * Execute the query against the given solr core and return result + * as Page. + * + * @param coreName + * @param query + * @param clazz + * @param method + * + * @return + */ + ScoredPage queryForPage(String coreName, Query query, Class clazz, RequestMethod method); + + /** + * Execute a facet query against the given solr core. Facet result + * will be returned along with query result within the FacetPage. + * + * @param coreName + * @param query + * @param clazz + * + * @return + */ + FacetPage queryForFacetPage(String coreName, FacetQuery query, Class clazz); + + /** + * Execute a facet query against the given solr core. Facet result + * will be returned along with query result within the FacetPage. + * + * @param coreName + * @param query + * @param clazz + * @param method + * + * @return + */ + FacetPage queryForFacetPage(String coreName, FacetQuery query, Class clazz, RequestMethod method); + + /** + * Execute a query against the given solr core and highlight matches + * in result. + * + * @param coreName + * @param query + * @param clazz + * + * @return + */ + HighlightPage queryForHighlightPage(String coreName, HighlightQuery query, Class clazz); + + /** + * Execute a query against the given solr core and highlight matches + * in result. + * + * @param coreName + * @param query + * @param clazz + * @param method + * + * @return + */ + HighlightPage queryForHighlightPage(String coreName, HighlightQuery query, Class clazz, RequestMethod method); + + /** + * Execute query against the given solr core using terms handler. + * + * @param coreName + * @param query + * + * @return + */ + TermsPage queryForTermsPage(String coreName, TermsQuery query); + + /** + * Execute query against the given solr core using terms handler. + * + * @param coreName + * @param query + * @param method + * + * @return + */ + TermsPage queryForTermsPage(String coreName, TermsQuery query, RequestMethod method); + + /** + * Executes the given Query against the given solr core and returns an + * open Cursor allowing to iterate of results, dynamically fetching + * additional ones if required. + * + * @param coreName + * @param query + * @param clazz + * + * @return + */ + Cursor queryForCursor(String coreName, Query query, Class clazz); + + /** + * Execute the query against the given solr core and return result as + * GroupPage. + * + * @param coreName + * @param query + * @param clazz + * + * @return + */ + GroupPage queryForGroupPage(String coreName, Query query, Class clazz); + + /** + * Execute the query against the given solr core and return result as + * GroupPage. + * + * @param coreName + * @param query + * @param clazz + * @param method + * + * @return + */ + GroupPage queryForGroupPage(String coreName, Query query, Class clazz, RequestMethod method); + + /** + * Execute the query against the given solr core and return result as + * StatsPage. + * + * @param coreName + * @param query + * @param clazz + * + * @return + */ + StatsPage queryForStatsPage(String coreName, Query query, Class clazz); + + /** + * Execute the query against the given solr core and return result as + * StatsPage. + * + * @param coreName + * @param query + * @param clazz + * @param method + * + * @return + */ + StatsPage queryForStatsPage(String coreName, Query query, Class clazz, RequestMethod method); + + /** + * Executes a realtime get against the given solr core using given id. + * + * @param coreName + * @param id + * @param clazz + * + * @return + */ + T getById(String coreName, Serializable id, Class clazz); + + /** + * Executes a realtime get against the given solr core using given ids. + * + * @param coreName + * @param ids + * @param clazz + * + * @return + */ + Collection getById(String coreName, Collection ids, Class clazz); + + /** + * Send commit command to the given solr core + * + * @param coreName + */ + void commit(String coreName); + + /** + * Send soft commit command to the given solr core. + * + * @param coreName + */ + void softCommit(String coreName); + + /** + * Send rollback command to the given solr core. + * + * @param coreName + */ + void rollback(String coreName); + + /** + * Execute action within callback against the given solr core. + * + * @param coreName + * @param action + * + * @return + */ + T execute(String coreName, SolrCallback action); + +} diff --git a/src/main/java/org/springframework/data/solr/core/SolrOperations.java b/src/main/java/org/springframework/data/solr/core/SolrOperations.java index 5b86c68fb..888ea6dd9 100644 --- a/src/main/java/org/springframework/data/solr/core/SolrOperations.java +++ b/src/main/java/org/springframework/data/solr/core/SolrOperations.java @@ -156,7 +156,7 @@ public interface SolrOperations { UpdateResponse delete(SolrDataQuery query); /** - * Detele the one object with provided id + * Delete the one object with provided id * * @param id * @return @@ -192,7 +192,7 @@ public interface SolrOperations { T queryForObject(Query query, Class clazz, RequestMethod method); /** - * Execute the query against solr and retrun result as {@link Page} + * Execute the query against solr and return result as {@link Page} * * @param query * @param clazz @@ -201,7 +201,7 @@ public interface SolrOperations { ScoredPage queryForPage(Query query, Class clazz); /** - * Execute the query against solr and retrun result as {@link Page} + * Execute the query against solr and return result as {@link Page} * * @param query must not be {@literal null}. * @param clazz must not be {@literal null}. diff --git a/src/main/java/org/springframework/data/solr/core/SolrTemplate.java b/src/main/java/org/springframework/data/solr/core/SolrTemplate.java index 745b1dada..bbe15eb67 100644 --- a/src/main/java/org/springframework/data/solr/core/SolrTemplate.java +++ b/src/main/java/org/springframework/data/solr/core/SolrTemplate.java @@ -79,6 +79,7 @@ import org.springframework.data.solr.core.schema.SolrSchemaRequest; import org.springframework.data.solr.server.SolrClientFactory; import org.springframework.data.solr.server.support.HttpSolrClientFactory; +import org.springframework.data.solr.server.support.SolrClientUtils; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -89,8 +90,9 @@ * @author Joachim Uhrlass * @author Francisco Spaeth * @author Shiradwade Sateesh Krishna + * @author Venil Noronha */ -public class SolrTemplate implements SolrOperations, InitializingBean, ApplicationContextAware { +public class SolrTemplate implements SolrOperations, MulticoreSolrOperations, InitializingBean, ApplicationContextAware { private static final Logger LOGGER = LoggerFactory.getLogger(SolrTemplate.class); private static final PersistenceExceptionTranslator EXCEPTION_TRANSLATOR = new SolrExceptionTranslator(); @@ -162,9 +164,20 @@ public SolrTemplate(SolrClientFactory solrClientFactory, SolrConverter solrConve @Override public T execute(SolrCallback action) { Assert.notNull(action); + SolrClient solrClient = this.getSolrClient(); + return execute(solrClient, action); + } + + @Override + public T execute(String coreName, SolrCallback action) { + Assert.notNull(coreName); + Assert.notNull(action); + SolrClient solrClient = this.getSolrClient(coreName); + return execute(solrClient, action); + } + private T execute(SolrClient solrClient, SolrCallback action) { try { - SolrClient solrClient = this.getSolrClient(); return action.doInSolr(solrClient); } catch (Exception e) { DataAccessException resolved = getExceptionTranslator() @@ -175,7 +188,13 @@ public T execute(SolrCallback action) { @Override public SolrPingResponse ping() { - return execute(new SolrCallback() { + return ping(solrCore); + } + + @Override + public SolrPingResponse ping(String coreName) { + Assert.notNull(coreName, "Core name must not be 'null'."); + return execute(coreName, new SolrCallback() { @Override public SolrPingResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.ping(); @@ -184,25 +203,31 @@ public SolrPingResponse doInSolr(SolrClient solrClient) throws SolrServerExcepti } @Override - public long count(final SolrDataQuery query) { + public long count(SolrDataQuery query) { return count(query, getDefaultRequestMethod()); } @Override - public long count(final SolrDataQuery query, final RequestMethod method) { + public long count(String coreName, SolrDataQuery query) { + return count(coreName, query, getDefaultRequestMethod()); + } + + @Override + public long count(SolrDataQuery query, RequestMethod method) { + return count(solrCore, query, method); + } + @Override + public long count(String coreName, final SolrDataQuery query, final RequestMethod method) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'."); Assert.notNull(method, "Method must not be 'null'."); - - return execute(new SolrCallback() { - + return execute(coreName, new SolrCallback() { @Override public Long doInSolr(SolrClient solrClient) throws SolrServerException, IOException { - SolrQuery solrQuery = queryParsers.getForClass(query.getClass()).constructSolrQuery(query); solrQuery.setStart(0); solrQuery.setRows(0); - return solrClient.query(solrQuery, getSolrRequestMethod(method)).getResults().getNumFound(); } }); @@ -214,9 +239,21 @@ public UpdateResponse saveBean(Object obj) { } @Override - public UpdateResponse saveBean(final Object objectToAdd, final int commitWithinMs) { + public UpdateResponse saveBean(String coreName, Object obj) { + return saveBean(coreName, obj, -1); + } + + @Override + public UpdateResponse saveBean(Object objectToAdd, int commitWithinMs) { + String coreName = SolrClientUtils.resolveSolrCoreName(objectToAdd.getClass(), solrCore); + return saveBean(coreName, objectToAdd, commitWithinMs); + } + + @Override + public UpdateResponse saveBean(String coreName, final Object objectToAdd, final int commitWithinMs) { + Assert.notNull(coreName, "Core name must not be 'null'."); assertNoCollection(objectToAdd); - return execute(new SolrCallback() { + return execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.add(convertBeanToSolrInputDocument(objectToAdd), commitWithinMs); @@ -230,8 +267,21 @@ public UpdateResponse saveBeans(Collection beans) { } @Override - public UpdateResponse saveBeans(final Collection beansToAdd, final int commitWithinMs) { - return execute(new SolrCallback() { + public UpdateResponse saveBeans(String coreName, Collection beans) { + return saveBeans(coreName, beans, -1); + } + + @Override + public UpdateResponse saveBeans(Collection beansToAdd, int commitWithinMs) { + Object oneBean = beansToAdd.iterator().next(); + String coreName = SolrClientUtils.resolveSolrCoreName(oneBean.getClass(), solrCore); + return saveBeans(coreName, beansToAdd, commitWithinMs); + } + + @Override + public UpdateResponse saveBeans(String coreName, final Collection beansToAdd, final int commitWithinMs) { + Assert.notNull(coreName, "Core name must not be 'null'."); + return execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.add(convertBeansToSolrInputDocuments(beansToAdd), commitWithinMs); @@ -245,8 +295,19 @@ public UpdateResponse saveDocument(SolrInputDocument document) { } @Override - public UpdateResponse saveDocument(final SolrInputDocument documentToAdd, final int commitWithinMs) { - return execute(new SolrCallback() { + public UpdateResponse saveDocument(String coreName, SolrInputDocument document) { + return saveDocument(coreName, document, -1); + } + + @Override + public UpdateResponse saveDocument(SolrInputDocument documentToAdd, int commitWithinMs) { + return saveDocument(solrCore, documentToAdd, commitWithinMs); + } + + @Override + public UpdateResponse saveDocument(String coreName, final SolrInputDocument documentToAdd, final int commitWithinMs) { + Assert.notNull(coreName, "Core name must not be 'null'."); + return execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.add(documentToAdd, commitWithinMs); @@ -260,8 +321,19 @@ public UpdateResponse saveDocuments(Collection documents) { } @Override - public UpdateResponse saveDocuments(final Collection documentsToAdd, final int commitWithinMs) { - return execute(new SolrCallback() { + public UpdateResponse saveDocuments(String coreName, Collection documents) { + return saveDocuments(coreName, documents, -1); + } + + @Override + public UpdateResponse saveDocuments(Collection documentsToAdd, int commitWithinMs) { + return saveDocuments(solrCore, documentsToAdd, commitWithinMs); + } + + @Override + public UpdateResponse saveDocuments(String coreName, final Collection documentsToAdd, final int commitWithinMs) { + Assert.notNull(coreName, "Core name must not be 'null'."); + return execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.add(documentsToAdd, commitWithinMs); @@ -271,11 +343,15 @@ public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException @Override public UpdateResponse delete(SolrDataQuery query) { - Assert.notNull(query, "Query must not be 'null'."); + return delete(solrCore, query); + } + @Override + public UpdateResponse delete(String coreName, SolrDataQuery query) { + Assert.notNull(coreName, "Core name must not be 'null'."); + Assert.notNull(query, "Query must not be 'null'."); final String queryString = this.queryParsers.getForClass(query.getClass()).getQueryString(query); - - return execute(new SolrCallback() { + return execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.deleteByQuery(queryString); @@ -284,10 +360,15 @@ public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException } @Override - public UpdateResponse deleteById(final String id) { - Assert.notNull(id, "Cannot delete 'null' id."); + public UpdateResponse deleteById(String id) { + return deleteById(solrCore, id); + } - return execute(new SolrCallback() { + @Override + public UpdateResponse deleteById(String coreName, final String id) { + Assert.notNull(coreName, "Core name must not be 'null'."); + Assert.notNull(id, "Cannot delete 'null' id."); + return execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.deleteById(id); @@ -297,10 +378,15 @@ public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException @Override public UpdateResponse deleteById(Collection ids) { - Assert.notNull(ids, "Cannot delete 'null' collection."); + return deleteById(solrCore, ids); + } + @Override + public UpdateResponse deleteById(String coreName, Collection ids) { + Assert.notNull(coreName, "Core name must not be 'null'."); + Assert.notNull(ids, "Cannot delete 'null' collection."); final List toBeDeleted = new ArrayList(ids); - return execute(new SolrCallback() { + return execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.deleteById(toBeDeleted); @@ -313,14 +399,25 @@ public T queryForObject(Query query, Class clazz) { return queryForObject(query, clazz, getDefaultRequestMethod()); } + @Override + public T queryForObject(String coreName, Query query, Class clazz) { + return queryForObject(coreName, query, clazz, getDefaultRequestMethod()); + } + @Override public T queryForObject(Query query, Class clazz, RequestMethod method) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return queryForObject(coreName, query, clazz, method); + } + @Override + public T queryForObject(String coreName, Query query, Class clazz, RequestMethod method) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'."); Assert.notNull(clazz, "Target class must not be 'null'."); query.setPageRequest(new PageRequest(0, 1)); - QueryResponse response = query(query, clazz, method); + QueryResponse response = query(coreName, query, clazz, method); if (response.getResults().size() > 0) { if (response.getResults().size() > 1) { @@ -331,11 +428,12 @@ public T queryForObject(Query query, Class clazz, RequestMethod method) { return null; } - private SolrResultPage doQueryForPage(Query query, Class clazz, RequestMethod requestMethod) { + private SolrResultPage doQueryForPage(String coreName, Query query, Class clazz, + RequestMethod requestMethod) { QueryResponse response = null; NamedObjectsQuery namedObjectsQuery = new NamedObjectsQuery(query); - response = query(namedObjectsQuery, clazz, requestMethod != null ? requestMethod : getDefaultRequestMethod()); + response = query(coreName, namedObjectsQuery, clazz, requestMethod != null ? requestMethod : getDefaultRequestMethod()); Map objectsName = namedObjectsQuery.getNamesAssociation(); return createSolrResultPage(query, clazz, response, objectsName); @@ -343,59 +441,77 @@ private SolrResultPage doQueryForPage(Query query, Class clazz, Reques @Override public ScoredPage queryForPage(Query query, Class clazz) { + return queryForPage(query, clazz, getDefaultRequestMethod()); + } - Assert.notNull(query, "Query must not be 'null'."); - Assert.notNull(clazz, "Target class must not be 'null'."); - - return doQueryForPage(query, clazz, getDefaultRequestMethod()); + @Override + public ScoredPage queryForPage(String coreName, Query query, Class clazz) { + return queryForPage(coreName, query, clazz, getDefaultRequestMethod()); } - /* - * (non-Javadoc) - * @see org.springframework.data.solr.core.SolrOperations#queryForPage(org.springframework.data.solr.core.query.Query, java.lang.Class, org.springframework.data.solr.core.RequestMethod) - */ @Override public ScoredPage queryForPage(Query query, Class clazz, RequestMethod method) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return queryForPage(coreName, query, clazz, method); + } + @Override + public ScoredPage queryForPage(String coreName, Query query, Class clazz, RequestMethod method) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'."); Assert.notNull(clazz, "Target class must not be 'null'."); Assert.notNull(method, "Method class must not be 'null'."); - - return doQueryForPage(query, clazz, method); + return doQueryForPage(coreName, query, clazz, method); } @Override public GroupPage queryForGroupPage(Query query, Class clazz) { - return queryForGroupPage(query, clazz, RequestMethod.GET); + return queryForGroupPage(query, clazz, getDefaultRequestMethod()); + } + + @Override + public GroupPage queryForGroupPage(String coreName, Query query, Class clazz) { + return queryForGroupPage(coreName, query, clazz, getDefaultRequestMethod()); } @Override public GroupPage queryForGroupPage(Query query, Class clazz, RequestMethod method) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return queryForGroupPage(coreName, query, clazz, method); + } + @Override + public GroupPage queryForGroupPage(String coreName, Query query, Class clazz, RequestMethod method) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'."); Assert.notNull(clazz, "Target class must not be 'null'."); Assert.notNull(method, "Method class must not be 'null'."); - - return doQueryForPage(query, clazz, method); + return doQueryForPage(coreName, query, clazz, method); } - /* - * (non-Javadoc) - * @see org.springframework.data.solr.core.SolrOperations#queryForStatsPage(org.springframework.data.solr.core.query.Query, java.lang.Class) - */ @Override public StatsPage queryForStatsPage(Query query, Class clazz) { return queryForStatsPage(query, clazz, getDefaultRequestMethod()); } + @Override + public StatsPage queryForStatsPage(String coreName, Query query, Class clazz) { + return queryForStatsPage(coreName, query, clazz, getDefaultRequestMethod()); + } + @Override public StatsPage queryForStatsPage(Query query, Class clazz, RequestMethod method) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return queryForStatsPage(coreName, query, clazz, method); + } + @Override + public StatsPage queryForStatsPage(String coreName, Query query, Class clazz, RequestMethod method) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'."); Assert.notNull(clazz, "Target class must not be 'null'."); Assert.notNull(method, "Method class must not be 'null'."); - - return doQueryForPage(query, clazz, method); + return doQueryForPage(coreName, query, clazz, method); } @Override @@ -403,14 +519,25 @@ public FacetPage queryForFacetPage(FacetQuery query, Class clazz) { return queryForFacetPage(query, clazz, getDefaultRequestMethod()); } + @Override + public FacetPage queryForFacetPage(String coreName, FacetQuery query, Class clazz) { + return queryForFacetPage(coreName, query, clazz, getDefaultRequestMethod()); + } + @Override public FacetPage queryForFacetPage(FacetQuery query, Class clazz, RequestMethod method) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return queryForFacetPage(coreName, query, clazz, method); + } + @Override + public FacetPage queryForFacetPage(String coreName, FacetQuery query, Class clazz, RequestMethod method) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'."); Assert.notNull(clazz, "Target class must not be 'null'."); NamedObjectsFacetQuery namedObjectsQuery = new NamedObjectsFacetQuery(query); - QueryResponse response = query(namedObjectsQuery, clazz, method); + QueryResponse response = query(coreName, namedObjectsQuery, clazz, method); Map objectsName = namedObjectsQuery.getNamesAssociation(); SolrResultPage page = createSolrResultPage(query, clazz, response, objectsName); @@ -428,14 +555,26 @@ public HighlightPage queryForHighlightPage(HighlightQuery query, Class return queryForHighlightPage(query, clazz, getDefaultRequestMethod()); } + @Override + public HighlightPage queryForHighlightPage(String coreName, HighlightQuery query, Class clazz) { + return queryForHighlightPage(coreName, query, clazz, getDefaultRequestMethod()); + } + @Override public HighlightPage queryForHighlightPage(HighlightQuery query, Class clazz, RequestMethod method) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return queryForHighlightPage(coreName, query, clazz, method); + } + @Override + public HighlightPage queryForHighlightPage(String coreName, HighlightQuery query, Class clazz, + RequestMethod method) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'."); Assert.notNull(clazz, "Target class must not be 'null'."); NamedObjectsHighlightQuery namedObjectsQuery = new NamedObjectsHighlightQuery(query); - QueryResponse response = query(namedObjectsQuery, clazz, getDefaultRequestMethod()); + QueryResponse response = query(coreName, namedObjectsQuery, clazz, getDefaultRequestMethod()); Map objectsName = namedObjectsQuery.getNamesAssociation(); @@ -470,23 +609,29 @@ public TermsPage queryForTermsPage(TermsQuery query) { } @Override - public TermsPage queryForTermsPage(TermsQuery query, RequestMethod method) { - - Assert.notNull(query, "Query must not be 'null'."); + public TermsPage queryForTermsPage(String coreName, TermsQuery query) { + return queryForTermsPage(coreName, query, getDefaultRequestMethod()); + } - QueryResponse response = query(query, null, method); + @Override + public TermsPage queryForTermsPage(TermsQuery query, RequestMethod method) { + return queryForTermsPage(solrCore, query, method); + } + @Override + public TermsPage queryForTermsPage(String coreName, TermsQuery query, RequestMethod method) { + QueryResponse response = query(coreName, query, null, method); TermsResultPage page = new TermsResultPage(); page.addAllTerms(ResultHelper.convertTermsQueryResponseToTermsMap(response)); return page; } final QueryResponse query(SolrDataQuery query, Class clazz) { - return query(query, clazz, defaultRequestMethod); + return query(solrCore, query, clazz, getDefaultRequestMethod()); } - final QueryResponse query(SolrDataQuery query, Class clazz, RequestMethod requestMethod) { - + final QueryResponse query(String coreName, SolrDataQuery query, Class clazz, RequestMethod requestMethod) { + Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'"); Assert.notNull(requestMethod, "RequestMethod must not be 'null'"); @@ -499,14 +644,17 @@ final QueryResponse query(SolrDataQuery query, Class clazz, RequestMethod req } } - LOGGER.debug("Executing query '" + solrQuery + "' against solr."); - - return executeSolrQuery(solrQuery, getSolrRequestMethod(requestMethod)); + LOGGER.debug("Executing query '" + solrQuery + "' against {} solr core.", coreName); + return executeSolrQuery(coreName, solrQuery, getSolrRequestMethod(requestMethod)); } - final QueryResponse executeSolrQuery(final SolrQuery solrQuery, final SolrRequest.METHOD method) { - - return execute(new SolrCallback() { + final QueryResponse executeSolrQuery(SolrQuery solrQuery, SolrRequest.METHOD method) { + return executeSolrQuery(solrCore, solrQuery, method); + } + + final QueryResponse executeSolrQuery(final String coreName, final SolrQuery solrQuery, + final SolrRequest.METHOD method) { + return execute(coreName, new SolrCallback() { @Override public QueryResponse doInSolr(SolrClient solrServer) throws SolrServerException, IOException { return solrServer.query(solrQuery, method); @@ -516,7 +664,13 @@ public QueryResponse doInSolr(SolrClient solrServer) throws SolrServerException, @Override public void commit() { - execute(new SolrCallback() { + commit(solrCore); + } + + @Override + public void commit(String coreName) { + Assert.notNull(coreName, "Core name must not be 'null'."); + execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.commit(); @@ -526,11 +680,17 @@ public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException @Override public void softCommit() { + softCommit(solrCore); + } + + @Override + public void softCommit(String coreName) { + Assert.notNull(coreName, "Core name must not be 'null'."); if (VersionUtil.isSolr3XAvailable()) { throw new UnsupportedOperationException( "Soft commit is not available for solr version lower than 4.x - Please check your depdendencies."); } - execute(new SolrCallback() { + execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.commit(true, true, true); @@ -540,7 +700,13 @@ public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException @Override public void rollback() { - execute(new SolrCallback() { + rollback(solrCore); + } + + @Override + public void rollback(String coreName) { + Assert.notNull(coreName, "Core name must not be 'null'."); + execute(coreName, new SolrCallback() { @Override public UpdateResponse doInSolr(SolrClient solrClient) throws SolrServerException, IOException { return solrClient.rollback(); @@ -565,8 +731,8 @@ public SolrInputDocument convertBeanToSolrInputDocument(Object bean) { * @since 1.3 */ public String getSchemaName(String collectionName) { - return execute(new SolrCallback() { - + Assert.notNull(collectionName, "Collection name must not be 'null'."); + return execute(collectionName, new SolrCallback() { @Override public String doInSolr(SolrClient solrClient) throws SolrServerException, IOException { SolrJsonResponse response = SolrSchemaRequest.name().process(solrClient); @@ -578,19 +744,21 @@ public String doInSolr(SolrClient solrClient) throws SolrServerException, IOExce }); } - /* - * (non-Javadoc) - * @see org.springframework.data.solr.core.SolrOperations#queryForCursor(org.springframework.data.solr.core.query.Query, java.lang.Class) - */ - public Cursor queryForCursor(Query query, final Class clazz) { + public Cursor queryForCursor(Query query, Class clazz) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return queryForCursor(coreName, query, clazz); + } + @Override + public Cursor queryForCursor(final String coreName, Query query, final Class clazz) { + Assert.notNull(coreName, "Core name must not be 'null'."); return new DelegatingCursor(queryParsers.getForClass(query.getClass()).constructSolrQuery(query)) { @Override protected org.springframework.data.solr.core.query.result.DelegatingCursor.PartialResult doLoad( SolrQuery nativeQuery) { - QueryResponse response = executeSolrQuery(nativeQuery, getSolrRequestMethod(getDefaultRequestMethod())); + QueryResponse response = executeSolrQuery(coreName, nativeQuery, getSolrRequestMethod(getDefaultRequestMethod())); if (response == null) { return new PartialResult("", Collections. emptyList()); } @@ -602,28 +770,35 @@ protected org.springframework.data.solr.core.query.result.DelegatingCursor.Parti } @Override - public Collection getById(final Collection ids, final Class clazz) { + public Collection getById(Collection ids, Class clazz) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return getById(coreName, ids, clazz); + } + @Override + public Collection getById(String coreName, final Collection ids, final Class clazz) { + Assert.notNull(coreName, "Core name must not be 'null'."); if (CollectionUtils.isEmpty(ids)) { return Collections.emptyList(); } - - return execute(new SolrCallback>() { + return execute(coreName, new SolrCallback>() { @Override public Collection doInSolr(SolrClient solrClient) throws SolrServerException, IOException { - QueryResponse response = new SolrRealtimeGetRequest(ids).process(solrClient); return convertSolrDocumentListToBeans(response.getResults(), clazz); } - }); } @Override public T getById(Serializable id, Class clazz) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return getById(coreName, id, clazz); + } + @Override + public T getById(String coreName, Serializable id, Class clazz) { Assert.notNull(id, "Id must not be 'null'."); - Collection result = getById(Collections.singletonList(id), clazz); if (result.isEmpty()) { return null; @@ -676,6 +851,11 @@ public final SolrClient getSolrClient() { return solrClientFactory.getSolrClient(this.solrCore); } + @Override + public final SolrClient getSolrClient(String coreName) { + return solrClientFactory.getSolrClient(coreName); + } + @Override public SolrConverter getConverter() { return this.solrConverter; diff --git a/src/main/java/org/springframework/data/solr/server/support/SolrClientUtils.java b/src/main/java/org/springframework/data/solr/server/support/SolrClientUtils.java index 545f62c8d..5adb345a7 100644 --- a/src/main/java/org/springframework/data/solr/server/support/SolrClientUtils.java +++ b/src/main/java/org/springframework/data/solr/server/support/SolrClientUtils.java @@ -50,6 +50,7 @@ * {@link SolrClientUtils} replaces SolrServerUtils from version 1.x * * @author Christoph Strobl + * @author Venil Noronha * @since 2.0 */ public class SolrClientUtils { @@ -67,11 +68,27 @@ private SolrClientUtils() {} * @since 1.1 */ public static String resolveSolrCoreName(Class type) { - SolrDocument annotation = AnnotationUtils.findAnnotation(type, SolrDocument.class); - if (annotation != null && StringUtils.isNotBlank(annotation.solrCoreName())) { - return annotation.solrCoreName(); + return SolrClientUtils.resolveSolrCoreName(type, ""); + } + + /** + * Resolves solr core/collection name from the given type's {@link SolrDocument} annotation. + * If type is null or isn't annotated with {@link SolrDocument}, the default + * core name is returned. + * + * @param type the {@link Class} for which core name is to be resolved. + * @param defaultCoreName the default core name. + * @return default core name if type is null or isn't annotated + * with {@link SolrDocument}. + */ + public static String resolveSolrCoreName(Class type, String defaultCoreName) { + if (type != null) { + SolrDocument annotation = AnnotationUtils.findAnnotation(type, SolrDocument.class); + if (annotation != null && StringUtils.isNotBlank(annotation.solrCoreName())) { + return annotation.solrCoreName(); + } } - return ""; + return defaultCoreName; } public static T clone(T solrClient) { From 86e7c33cfe5f5e0a6eaa64bba0966688d0769392 Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Sat, 26 Mar 2016 15:36:37 +0530 Subject: [PATCH 2/6] Refactored SolrTemplate and fixed Tests. --- .../springframework/data/solr/core/SolrTemplate.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/solr/core/SolrTemplate.java b/src/main/java/org/springframework/data/solr/core/SolrTemplate.java index bbe15eb67..1452c665c 100644 --- a/src/main/java/org/springframework/data/solr/core/SolrTemplate.java +++ b/src/main/java/org/springframework/data/solr/core/SolrTemplate.java @@ -627,9 +627,18 @@ public TermsPage queryForTermsPage(String coreName, TermsQuery query, RequestMet } final QueryResponse query(SolrDataQuery query, Class clazz) { - return query(solrCore, query, clazz, getDefaultRequestMethod()); + return query(query, clazz, getDefaultRequestMethod()); } + final QueryResponse query(String coreName, SolrDataQuery query, Class clazz) { + return query(coreName, query, clazz, getDefaultRequestMethod()); + } + + final QueryResponse query(SolrDataQuery query, Class clazz, RequestMethod requestMethod) { + String coreName = SolrClientUtils.resolveSolrCoreName(clazz, solrCore); + return query(coreName, query, clazz, requestMethod); + } + final QueryResponse query(String coreName, SolrDataQuery query, Class clazz, RequestMethod requestMethod) { Assert.notNull(coreName, "Core name must not be 'null'."); Assert.notNull(query, "Query must not be 'null'"); From bc5af67591188c61260884544f3ac773d659efb0 Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Mon, 28 Mar 2016 06:41:59 +0530 Subject: [PATCH 3/6] Extended SolrOperations in MulticoreSolrOperations --- .../springframework/data/solr/core/MulticoreSolrOperations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java b/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java index 5b31da05d..1f8542525 100644 --- a/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java +++ b/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java @@ -25,7 +25,7 @@ * * @author Venil Noronha */ -public interface MulticoreSolrOperations { +public interface MulticoreSolrOperations extends SolrOperations { /** * Get the SolrClient instance for the given solr core. From 35692554d9deeba156650b9afae1a122f9ed3eb2 Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Thu, 31 Mar 2016 08:55:12 +0530 Subject: [PATCH 4/6] Added SolrClientUtil tests. --- .../data/solr/core/MulticoreSolrOperations.java | 15 +++++++++++++++ .../solr/server/support/SolrClientUtilTests.java | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java b/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java index 1f8542525..186b85ed1 100644 --- a/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java +++ b/src/main/java/org/springframework/data/solr/core/MulticoreSolrOperations.java @@ -1,3 +1,18 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.solr.core; import java.io.Serializable; diff --git a/src/test/java/org/springframework/data/solr/server/support/SolrClientUtilTests.java b/src/test/java/org/springframework/data/solr/server/support/SolrClientUtilTests.java index 5a686cf68..4aa1112cd 100644 --- a/src/test/java/org/springframework/data/solr/server/support/SolrClientUtilTests.java +++ b/src/test/java/org/springframework/data/solr/server/support/SolrClientUtilTests.java @@ -47,6 +47,7 @@ /** * @author Christoph Strobl + * @author Venil Noronha */ public class SolrClientUtilTests { @@ -203,6 +204,21 @@ public void testResolveSolrCoreNameShouldReturnAnnotationValueWhenPresent() { Assert.assertThat(SolrClientUtils.resolveSolrCoreName(ClassWithSolrDocumentAnnotation.class), equalTo("core1")); } + @Test + public void testResolveDefaultSolrCoreName() { + Assert.assertEquals("default-core", SolrClientUtils.resolveSolrCoreName(ClassWithoutSolrDocumentAnnotation.class, "default-core")); + } + + @Test + public void testResolveDefaultSolrCoreNameWithEmptyAnnotation() { + Assert.assertEquals("default-core", SolrClientUtils.resolveSolrCoreName(ClassWithEmptySolrDocumentAnnotation.class, "default-core")); + } + + @Test + public void testResolveDefaultSolrCoreNameWithAnnotation() { + Assert.assertEquals("core1", SolrClientUtils.resolveSolrCoreName(ClassWithSolrDocumentAnnotation.class, "default-core")); + } + /** * @see DATASOLR-189 */ From 82914d58fc5b49d105ccc688c4c2bc59837732d3 Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Thu, 31 Mar 2016 09:25:18 +0530 Subject: [PATCH 5/6] Added few basic multicore solr operations tests. --- .../solr/core/SolrTemplateMulticoreTests.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java diff --git a/src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java b/src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java new file mode 100644 index 000000000..ae74285d2 --- /dev/null +++ b/src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java @@ -0,0 +1,109 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.solr.core; + +import java.io.IOException; + +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrRequest; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.client.solrj.response.SolrPingResponse; +import org.apache.solr.common.SolrDocumentList; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.solr.core.query.Criteria; +import org.springframework.data.solr.core.query.SimpleQuery; +import org.springframework.data.solr.server.SolrClientFactory; + +/** + * + * @author Venil Noronha + */ +@RunWith(MockitoJUnitRunner.class) +public class SolrTemplateMulticoreTests { + + private SolrTemplate solrTemplate; + private @Mock SolrClient defaultSolrClient; + private @Mock SolrClient core1Client; + private @Mock SolrClient core2Client; + private @Mock SolrClientFactory solrClientFactory; + + @Before + public void setUp() { + Mockito.when(solrClientFactory.getSolrClient()).thenReturn(defaultSolrClient); + Mockito.when(solrClientFactory.getSolrClient("core1")).thenReturn(core1Client); + Mockito.when(solrClientFactory.getSolrClient("core2")).thenReturn(core2Client); + solrTemplate = new SolrTemplate(solrClientFactory); + solrTemplate.afterPropertiesSet(); + } + + @Test + public void testGetSolrClients() throws SolrServerException, IOException { + SolrClient client1 = solrClientFactory.getSolrClient("core1"); + SolrClient client2 = solrClientFactory.getSolrClient("core2"); + Assert.assertNotNull(client1); + Assert.assertNotNull(client2); + Assert.assertEquals(core1Client, client1); + Assert.assertEquals(core2Client, client2); + } + + @Test + public void testPingSpecificCores() throws SolrServerException, IOException { + Mockito.when(core1Client.ping()).thenReturn(new SolrPingResponse()); + Mockito.when(core2Client.ping()).thenReturn(new SolrPingResponse()); + SolrPingResponse pingResult1 = solrTemplate.ping("core1"); + SolrPingResponse pingResult2 = solrTemplate.ping("core2"); + Assert.assertNotNull(pingResult1); + Assert.assertNotNull(pingResult2); + Mockito.verify(core1Client, Mockito.times(1)).ping(); + Mockito.verify(core2Client, Mockito.times(1)).ping(); + } + + @Test + public void testCountQueries() throws SolrServerException, IOException { + ArgumentCaptor captor1 = ArgumentCaptor.forClass(SolrQuery.class); + ArgumentCaptor captor2 = ArgumentCaptor.forClass(SolrQuery.class); + + QueryResponse response1Mock = Mockito.mock(QueryResponse.class); + SolrDocumentList resultList1 = new SolrDocumentList(); + resultList1.setNumFound(10); + Mockito.when(response1Mock.getResults()).thenReturn(resultList1); + QueryResponse response2Mock = Mockito.mock(QueryResponse.class); + SolrDocumentList resultList2 = new SolrDocumentList(); + resultList2.setNumFound(10); + Mockito.when(response2Mock.getResults()).thenReturn(resultList2); + + Mockito.when(core1Client.query(Mockito.any(SolrQuery.class), Mockito.eq(SolrRequest.METHOD.GET))).thenReturn(response1Mock); + Mockito.when(core2Client.query(Mockito.any(SolrQuery.class), Mockito.eq(SolrRequest.METHOD.GET))).thenReturn(response2Mock); + + long result1 = solrTemplate.count("core1", new SimpleQuery(new Criteria("field_1").is("value1"))); + long result2 = solrTemplate.count("core2", new SimpleQuery(new Criteria("field_2").is("value2"))); + Assert.assertEquals(resultList1.getNumFound(), result1); + Assert.assertEquals(resultList2.getNumFound(), result2); + + Mockito.verify(core1Client, Mockito.times(1)).query(captor1.capture(), Mockito.eq(SolrRequest.METHOD.GET)); + Mockito.verify(core2Client, Mockito.times(1)).query(captor2.capture(), Mockito.eq(SolrRequest.METHOD.GET)); + } + +} From 28964379481c59d4454ba4884b5a66eaf4fd75ad Mon Sep 17 00:00:00 2001 From: Venil Noronha Date: Fri, 1 Apr 2016 08:44:59 +0530 Subject: [PATCH 6/6] Added test to verify SolrDocument handling in queryForFacetPage. --- .../solr/core/SolrTemplateMulticoreTests.java | 69 ++++++++++++++++--- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java b/src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java index ae74285d2..44c1ac657 100644 --- a/src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java +++ b/src/test/java/org/springframework/data/solr/core/SolrTemplateMulticoreTests.java @@ -15,16 +15,22 @@ */ package org.springframework.data.solr.core; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.FacetField; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.client.solrj.response.SolrPingResponse; import org.apache.solr.common.SolrDocumentList; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,8 +38,14 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.solr.core.mapping.SolrDocument; import org.springframework.data.solr.core.query.Criteria; +import org.springframework.data.solr.core.query.FacetOptions; +import org.springframework.data.solr.core.query.FacetQuery; +import org.springframework.data.solr.core.query.Field; +import org.springframework.data.solr.core.query.SimpleFacetQuery; import org.springframework.data.solr.core.query.SimpleQuery; +import org.springframework.data.solr.core.query.result.FacetPage; import org.springframework.data.solr.server.SolrClientFactory; /** @@ -62,10 +74,10 @@ public void setUp() { public void testGetSolrClients() throws SolrServerException, IOException { SolrClient client1 = solrClientFactory.getSolrClient("core1"); SolrClient client2 = solrClientFactory.getSolrClient("core2"); - Assert.assertNotNull(client1); - Assert.assertNotNull(client2); - Assert.assertEquals(core1Client, client1); - Assert.assertEquals(core2Client, client2); + assertNotNull(client1); + assertNotNull(client2); + assertEquals(core1Client, client1); + assertEquals(core2Client, client2); } @Test @@ -74,8 +86,8 @@ public void testPingSpecificCores() throws SolrServerException, IOException { Mockito.when(core2Client.ping()).thenReturn(new SolrPingResponse()); SolrPingResponse pingResult1 = solrTemplate.ping("core1"); SolrPingResponse pingResult2 = solrTemplate.ping("core2"); - Assert.assertNotNull(pingResult1); - Assert.assertNotNull(pingResult2); + assertNotNull(pingResult1); + assertNotNull(pingResult2); Mockito.verify(core1Client, Mockito.times(1)).ping(); Mockito.verify(core2Client, Mockito.times(1)).ping(); } @@ -99,11 +111,50 @@ public void testCountQueries() throws SolrServerException, IOException { long result1 = solrTemplate.count("core1", new SimpleQuery(new Criteria("field_1").is("value1"))); long result2 = solrTemplate.count("core2", new SimpleQuery(new Criteria("field_2").is("value2"))); - Assert.assertEquals(resultList1.getNumFound(), result1); - Assert.assertEquals(resultList2.getNumFound(), result2); + assertEquals(resultList1.getNumFound(), result1); + assertEquals(resultList2.getNumFound(), result2); + + Mockito.verify(core1Client, Mockito.times(1)).query(captor1.capture(), Mockito.eq(SolrRequest.METHOD.GET)); + Mockito.verify(core2Client, Mockito.times(1)).query(captor2.capture(), Mockito.eq(SolrRequest.METHOD.GET)); + } + + @Test + public void testMultipleSolrDocumentBasedQueryForFacetPage() throws SolrServerException, IOException { + ArgumentCaptor captor1 = ArgumentCaptor.forClass(SolrQuery.class); + ArgumentCaptor captor2 = ArgumentCaptor.forClass(SolrQuery.class); + QueryResponse response1Mock = Mockito.mock(QueryResponse.class); + Mockito.when(response1Mock.getFacetFields()).thenReturn(Arrays.asList(new FacetField("field_1"))); + QueryResponse response2Mock = Mockito.mock(QueryResponse.class); + Mockito.when(response2Mock.getFacetFields()).thenReturn(Arrays.asList(new FacetField("field_2"))); + + Mockito.when(core1Client.query(Mockito.any(SolrQuery.class), Mockito.eq(SolrRequest.METHOD.GET))).thenReturn(response1Mock); + Mockito.when(core2Client.query(Mockito.any(SolrQuery.class), Mockito.eq(SolrRequest.METHOD.GET))).thenReturn(response2Mock); + + FacetQuery query1 = new SimpleFacetQuery(Criteria.where("field_1").isNotNull()); + query1.setFacetOptions(new FacetOptions("field_1")); + FacetQuery query2 = new SimpleFacetQuery(Criteria.where("field_2").isNotNull()); + query2.setFacetOptions(new FacetOptions("field_2")); + + FacetPage result1 = solrTemplate.queryForFacetPage(query1, Core1Document.class); + FacetPage result2 = solrTemplate.queryForFacetPage(query2, Core2Document.class); + Collection facetFields1 = result1.getFacetFields(); + Collection facetFields2 = result2.getFacetFields(); + + assertTrue(facetFields1.iterator().next().getName().equals("field_1")); + assertTrue(facetFields2.iterator().next().getName().equals("field_2")); Mockito.verify(core1Client, Mockito.times(1)).query(captor1.capture(), Mockito.eq(SolrRequest.METHOD.GET)); Mockito.verify(core2Client, Mockito.times(1)).query(captor2.capture(), Mockito.eq(SolrRequest.METHOD.GET)); } + + @SolrDocument(solrCoreName = "core1") + public class Core1Document { + + } + + @SolrDocument(solrCoreName = "core2") + public class Core2Document { + + } }