You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2012/08/02 21:51:01 UTC

svn commit: r1368669 - in /karaf/branches/karaf-2.3.x: assemblies/apache-karaf/src/main/filtered-resources/etc/ assemblies/apache-karaf/src/main/filtered-resources/minimal/ main/src/main/java/org/apache/karaf/main/ shell/console/src/main/java/org/apach...

Author: gnodet
Date: Thu Aug  2 19:51:00 2012
New Revision: 1368669

URL: http://svn.apache.org/viewvc?rev=1368669&view=rev
Log:
[KARAF-1640] Make sure the local console is fully working before the user can type commands

Modified:
    karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties
    karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/minimal/startup.properties
    karaf/branches/karaf-2.3.x/main/src/main/java/org/apache/karaf/main/Main.java
    karaf/branches/karaf-2.3.x/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java

Modified: karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties?rev=1368669&r1=1368668&r2=1368669&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties (original)
+++ karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/etc/startup.properties Thu Aug  2 19:51:00 2012
@@ -41,7 +41,8 @@ org/apache/aries/blueprint/org.apache.ar
 org/apache/aries/blueprint/org.apache.aries.blueprint.core/${aries.blueprint.core.version}/org.apache.aries.blueprint.core-${aries.blueprint.core.version}.jar=20
 org/apache/aries/blueprint/org.apache.aries.blueprint.cm/${aries.blueprint.cm.version}/org.apache.aries.blueprint.cm-${aries.blueprint.cm.version}.jar=20
 
-org/apache/karaf/shell/org.apache.karaf.shell.console/${project.version}/org.apache.karaf.shell.console-${project.version}.jar=30
+org/apache/karaf/shell/org.apache.karaf.shell.console/${project.version}/org.apache.karaf.shell.console-${project.version}.jar=25
+
 org/apache/karaf/shell/org.apache.karaf.shell.osgi/${project.version}/org.apache.karaf.shell.osgi-${project.version}.jar=30
 org/apache/karaf/shell/org.apache.karaf.shell.log/${project.version}/org.apache.karaf.shell.log-${project.version}.jar=30
 org/apache/karaf/shell/org.apache.karaf.shell.packages/${project.version}/org.apache.karaf.shell.packages-${project.version}.jar=30

Modified: karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/minimal/startup.properties
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/minimal/startup.properties?rev=1368669&r1=1368668&r2=1368669&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/minimal/startup.properties (original)
+++ karaf/branches/karaf-2.3.x/assemblies/apache-karaf/src/main/filtered-resources/minimal/startup.properties Thu Aug  2 19:51:00 2012
@@ -41,7 +41,8 @@ org/apache/aries/blueprint/org.apache.ar
 org/apache/aries/blueprint/org.apache.aries.blueprint.core/${aries.blueprint.core.version}/org.apache.aries.blueprint.core-${aries.blueprint.core.version}.jar=20
 org/apache/aries/blueprint/org.apache.aries.blueprint.cm/${aries.blueprint.cm.version}/org.apache.aries.blueprint.cm-${aries.blueprint.cm.version}.jar=20
 
