Author: ivol37 at gmail.com
Date: Mon Jan 31 16:27:40 2011
New Revision: 731
Log:
Added:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/ContextClassLoaderScope.java
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/SolrApi.java
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrApiImpl.java
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfiguration.java
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfigurationImpl.java
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonService.java
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonServiceImpl.java
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/rest/SolrRestServiceImpl.java
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/util/SolrUtil.java
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/SolrApi.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/SolrApi.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/SolrApi.java
Mon Jan 31 16:27:40 2011
@@ -17,15 +17,15 @@
package org.amdatu.searchandindex.solr;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Collection;
-import java.util.List;
-import javax.xml.stream.XMLStreamException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.amdatu.core.tenant.Tenant;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.common.SolrInputDocument;
/**
* This class represents a Java Solr API, a little wrapper around the Solrj
API. It is invoked by the
@@ -48,11 +48,96 @@
*/
final String CONFIG_WORKDIR = "workdir";
- void updateIndex(Tenant tenant, String index, List<SolrInputDocument>
solrDocuments) throws XMLStreamException, SolrServerException, IOException;
+ /**
+ * Returns if the specified index exists.
+ * @param tenant The tenant of the index to check
+ * @param index The index name to check
+ * @return true if the index exists, false otherwise
+ */
+ boolean indexExists(Tenant tenant, String index);
- QueryResponse queryIndex(Tenant tenant, String index, String query) throws
SolrServerException;
+ /**
+ * Create a new index for the specified tenant with the specified index
name. If it already
+ * exists, nothing happens.
+ * @param tenant tenant for which to create the index
+ * @param index name of the index to create
+ * @throws SolrServerException In case an internal Solr error occurred
+ */
+ void createOrUpdateIndex(Tenant tenant, String index) throws
SolrServerException;
+
+ /**
+ * Create a new index for the specified tenant with the specified index
name and schema. If the index
+ * already exists, its schema is updated (if provided) and the core is
reloaded.
+ * @param tenant tenant for which to create the index
+ * @param index name of the index to create
+ * @param is InpumStream of the schema to create the new index with
+ * @throws SolrServerException In case an internal Solr error occurred
+ */
+ void createOrUpdateIndex(Tenant tenant, String index, InputStream is)
throws SolrServerException;
- Collection<String> getCores(Tenant tenant) throws SolrServerException;
+ /**
+ * Adds the provided Solr documents to the index.
+ * @param tenant Tenant of the index to append the documents to
+ * @param index The name of the index to append to
+ * @param is The SolrDocuments to add
+ * @throws SolrServerException In case any exception occurred while adding
the Solr documents to the index
+ */
+ void addDocumentsToIndex(Tenant tenant, String index, InputStream is)
throws SolrServerException;
+ /**
+ * Returns the schema of the specified index.
+ * @param tenant Tenant of the index to retrieve the schema for
+ * @param index name of the index to retrieve the schema for
+ * @return The schema
+ * @throws IOException In case the schema could not be retrieved
+ */
String getSchema(Tenant tenant, String index) throws IOException;
+
+ /**
+ * Updates the schema of an existing index and reload the index.
+ * @param tenant The tenant of the index to update the schema for
+ * @param index the name of the index to update the schema for
+ * @param is The schema
+ * @throws SolrServerException In case any exception occurred while
updating the schema of the index
+ */
+ void updateSchema(Tenant tenant, String index, InputStream is) throws
SolrServerException;
+
+ /**
+ * Deletes the specified index.
+ * @param tenant The tenant for which the index shoiuld be removed
+ * @param index The name of the index to remove
+ * @throws SolrServerException In case any exception occurred while
removing the index from Solr
+ */
+ void deleteIndex(Tenant tenant, String index) throws SolrServerException;
+
+ /**
+ * Returns a collection of available indices in the specified tenant.
+ * @param tenant The tenant to retrieve the indices for
+ * @return The collection of available indices.
+ * @throws SolrServerException In case any exception occurred while
retrieving the indices from Solr
+ */
+ Collection<String> getIndices(Tenant tenant) throws SolrServerException;
+
+ /**
+ * Execute a Solr query and returns the results.
+ * @param tenant Tenant of the index to query
+ * @param index Name of the index to query
+ * @param query The Solr query
+ * @return Result of the Solr query
+ * @throws SolrServerException In case any exception occurred while
executing the Solr query
+ */
+ QueryResponse queryIndex(Tenant tenant, String index, String query) throws
SolrServerException;
+
+ /**
+ * Execute a Solr query defined by request parameters in the specified
HttpServletRequest and writes
+ * the result directly to the HttpServletResponse.
+ * @param tenant Tenant of the index to query
+ * @param index Name of the index to query
+ * @param query The Solr query
+ * @param request The http request containing the Solr query parameters
+ * @param response The http response to which the result of the Solr query
is written
+ * @return Result of the Solr query
+ * @throws SolrServerException In case any exception occurred while
executing the Solr query
+ */
+ void queryIndex(Tenant tenant, String index, HttpServletRequest request,
HttpServletResponse response) throws SolrServerException;
}
Added:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/ContextClassLoaderScope.java
==============================================================================
--- (empty file)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/ContextClassLoaderScope.java
Mon Jan 31 16:27:40 2011
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2010 Amdatu.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.searchandindex.solr.impl;
+
+import org.apache.solr.client.solrj.SolrServerException;
+
+/**
+ * Utility interface to enable running a particular piece of code with the
bundle classloader
+ * set on the thread classloader context.
+ *
+ * @author ivol
+ */
+public interface ContextClassLoaderScope {
+ /**
+ * Implement this method run this code with the bundle classloader set as
as context loader
+ * of the current thread. The classloader will be reset to the original
classloader when the
+ * run() method has been executed.
+ * @param classLoader The bundle classloader which has been set as the
context classloader
+ * on the current thread.
+ * @throws SolrServerException In case any Solr related exception occurred
during execution.
+ */
+ void run(ClassLoader classLoader) throws SolrServerException ;
+}
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrApiImpl.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrApiImpl.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrApiImpl.java
Mon Jan 31 16:27:40 2011
@@ -20,18 +20,15 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLStreamException;
import org.amdatu.core.tenant.Tenant;
import org.amdatu.searchandindex.solr.SolrApi;
@@ -51,12 +48,9 @@
import org.apache.solr.request.SolrQueryResponse;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.servlet.SolrRequestParsers;
-import org.apache.solr.servlet.cache.HttpCacheHeaderUtil;
import org.apache.solr.servlet.cache.Method;
import org.osgi.service.log.LogService;
-import org.xml.sax.SAXException;
- at SuppressWarnings("restriction")
public class SolrApiImpl implements SolrApi {
// Service dependencies injected by the dependency manager
private volatile LogService m_logService;
@@ -65,6 +59,7 @@
// Private members
private CoreContainer m_coreContainer;
private SolrDaemonService m_daemon;
+ protected final Map<SolrConfig, SolrRequestParsers> m_parsers = new
WeakHashMap<SolrConfig, SolrRequestParsers>();
public SolrApiImpl(SolrDaemonService daemon, CoreContainer coreContainer,
SolrConfiguration solrConfig) {
m_coreContainer = coreContainer;
@@ -72,78 +67,102 @@
m_daemon = daemon;
}
- public void createIndex(Tenant tenant, String index) {
- createIndex(tenant, index, null);
- }
-
- public void createIndex(Tenant tenant, String index, InputStream is) {
- // Verify if a core for this index already exists
+ public boolean indexExists(Tenant tenant, String index) {
String coreName = tenant.getId() + "_" + index;
if (m_coreContainer.getCore(coreName) == null) {
- try {
- m_logService.log(LogService.LOG_INFO, "Creating new Solr index
'" + index + "' for tenant '" + tenant.getId() + "'");
+ return false;
+ } else {
+ return true;
+ }
+ }
- // Create a new core. The name of that core will be <tenant
id>/<index name>
- createCore(tenant.getId(), index, is);
- }
- catch (IOException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not create Solr
core configuration for '" + coreName + "'", e);
- }
- catch (ParserConfigurationException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not create Solr
core configuration for '" + coreName + "'", e);
+ public void createOrUpdateIndex(Tenant tenant, String index) throws
SolrServerException {
+ createOrUpdateIndex(tenant, index, null);
+ }
+
+ public void createOrUpdateIndex(Tenant tenant, String index, InputStream
is) throws SolrServerException {
+ try {
+ // Verify if a core for this index already exists and if not,
create is
+ String coreName = tenant.getId() + "_" + index;
+ if (!indexExists(tenant, index)) {
+ try {
+ m_logService.log(LogService.LOG_INFO, "Creating new Solr
index '" + index + "' for tenant '" + tenant.getId() + "'");
+
+ // Create a new core. The name of that core will be
<tenant id>/<index name>
+ createCore(tenant.getId(), index, is);
+
+ m_logService.log(LogService.LOG_INFO, "new Solr index '" +
index + "' for tenant '" + tenant.getId() + "'");
+ }
+ catch (Exception e) {
+ m_logService.log(LogService.LOG_ERROR, "Could not create
Solr core configuration for '" + coreName + "'", e);
+ throw new SolrServerException(e);
+ }
}
- catch (SAXException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not create Solr
core configuration for '" + coreName + "'", e);
+
+ // If an InputStream with Solr documents was provided, add those
to the index
+ if (is != null && is.available() > 0) {
+ updateSchema(tenant, index, is);
+ m_logService.log(LogService.LOG_DEBUG, "Solr index '" + index
+ "' for tenant '" + tenant.getId()
+ + "' updated with new Solr documents.");
+ } else {
+ m_logService.log(LogService.LOG_DEBUG, "Solr index '" + index
+ "' for tenant '" + tenant.getId()
+ + "' already exists, creating index ignored.");
}
+ } catch (Exception e) {
+ throw new SolrServerException(e);
}
}
- public void deleteIndex(Tenant tenant, String index) {
- String coreDirName = tenant.getId() + "/" + index;
- String coreName = tenant.getId() + "_" + index;
- deleteCore(coreName, coreDirName);
- m_solrConfig.deleteCore(tenant.getId(), index);
- m_logService.log(LogService.LOG_DEBUG, "Index '" + coreName + "'
deleted");
+ public String getSchema(Tenant tenant, String index) throws IOException {
+ File schema = m_solrConfig.getCoreSchema(tenant.getId(), index);
+ String contents = SolrUtil.loadFromFile(schema);
+ return contents;
}
- public void updateIndex(Tenant tenant, String index, InputStream is)
throws XMLStreamException, SolrServerException, IOException {
- String coreName = tenant.getId() + "_" + index;
- m_logService.log(LogService.LOG_DEBUG, "Starting update for index '" +
coreName + "'");
- SolrServer server = new EmbeddedSolrServer(m_coreContainer, coreName);
- List<SolrInputDocument> solrDocuments = SolrUtil.fromXMLStream(is);
- for (SolrInputDocument solrDocument : solrDocuments) {
- server.add(solrDocument);
- }
- server.commit();
- m_logService.log(LogService.LOG_DEBUG, "Index '" + coreName + "'
updated");
+ public void updateSchema(Tenant tenant, String index, InputStream is)
throws SolrServerException {
+ // When the schema is updated, most likely the index must be
re-created. So the best
+ // solution is just to delete and re-create the index
+ deleteIndex(tenant, index);
+ createOrUpdateIndex(tenant, index, is);
}
- public void updateIndex(Tenant tenant, String index,
List<SolrInputDocument> solrDocuments) throws XMLStreamException,
SolrServerException, IOException {
- String coreName = tenant.getId() + "_" + index;
- SolrServer server = new EmbeddedSolrServer(m_coreContainer, coreName);
- for (SolrInputDocument solrDocument : solrDocuments) {
- server.add(solrDocument);
- }
- server.commit();
- m_logService.log(LogService.LOG_DEBUG, "Index '" + coreName + "'
updated");
- }
+ public void addDocumentsToIndex(Tenant tenant, String index, InputStream
is) throws SolrServerException {
+ try {
+ String coreName = tenant.getId() + "_" + index;
- public Collection<String> getCores(Tenant tenant) throws
SolrServerException {
- return m_coreContainer.getCoreNames();
+ m_logService.log(LogService.LOG_DEBUG, "Starting update for index
'" + coreName + "'");
+ SolrServer server = new EmbeddedSolrServer(m_coreContainer,
coreName);
+ List<SolrInputDocument> solrDocuments = SolrUtil.fromXMLStream(is);
+ for (SolrInputDocument solrDocument : solrDocuments) {
+ server.add(solrDocument);
+ }
+ server.commit();
+ m_logService.log(LogService.LOG_DEBUG, "Index '" + coreName + "'
updated");
+ } catch (Exception e) {
+ throw new SolrServerException(e);
+ }
}
- public QueryResponse queryIndex(Tenant tenant, String index, String query)
throws SolrServerException {
+ public void deleteIndex(Tenant tenant, String index) throws
SolrServerException {
+ String coreDirName = tenant.getId() + "/" + index;
String coreName = tenant.getId() + "_" + index;
- return queryCore(coreName, query);
+ deleteCore(tenant.getId(), index, coreDirName);
+ m_solrConfig.deleteCoreConfiguration(tenant.getId(), index);
+ m_logService.log(LogService.LOG_DEBUG, "Index '" + coreName + "'
deleted");
}
- public void queryIndex(Tenant tenant, String index, HttpServletRequest
request, HttpServletResponse response) throws SolrServerException, IOException,
ServletException {
- doQuery(request, response);
+ public Collection<String> getIndices(Tenant tenant) throws
SolrServerException {
+ List<String> indices = new ArrayList<String>();
+ Collection<String> cores = m_coreContainer.getCoreNames();
+ String tenantPrefix = tenant.getId() + "_";
+ for (String core : cores) {
+ indices.add(core.substring(tenantPrefix.length()));
+ }
+ return indices;
}
- protected final Map<SolrConfig, SolrRequestParsers> parsers = new
WeakHashMap<SolrConfig, SolrRequestParsers>();
-
- public QueryResponse queryCore(String coreName, String query) throws
SolrServerException {
+ public QueryResponse queryIndex(Tenant tenant, String index, String query)
throws SolrServerException {
+ String coreName = tenant.getId() + "_" + index;
EmbeddedSolrServer server = new EmbeddedSolrServer(m_coreContainer,
coreName);
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(query);
@@ -151,25 +170,74 @@
return response;
}
- public String getSchema(Tenant tenant, String index) throws IOException {
- File schema = m_solrConfig.getCoreSchema(tenant.getId(), index);
- String contents = SolrUtil.loadFromFile(schema);
- return contents;
+ public void queryIndex(Tenant tenant, String index, HttpServletRequest
request, HttpServletResponse response) throws SolrServerException {
+ String coreName = SolrUtil.getCoreName(tenant.getId(), index);
+ SolrQueryRequest solrRequest = null;
+ try {
+ // Put the core container in request attribute
+ request.setAttribute("org.apache.solr.CoreContainer",
m_coreContainer);
+ SolrCore core = m_coreContainer.getCore(coreName);
+ final SolrConfig config = core.getSolrConfig();
+
+ // Get or create/cache the parser for the core
+ SolrRequestParsers parser = null;
+ parser = m_parsers.get(config);
+ if (parser == null) {
+ parser = new SolrRequestParsers(config);
+ m_parsers.put(config, parser);
+ }
+
+ SolrRequestHandler handler = core.getRequestHandler("standard");
+ solrRequest = parser.parse(core, index, request);
+
+ final Method reqMethod = Method.getMethod(request.getMethod());
+ SolrQueryResponse solrRsp = new SolrQueryResponse();
+ execute(request, handler, solrRequest, solrRsp);
+ QueryResponseWriter responseWriter =
core.getQueryResponseWriter(solrRequest);
+ writeResponse(solrRsp, response, responseWriter, solrRequest,
reqMethod);
+ } catch (Exception e) {
+ throw new SolrServerException(e);
+ } finally {
+ if (solrRequest != null) {
+ solrRequest.close();
+ }
+ }
}
- public void setSchema(Tenant tenant, String index, InputStream is) throws
IOException {
- deleteIndex(tenant, index);
- createIndex(tenant, index, is);
+ private void writeResponse(SolrQueryResponse solrRsp, ServletResponse
response, QueryResponseWriter responseWriter,
+ SolrQueryRequest solrReq, Method reqMethod) throws IOException {
+ if (solrRsp.getException() != null) {
+ throw new IOException(solrRsp.getException().toString());
+ } else {
+ // Now write it out
+ response.setContentType(responseWriter.getContentType(solrReq,
solrRsp));
+ if (Method.HEAD != reqMethod) {
+ if (responseWriter instanceof BinaryQueryResponseWriter) {
+ BinaryQueryResponseWriter binWriter =
(BinaryQueryResponseWriter) responseWriter;
+ binWriter.write(response.getOutputStream(), solrReq,
solrRsp);
+ } else {
+ PrintWriter out = response.getWriter();
+ responseWriter.write(out, solrReq, solrRsp);
+
+ }
+ }
+ // else http HEAD request, nothing to write out, waited this long
just to get ContentType
+ }
+ }
+
+ protected void execute(HttpServletRequest req, SolrRequestHandler handler,
SolrQueryRequest sreq,
+ SolrQueryResponse rsp) {
+ sreq.getCore().execute(handler, sreq, rsp);
}
- private void deleteCore(String coreName, String coreDirName) {
+ private void deleteCore(String tenantId, String indexName, String
coreDirName) throws SolrServerException {
// Save the current context classloader
final ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
try {
// Classloader switcheroo
final ClassLoader classLoader = this.getClass().getClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
- m_coreContainer.remove(coreName);
+ m_daemon.stopCore(tenantId, indexName);
File solr = m_solrConfig.getSolr();
m_coreContainer.persistFile(solr);
} finally {
@@ -178,7 +246,7 @@
}
}
- private void createCore(String tenantId, String indexName, InputStream is)
throws IOException, ParserConfigurationException, SAXException {
+ private void createCore(String tenantId, String indexName, InputStream is)
throws SolrServerException, IOException {
// Save the current context classloader
final ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
try {
@@ -187,10 +255,10 @@
Thread.currentThread().setContextClassLoader(classLoader);
// Prepare the configuration files of this new core
- m_solrConfig.prepareCore(tenantId, indexName, is);
+ m_solrConfig.addCoreConfiguration(tenantId, indexName, is);
// Now load the new core
- m_daemon.startCore(tenantId, indexName, classLoader);
+ m_daemon.startCore(tenantId, indexName);
// Persist cores
File solr = m_solrConfig.getSolr();
@@ -200,101 +268,4 @@
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
}
-
- public String getCoreName(String tenantId, String index) {
- return tenantId + "_" + index;
- }
-
- public String getCoreName(Tenant tenant, String index) {
- return tenant.getId() + "_" + index;
- }
-
- public String getIndexName(Tenant tenant, String coreName) {
- String corePrefix = tenant.getId() + "_";
- return coreName.substring(corePrefix.length());
- }
-
- /**
- * {@inheritDoc}
- */
- public void doQuery(ServletRequest request, ServletResponse response)
throws IOException,
- ServletException {
- if (request instanceof HttpServletRequest && request.getParameter("q")
!= null && !request.getParameter("q").isEmpty()) {
- HttpServletRequest req = (HttpServletRequest) request;
- HttpServletResponse resp = (HttpServletResponse) response;
- SolrRequestHandler handler = null;
- SolrQueryRequest solrReq = null;
-
- try {
- // put the core container in request attribute
- req.setAttribute("org.apache.solr.CoreContainer",
m_coreContainer);
- SolrCore core = m_coreContainer.getCore("nu_articles");
- final SolrConfig config = core.getSolrConfig();
-
- // get or create/cache the parser for the core
- SolrRequestParsers parser = null;
- parser = parsers.get(config);
- if (parser == null) {
- parser = new SolrRequestParsers(config);
- parsers.put(config, parser);
- }
-
- handler = core.getRequestHandler("standard");
- String path = "articles";
-
- solrReq = parser.parse(core, path, req);
-
- final Method reqMethod = Method.getMethod(req.getMethod());
- HttpCacheHeaderUtil.setCacheControlHeader(config, resp,
reqMethod);
- // unless we have been explicitly told not to, do cache
validation
- // if we fail cache validation, execute the query
- if (config.getHttpCachingConfig().isNever304()
- ||
!HttpCacheHeaderUtil.doCacheHeaderValidation(solrReq, req, reqMethod, resp)) {
- SolrQueryResponse solrRsp = new SolrQueryResponse();
-
- execute(req, handler, solrReq, solrRsp);
- HttpCacheHeaderUtil.checkHttpCachingVeto(solrRsp, resp,
reqMethod);
-
- QueryResponseWriter responseWriter =
core.getQueryResponseWriter(solrReq);
- writeResponse(solrRsp, response, responseWriter, solrReq,
reqMethod);
- }
- return;
- // log.debug("no handler or core retrieved for " + path + ",
follow through...");
- } catch (Throwable ex) {
- //sendError((HttpServletResponse) response, ex);
- return;
- } finally {
- if (solrReq != null) {
- solrReq.close();
- }
-
- }
- }
- }
-
- private void writeResponse(SolrQueryResponse solrRsp, ServletResponse
response, QueryResponseWriter responseWriter,
- SolrQueryRequest solrReq, Method reqMethod) throws IOException {
- if (solrRsp.getException() != null) {
- throw new IOException("error nog fixen hier");
- } else {
- // Now write it out
- response.setContentType(responseWriter.getContentType(solrReq,
solrRsp));
- if (Method.HEAD != reqMethod) {
- if (responseWriter instanceof BinaryQueryResponseWriter) {
- BinaryQueryResponseWriter binWriter =
(BinaryQueryResponseWriter) responseWriter;
- binWriter.write(response.getOutputStream(), solrReq,
solrRsp);
- } else {
- PrintWriter out = response.getWriter();
- responseWriter.write(out, solrReq, solrRsp);
-
- }
- }
- // else http HEAD request, nothing to write out, waited this long
just to get ContentType
- }
- }
-
- protected void execute(HttpServletRequest req, SolrRequestHandler handler,
SolrQueryRequest sreq,
- SolrQueryResponse rsp) {
- sreq.getCore().execute(handler, sreq, rsp);
- }
}
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfiguration.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfiguration.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfiguration.java
Mon Jan 31 16:27:40 2011
@@ -21,6 +21,10 @@
import java.io.InputStream;
public interface SolrConfiguration {
+ /**
+ * Returns the Solr work directory; the root of all Solr related files.
+ * @return the Solr work directory
+ */
File getWorkDirectory();
/**
@@ -57,18 +61,21 @@
* Initialize generic Solr configuration.
* @throws IOException
*/
- void initSolr() throws IOException;
+ void initializeSolr() throws IOException;
/**
- * Prepare configuration of a particular core.
- * @param tenantId
- * @param indexName
- * @param schema
- * @throws IOException
+ * Creates configuration files for the specified core.
+ * @param tenantId Tenant id of the core to create the configuration files
for
+ * @param indexName Index name of the core to create the configuration
files for
+ * @param schema The schema to use for this new core
+ * @throws IOException In case core configuration files could not be
written
*/
- void prepareCore(String tenantId, String indexName, InputStream schema)
throws IOException;
+ void addCoreConfiguration(String tenantId, String indexName, InputStream
schema) throws IOException;
- void deleteCore(String tenantId, String indexName);
-
- String getCoreName(String tenantId, String index);
+ /**
+ * Deletes the core configuration files for the specified core.
+ * @param tenantId Tenant id of the core to delete the configuration files
for
+ * @param indexName Index name of the core to delete the configuration
files for
+ */
+ void deleteCoreConfiguration(String tenantId, String indexName);
}
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfigurationImpl.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfigurationImpl.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrConfigurationImpl.java
Mon Jan 31 16:27:40 2011
@@ -17,12 +17,9 @@
package org.amdatu.searchandindex.solr.impl;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
-import java.nio.channels.FileChannel;
import java.util.Dictionary;
import org.amdatu.core.config.templates.ConfigTemplateManager;
@@ -78,10 +75,7 @@
}
}
- /**
- * Initialize Solr configuration.
- */
- public void initSolr() throws IOException {
+ public void initializeSolr() throws IOException {
// Check if the solr.xml file exists. If not, we create the necessary
configuration files
File solrFile = new File(m_workDir, SOLR);
if (!solrFile.exists()) {
@@ -101,19 +95,10 @@
} else {
// Solr uses this system property to find its storage location, so
set it.
System.setProperty("solr.solr.home",
solrFile.getParentFile().getAbsolutePath());
-
-
}
}
-
- /**
- * Prepare a new core. Copies configuration files from the default
configuration directory
- * to the directory created for the new core.
- * @param coreName
- * @throws IOException
- */
- public void prepareCore(String tenantId, String indexName, InputStream
schema) throws IOException {
+ public void addCoreConfiguration(String tenantId, String indexName,
InputStream schema) throws IOException {
// Prepare /conf directory for this core
File coreConfDir = getCoreConfDirectory(tenantId, indexName);
coreConfDir.mkdirs();
@@ -134,7 +119,7 @@
}
}
- public void deleteCore(String tenantId, String indexName) {
+ public void deleteCoreConfiguration(String tenantId, String indexName) {
SolrUtil.deleteDirectory(getCoreConfDirectory(tenantId, indexName));
}
@@ -167,7 +152,7 @@
private void copyConfigFile(File coreConfDir, String file) throws
IOException {
File solrConfig = new File(m_defaultConfigDir, file);
- copyFile(solrConfig, new File(coreConfDir, file));
+ SolrUtil.copyFile(solrConfig, new File(coreConfDir, file));
}
/**
@@ -192,30 +177,4 @@
URL resUrl = m_bundleContext.getBundle().getResource(resource);
m_configTemplateManager.writeConfiguration(resUrl, target);
}
-
- private void copyFile(File in, File out) throws IOException {
- FileChannel inChannel = null;
- FileChannel outChannel = null;
- try {
- inChannel = new FileInputStream(in).getChannel();
- outChannel = new FileOutputStream(out).getChannel();
- inChannel.transferTo(0, inChannel.size(), outChannel);
- }
- finally {
- if (inChannel != null) {
- try {
- inChannel.close();
- } finally {
- if (outChannel != null) {
- outChannel.close();
- }
- }
- }
-
- }
- }
-
- public String getCoreName(String tenantId, String index) {
- return tenantId + "_" + index;
- }
}
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonService.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonService.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonService.java
Mon Jan 31 16:27:40 2011
@@ -1,11 +1,43 @@
-package org.amdatu.searchandindex.solr.impl;
+/*
+ Copyright (C) 2010 Amdatu.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
-import java.io.IOException;
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-import javax.xml.parsers.ParserConfigurationException;
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.searchandindex.solr.impl;
-import org.xml.sax.SAXException;
+import org.apache.solr.client.solrj.SolrServerException;
+/**
+ * Interface of the Solr daemon service. The daemon service is responsible for
lifecycle management
+ * of the Solr cores.
+ *
+ * @author ivol
+ */
public interface SolrDaemonService {
- void startCore(String tenantId, String indexName, ClassLoader classLoader)
throws ParserConfigurationException, IOException, SAXException;
+ /**
+ * Start a core that already has been pre-configured (using
SolrConfiguration.prepareCore).
+ * @param tenantId The tenant id of the core to start
+ * @param indexName The index name of the core to start
+ * @throws SolrServerException In case a Solr related error occurred while
starting the core.
+ */
+ void startCore(String tenantId, String indexName) throws
SolrServerException;
+
+ /**
+ * Stops an existing core.
+ * @param tenantId The tenant id of the core to stop
+ * @param indexName The index name of the core to stop
+ * @throws SolrServerException In case a Solr related error occurred while
stopping the core.
+ */
+ void stopCore(String tenantId, String indexName) throws
SolrServerException;
}
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonServiceImpl.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonServiceImpl.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/impl/SolrDaemonServiceImpl.java
Mon Jan 31 16:27:40 2011
@@ -21,7 +21,6 @@
import java.io.IOException;
import java.util.List;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathConstants;
import org.amdatu.core.config.templates.ConfigTemplateManager;
@@ -29,10 +28,12 @@
import org.amdatu.searchandindex.solr.SolrApi;
import org.amdatu.searchandindex.solr.SolrRestService;
import org.amdatu.searchandindex.solr.rest.SolrRestServiceImpl;
+import org.amdatu.searchandindex.solr.util.SolrUtil;
import org.amdatu.web.httpcontext.HttpContextServiceFactory;
import org.amdatu.web.httpcontext.ResourceProvider;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.ServiceDependency;
+import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.util.DOMUtil;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.Config;
@@ -47,7 +48,6 @@
import org.osgi.service.log.LogService;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
/**
* Implementation of the {@link SolrService} interface.
@@ -62,18 +62,18 @@
private CoreContainer m_coreContainer;
public void init() throws IOException {
- m_solrConfig.initSolr();
+ m_solrConfig.initializeSolr();
}
public void start() throws Exception {
// Start the Solr daemon
startSolrDaemon();
- // Register the Solr API service
- SolrApiImpl solrApi = registerSolrApi();
+ // Register the Solr Java API
+ registerSolrApi();
- // Register the Solr dispatch filter
- registerRestAPI(solrApi);
+ // Register the Solr REST API
+ registerRestAPI();
m_logService.log(LogService.LOG_INFO, "Solr daemon started");
}
@@ -101,73 +101,91 @@
}
// Register the REST service
- private void registerRestAPI(SolrApiImpl solrApi) {
- SolrRestServiceImpl restService = new SolrRestServiceImpl(solrApi);
+ private void registerRestAPI() {
m_dependencyManager.add(m_dependencyManager.createComponent()
- .setImplementation(restService)
+ .setImplementation(SolrRestServiceImpl.class)
.setInterface(new String[]{SolrRestService.class.getName(),
ResourceProvider.class.getName()}, null)
- .add(createServiceDependency(LogService.class))
- .add(createServiceDependency(TenantManagementService.class))
- .add(createServiceDependency(HttpContextServiceFactory.class)));
+ .add(createServiceDependency(LogService.class).setRequired(true))
+ .add(createServiceDependency(SolrApi.class).setRequired(true))
+
.add(createServiceDependency(TenantManagementService.class).setRequired(true))
+
.add(createServiceDependency(HttpContextServiceFactory.class).setRequired(true)));
}
private ServiceDependency createServiceDependency(Class<?> clazz) {
return
m_dependencyManager.createServiceDependency().setService(clazz).setRequired(true);
}
- private void startCores() throws IOException,
ParserConfigurationException, SAXException {
- // Save the current context classloader
- final ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
- try {
- // Classloader switcheroo
- final ClassLoader classLoader = this.getClass().getClassLoader();
- Thread.currentThread().setContextClassLoader(classLoader);
-
- SolrResourceLoader loader = new
SolrResourceLoader(m_solrConfig.getWorkDirectory().getAbsolutePath());
- FileInputStream cfgis = null;
- try {
- cfgis = new FileInputStream(m_solrConfig.getSolr());
- Config cfg = new Config(loader, null, cfgis, null);
- NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core",
XPathConstants.NODESET);
- for (int i=0; i<nodes.getLength(); i++) {
- Node node = nodes.item(i);
- String names = DOMUtil.getAttr(node, "name", null);
- List<String> aliases = StrUtils.splitSmart(names,',');
- String name = aliases.get(0);
- CoreDescriptor coreDescriptor = new
CoreDescriptor(m_coreContainer, name, DOMUtil.getAttr(node, "instanceDir",
null));
-
- // Get the directory [tenantId]/[indexName]
- String tenantCoreSubDir =
getTenantCoreSubDir(coreDescriptor);
- String tenantId = tenantCoreSubDir.split("/")[0];
- String indexName = tenantCoreSubDir.split("/")[1];
- startCore(tenantId, indexName, classLoader);
+ private void startCores() throws SolrServerException {
+ SolrUtil.runInBundleContextClassLoader(new ContextClassLoaderScope() {
+ public void run(ClassLoader classLoader) throws
SolrServerException {
+ FileInputStream cfgis = null;
+ try {
+ cfgis = new FileInputStream(m_solrConfig.getSolr());
+ SolrResourceLoader loader = new
SolrResourceLoader(m_solrConfig.getWorkDirectory().getAbsolutePath());
+ Config cfg = new Config(loader, null, cfgis, null);
+ NodeList nodes = (NodeList)cfg.evaluate("solr/cores/core",
XPathConstants.NODESET);
+ for (int i=0; i<nodes.getLength(); i++) {
+ Node node = nodes.item(i);
+ String names = DOMUtil.getAttr(node, "name", null);
+ List<String> aliases = StrUtils.splitSmart(names,',');
+ String name = aliases.get(0);
+ CoreDescriptor coreDescriptor = new
CoreDescriptor(m_coreContainer, name, DOMUtil.getAttr(node, "instanceDir",
null));
+
+ // Get the directory [tenantId]/[indexName]
+ String tenantCoreSubDir =
getTenantCoreSubDir(coreDescriptor);
+ String tenantId = tenantCoreSubDir.split("/")[0];
+ String indexName = tenantCoreSubDir.split("/")[1];
+ startCore(tenantId, indexName);
+ }
+ } catch (Exception e) {
+ throw new SolrServerException(e);
+ } finally {
+ if (cfgis != null) {
+ try {
+ cfgis.close();
+ }
+ catch (IOException e) {
+ throw new SolrServerException(e);
+ }
+ }
}
- } finally {
- if (cfgis != null) {
- cfgis.close();
+ }
+ });
+ }
+
+ public void startCore(final String tenantId, final String indexName)
throws SolrServerException {
+ SolrUtil.runInBundleContextClassLoader(new ContextClassLoaderScope() {
+ public void run(ClassLoader classLoader) throws
SolrServerException {
+ String coreName = SolrUtil.getCoreName(tenantId, indexName);
+ try {
+ m_logService.log(LogService.LOG_INFO, "Starting Solr core
'" + coreName + "'");
+ File coreDir = m_solrConfig.getCoreDirectory(tenantId,
indexName);
+ File solrConfig = m_solrConfig.getCoreSolrConfig(tenantId,
indexName);
+ File schema = m_solrConfig.getCoreSchema(tenantId,
indexName);
+ File workDir = m_solrConfig.getWorkDirectory();
+
+ SolrResourceLoader loader = new
NakamuraSolrResourceLoader(workDir.getAbsolutePath(), classLoader);
+ SolrConfig config = new NakamuraSolrConfig(loader,
"solrconfig.xml", new FileInputStream(solrConfig));
+ IndexSchema indexSchema = new IndexSchema(config, null,
new FileInputStream(schema));
+
+ CoreDescriptor desc = new CoreDescriptor(m_coreContainer,
coreName, coreDir.getAbsolutePath());
+ SolrCore nakamuraCore = new SolrCore(coreName,
coreDir.getAbsolutePath(), config, indexSchema, desc);
+ m_coreContainer.register(coreName, nakamuraCore, false);
+ m_logService.log(LogService.LOG_INFO, "Solr core '" +
coreName + "' started successfully");
+ }
+ catch (Exception e) {
+ m_logService.log(LogService.LOG_ERROR, "Failed to start
core '" + coreName, e);
+ throw new SolrServerException(e);
}
}
- } finally {
- // Restore classloader
- Thread.currentThread().setContextClassLoader(contextClassLoader);
- }
+ });
}
- public void startCore(String tenantId, String indexName, ClassLoader
classLoader) throws ParserConfigurationException, IOException, SAXException {
- String coreName = m_solrConfig.getCoreName(tenantId, indexName);
- m_logService.log(LogService.LOG_INFO, "Starting Solr core '" +
coreName + "'");
- File coreDir = m_solrConfig.getCoreDirectory(tenantId, indexName);
- File solrConfig = m_solrConfig.getCoreSolrConfig(tenantId, indexName);
- File schema = m_solrConfig.getCoreSchema(tenantId, indexName);
- File workDir = m_solrConfig.getWorkDirectory();
-
- SolrResourceLoader loader = new
NakamuraSolrResourceLoader(workDir.getAbsolutePath(), classLoader);
- SolrConfig config = new NakamuraSolrConfig(loader, "solrconfig.xml",
new FileInputStream(solrConfig));
- IndexSchema indexSchema = new IndexSchema(config, null, new
FileInputStream(schema));
- CoreDescriptor desc = new CoreDescriptor(m_coreContainer, coreName,
coreDir.getAbsolutePath());
- SolrCore nakamuraCore = new SolrCore(coreName,
coreDir.getAbsolutePath(), config, indexSchema, desc);
- m_coreContainer.register(coreName, nakamuraCore, false);
- m_logService.log(LogService.LOG_INFO, "Solr core '" + coreName + "'
started successfully");
+ public void stopCore(String tenantId, String indexName) throws
SolrServerException {
+ String coreName = SolrUtil.getCoreName(tenantId, indexName);
+ m_logService.log(LogService.LOG_INFO, "Stopping Solr core '" +
coreName + "'");
+ m_coreContainer.remove(coreName);
+ m_logService.log(LogService.LOG_INFO, "Solr core '" + coreName + "'
stopped successfully");
}
private void stopCores() {
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/rest/SolrRestServiceImpl.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/rest/SolrRestServiceImpl.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/rest/SolrRestServiceImpl.java
Mon Jan 31 16:27:40 2011
@@ -16,14 +16,12 @@
*/
package org.amdatu.searchandindex.solr.rest;
-import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
@@ -31,7 +29,6 @@
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
@@ -42,24 +39,31 @@
import org.amdatu.core.tenant.Tenant;
import org.amdatu.core.tenant.TenantException;
import org.amdatu.core.tenant.TenantManagementService;
+import org.amdatu.searchandindex.solr.SolrApi;
import org.amdatu.searchandindex.solr.SolrRestService;
-import org.amdatu.searchandindex.solr.impl.SolrApiImpl;
import org.amdatu.searchandindex.solr.osgi.Activator;
import org.amdatu.searchandindex.solr.rest.bean.SolrErrorBean;
import org.amdatu.searchandindex.solr.rest.bean.SolrIndexBean;
import org.amdatu.searchandindex.solr.rest.bean.SolrTenantIndicesBean;
+import org.amdatu.searchandindex.solr.util.SolrUtil;
import org.amdatu.web.httpcontext.HttpContextServiceFactory;
import org.amdatu.web.httpcontext.ResourceProvider;
import org.apache.felix.dm.Component;
-import org.apache.felix.dm.DependencyManager;
-import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
+
/**
* This class provides a REST interface on the Solr index service. The REST
API can be used to create, update
* and remove indices from Solr as well as performing index queries.
- * The base URL for this REST service is /rest/index
+ * The base URL for this REST service is /rest/index. It supports the
following REST APIs:
+ *
+ * GET /rest/index/status -> Returns the text "Index service
online", can be used to check the status of this REST service
+ * PUT /rest/index/[indexname] -> Creates a new index named
[indexname] for the current tenant
+ * PUT /rest/index/[indexname]/schema -> Updates the schema of
[indexname]
+ * GET /rest/index/[indexname]?[arguments] -> Performs a Solr query on
[indexname] with arguments [arguments]
+ * GET /rest/index -> Returns a list of all available
indices
+ *
* @author ivol
*/
@Path("index")
@@ -69,9 +73,8 @@
private volatile Component m_contextComponent;
private volatile HttpContextServiceFactory m_httpContextServiceFactory;
private volatile BundleContext m_bundleContext;
- private volatile DependencyManager m_dependencyManager;
private volatile TenantManagementService m_tenantService;
- private volatile SolrApiImpl m_solrApi;
+ private volatile SolrApi m_solrApi;
// Disable HTTP caching in this REST interface
private static CacheControl m_cacheControl;
@@ -80,14 +83,9 @@
m_cacheControl.setNoCache(true);
}
- public SolrRestServiceImpl(SolrApiImpl solrApi) {
- m_solrApi = solrApi;
- }
-
public void init() {
m_logService.log(LogService.LOG_INFO, "Initializing Solr REST
interface");
m_contextComponent =
m_httpContextServiceFactory.create(m_bundleContext, this);
- //registerSolrDispatchFilter();
}
public void destroy() {
@@ -105,23 +103,10 @@
return Activator.RESOURCE_ID;
}
- // Registers the Solr dispatch filter
-/* private void registerSolrDispatchFilter() {
- // Create and register a http servlet filter. This filter is mapped on
.*
- Dictionary<String, Object> filterProperties = new Hashtable<String,
Object>();
- filterProperties.put("pattern", "/" + Activator.RESOURCE_ID +
"(|\\?.*|/.*)");
- filterProperties.put(Constants.SERVICE_RANKING, 10);
- filterProperties.put("contextId", Activator.RESOURCE_ID);
-
- SolrDispatchFilter filter = new SolrDispatchFilter("/" +
Activator.RESOURCE_ID, m_workDir.getAbsolutePath());
- m_dependencyManager.add(m_dependencyManager.createComponent()
- .setImplementation(filter)
- .setInterface(Filter.class.getName(), filterProperties));
- }*/
-
/**
* This method can be used to check the availability of the Index Service.
* GET /rest/index/status
+ *
* @return The text "Index service online"
*/
@GET
@@ -132,14 +117,14 @@
}
/**
- * This method can be used to add a new index or update it.
+ * Creates a new index or updates the existing one.
* PUT /rest/index/[indexname]
- * @return The text "Index service online"
*/
@PUT
@Path("{indexname}")
- @Produces({MediaType.APPLICATION_XML})
- public Response createIndex(@PathParam("indexname") final String
indexname, @Context final HttpServletRequest request, InputStream is) {
+ @Produces( { MediaType.APPLICATION_XML })
+ public Response createIndex(@PathParam("indexname") final String indexname,
+ @Context final HttpServletRequest request, InputStream is) {
if (indexname == null || indexname.isEmpty()) {
m_logService.log(LogService.LOG_ERROR, "Could not create index '"
+ indexname + "'");
return Response.status(Response.Status.BAD_REQUEST).build();
@@ -147,14 +132,17 @@
try {
// Resolve tenant from hostname
Tenant tenant = resolveTenant(request);
+
// This is the tenant for which the index should be created
- m_solrApi.createIndex(tenant, indexname);
+ m_solrApi.createOrUpdateIndex(tenant, indexname);
+
if (is.available() > 0) {
// When more then 0 bytes are available, a document is send
along with the PUT request
// that should be added to this index
- m_solrApi.updateIndex(tenant, indexname, is);
+ m_solrApi.addDocumentsToIndex(tenant, indexname, is);
}
- } catch (Exception e) {
+ }
+ catch (Exception e) {
m_logService.log(LogService.LOG_ERROR, "Could not create index '"
+ indexname + "'", e);
throw new WebApplicationException(e);
}
@@ -162,14 +150,51 @@
}
/**
- * Perform Solr query on the specified index.
- * GET /rest/index/[indexname]?q=[Solr query]
+ * Updates the schema of an existing index. Returns 404 if the index does
not exist.
+ * PUT /rest/index/[indexname]/schema
+ */
+ @PUT
+ @Path("{indexname}/schema")
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ public Response putSchema(@PathParam("indexname") final String indexname,
+ @Context final HttpServletRequest request, InputStream is) {
+ Tenant tenant = null;
+ try {
+ tenant = resolveTenant(request);
+ if (tenant == null || indexname == null || indexname.isEmpty() ||
is == null || is.available() == 0) {
+ // Illegal arguments passes, return 400 - Bad request
+ String errorMsg = "Could not update schema for index '" +
indexname + "'.";
+ if (is == null || is.available() == 0) {
+ errorMsg += " No schema provided.";
+ }
+ m_logService.log(LogService.LOG_ERROR, errorMsg);
+ SolrErrorBean errorBean = new SolrErrorBean(errorMsg);
+ return
Response.status(Response.Status.BAD_REQUEST).entity(errorBean).cacheControl(m_cacheControl)
+ .build();
+ }
+ else if (!m_solrApi.indexExists(tenant, indexname)) {
+ // Index not found, return a 404 - Not found
+ return
Response.status(Status.NOT_FOUND).cacheControl(m_cacheControl).build();
+ }
+ m_solrApi.updateSchema(tenant, indexname, is);
+ return Response.ok().cacheControl(m_cacheControl).build();
+ }
+ catch (Exception e) {
+ m_logService.log(LogService.LOG_ERROR, "Could not update schema
for index '" + indexname + "' on tenant '"
+ + tenant + "'", e);
+ throw new WebApplicationException(e);
+ }
+ }
+
+ /**
+ * Performs a Solr query on the specified index.
+ * GET /rest/index/[indexname]?[Solr query arguments]
*/
@GET
@Path("{indexname}")
- @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
- public Response queryIndex(@PathParam("indexname") final String indexname,
@QueryParam("q") final String q,
- @Context final HttpServletRequest request, @Context final
HttpServletResponse response) {
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ public Response queryIndex(@PathParam("indexname") final String indexname,
@Context final HttpServletRequest request,
+ @Context final HttpServletResponse response) {
Tenant tenant = null;
if (indexname == null || indexname.isEmpty()) {
// No indexname passed which is required, return 400 (BAD_REQUEST)
@@ -178,38 +203,19 @@
}
try {
tenant = resolveTenant(request);
- if
(!m_solrApi.getCores(tenant).contains(m_solrApi.getCoreName(tenant,
indexname))) {
+ if (!m_solrApi.indexExists(tenant, indexname)) {
// Index does not exist, return a 404 (NOT_FOUND)
return
Response.status(Status.NOT_FOUND).cacheControl(m_cacheControl).build();
}
- String query = q;
- if (query == null || query.isEmpty()) {
- query = "*:*";
- }
- /* QueryResponse response = m_solrApi.queryIndex(tenant,
indexname, query);
- int size = response.getResults().size();
- SolrSearchResultBean resultbean = new SolrSearchResultBean(size);
- return
Response.ok(resultbean).cacheControl(m_cacheControl).build();*/
+
m_solrApi.queryIndex(tenant, indexname, request, response);
return Response.ok().build();
}
- catch (TenantException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not retrieve index
'" + indexname + "' for tenant '" + tenant + "'", e);
- throw new WebApplicationException(e);
- }
- catch (SolrServerException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not retrieve index
'" + indexname + "' for tenant '" + tenant + "'", e);
+ catch (Exception e) {
+ m_logService.log(LogService.LOG_ERROR, "Could not query index '" +
indexname + "' for tenant '" + tenant
+ + "'", e);
throw new WebApplicationException(e);
}
- catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- catch (ServletException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return Response.ok().build();
}
/**
@@ -217,7 +223,7 @@
* GET /rest/index
*/
@GET
- @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+ @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getIndices(@Context final HttpServletRequest request) {
try {
// Resolve tenant and create the tenant indices bean
@@ -226,70 +232,45 @@
// Create index beans for each index contained for this tenant
List<SolrIndexBean> indexBeans = new ArrayList<SolrIndexBean>();
- Collection<String> cores = m_solrApi.getCores(tenant);
- for (String core : cores) {
- QueryResponse response = m_solrApi.queryCore(core, "*:*");
+ Collection<String> indices = m_solrApi.getIndices(tenant);
+ for (String index : indices) {
+ QueryResponse response = m_solrApi.queryIndex(tenant, index,
"*:*");
long size = response.getResults().getNumFound();
- indexBeans.add(new SolrIndexBean(core,
m_solrApi.getIndexName(tenant, core), size));
+ String coreName = SolrUtil.getCoreName(tenant.getId(), index);
+ indexBeans.add(new SolrIndexBean(index, coreName, size));
}
tenantBean.setIndices(indexBeans);
return
Response.ok(tenantBean).cacheControl(m_cacheControl).build();
- } catch (TenantException e) {
- m_logService.log(LogService.LOG_ERROR, "Could not retrieve
indices", e);
- throw new WebApplicationException(e);
}
- catch (SolrServerException e) {
+ catch (Exception e) {
m_logService.log(LogService.LOG_ERROR, "Could not retrieve
indices", e);
throw new WebApplicationException(e);
}
}
/**
- * Returns a list of all available incdices for this tenant.
+ * Returns a list of all available indices for this tenant.
* GET /rest/index/[indexname]/schema
*/
@GET
@Path("{indexname}/schema")
@Produces( { MediaType.TEXT_PLAIN })
- public String getSchema(@PathParam("indexname") final String indexname,
@Context final HttpServletRequest request) {
+ public Response getSchema(@PathParam("indexname") final String indexname,
@Context final HttpServletRequest request) {
if (indexname == null || indexname.isEmpty()) {
- m_logService.log(LogService.LOG_ERROR, "Could not query index '" +
indexname + "'");
- return "FAIL";
+ m_logService.log(LogService.LOG_ERROR, "Could not retrieve schema
for index '" + indexname + "'");
+ return Response.status(Response.Status.BAD_REQUEST).build();
}
try {
Tenant tenant = resolveTenant(request);
+ if (!m_solrApi.indexExists(tenant, indexname)) {
+ // Index does not exist, return a 404 (NOT_FOUND)
+ return
Response.status(Status.NOT_FOUND).cacheControl(m_cacheControl).build();
+ }
String schema = m_solrApi.getSchema(tenant, indexname);
- return schema;
- } catch (Exception e) {
- e.printStackTrace();
+ return Response.ok(schema).cacheControl(m_cacheControl).build();
}
- return "NOPE";
- }
-
- /**
- * Returns a list of all available indices for this tenant.
- * GET /rest/index/[indexname]/schema
- */
- @PUT
- @Path("{indexname}/schema")
- @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
- public Response putSchema(@PathParam("indexname") final String indexname,
@Context final HttpServletRequest request, InputStream is) {
- Tenant tenant = null;
- try {
- tenant = resolveTenant(request);
- if (tenant == null || indexname == null || indexname.isEmpty() ||
is == null || is.available() == 0) {
- String errorMsg = "Could not update schema for index '" +
indexname + "'.";
- if (is == null || is.available() == 0) {
- errorMsg += " No schema provided.";
- }
- m_logService.log(LogService.LOG_ERROR, errorMsg);
- SolrErrorBean errorBean = new SolrErrorBean(errorMsg);
- return
Response.status(Response.Status.BAD_REQUEST).entity(errorBean).cacheControl(m_cacheControl).build();
- }
- m_solrApi.setSchema(tenant, indexname ,is);
- return Response.ok().cacheControl(m_cacheControl).build();
- } catch (Exception e) {
- m_logService.log(LogService.LOG_ERROR, "Could not update schema
for index '" + indexname + "' on tenant '" + tenant + "'", e);
+ catch (Exception e) {
+ m_logService.log(LogService.LOG_ERROR, "Could not retrieve schema
for index '" + indexname + "'", e);
throw new WebApplicationException(e);
}
}
Modified:
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/util/SolrUtil.java
==============================================================================
---
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/util/SolrUtil.java
(original)
+++
sandbox/ivol/amdatu-searchandindex/solr/src/main/java/org/amdatu/searchandindex/solr/util/SolrUtil.java
Mon Jan 31 16:27:40 2011
@@ -12,6 +12,7 @@
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
@@ -20,12 +21,54 @@
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
+import org.amdatu.searchandindex.solr.impl.ContextClassLoaderScope;
+import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.util.StrUtils;
public class SolrUtil {
+ public static String getCoreName(String tenantId, String indexName) {
+ return tenantId + "_" + indexName;
+ }
+
+ public static void runInBundleContextClassLoader(ContextClassLoaderScope
runnable) throws SolrServerException {
+ // Save the current context classloader
+ final ClassLoader contextClassLoader =
Thread.currentThread().getContextClassLoader();
+ try {
+ // Classloader switcheroo
+ final ClassLoader classLoader = SolrUtil.class.getClassLoader();
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ runnable.run(classLoader);
+ } finally {
+ // Restore classloader
+ Thread.currentThread().setContextClassLoader(contextClassLoader);
+ }
+ }
+
+ public static void copyFile(File in, File out) throws IOException {
+ FileChannel inChannel = null;
+ FileChannel outChannel = null;
+ try {
+ inChannel = new FileInputStream(in).getChannel();
+ outChannel = new FileOutputStream(out).getChannel();
+ inChannel.transferTo(0, inChannel.size(), outChannel);
+ }
+ finally {
+ if (inChannel != null) {
+ try {
+ inChannel.close();
+ } finally {
+ if (outChannel != null) {
+ outChannel.close();
+ }
+ }
+ }
+ }
+ }
+
public static InputStream toXMLStream(List<SolrInputDocument> documents)
throws UnsupportedEncodingException {
StringBuffer xml = new StringBuffer("<docs>");
for (SolrInputDocument doc : documents) {