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) {

Reply via email to