-org/apache/karaf/shell/org.apache.karaf.shell.console/${project.version}/org.apache.karaf.shell.console-${project.version}.jar=30
+org/apache/karaf/shell/org.apache.karaf.shell.console/${project.version}/org.apache.karaf.shell.console-${project.version}.jar=25
+
 org/apache/karaf/shell/org.apache.karaf.shell.osgi/${project.version}/org.apache.karaf.shell.osgi-${project.version}.jar=30
 org/apache/karaf/shell/org.apache.karaf.shell.log/${project.version}/org.apache.karaf.shell.log-${project.version}.jar=30
 org/apache/karaf/shell/org.apache.karaf.shell.packages/${project.version}/org.apache.karaf.shell.packages-${project.version}.jar=30

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=1368669&r1=1368668&r2=1368669&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 Aug  2 19:51:00 2012
@@ -48,12 +48,16 @@ import java.util.regex.Pattern;
 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.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.framework.launch.Framework;
 import org.osgi.framework.launch.FrameworkFactory;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
 import org.osgi.service.startlevel.StartLevel;
 
 /**
@@ -188,6 +192,8 @@ public class Main {
 
     public static final String SECURITY_PROVIDERS = "org.apache.karaf.security.providers";
 
+    public static final String KARAF_STARTUP_MESSAGE = "karaf.startup.message";
+
     Logger LOG = Logger.getLogger(this.getClass().getName());
 
     private File karafHome;
@@ -244,6 +250,8 @@ public class Main {
         // Copy framework properties from the system properties.
         Main.copySystemProperties(configProps);
 
+        System.out.println(configProps.getProperty(KARAF_STARTUP_MESSAGE, "Apache Karaf starting up..."));
+
         ClassLoader classLoader = createClassLoader(configProps);
 
         processSecurityProperties(configProps);
@@ -259,6 +267,7 @@ public class Main {
         }
         
         defaultStartLevel = Integer.parseInt(configProps.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
+        System.setProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, Integer.toString(this.defaultStartLevel));
         lockStartLevel = Integer.parseInt(configProps.getProperty(PROPERTY_LOCK_LEVEL, Integer.toString(lockStartLevel)));
         lockDelay = Integer.parseInt(configProps.getProperty(PROPERTY_LOCK_DELAY, Integer.toString(lockDelay)));
         configProps.setProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, Integer.toString(lockStartLevel));
@@ -281,6 +290,8 @@ public class Main {
         framework.start();
         // Start custom activators
         startKarafActivators(classLoader);
+        // Progress bar
+        new StartupListener(framework.getBundleContext());
         // Start lock monitor
         new Thread() {
             public void run() {
@@ -289,6 +300,61 @@ public class Main {
         }.start();
     }
 
+    private static class StartupListener implements FrameworkListener, SynchronousBundleListener {
+        private final BundleContext context;
+        private StartupListener(BundleContext context) {
+            this.context = context;
+            context.addBundleListener(this);
+            context.addFrameworkListener(this);
+        }
+        public synchronized void bundleChanged(BundleEvent bundleEvent) {
+            Bundle[] bundles = context.getBundles();
+            int numActive = 0;
+            int numBundles = bundles.length;
+            for (Bundle bundle : bundles) {
+                if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null) {
+                    numBundles--;
+                } else if (bundle.getState() == Bundle.ACTIVE) {
+                    numActive ++;
+                }
+            }
+            boolean started = Boolean.parseBoolean(System.getProperty("karaf.console.started", "false"));
+            if (!started) {
+                update(numActive, numBundles);
+            }
+        }
+        public synchronized void frameworkEvent(FrameworkEvent frameworkEvent) {
+            if (frameworkEvent.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
+                int defStartLevel = Integer.parseInt(System.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
+                int startLevel = context.getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
+                if (startLevel >= defStartLevel) {
+                    context.removeBundleListener(this);
+                    context.removeFrameworkListener(this);
+                }
+            }
+        }
+        public void update(int done, int total) {
+            int percent = (done * 100) / total;
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format("\r%3d%% [", percent));
+            for (int i = 0; i < 100; i++) {
+                if (i < percent) {
+                    sb.append('=');
+                } else if (i == percent) {
+                    sb.append('>');
+                } else {
+                    sb.append(' ');
+                }
+            }
+            sb.append(']');
+            System.out.print(sb.toString());
+            System.out.flush();
+            if (done == total) {
+                System.out.println();
+            }
+        }
+    }
+
     private void startKarafActivators(ClassLoader classLoader) throws IOException {
         Enumeration<URL> urls = classLoader.getResources("META-INF/MANIFEST.MF");
         while (urls != null && urls.hasMoreElements()) {

Modified: karaf/branches/karaf-2.3.x/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java?rev=1368669&r1=1368668&r2=1368669&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java (original)
+++ karaf/branches/karaf-2.3.x/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java Thu Aug  2 19:51:00 2012
@@ -28,6 +28,7 @@ import java.security.KeyPair;
 import java.security.PrivilegedExceptionAction;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 import javax.security.auth.Subject;
 
 import jline.Terminal;
@@ -39,7 +40,11 @@ import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.local.AgentImpl;
 import org.fusesource.jansi.AnsiConsole;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -150,7 +155,57 @@ public class ConsoleFactory {
         });
         session.put(".jline.terminal", terminal);
         session.put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, agentId);
-        new Thread(console, "Karaf Shell Console Thread").start();
+
+        new DelayedStarted(unwrappedIn).start();
+    }
+
+    class DelayedStarted extends Thread implements FrameworkListener {
+        final AtomicBoolean started = new AtomicBoolean(false);
+        final InputStream in;
+        DelayedStarted(InputStream in) {
+            super("Karaf Shell Console Thread");
+            this.in = in;
+            int defaultStartLevel = Integer.parseInt(System.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
+            int startLevel = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
+            if (startLevel >= defaultStartLevel) {
+                started.set(true);
+            } else {
+                bundleContext.addFrameworkListener(this);
+                frameworkEvent(new FrameworkEvent(FrameworkEvent.STARTLEVEL_CHANGED, bundleContext.getBundle(), null));
+            }
+        }
+
+        public void run() {
+            try {
+                while (!started.get()) {
+                    if (in.available() == 0) {
+                        Thread.sleep(10);
+                    }
+                    while (in.available() > 0) {
+                        char ch = (char) in.read();
+                        if (ch == '\r' || ch == '\n') {
+                            started.set(true);
+                            break;
+                        }
+                    }
+                }
+            } catch (Throwable t) {
+                // Ignore
+            }
+            System.setProperty("karaf.console.started", "true");
+            System.out.println();
+            bundleContext.removeFrameworkListener(this);
+            console.run();
+        }
+        public void frameworkEvent(FrameworkEvent event) {
+            if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
+                int defaultStartLevel = Integer.parseInt(System.getProperty(Constants.FRAMEWORK_BEGINNING_STARTLEVEL));
+                int startLevel = bundleContext.getBundle(0).adapt(FrameworkStartLevel.class).getStartLevel();
+                if (startLevel >= defaultStartLevel) {
+                    started.set(true);
+                }
+            }
+        }
     }
 
     protected String startAgent(String user) {