karaf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (KARAF-5798) Karaf slave instance does not write pid or port file until it becomes master
Date Fri, 03 Aug 2018 09:30:00 GMT

    [ https://issues.apache.org/jira/browse/KARAF-5798?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16567998#comment-16567998
] 

ASF GitHub Bot commented on KARAF-5798:
---------------------------------------

jbonofre closed pull request #542: [KARAF-5798] use a consistent way to get the Karaf process
ID; write …
URL: https://github.com/apache/karaf/pull/542
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

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 5cf5826fe8..8ea33be8fd 100644
--- a/main/src/main/java/org/apache/karaf/main/InstanceHelper.java
+++ b/main/src/main/java/org/apache/karaf/main/InstanceHelper.java
@@ -24,7 +24,6 @@
 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;
@@ -107,27 +106,26 @@ static void updateInstancePid(final File karafHome, final File karafBase,
final
         }
     }
 
+    /* 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();
@@ -135,7 +133,6 @@ private static void writePid(String pidFile) {
     }
 
     static AutoCloseable 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 2d80607c03..09c4a9535f 100644
--- a/main/src/main/java/org/apache/karaf/main/Main.java
+++ b/main/src/main/java/org/apache/karaf/main/Main.java
@@ -239,7 +239,8 @@ public void launch() throws Exception {
         }
         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) {
@@ -746,6 +747,8 @@ public void stopShutdownThread() {
         @Override
         public void lockAcquired() {
             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);
             shutdownThread = 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 78d5a328b4..46585ec288 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 @@
 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.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 void testLostMasterLock() throws Exception {
         // 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 e2ac2b25fa..13b7564cb4 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 @@
     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 {


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> Karaf slave instance does not write pid or port file until it becomes master
> ----------------------------------------------------------------------------
>
>                 Key: KARAF-5798
>                 URL: https://issues.apache.org/jira/browse/KARAF-5798
>             Project: Karaf
>          Issue Type: Bug
>          Components: karaf-boot
>    Affects Versions: 4.0.9
>            Reporter: Matthew Zipay
>            Assignee: Jean-Baptiste Onofré
>            Priority: Major
>             Fix For: 4.1.6, 4.2.1
>
>
> In a Karaf master/slave environment, the slave process does not write its pid or port
file until it acquires the lock and becomes the master.
> I am running Karaf 4.0.9 (ServiceMix 7.0.1).
> Karaf is configured as master/slave using the following from system.properties. Master
and slave are on different physical nodes.
> {code:java}
> karaf.lock=true
> karaf.lock.class=org.apache.karaf.main.lock.OracleJDBCLock
> karaf.lock.level=79
> karaf.lock.delay=10000
> karaf.lock.jdbc.url=jdbc:oracle:thin:#REMOVED#
> karaf.lock.jdbc.driver=oracle.jdbc.driver.OracleDriver
> karaf.lock.jdbc.user=#REMOVED#
> karaf.lock.jdbc.password=#REMOVED#
> karaf.lock.jdbc.table=KARAF_LOCK
> karaf.lock.jdbc.clustername=karaf
> karaf.lock.jdbc.timeout=30
> karaf.lock.slave.block=false
> {code}
> Attempting to stop the slave Karaf process results in _"Can't connect to the container.
The container is not running."_ This is not true, as a simple {{ps -ef | grep karaf}} confirms
that it is in fact running. I am able to enter the Karaf shell just fine, use the web console,
etc.
> I have confirmed through multiple tests that the pid and port files don't get written
until the master lock is acquired.
> Steps:
> # With the Karaf slave node not started, note the pid and port files do not exist (or
contain outdated values from a previous process).
> # Start the Karaf slave process.
> # Note that the pid and port files have not been written.
> # Stop the master process.
> # Observe the slave process acquire the lock and become master.
> # Note that the pid and port files have now been written.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Mime
View raw message