FELIX-1517 and FELIX-1528: use a defined location for the storage of the list of managed instances and avoid an exception if one instance has been deleted
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@808019 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/AdminServiceMBean.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/AdminServiceMBean.java
index 8e3f8ae..8e18445 100644
--- a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/AdminServiceMBean.java
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/AdminServiceMBean.java
@@ -22,7 +22,7 @@
String[] getInstances();
- int getPort(String name) throws Exception;
+ int getPort(String name);
void changePort(String name, int port) throws Exception;
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/Instance.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/Instance.java
index e60485d..01bd510 100644
--- a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/Instance.java
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/Instance.java
@@ -21,6 +21,7 @@
String STOPPED = "Stopped";
String STARTING = "Starting";
String STARTED = "Started";
+ String ERROR = "Error";
String getName();
@@ -28,7 +29,7 @@
int getPid();
- int getPort() throws Exception;
+ int getPort();
void changePort(int port) throws Exception;
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceImpl.java
index 1b1190b..b072805 100644
--- a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceImpl.java
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceImpl.java
@@ -22,16 +22,15 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.io.FileInputStream;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
+import java.util.Properties;
import org.apache.felix.karaf.gshell.admin.AdminService;
import org.apache.felix.karaf.gshell.admin.Instance;
-import org.osgi.service.prefs.BackingStoreException;
-import org.osgi.service.prefs.Preferences;
-import org.osgi.service.prefs.PreferencesService;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.fusesource.jansi.Ansi;
@@ -40,30 +39,56 @@
private static final Logger LOGGER = LoggerFactory.getLogger(AdminServiceImpl.class);
- private PreferencesService preferences;
-
private Map<String, Instance> instances = new HashMap<String, Instance>();
private int defaultPortStart = 8101;
- public PreferencesService getPreferences() {
- return preferences;
+ private File storageLocation;
+
+ public File getStorageLocation() {
+ return storageLocation;
}
- public void setPreferences(PreferencesService preferences) {
- this.preferences = preferences;
+ public void setStorageLocation(File storage) {
+ this.storageLocation = storage;
+ }
+
+ private Properties loadStorage(File location) throws IOException {
+ InputStream is = null;
+ try {
+ is = new FileInputStream(location);
+ Properties props = new Properties();
+ props.load(is);
+ return props;
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ private void saveStorage(Properties props, File location) throws IOException {
+ OutputStream os = null;
+ try {
+ os = new FileOutputStream(location);
+ props.store(os, "Admin Service storage");
+ } finally {
+ if (os != null) {
+ os.close();
+ }
+ }
}
public synchronized void init() throws Exception {
try {
- Preferences prefs = preferences.getUserPreferences("AdminServiceState");
- Preferences child = prefs.node("Instances");
- int count = child.getInt("count", 0);
+ Properties storage = loadStorage(storageLocation);
+ int count = Integer.parseInt(storage.getProperty("count", "0"));
+ defaultPortStart = Integer.parseInt(storage.getProperty("port", Integer.toString(defaultPortStart)));
Map<String, Instance> newInstances = new HashMap<String, Instance>();
for (int i = 0; i < count; i++) {
- String name = child.get("item." + i + ".name", null);
- String loc = child.get("item." + i + ".loc", null);
- int pid = child.getInt("item." + i + ".pid", 0);
+ 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"));
if (name != null) {
InstanceImpl instance = new InstanceImpl(this, name, loc);
if (pid > 0) {
@@ -89,23 +114,7 @@
File serviceMixBase = new File(location != null ? location : ("instances/" + name)).getCanonicalFile();
int sshPort = port;
if (sshPort <= 0) {
- try {
- Preferences prefs = preferences.getUserPreferences("AdminServiceState");
- sshPort = prefs.getInt("port", defaultPortStart + 1);
- prefs.putInt("port", sshPort + 1);
- prefs.flush();
- prefs.sync();
- } catch (Exception e) {
- try {
- ServerSocket ss = new ServerSocket(0);
- sshPort = ss.getLocalPort();
- ss.close();
- } catch (Exception t) {
- }
- }
- if (sshPort <= 0) {
- sshPort = defaultPortStart;
- }
+ sshPort = ++defaultPortStart;
}
println("Creating new instance on port " + sshPort + " at: @|bold " + serviceMixBase + "|");
@@ -156,19 +165,17 @@
instances.remove(name);
}
- synchronized void saveState() throws IOException, BackingStoreException {
- Preferences prefs = preferences.getUserPreferences("AdminServiceState");
- Preferences child = prefs.node("Instances");
- child.clear();
+ synchronized void saveState() throws IOException {
+ Properties storage = new Properties();
Instance[] data = getInstances();
- child.putInt("count", data.length);
+ storage.setProperty("port", Integer.toString(defaultPortStart));
+ storage.setProperty("count", Integer.toString(data.length));
for (int i = 0; i < data.length; i++) {
- child.put("item." + i + ".name", data[i].getName());
- child.put("item." + i + ".loc", data[i].getLocation());
- child.putInt("item." + i + ".pid", data[i].getPid());
+ storage.setProperty("item." + i + ".name", data[i].getName());
+ storage.setProperty("item." + i + ".loc", data[i].getLocation());
+ storage.setProperty("item." + i + ".pid", Integer.toString(data[i].getPid()));
}
- prefs.flush();
- prefs.sync();
+ saveStorage(storage, storageLocation);
}
private void copyResourceToDir(File target, String resource, boolean text) throws Exception {
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceMBeanImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceMBeanImpl.java
index afa3d83..b83cb83 100644
--- a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceMBeanImpl.java
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/AdminServiceMBeanImpl.java
@@ -45,7 +45,7 @@
return names;
}
- public int getPort(String name) throws Exception {
+ public int getPort(String name) {
return getExistingInstance(name).getPort();
}
diff --git a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/InstanceImpl.java b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/InstanceImpl.java
index e851e1e..0d22a08 100644
--- a/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/InstanceImpl.java
+++ b/karaf/gshell/gshell-admin/src/main/java/org/apache/felix/karaf/gshell/admin/internal/InstanceImpl.java
@@ -64,12 +64,16 @@
return location;
}
+ public boolean exists() {
+ return new File(location).isDirectory();
+ }
+
public int getPid() {
checkProcess();
return this.process != null ? this.process.getPid() : 0;
}
- public int getPort() throws Exception {
+ public int getPort() {
InputStream is = null;
try {
File f = new File(location, "etc/org.apache.felix.karaf.shell.cfg");
@@ -78,9 +82,15 @@
props.load(is);
String loc = props.getProperty("sshPort");
return Integer.parseInt(loc);
+ } catch (Exception e) {
+ return 0;
} finally {
if (is != null) {
- is.close();
+ try {
+ is.close();
+ } catch (IOException e) {
+ // Ignore
+ }
}
}
}
@@ -165,12 +175,15 @@
public synchronized String getState() {
+ int port = getPort();
+ if (!exists() || port <= 0) {
+ return ERROR;
+ }
checkProcess();
if (this.process == null) {
return STOPPED;
} else {
try {
- int port = getPort();
Socket s = new Socket("localhost", port);
s.close();
return STARTED;
diff --git a/karaf/gshell/gshell-admin/src/main/resources/OSGI-INF/blueprint/gshell-admin.xml b/karaf/gshell/gshell-admin/src/main/resources/OSGI-INF/blueprint/gshell-admin.xml
index d92260a..361fa9f 100644
--- a/karaf/gshell/gshell-admin/src/main/resources/OSGI-INF/blueprint/gshell-admin.xml
+++ b/karaf/gshell/gshell-admin/src/main/resources/OSGI-INF/blueprint/gshell-admin.xml
@@ -18,6 +18,7 @@
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:ext="http://geronimo.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
default-activation="lazy">
<command-bundle xmlns="http://felix.apache.org/karaf/xmlns/gshell/v1.0.0">
@@ -78,10 +79,8 @@
</command>
</command-bundle>
- <reference id="preferences" interface="org.osgi.service.prefs.PreferencesService" availability="optional"/>
-
<bean id="adminService" class="org.apache.felix.karaf.gshell.admin.internal.AdminServiceImpl" init-method="init">
- <property name="preferences" ref="preferences" />
+ <property name="storageLocation" value="${karaf.home}/etc/instances.properties" />
</bean>
<bean id="instanceCompleter" class="org.apache.felix.karaf.gshell.admin.internal.completers.InstanceCompleter">
@@ -90,4 +89,7 @@
<service ref="adminService" interface="org.apache.felix.karaf.gshell.admin.AdminService" />
+ <!-- Allow the use of system properties -->
+ <ext:property-placeholder />
+
</blueprint>