blob: 3815ca544bd3a8b8532f66c9b81a9b75523c7b86 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.servicemix.kernel.gshell.admin.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.jpm.Process;
import org.apache.servicemix.jpm.ProcessBuilderFactory;
import org.apache.servicemix.jpm.impl.ScriptUtils;
import org.apache.servicemix.kernel.gshell.admin.Instance;
public class InstanceImpl implements Instance {
private static final Log LOG = LogFactory.getLog(InstanceImpl.class);
private AdminServiceImpl service;
private String name;
private String location;
private Process process;
public InstanceImpl(AdminServiceImpl service, String name, String location) {
this.service = service;
this.name = name;
this.location = location;
}
public void attach(int pid) throws IOException {
checkProcess();
if (this.process != null) {
throw new IllegalStateException("Instance already started");
}
this.process = ProcessBuilderFactory.newInstance().newBuilder().attach(pid);
}
public String getName() {
return this.name;
}
public String getLocation() {
return location;
}
public int getPid() {
checkProcess();
return this.process != null ? this.process.getPid() : 0;
}
public int getPort() throws Exception {
InputStream is = null;
try {
File f = new File(location, "etc/org.apache.servicemix.shell.cfg");
is = new FileInputStream(f);
Properties props = new Properties();
props.load(is);
String loc = props.getProperty("sshPort");
return Integer.parseInt(loc);
} finally {
if (is != null) {
is.close();
}
}
}
public void changePort(int port) throws Exception {
checkProcess();
if (this.process != null) {
throw new IllegalStateException("Instance not stopped");
}
Properties props = new Properties();
File f = new File(location, "etc/org.apache.servicemix.shell.cfg");
InputStream is = new FileInputStream(f);
try {
props.load(is);
} finally {
is.close();
}
props.setProperty("sshPort", Integer.toString(port));
OutputStream os = new FileOutputStream(f);
try {
props.store(os, null);
} finally {
os.close();
}
}
public synchronized void start(String javaOpts) throws Exception {
checkProcess();
if (this.process != null) {
throw new IllegalStateException("Instance already started");
}
if (javaOpts == null) {
javaOpts = "-server -Xmx512M -Dcom.sun.management.jmxremote";
}
File libDir = new File(System.getProperty("servicemix.home"), "lib");
File[] jars = libDir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
StringBuilder classpath = new StringBuilder();
for (File jar : jars) {
if (classpath.length() > 0) {
classpath.append(System.getProperty("path.separator"));
}
classpath.append(jar.getCanonicalPath());
}
String command = new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath()
+ " " + javaOpts
+ " -Dservicemix.home=\"" + System.getProperty("servicemix.home") + "\""
+ " -Dservicemix.base=\"" + new File(location).getCanonicalPath() + "\""
+ " -Dservicemix.startLocalConsole=false"
+ " -Dservicemix.startRemoteShell=true"
+ " -classpath " + classpath.toString()
+ " org.apache.servicemix.kernel.main.Main";
LOG.debug("Starting instance with command: " + command);
this.process = ProcessBuilderFactory.newInstance().newBuilder()
.directory(new File(location))
.command(command)
.start();
this.service.saveState();
}
public synchronized void stop() throws Exception {
checkProcess();
if (this.process == null) {
throw new IllegalStateException("Instance not started");
}
this.process.destroy();
}
public synchronized void destroy() throws Exception {
checkProcess();
if (this.process != null) {
throw new IllegalStateException("Instance not stopped");
}
deleteFile(new File(location));
this.service.forget(name);
this.service.saveState();
}
public synchronized String getState() {
checkProcess();
if (this.process == null) {
return STOPPED;
} else {
try {
int port = getPort();
Socket s = new Socket("localhost", port);
s.close();
return STARTED;
} catch (Exception e) {
// ignore
}
return STARTING;
}
}
protected void checkProcess() {
if (this.process != null) {
try {
if (!this.process.isRunning()) {
this.process = null;
}
} catch (IOException e) {
}
}
}
protected static boolean deleteFile(File fileToDelete) {
if (fileToDelete == null || !fileToDelete.exists()) {
return true;
}
boolean result = true;
if (fileToDelete.isDirectory()) {
File[] files = fileToDelete.listFiles();
if (files == null) {
result = false;
} else {
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (file.getName().equals(".") || file.getName().equals("..")) {
continue;
}
if (file.isDirectory()) {
result &= deleteFile(file);
} else {
result &= file.delete();
}
}
}
}
result &= fileToDelete.delete();
return result;
}
}