You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2018/08/03 09:53:18 UTC
[karaf] branch karaf-4.1.x updated: [KARAF-5798] use a consistent
way to get the Karaf process ID;
write the pid file when the process launches so that it contains an accurate
value for either a master or slave instance;
only update the instance PID for the current running master (i.e. once lock
is acquired)
This is an automated email from the ASF dual-hosted git repository.
jbonofre pushed a commit to branch karaf-4.1.x
in repository https://gitbox.apache.org/repos/asf/karaf.git
The following commit(s) were added to refs/heads/karaf-4.1.x by this push:
new 796cba8 [KARAF-5798] use a consistent way to get the Karaf process ID; write the pid file when the process launches so that it contains an accurate value for either a master or slave instance; only update the instance PID for the current running master (i.e. once lock is acquired)
796cba8 is described below
commit 796cba8aa09d115d6bbd806f6f76ef6aa9b755ad
Author: Zipay, Matthew <mz...@contractor.express.com>
AuthorDate: Mon Jul 9 16:32:07 2018 -0400
[KARAF-5798] use a consistent way to get the Karaf process ID; write the pid file when the process launches so that it contains an accurate value for either a master or slave instance; only update the instance PID for the current running master (i.e. once lock is acquired)
---
.../java/org/apache/karaf/main/InstanceHelper.java | 35 ++++---
main/src/main/java/org/apache/karaf/main/Main.java | 5 +-
.../org/apache/karaf/main/MainLockingTest.java | 101 +++++++++++++++++++--
.../test/java/org/apache/karaf/main/MockLock.java | 2 +
4 files changed, 114 insertions(+), 29 deletions(-)
diff --git a/main/src/main/java/org/apache/karaf/main/InstanceHelper.java b/main/src/main/java/org/apache/karaf/main/InstanceHelper.java
index deeb739..d610a2d 100644
--- a/main/src/main/java/org/apache/karaf/main/InstanceHelper.java
+++ b/main/src/main/java/org/apache/karaf/main/InstanceHelper.java
@@ -25,7 +25,6 @@ import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.io.Writer;
import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.nio.channels.FileLock;
@@ -112,27 +111,26 @@ public class InstanceHelper {
}
}
+ /* KARAF-5798: consistent way to obtain the process ID */
private static String getPid() {
- String pid = ManagementFactory.getRuntimeMXBean().getName();
- if (pid.indexOf('@') > 0) {
- pid = pid.substring(0, pid.indexOf('@'));
- }
- return pid;
- }
+ String name = ManagementFactory.getRuntimeMXBean().getName();
+ /*
+ * RuntimeMXBean#getName() makes no guarantees about the name, so use a
+ * regex to match the common(?) "pid@host" format
+ */
+ Pattern pattern = Pattern.compile("^([0-9]+)@.+$");
+ Matcher matcher = pattern.matcher(name);
+ return matcher.matches() ? matcher.group(1) : name;
+ }
- private static void writePid(String pidFile) {
+ /* KARAF-5798: now called by Main#launch() */
+ static void writePid(String pidFile) {
try {
if (pidFile != null) {
- RuntimeMXBean rtb = ManagementFactory.getRuntimeMXBean();
- String processName = rtb.getName();
- Pattern pattern = Pattern.compile("^([0-9]+)@.+$", Pattern.CASE_INSENSITIVE);
- Matcher matcher = pattern.matcher(processName);
- if (matcher.matches()) {
- int pid = Integer.parseInt(matcher.group(1));
- Writer w = new OutputStreamWriter(new FileOutputStream(pidFile));
- w.write(Integer.toString(pid));
- w.close();
- }
+ int pid = Integer.parseInt(getPid());
+ Writer w = new OutputStreamWriter(new FileOutputStream(pidFile));
+ w.write(Integer.toString(pid));
+ w.close();
}
} catch (Exception e) {
e.printStackTrace();
@@ -140,7 +138,6 @@ public class InstanceHelper {
}
static void setupShutdown(ConfigProperties config, Framework framework) {
- writePid(config.pidFile);
try {
int port = config.shutdownPort;
String host = config.shutdownHost;
diff --git a/main/src/main/java/org/apache/karaf/main/Main.java b/main/src/main/java/org/apache/karaf/main/Main.java
index 66b6a81..817a30d 100644
--- a/main/src/main/java/org/apache/karaf/main/Main.java
+++ b/main/src/main/java/org/apache/karaf/main/Main.java
@@ -240,7 +240,8 @@ public class Main {
}
String log4jConfigPath = System.getProperty("karaf.etc") + "/org.ops4j.pax.logging.cfg";
BootstrapLogManager.setProperties(config.props, log4jConfigPath);
- InstanceHelper.updateInstancePid(config.karafHome, config.karafBase, true);
+ /* KARAF-5798: write the PID whether or not the lock has been acquired */
+ InstanceHelper.writePid(config.pidFile);
BootstrapLogManager.configureLogger(LOG);
for (String provider : config.securityProviders) {
@@ -717,6 +718,8 @@ public class Main {
@Override
public void lockAquired() {
LOG.info("Lock acquired. Setting startlevel to " + config.defaultStartLevel);
+ /* KARAF-5798: instance PID should reflect the current running master */
+ InstanceHelper.updateInstancePid(config.karafHome, config.karafBase, true);
InstanceHelper.setupShutdown(config, framework);
setStartLevel(config.defaultStartLevel);
}
diff --git a/main/src/test/java/org/apache/karaf/main/MainLockingTest.java b/main/src/test/java/org/apache/karaf/main/MainLockingTest.java
index 78d5a32..46585ec 100644
--- a/main/src/test/java/org/apache/karaf/main/MainLockingTest.java
+++ b/main/src/test/java/org/apache/karaf/main/MainLockingTest.java
@@ -21,9 +21,12 @@ package org.apache.karaf.main;
import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
import java.io.File;
+import java.io.IOException;
import org.apache.karaf.main.util.Utils;
+import org.junit.After;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.ops4j.pax.tinybundles.core.TinyBundles;
import org.osgi.framework.Bundle;
@@ -32,24 +35,36 @@ import org.osgi.framework.launch.Framework;
import org.osgi.framework.startlevel.FrameworkStartLevel;
public class MainLockingTest {
-
- @Test
- public void testLostMasterLock() throws Exception {
+ private File home;
+
+ private File data;
+
+ @Before
+ public void setUp() throws IOException {
File basedir = new File(getClass().getClassLoader().getResource("foo").getPath()).getParentFile();
- File home = new File(basedir, "test-karaf-home");
- File data = new File(home, "data");
+ home = new File(basedir, "test-karaf-home");
+ 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");
- System.setProperty("karaf.lock","true");
- System.setProperty("karaf.lock.delay","1000");
- System.setProperty("karaf.lock.class","org.apache.karaf.main.MockLock");
+ System.setProperty("karaf.lock", "true");
+ System.setProperty("karaf.lock.delay", "1000");
+ System.setProperty("karaf.lock.class", "org.apache.karaf.main.MockLock");
+ }
+
+ @After
+ public void tearDown() {
+ home = null;
+ data = null;
+ }
+ @Test
+ public void testLostMasterLock() throws Exception {
+ String[] args = new String[0];
Main main = new Main(args);
main.launch();
Framework framework = main.getFramework();
@@ -89,4 +104,72 @@ public class MainLockingTest {
// exit framework + lock loop
main.destroy();
}
+
+ @Test
+ public void testMasterWritesPid() throws Exception {
+ // use data because it's always deleted at the beginning of the test
+ File pidFile = new File(data, "test-karaf.pid");
+ System.setProperty("karaf.pid.file", pidFile.toString());
+
+ try {
+ Assert.assertFalse(pidFile.isFile());
+
+ String[] args = new String[0];
+ Main main = new Main(args);
+ main.launch();
+
+ Thread.sleep(1000);
+
+ Framework framework = main.getFramework();
+ FrameworkStartLevel sl = framework.adapt(FrameworkStartLevel.class);
+ Assert.assertEquals(100, sl.getStartLevel());
+
+ MockLock lock = (MockLock) main.getLock();
+
+ Assert.assertTrue(lock.lock());
+ Assert.assertTrue(lock.isAlive());
+ Assert.assertTrue(pidFile.isFile());
+
+ main.destroy();
+ } finally {
+ System.clearProperty("karaf.pid.file");
+ }
+ }
+
+ @Test
+ public void testSlaveWritesPid() throws Exception {
+ // simulate that the lock is not acquired (i.e. instance runs as slave)
+ System.setProperty("test.karaf.mocklock.initiallyLocked", "false");
+ System.setProperty("karaf.lock.level", "59");
+
+ // use data because it's always deleted at the beginning of the test
+ File pidFile = new File(data, "test-karaf.pid");
+ System.setProperty("karaf.pid.file", pidFile.toString());
+
+ try {
+ Assert.assertFalse(pidFile.isFile());
+
+ String[] args = new String[0];
+ Main main = new Main(args);
+ main.launch();
+
+ Thread.sleep(1000);
+
+ Framework framework = main.getFramework();
+ FrameworkStartLevel sl = framework.adapt(FrameworkStartLevel.class);
+ Assert.assertEquals(59, sl.getStartLevel());
+
+ MockLock lock = (MockLock) main.getLock();
+
+ Assert.assertFalse(lock.lock());
+ Assert.assertTrue(lock.isAlive());
+ Assert.assertTrue(pidFile.isFile());
+
+ main.destroy();
+ } finally {
+ System.clearProperty("test.karaf.mocklock.initiallyLocked");
+ System.clearProperty("karaf.lock.level");
+ System.clearProperty("karaf.pid.file");
+ }
+ }
}
diff --git a/main/src/test/java/org/apache/karaf/main/MockLock.java b/main/src/test/java/org/apache/karaf/main/MockLock.java
index e2ac2b2..13b7564 100644
--- a/main/src/test/java/org/apache/karaf/main/MockLock.java
+++ b/main/src/test/java/org/apache/karaf/main/MockLock.java
@@ -31,6 +31,8 @@ public class MockLock implements Lock {
private Object lockLock = new Object();
public MockLock(Properties props) {
+ /* KARAF-5798: allow tests to simulate slave instances */
+ lock = Boolean.valueOf(System.getProperty("test.karaf.mocklock.initiallyLocked", "true"));
}
public boolean lock() throws Exception {