Author: rwesten
Date: Sun Apr 14 10:59:37 2013
New Revision: 1467763

URL: http://svn.apache.org/r1467763
Log:
STANBOL-1023: The Sling OSGI Installer plugin for installing SolrCores on 
ManagedSolrServers not register itself only after the first ManagedSolrServer 
is available. By this the timing issues mentioned in the issues are avoided

Modified:
    
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexInstallTask.java
    
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexRemoveTask.java
    
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/SolrIndexInstaller.java

Modified: 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexInstallTask.java
URL: 
http://svn.apache.org/viewvc/stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexInstallTask.java?rev=1467763&r1=1467762&r2=1467763&view=diff
==============================================================================
--- 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexInstallTask.java
 (original)
+++ 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexInstallTask.java
 Sun Apr 14 10:59:37 2013
@@ -71,11 +71,11 @@ public class IndexInstallTask extends In
             String serverName = (String) 
getResource().getAttribute(ManagedIndexConstants.SERVER_NAME);
             ManagedSolrServer server = managedServers.get(serverName);
             if(server == null){
-                log.warn("Unable to remove Managed Solr Index {} because the 
{} " +
+                log.warn("Unable to install Managed Solr Index {} because the 
{} " +
                         "Server {} is currently not active!", 
                         new Object[]{indexName,serverName == null ? "default" 
: "",
                                 serverName != null ? serverName : ""});
-                setFinishedState(ResourceState.IGNORED);
+                setFinishedState(ResourceState.IGNORED); //needs still to be 
installed
             } else {
                 //we have an index name and a server to in stall it ... 
                 //  ... let's do the work

Modified: 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexRemoveTask.java
URL: 
http://svn.apache.org/viewvc/stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexRemoveTask.java?rev=1467763&r1=1467762&r2=1467763&view=diff
==============================================================================
--- 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexRemoveTask.java
 (original)
+++ 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/IndexRemoveTask.java
 Sun Apr 14 10:59:37 2013
@@ -30,16 +30,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * TODO: To remove a SolrIndex one would need first to close the SolrCore or 
shutdown the SolrContainer. This
- * is currently not possible be cause the current architecture was not 
intended to support that.
- * <p>
- * To implement this one would need access to the CoreContainer with the core 
running on top of the Core to
- * remove. Than one would need to call {@link CoreContainer#remove(String)} 
with the core and
- * {@link CoreContainer#persist()} to remove the core also from the solr.xml. 
After that one can remove the
- * files from the disk.
- * <p>
- * This would still have the problem that other components using an {@link 
EmbeddedSolrServer} that is based
- * on this core would not be notified about such a change.
+ * Removes the SolrCore from the {@link ManagedSolrServer} by calling
+ * {@link ManagedSolrServer#removeIndex(String, boolean)}.
  * 
  * @author Rupert Westenthaler
  * 

Modified: 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/SolrIndexInstaller.java
URL: 
http://svn.apache.org/viewvc/stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/SolrIndexInstaller.java?rev=1467763&r1=1467762&r2=1467763&view=diff
==============================================================================
--- 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/SolrIndexInstaller.java
 (original)
+++ 
stanbol/trunk/commons/solr/install/src/main/java/org/apache/stanbol/commons/solr/install/impl/SolrIndexInstaller.java
 Sun Apr 14 10:59:37 2013
@@ -22,18 +22,19 @@ import static org.apache.stanbol.commons
 import static 
org.apache.stanbol.commons.solr.utils.ConfigUtils.SOLR_INDEX_ARCHIVE_EXTENSION;
 import static 
org.apache.stanbol.commons.solr.utils.ConfigUtils.SUPPORTED_SOLR_ARCHIVE_FORMAT;
 
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.apache.commons.io.FilenameUtils;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.felix.scr.annotations.Services;
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.tasks.InstallTask;
 import org.apache.sling.installer.api.tasks.InstallTaskFactory;
@@ -45,11 +46,13 @@ import org.apache.sling.installer.api.ta
 import org.apache.sling.installer.api.tasks.TransformationResult;
 import org.apache.stanbol.commons.solr.install.IndexInstallerConstants;
 import org.apache.stanbol.commons.solr.managed.ManagedSolrServer;
-import org.apache.stanbol.commons.solr.utils.ServiceReferenceRankingComparator;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -73,60 +76,131 @@ import org.slf4j.LoggerFactory;
  * framework. If {@link #transform(RegisteredResource)} returns 
<code>null</code> the Sling Installer
  * framework will call the next registered {@link ResourceTransformer} 
instance. By returning a
  * {@link TransformationResult} no further {@link ResourceTransformer} will be 
called.
- * 
+ * <p>
+ * <b>NOTE</b>(related to STANBOL-10
  * @author Rupert Westenthaler
  * 
  */
 @Component(immediate = true)
-@Service(value = {InstallTaskFactory.class, ResourceTransformer.class})
 @Property(name = Constants.SERVICE_RANKING, intValue = 100)
 // we need to be in front of the Sling Components
 public class SolrIndexInstaller implements InstallTaskFactory, 
ResourceTransformer {
 
     private static final Logger log = 
LoggerFactory.getLogger(SolrIndexInstaller.class);
 
-
-    
+    private ReadWriteLock lock = new ReentrantReadWriteLock();
+    private ServiceRegistration registration;
     private ServiceTracker serverTracker;
+    private Map<String,ManagedSolrServer> activeServers = 
Collections.emptyMap();
+    private BundleContext bc;
     
     @Activate
-    public void activate(ComponentContext context){
-        
-        serverTracker = new ServiceTracker(context.getBundleContext(), 
-            ManagedSolrServer.class.getName(), null);
+    protected void activate(ComponentContext context){
+        bc = context.getBundleContext();
+        serverTracker = new ServiceTracker(bc, 
ManagedSolrServer.class.getName(), 
+            new ServiceTrackerCustomizer() {
+                /**
+                 * The servers managed by this instance
+                 */
+                private SortedMap<ServiceReference,ManagedSolrServer> servers 
= 
+                        new TreeMap<ServiceReference,ManagedSolrServer>();
+                
+                @Override
+                public void removedService(ServiceReference reference, Object 
service) {
+                    lock.writeLock().lock();
+                    try {
+                        servers.remove(reference);
+                        updateRegistration(servers);
+                    } finally {
+                        lock.writeLock().unlock();
+                    }
+                }
+                
+                @Override
+                public void modifiedService(ServiceReference reference, Object 
service) {
+                    lock.writeLock().lock();
+                    try {
+                        servers.put(reference, (ManagedSolrServer)service);
+                        updateRegistration(servers);
+                    } finally {
+                        lock.writeLock().unlock();
+                    }
+                }
+                
+                @Override
+                public Object addingService(ServiceReference reference) {
+                    ManagedSolrServer server = 
(ManagedSolrServer)bc.getService(reference);
+                    if(server != null){
+                        lock.writeLock().lock();
+                        try {
+                            servers.put(reference, server);
+                            updateRegistration(servers);
+                        } finally {
+                            lock.writeLock().unlock();
+                        }
+                    }
+                    return server;
+                }
+            });
         serverTracker.open();
     }
+    
     @Deactivate
-    public void deactivate(ComponentContext context){
+    protected void deactivate(ComponentContext context){
         if(serverTracker != null){
             serverTracker.close();
+        }
+        lock.writeLock().lock();
+        try {
+            bc = null;
             serverTracker = null;
+        } finally {
+            lock.writeLock().unlock();
         }
     }
-    
-    private Map<String,ManagedSolrServer> getActiveServers(){
+    /**
+     * Basically adds/removes the {@link ServiceRegistration} when the 
first/last
+     * {@link ManagedSolrServer} becomes available / is deactivated.<p>
+     * Registers this as {@link InstallTaskFactory} and {@link 
ResourceTransformer}
+     */
+    private void 
updateRegistration(SortedMap<ServiceReference,ManagedSolrServer>servers){
+        log.debug(" ... updateRegistration for SolrIndexInstaller (bc: {}, 
server: {}, registration {}",
+            new Object[]{bc,servers,registration});
+        if((bc == null || servers.isEmpty()) && registration != null){
+            registration.unregister();
+            registration = null;
+            log.info(" ... unregistered InstallTaskFactory and 
ResourceTransformer for SolrCores on ManagedSolrServers");
+        } else if(bc != null && registration == null && !servers.isEmpty()) {
+            registration = bc.registerService(new String[]{
+                    InstallTaskFactory.class.getName(),
+                    ResourceTransformer.class.getName()}, 
+                    this, null);
+            log.info(" ... registered InstallTaskFactory and 
ResourceTransformer for SolrCores on ManagedSolrServers");
+        }
+        activeServers = createActiveServersMap(servers);
+        log.info(" ... set activeServers to {}",activeServers);
+    }
+    /**
+     * Assumed to be called while a writeLock is active on {@link #lock}
+     * @return
+     */
+    private Map<String,ManagedSolrServer> createActiveServersMap(
+            SortedMap<ServiceReference,ManagedSolrServer> servers){
         Map<String,ManagedSolrServer> map;
-        ServiceReference[] serverRefs = serverTracker.getServiceReferences();
-        if(serverRefs == null){
+        if(servers.isEmpty()){
             map = Collections.emptyMap();
         } else {
             map = new HashMap<String,ManagedSolrServer>();
-            if(serverRefs.length > 1){
-                
Arrays.sort(serverRefs,ServiceReferenceRankingComparator.INSTANCE);
-            }
-            ManagedSolrServer defaultServer = null;
-            for(ServiceReference ref : serverRefs){
-                ManagedSolrServer server = 
(ManagedSolrServer)serverTracker.getService(ref);
-                if(server != null){ //may become inactive in the meantime
-                    map.put(server.getServerName(), server);
-                    if(defaultServer == null){
-                        defaultServer = server;
-                    }
+            //this is a sorted iteration over the ManagedSolrServers
+            boolean first = true; //so the first will be the default server
+            for(ManagedSolrServer server : servers.values()){
+                map.put(server.getServerName(), server);
+                if(first){
+                    //put the default server under null
+                    map.put(null, server);
+                    first = false;
                 }
             }
-            if(defaultServer != null){
-                map.put(null, defaultServer);
-            }
         }
         return map;
     }
@@ -134,10 +208,17 @@ public class SolrIndexInstaller implemen
     public InstallTask createTask(TaskResourceGroup taskResourceGroup) {
         TaskResource toActivate = taskResourceGroup.getActiveResource();
         if (SOLR_INDEX_ARCHIVE_RESOURCE_TYPE.equals(toActivate.getType())) {
-            if (toActivate.getState() == ResourceState.UNINSTALL) {
-                return new IndexRemoveTask(taskResourceGroup, 
getActiveServers());
-            } else {
-                return new IndexInstallTask(taskResourceGroup, 
getActiveServers());
+            lock.readLock().lock();
+            try {
+                if (toActivate.getState() == ResourceState.UNINSTALL) {
+                    log.debug(" ... create IndexRemoveTask with servers 
{}",activeServers);
+                    return new IndexRemoveTask(taskResourceGroup, 
activeServers);
+                } else {
+                    log.debug(" ... create IndexInstallTask with servers 
{}",activeServers);
+                    return new IndexInstallTask(taskResourceGroup, 
activeServers);
+                }
+            } finally {
+                lock.readLock().unlock();
             }
         } else {
             return null;


Reply via email to