FELIX-1850 and FELIX-1849: enhancements to AdminServiceMBean

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@880721 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/Instance.java b/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/Instance.java
index 4f267c7..259704d 100644
--- a/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/Instance.java
+++ b/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/Instance.java
@@ -24,6 +24,8 @@
     String ERROR = "Error";
 
     String getName();
+    
+    boolean isRoot();
 
     String getLocation();
 
diff --git a/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/AdminServiceImpl.java b/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/AdminServiceImpl.java
index b80ad5c..2cb29e2 100644
--- a/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/AdminServiceImpl.java
+++ b/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/AdminServiceImpl.java
@@ -99,8 +99,9 @@
                 String name = storage.getProperty("item." + i + ".name", null);
                 String loc = storage.getProperty("item." + i + ".loc", null);
                 int pid = Integer.parseInt(storage.getProperty("item." + i + ".pid", "0"));
+                boolean root = Boolean.parseBoolean(storage.getProperty("item." + i + ".root", "false"));
                 if (name != null) {
-                    InstanceImpl instance = new InstanceImpl(this, name, loc);
+                    InstanceImpl instance = new InstanceImpl(this, name, loc, root);
                     if (pid > 0) {
                         try {
                             instance.attach(pid);
diff --git a/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/InstanceImpl.java b/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/InstanceImpl.java
index 40a76a5..c3131c7 100644
--- a/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/InstanceImpl.java
+++ b/karaf/admin/core/src/main/java/org/apache/felix/karaf/admin/internal/InstanceImpl.java
@@ -41,11 +41,17 @@
     private String name;
     private String location;
     private Process process;
+    private boolean root;
 
     public InstanceImpl(AdminServiceImpl service, String name, String location) {
+        this(service, name, location, false);
+    }
+    
+    public InstanceImpl(AdminServiceImpl service, String name, String location, boolean root) {
         this.service = service;
         this.name = name;
         this.location = location;
+        this.root = root;
     }
 
     public void attach(int pid) throws IOException {
@@ -59,6 +65,10 @@
     public String getName() {
         return this.name;
     }
+    
+    public boolean isRoot() {
+        return root;
+    }
 
     public String getLocation() {
         return location;
diff --git a/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/AdminServiceMBean.java b/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/AdminServiceMBean.java
index 7d5427a..0decb21 100644
--- a/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/AdminServiceMBean.java
+++ b/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/AdminServiceMBean.java
@@ -22,11 +22,12 @@
 
     String INSTANCE_PID = "Pid";
     String INSTANCE_NAME = "Name";
+    String INSTANCE_IS_ROOT = "Is Root";
     String INSTANCE_PORT = "Port";
     String INSTANCE_STATE = "State";
     String INSTANCE_LOCATION = "Location";
 
-    String[] INSTANCE = {INSTANCE_PID, INSTANCE_NAME, INSTANCE_PORT,
+    String[] INSTANCE = {INSTANCE_PID, INSTANCE_NAME, INSTANCE_IS_ROOT, INSTANCE_PORT,
             INSTANCE_STATE, INSTANCE_LOCATION };
 
     // Operations
diff --git a/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/codec/JmxInstance.java b/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/codec/JmxInstance.java
index 5f398db..264c5c9 100644
--- a/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/codec/JmxInstance.java
+++ b/karaf/admin/management/src/main/java/org/apache/felix/karaf/admin/management/codec/JmxInstance.java
@@ -52,13 +52,14 @@
             Object[] itemValues = new Object[itemNames.length];
             itemValues[0] = instance.getPid();
             itemValues[1] = instance.getName();
-            itemValues[2] = instance.getPort();
+            itemValues[2] = instance.isRoot();
+            itemValues[3] = instance.getPort();
             try {
-                itemValues[3] = instance.getState();
+                itemValues[4] = instance.getState();
             } catch (Exception e) {
-                itemValues[3] = "Error";
+                itemValues[4] = "Error";
             }
-            itemValues[4] = instance.getLocation();
+            itemValues[5] = instance.getLocation();
 
             data = new CompositeDataSupport(INSTANCE, itemNames, itemValues);
         } catch (OpenDataException e) {
@@ -78,15 +79,18 @@
 
             itemTypes[1] = SimpleType.STRING;
             descriptions[1] = "The name of the instance.";
+            
+            itemTypes[2] = SimpleType.BOOLEAN;
+            descriptions[2] = "Whether the instance is root.";
 
-            itemTypes[2] = SimpleType.INTEGER;
-            descriptions[2] = "The SSH port that can be used to connect to the instance.";
-
-            itemTypes[3] = SimpleType.STRING;
-            descriptions[3] = "The state of the instance.";
+            itemTypes[3] = SimpleType.INTEGER;
+            descriptions[3] = "The SSH port that can be used to connect to the instance.";
 
             itemTypes[4] = SimpleType.STRING;
-            descriptions[4] = "The location of the instance.";
+            descriptions[4] = "The state of the instance.";
+
+            itemTypes[5] = SimpleType.STRING;
+            descriptions[5] = "The location of the instance.";
 
             return new CompositeType("Instance", desc, itemNames, descriptions, itemTypes);
         } catch (OpenDataException e) {
diff --git a/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/codec/JmxInstanceTest.java b/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/codec/JmxInstanceTest.java
index bc06679..f2f174b 100644
--- a/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/codec/JmxInstanceTest.java
+++ b/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/codec/JmxInstanceTest.java
@@ -47,6 +47,7 @@
         Instance i = EasyMock.createMock(Instance.class);
         EasyMock.expect(i.getPid()).andReturn(1712);
         EasyMock.expect(i.getName()).andReturn("MyInstance");
+        EasyMock.expect(i.isRoot()).andReturn(false);
         EasyMock.expect(i.getPort()).andReturn(0);
         EasyMock.expect(i.getState()).andThrow(new Exception("gotcha"));
         EasyMock.expect(i.getLocation()).andReturn("somewhere");
@@ -60,6 +61,7 @@
         CompositeData cd = td.get(keys.toArray());
         Assert.assertEquals(1712, cd.get("Pid"));
         Assert.assertEquals("MyInstance", cd.get("Name"));
+        Assert.assertEquals(false, cd.get("Is Root"));
         Assert.assertEquals(0, cd.get("Port"));
         Assert.assertEquals("Error", cd.get("State"));
         Assert.assertEquals("somewhere", cd.get("Location"));
@@ -69,6 +71,7 @@
         Instance i = EasyMock.createMock(Instance.class);
         EasyMock.expect(i.getPid()).andReturn(1712);
         EasyMock.expect(i.getName()).andReturn("MyInstance");
+        EasyMock.expect(i.isRoot()).andReturn(true);
         EasyMock.expect(i.getPort()).andReturn(0);
         EasyMock.expect(i.getState()).andReturn("Started");
         EasyMock.expect(i.getLocation()).andReturn(null);
@@ -82,6 +85,7 @@
         CompositeData cd = td.get(keys.toArray());
         Assert.assertEquals(1712, cd.get("Pid"));
         Assert.assertEquals("MyInstance", cd.get("Name"));
+        Assert.assertEquals(true, cd.get("Is Root"));
         Assert.assertEquals(0, cd.get("Port"));
         Assert.assertEquals("Started", cd.get("State"));
         Assert.assertNull(cd.get("Location"));
diff --git a/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/internal/AdminServiceMBeanImplTest.java b/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/internal/AdminServiceMBeanImplTest.java
index 5a2cfca..11cb0c2 100644
--- a/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/internal/AdminServiceMBeanImplTest.java
+++ b/karaf/admin/management/src/test/java/org/apache/felix/karaf/admin/management/internal/AdminServiceMBeanImplTest.java
@@ -69,6 +69,7 @@
         EasyMock.expect(i1.getPid()).andReturn(1234);
         EasyMock.expect(i1.getPort()).andReturn(8818);
         EasyMock.expect(i1.getName()).andReturn("i1");
+        EasyMock.expect(i1.isRoot()).andReturn(true);
         EasyMock.expect(i1.getLocation()).andReturn("somewhere");
         EasyMock.expect(i1.getState()).andReturn("Stopped");
         EasyMock.replay(i1);
@@ -87,6 +88,7 @@
         Assert.assertEquals(2, td.size());
         CompositeData cd1 = td.get(new Object [] {"i1"});
         Assert.assertTrue(cd1.containsValue("i1"));
+        Assert.assertTrue(cd1.containsValue(true));
         Assert.assertTrue(cd1.containsValue(1234));
         Assert.assertTrue(cd1.containsValue(8818));
         Assert.assertTrue(cd1.containsValue("somewhere"));
diff --git a/karaf/main/src/main/java/org/apache/felix/karaf/main/Main.java b/karaf/main/src/main/java/org/apache/felix/karaf/main/Main.java
index fa12d90..15b51b1 100644
--- a/karaf/main/src/main/java/org/apache/felix/karaf/main/Main.java
+++ b/karaf/main/src/main/java/org/apache/felix/karaf/main/Main.java
@@ -340,21 +340,24 @@
 
     private void updateInstancePid() {
         try {
-            if (!karafHome.equals(karafBase)) {
-                String instanceName = System.getProperty("karaf.name");
-                String pid = ManagementFactory.getRuntimeMXBean().getName();
-                if (pid.indexOf('@') > 0) {
-                    pid = pid.substring(0, pid.indexOf('@'));
+            String instanceName = System.getProperty("karaf.name");
+            String pid = ManagementFactory.getRuntimeMXBean().getName();
+            if (pid.indexOf('@') > 0) {
+                pid = pid.substring(0, pid.indexOf('@'));
+            }
+            
+            boolean isRoot = karafHome.equals(karafBase);
+            
+            if (instanceName != null) {
+                String storage = System.getProperty("storage.location");
+                if (storage == null) {
+                    throw new Exception("System property 'storage.location' is not set. \n" +
+                        "This property needs to be set to the full path of the instance.properties file.");
                 }
-                if (instanceName != null) {
-                    String storage = System.getProperty("storage.location");
-                    if (storage == null) {
-                        throw new Exception("System property 'storage.location' is not set. \n" +
-                            "This property needs to be set to the full path of the instance.properties file.");
-                    }
-                    File storageFile = new File(storage);
-                    File propertiesFile = new File(storageFile, "instance.properties");
-                    Properties props = new Properties();
+                File storageFile = new File(storage);
+                File propertiesFile = new File(storageFile, "instance.properties");
+                Properties props = new Properties();
+                if (propertiesFile.exists()) {
                     props.load(new FileInputStream(propertiesFile));
                     int count = Integer.parseInt(props.getProperty("count"));
                     for (int i = 0; i < count; i++) {
@@ -365,7 +368,19 @@
                             return;
                         }
                     }
-                    throw new Exception("Instance " + instanceName + " not found");
+                    if (!isRoot) {
+                        throw new Exception("Instance " + instanceName + " not found");
+                    } 
+                } else if (isRoot) {
+                    if (!propertiesFile.getParentFile().exists()) {
+                        propertiesFile.getParentFile().mkdirs();
+                    }
+                    props.setProperty("count", "1");
+                    props.setProperty("item.0.name", instanceName);
+                    props.setProperty("item.0.loc", karafHome.getAbsolutePath());
+                    props.setProperty("item.0.pid", pid);
+                    props.setProperty("item.0.root", "true");
+                    props.store(new FileOutputStream(propertiesFile), null);
                 }
             }
         } catch (Exception e) {