You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by ff...@apache.org on 2012/10/25 03:34:47 UTC
svn commit: r1401944 - in /karaf/branches/karaf-2.3.x/main/src:
main/java/org/apache/karaf/main/ test/java/org/apache/karaf/main/
Author: ffang
Date: Thu Oct 25 01:34:46 2012
New Revision: 1401944
URL: http://svn.apache.org/viewvc?rev=1401944&view=rev
Log:
[KARAF-1938]Lock logic should wait for start level change to occur
Added:
karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/StartLevelListener.java
karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MainLockingTest.java
karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MockLock.java
Modified:
karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/Main.java
Modified: karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/Main.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/Main.java?rev=1401944&r1=1401943&r2=1401944&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/Main.java (original)
+++ karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/Main.java Thu Oct 25 01:34:46 2012
@@ -51,6 +51,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
@@ -210,7 +211,8 @@ public class Main {
private boolean exiting = false;
private ShutdownCallback shutdownCallback;
private List<BundleActivator> karafActivators = new ArrayList<BundleActivator>();
-
+ private Object startLevelLock = new Object();
+ private StartLevelListener startLevelListener;
public Main(String[] args) {
this.args = args;
@@ -290,6 +292,10 @@ public class Main {
// Process properties
loadStartupProperties(configProps);
processAutoProperties(framework.getBundleContext());
+
+ startLevelListener = new StartLevelListener(startLevelLock);
+ framework.getBundleContext().addFrameworkListener(startLevelListener);
+
framework.start();
// Start custom activators
startKarafActivators(classLoader);
@@ -1370,8 +1376,16 @@ public class Main {
Thread.sleep(lockDelay);
}
if (framework.getState() == Bundle.ACTIVE && !exiting) {
- LOG.info("Lost the lock, stopping this instance ...");
- setStartLevel(lockStartLevel);
+ LOG.info("Lost the lock, reducing start level to " + lockStartLevel);
+ synchronized (startLevelLock) {
+ setStartLevel(lockStartLevel);
+
+ // we have to wait for the start level to be reduced here because
+ // if the lock is regained before the start level is fully changed
+ // things may not come up as expected
+ LOG.fine("Waiting for start level change to complete...");
+ startLevelLock.wait(shutdownTimeout);
+ }
}
} else if (!lockLogged) {
LOG.info("Waiting for the lock ...");
@@ -1444,6 +1458,10 @@ public class Main {
}
}
+ public Lock getLock() {
+ return lock;
+ }
+
private class ShutdownSocketThread extends Thread {
private final String shutdown;
Added: karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/StartLevelListener.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/StartLevelListener.java?rev=1401944&view=auto
==============================================================================
--- karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/StartLevelListener.java (added)
+++ karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/StartLevelListener.java Thu Oct 25 01:34:46 2012
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.karaf.main;
+
+import java.util.logging.Logger;
+
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+
+public class StartLevelListener implements FrameworkListener {
+
+ Logger LOG = Logger.getLogger(this.getClass().getName());
+ private Object startLevelLock;
+
+ public StartLevelListener(Object startLevelLock) {
+ this.startLevelLock = startLevelLock;
+ }
+
+ public void frameworkEvent(FrameworkEvent event) {
+ if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
+ synchronized (startLevelLock) {
+ LOG.fine("Start level change complete.");
+ startLevelLock.notifyAll();
+ }
+ }
+ }
+}
Added: karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MainLockingTest.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MainLockingTest.java?rev=1401944&view=auto
==============================================================================
--- karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MainLockingTest.java (added)
+++ karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MainLockingTest.java Thu Oct 25 01:34:46 2012
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.karaf.main;
+
+import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.withBnd;
+
+import java.io.File;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.launch.Framework;
+import org.osgi.service.startlevel.StartLevel;
+
+public class MainLockingTest {
+
+ @Test
+ public void testLostMasterLock() throws Exception {
+ File basedir = new File(getClass().getClassLoader().getResource("foo").getPath()).getParentFile();
+ File home = new File(basedir, "test-karaf-home");
+ File data = new File(home, "data");
+
+ Utils.deleteDirectory(data);
+
+ String[] args = new String[0];
+ System.setProperty("karaf.home", home.toString());
+ System.setProperty("karaf.data", data.toString());
+ System.setProperty("karaf.framework.factory", "org.apache.felix.framework.FrameworkFactory");
+
+ // enable locking
+ System.setProperty("karaf.lock","true");
+ System.setProperty("karaf.lock.delay","1000");
+ System.setProperty("karaf.lock.class","org.apache.karaf.main.MockLock");
+
+ Main main = new Main(args);
+ main.launch();
+ Thread.sleep(1000);
+
+ Framework framework = main.getFramework();
+ String activatorName = TimeoutShutdownActivator.class.getName().replace('.', '/') + ".class";
+ Bundle bundle = framework.getBundleContext().installBundle("foo",
+ TinyBundles.newBundle()
+ .set( Constants.BUNDLE_ACTIVATOR, TimeoutShutdownActivator.class.getName() )
+ .add( activatorName, getClass().getClassLoader().getResourceAsStream( activatorName ) )
+ .build( withBnd() )
+ );
+ bundle.start();
+
+ BundleContext ctx = framework.getBundleContext();
+ ServiceReference[] refs = ctx.getServiceReferences(StartLevel.class.getName(), null);
+ StartLevel sl = (StartLevel) ctx.getService(refs[0]);
+
+ MockLock lock = (MockLock) main.getLock();
+
+ Assert.assertEquals(100, sl.getStartLevel());
+
+ // simulate losing a lock
+ lock.setIsAlive(false);
+ lock.setLock(false);
+
+ // lets wait until the start level change is complete
+ lock.waitForLock();
+ Assert.assertEquals(1, sl.getStartLevel());
+
+ Thread.sleep(1000);
+
+ // get lock back
+ lock.setIsAlive(true);
+ lock.setLock(true);
+
+ // wait for loop to recognize lock
+ lock.waitForLock();
+
+ Thread.sleep(1000);
+
+ // exit framework + lock loop
+ main.destroy();
+ }
+}
Added: karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MockLock.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MockLock.java?rev=1401944&view=auto
==============================================================================
--- karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MockLock.java (added)
+++ karaf/branches/karaf-2.3.x/main/src/test/java/org/apache/karaf/main/MockLock.java Thu Oct 25 01:34:46 2012
@@ -0,0 +1,64 @@
+package org.apache.karaf.main;
+
+import java.util.Properties;
+import java.util.logging.Logger;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+public class MockLock implements Lock {
+
+ private boolean lock = true;
+ private boolean isAlive = true;
+ private static final Logger LOG = Logger.getLogger(MockLock.class.getName());
+ private Object lockLock = new Object();
+
+ public MockLock(Properties props) {
+ }
+
+ public boolean lock() throws Exception {
+ synchronized (lockLock) {
+ LOG.fine("lock = " + lock);
+ lockLock.notifyAll();
+ }
+ return lock;
+ }
+
+ public void release() throws Exception {
+ LOG.fine("release");
+ }
+
+ public boolean isAlive() throws Exception {
+ LOG.fine("isAlive = " + isAlive);
+ return isAlive;
+ }
+
+ public void setLock(boolean lock) {
+ this.lock = lock;
+ }
+
+ public void setIsAlive(boolean isAlive) {
+ this.isAlive = isAlive;
+ }
+
+ public void waitForLock() throws InterruptedException {
+ synchronized (lockLock) {
+ lockLock.wait(1000 * 60 * 5);
+ }
+ }
+}