Skip to content

Commit da3cd35

Browse files
committed
added daemon mode
1 parent 04f256c commit da3cd35

File tree

2 files changed

+82
-46
lines changed

2 files changed

+82
-46
lines changed

pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>com.browserstack</groupId>
55
<artifactId>browserstack-local-java</artifactId>
66
<packaging>jar</packaging>
7-
<version>0.1.0</version>
7+
<version>0.2.0</version>
88

99
<name>browserstack-local-java</name>
1010
<description>Java bindings for BrowserStack Local</description>
@@ -51,6 +51,11 @@
5151
<artifactId>commons-io</artifactId>
5252
<version>1.3.2</version>
5353
</dependency>
54+
<dependency>
55+
<groupId>org.json</groupId>
56+
<artifactId>json</artifactId>
57+
<version>20160212</version>
58+
</dependency>
5459
</dependencies>
5560

5661
<profiles>
Lines changed: 76 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
package com.browserstack.local;
22

33
import java.io.BufferedReader;
4+
import java.io.InputStreamReader;
45
import java.io.FileReader;
56
import java.io.FileWriter;
67
import java.util.ArrayList;
78
import java.util.HashMap;
89
import java.util.Arrays;
910
import java.util.List;
1011
import java.util.Map;
12+
import org.json.*;
1113

1214
/**
1315
* Creates and manages a secure tunnel connection to BrowserStack.
1416
*/
1517
public class Local {
1618

1719
List<String> command;
20+
Map<String, String> startOptions;
21+
String binaryPath;
22+
String logFilePath;
23+
int pid = 0;
1824

1925
private Process proc = null;
2026

@@ -44,22 +50,16 @@ public Local() {
4450
* @throws Exception
4551
*/
4652
public void start(Map<String, String> options) throws Exception {
47-
command = new ArrayList<String>();
48-
53+
startOptions = options;
4954
if (options.get("binarypath") != null) {
50-
command.add(options.get("binarypath"));
55+
binaryPath = options.get("binarypath");
5156
} else {
5257
LocalBinary lb = new LocalBinary();
53-
command.add(lb.getBinaryPath());
58+
binaryPath = lb.getBinaryPath();
5459
}
5560

56-
String logFilePath = options.get("logfile") == null ?
57-
(System.getProperty("user.dir") + "/local.log") : options.get("logfile");
58-
command.add("-logFile");
59-
command.add(logFilePath);
60-
61-
command.add(options.get("key"));
62-
makeCommand(options);
61+
logFilePath = options.get("logfile") == null ? (System.getProperty("user.dir") + "/local.log") : options.get("logfile");
62+
makeCommand(options, "start");
6363

6464
if (options.get("onlyCommand") != null) return;
6565

@@ -71,26 +71,24 @@ public void start(Map<String, String> options) throws Exception {
7171
fw.close();
7272

7373
proc = processBuilder.start();
74-
FileReader f = new FileReader(logFilePath);
75-
BufferedReader reader = new BufferedReader(f);
76-
String string;
77-
78-
while (true) {
79-
string = reader.readLine();
80-
if (string == null) continue;
81-
82-
if (string.equalsIgnoreCase("Press Ctrl-C to exit")) {
83-
f.close();
84-
break;
85-
}
86-
87-
if (string.contains("*** Error")) {
88-
f.close();
89-
stop();
90-
throw new LocalException(string);
91-
}
74+
BufferedReader stdoutbr = new BufferedReader(new InputStreamReader(proc.getInputStream()));
75+
BufferedReader stderrbr = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
76+
String stdout="", stderr="", line;
77+
while ((line = stdoutbr.readLine()) != null) {
78+
stdout += line;
79+
}
80+
while ((line = stderrbr.readLine()) != null) {
81+
stderr += line;
9282
}
83+
int r = proc.waitFor();
9384

85+
JSONObject obj = new JSONObject(stdout != "" ? stdout : stderr);
86+
if(!obj.getString("state").equals("connected")){
87+
throw new LocalException(obj.getString("message"));
88+
}
89+
else {
90+
pid = obj.getInt("pid");
91+
}
9492
}
9593
}
9694

@@ -99,12 +97,13 @@ public void start(Map<String, String> options) throws Exception {
9997
*
10098
* @throws InterruptedException
10199
*/
102-
public void stop() throws InterruptedException {
103-
if (proc != null) {
104-
proc.destroy();
105-
while (isRunning()) {
106-
Thread.sleep(1000);
107-
}
100+
public void stop() throws Exception {
101+
if (pid != 0) {
102+
makeCommand(startOptions, "stop");
103+
ProcessBuilder processBuilder = new ProcessBuilder(command);
104+
proc = processBuilder.start();
105+
proc.waitFor();
106+
pid = 0;
108107
}
109108
}
110109

@@ -113,23 +112,25 @@ public void stop() throws InterruptedException {
113112
*
114113
* @return true if Local instance is running, else false
115114
*/
116-
public boolean isRunning() {
117-
if (proc == null) return false;
118-
119-
try {
120-
proc.exitValue();
121-
return false;
122-
} catch (IllegalThreadStateException e) {
123-
return true;
124-
}
115+
public boolean isRunning() throws Exception {
116+
if (pid == 0) return false;
117+
return isProcessRunning(pid);
125118
}
126119

127120
/**
128121
* Creates a list of command-line arguments for the Local instance
129122
*
130123
* @param options Options supplied for the Local instance
131124
*/
132-
private void makeCommand(Map<String, String> options) {
125+
private void makeCommand(Map<String, String> options, String opCode) {
126+
command = new ArrayList<String>();
127+
command.add(binaryPath);
128+
command.add("-d");
129+
command.add(opCode);
130+
command.add("-logFile");
131+
command.add(logFilePath);
132+
command.add(options.get("key"));
133+
133134
for (Map.Entry<String, String> opt : options.entrySet()) {
134135
List<String> ignoreKeys = Arrays.asList("key", "logfile", "binarypath");
135136
String parameter = opt.getKey().trim();
@@ -146,4 +147,34 @@ private void makeCommand(Map<String, String> options) {
146147
}
147148
}
148149
}
150+
151+
/**
152+
* Checks if process with pid is running
153+
*
154+
* @param options Options supplied for the Local instance
155+
* @link http://stackoverflow.com/a/26423642/941691
156+
*/
157+
private boolean isProcessRunning(int pid) throws Exception {
158+
ArrayList<String> cmd = new ArrayList<String>();
159+
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
160+
//tasklist exit code is always 0. Parse output
161+
//findstr exit code 0 if found pid, 1 if it doesn't
162+
cmd.add("cmd");
163+
cmd.add("/c");
164+
cmd.add("\"tasklist /FI \"PID eq " + pid + "\" | findstr " + pid + "\"");
165+
}
166+
else {
167+
//ps exit code 0 if process exists, 1 if it doesn't
168+
cmd.add("ps");
169+
cmd.add("-p");
170+
cmd.add(String.valueOf(pid));
171+
}
172+
173+
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
174+
proc = processBuilder.start();
175+
int exitValue = proc.waitFor();
176+
177+
// 0 is the default exit code which means the process exists
178+
return exitValue == 0;
179+
}
149180
}

0 commit comments

Comments
 (0)