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;