You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ch...@apache.org on 2015/08/17 06:07:06 UTC
svn commit: r1696190 - in /jackrabbit/oak/trunk/oak-pojosr/src:
main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy
Author: chetanm
Date: Mon Aug 17 04:07:06 2015
New Revision: 1696190
URL: http://svn.apache.org/r1696190
Log:
OAK-3203 - Make shutdown in PojoSR wait for framework shutdown
Modified:
jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy
Modified: jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java?rev=1696190&r1=1696189&r2=1696190&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java (original)
+++ jackrabbit/oak/trunk/oak-pojosr/src/main/java/org/apache/jackrabbit/oak/run/osgi/OakOSGiRepositoryFactory.java Mon Aug 17 04:07:06 2015
@@ -29,6 +29,7 @@ import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -50,11 +51,14 @@ import org.apache.felix.connect.launch.P
import org.apache.felix.connect.launch.PojoServiceRegistryFactory;
import org.apache.jackrabbit.api.JackrabbitRepository;
import org.apache.jackrabbit.oak.commons.PropertiesUtil;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -84,8 +88,8 @@ import static com.google.common.base.Pre
* <dt>org.apache.jackrabbit.oak.repository.bundleFilter</dt>
* <dd>Used to specify the bundle filter string which is passed to ClasspathScanner</dd>
*
- * <dt>org.apache.jackrabbit.oak.repository.startupTimeout</dt>
- * <dd>Timeout in seconds for the repository startup should wait. Defaults to 10 minutes</dd>
+ * <dt>org.apache.jackrabbit.oak.repository.timeoutInSecs</dt>
+ * <dd>Timeout in seconds for the repository startup/shutdown should wait. Defaults to 10 minutes</dd>
*
* <dt>org.apache.jackrabbit.oak.repository.shutDownOnTimeout</dt>
* <dd>Boolean flag to determine if the OSGi container should be shutdown upon timeout. Defaults to false</dd>
@@ -104,8 +108,8 @@ public class OakOSGiRepositoryFactory im
/**
* Timeout in seconds for the repository startup should wait
*/
- public static final String REPOSITORY_STARTUP_TIMEOUT
- = "org.apache.jackrabbit.oak.repository.startupTimeout";
+ public static final String REPOSITORY_TIMEOUT_IN_SECS
+ = "org.apache.jackrabbit.oak.repository.timeoutInSecs";
/**
* Config key which refers to the map of config where key in that map refers to OSGi
@@ -166,16 +170,17 @@ public class OakOSGiRepositoryFactory im
new RunnableJobTracker(registry.getBundleContext());
+ int timeoutInSecs = PropertiesUtil.toInteger(config.get(REPOSITORY_TIMEOUT_IN_SECS), DEFAULT_TIMEOUT);
+
//Start the tracker for repository creation
- new RepositoryTracker(registry, activator, repoFuture);
+ new RepositoryTracker(registry, activator, repoFuture, timeoutInSecs);
//Now wait for repository to be created with given timeout
//if repository creation takes more time. This is required to handle case
// where OSGi runtime fails to start due to bugs (like cycles)
- int timeout = getTimeoutInSeconds(config);
try {
- return repoFuture.get(timeout, TimeUnit.SECONDS);
+ return repoFuture.get(timeoutInSecs, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RepositoryException("Repository initialization was interrupted");
@@ -184,8 +189,8 @@ public class OakOSGiRepositoryFactory im
} catch (TimeoutException e) {
try {
if (PropertiesUtil.toBoolean(config.get(REPOSITORY_SHUTDOWN_ON_TIMEOUT), true)) {
- shutdown(registry);
- log.info("OSGi container shutdown after waiting for repository initialization for {} sec",timeout);
+ shutdown(registry, timeoutInSecs);
+ log.info("OSGi container shutdown after waiting for repository initialization for {} sec",timeoutInSecs);
}else {
log.warn("[{}] found to be false. Container is not stopped", REPOSITORY_SHUTDOWN_ON_TIMEOUT);
}
@@ -194,7 +199,7 @@ public class OakOSGiRepositoryFactory im
"startup timeout) backing the Repository ", be);
}
throw new RepositoryException("Repository could not be started in " +
- timeout + " seconds", e);
+ timeoutInSecs + " seconds", e);
}
}
@@ -237,9 +242,32 @@ public class OakOSGiRepositoryFactory im
return descriptors;
}
- static void shutdown(PojoServiceRegistry registry) throws BundleException {
- if (registry != null) {
- registry.getBundleContext().getBundle().stop();
+ private static void shutdown(PojoServiceRegistry registry, int timeoutInSecs) throws BundleException {
+ if (registry == null){
+ return;
+ }
+ final Bundle systemBundle = registry.getBundleContext().getBundle();
+ final CountDownLatch shutdownLatch = new CountDownLatch(1);
+
+ //Logic here is similar to org.apache.felix.connect.PojoServiceRegistryFactoryImpl.FrameworkImpl.waitForStop()
+ systemBundle.getBundleContext().addBundleListener(new SynchronousBundleListener() {
+ public void bundleChanged(BundleEvent event) {
+ if (event.getBundle() == systemBundle && event.getType() == BundleEvent.STOPPED) {
+ shutdownLatch.countDown();
+ }
+ }
+ });
+
+ //Initiate shutdown
+ systemBundle.stop();
+
+ //Wait for framework shutdown to complete
+ try {
+ shutdownLatch.await(timeoutInSecs, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new BundleException("Timed out while waiting for repository " +
+ "shutdown for "+ timeoutInSecs + " secs", e);
}
}
@@ -247,14 +275,6 @@ public class OakOSGiRepositoryFactory im
new ConfigTracker(config, registry.getBundleContext());
}
- private static int getTimeoutInSeconds(Map config) {
- Integer timeout = (Integer) config.get(REPOSITORY_STARTUP_TIMEOUT);
- if (timeout == null) {
- timeout = DEFAULT_TIMEOUT;
- }
- return timeout;
- }
-
/**
* Return the BundleActivator provided by the embedding application
* @param config config passed to factory for initialization
@@ -350,12 +370,15 @@ public class OakOSGiRepositoryFactory im
private final PojoServiceRegistry registry;
private final BundleActivator activator;
private RepositoryProxy proxy;
+ private final int timeoutInSecs;
- public RepositoryTracker(PojoServiceRegistry registry, BundleActivator activator, SettableFuture<Repository> repoFuture) {
+ public RepositoryTracker(PojoServiceRegistry registry, BundleActivator activator,
+ SettableFuture<Repository> repoFuture, int timeoutInSecs) {
super(registry.getBundleContext(), Repository.class.getName(), null);
this.repoFuture = repoFuture;
this.registry = registry;
this.activator = activator;
+ this.timeoutInSecs = timeoutInSecs;
this.open();
}
@@ -394,7 +417,7 @@ public class OakOSGiRepositoryFactory im
} catch (Exception e) {
log.warn("Error occurred while shutting down activator {}", activator.getClass(), e);
}
- shutdown(getRegistry());
+ shutdown(getRegistry(), timeoutInSecs);
}
}
Modified: jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy?rev=1696190&r1=1696189&r2=1696190&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy (original)
+++ jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/AbstractRepositoryFactoryTest.groovy Mon Aug 17 04:07:06 2015
@@ -34,7 +34,7 @@ import javax.jcr.*
import java.util.concurrent.TimeUnit
import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_HOME
-import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_STARTUP_TIMEOUT
+import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_TIMEOUT_IN_SECS
import static org.apache.jackrabbit.oak.run.osgi.OakOSGiRepositoryFactory.REPOSITORY_BUNDLE_FILTER
abstract class AbstractRepositoryFactoryTest{
@@ -52,7 +52,7 @@ abstract class AbstractRepositoryFactory
workDir = tmpFolder.getRoot();
config = [
(REPOSITORY_HOME): workDir.absolutePath,
- (REPOSITORY_STARTUP_TIMEOUT) : 60,
+ (REPOSITORY_TIMEOUT_IN_SECS) : 60,
(REPOSITORY_BUNDLE_FILTER) : '''
(|
(Bundle-SymbolicName=org.apache.jackrabbit*)