Proces Controller Object

This commit is contained in:
Aidan Hahn 2019-05-22 16:23:33 -07:00
parent 37cd129b8b
commit 622da2d238
No known key found for this signature in database
GPG key ID: 327711E983899316
2 changed files with 131 additions and 31 deletions

View file

@ -51,7 +51,7 @@ public class JobServClient {
* Spawns a new blockingStub for network operations with the server * Spawns a new blockingStub for network operations with the server
*/ */
public JobServClient(ManagedChannel channel) { public JobServClient(ManagedChannel channel) {
this.channel = channel; this.channel = channel;
blockingStub = ShellServerGrpc.newBlockingStub(this.channel); blockingStub = ShellServerGrpc.newBlockingStub(this.channel);
} }
@ -146,8 +146,8 @@ public class JobServClient {
/* /*
* sends PID to server * sends PID to server
* returns process exit code * returns process exit code
* returns a 0-255 return code or 277 if still running * returns a 0-255 return code or 256 if still running
* or 278 if error in API * or 257 if error in API
*/ */
public int getProcessReturn(int pid) { public int getProcessReturn(int pid) {
logger.info("[+] Requesting return code of a job"); logger.info("[+] Requesting return code of a job");
@ -162,7 +162,7 @@ public class JobServClient {
response = blockingStub.getReturn(request); response = blockingStub.getReturn(request);
} catch (StatusRuntimeException e) { } catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "(API Failure) Failed to get return code: " + e.getStatus()); logger.log(Level.WARNING, "(API Failure) Failed to get return code: " + e.getStatus());
return 278; return 257;
} }
return response.getProcessReturnCode(); return response.getProcessReturnCode();
@ -211,14 +211,13 @@ public class JobServClient {
JobServClient client; JobServClient client;
try { try {
SslContextBuilder builder = GrpcSslContexts.forClient(); SslContextBuilder builder = GrpcSslContexts.forClient();
builder.trustManager(new File(args[2])); builder.trustManager(new File(args[2]));
builder.keyManager(new File(args[1]), new File(args[0])); builder.keyManager(new File(args[1]), new File(args[0]));
ManagedChannel channel = NettyChannelBuilder.forAddress(args[3], Integer.parseInt(args[4])) ManagedChannel channel = NettyChannelBuilder.forAddress(args[3], Integer.parseInt(args[4]))
.sslContext(builder.build()) .sslContext(builder.build())
.build(); .build();
client = new JobServClient(channel); client = new JobServClient(channel);
// Likely bad port // Likely bad port
@ -226,7 +225,7 @@ public class JobServClient {
System.out.println("Invalid Port"); System.out.println("Invalid Port");
return; return;
// bad cert or key format // bad cert or key format
} catch (SSLException e) { } catch (SSLException e) {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
return; return;
@ -253,19 +252,19 @@ public class JobServClient {
case "output": case "output":
candidatePid = getPidArg(args, 6); candidatePid = getPidArg(args, 6);
if (candidatePid < 0) { if (candidatePid < 0) {
break; break;
} }
String processOutput = client.getProcessOutput(candidatePid); String processOutput = client.getProcessOutput(candidatePid);
System.out.println(processOutput); System.out.println(processOutput);
break; break;
case "status": case "status":
candidatePid = getPidArg(args, 6); candidatePid = getPidArg(args, 6);
if (candidatePid < 0) { if (candidatePid < 0) {
break; break;
} }
Boolean processStatus = client.getProcessStatus(candidatePid); Boolean processStatus = client.getProcessStatus(candidatePid);
System.out.printf("Process is currently running? %b\n", processStatus); System.out.printf("Process is currently running? %b\n", processStatus);
@ -273,9 +272,9 @@ public class JobServClient {
case "kill": case "kill":
candidatePid = getPidArg(args, 6); candidatePid = getPidArg(args, 6);
if (candidatePid < 0) { if (candidatePid < 0) {
break; break;
} }
client.killProcess(candidatePid); client.killProcess(candidatePid);
System.out.println("End process request recieved!"); System.out.println("End process request recieved!");
@ -283,9 +282,9 @@ public class JobServClient {
case "return": case "return":
candidatePid = getPidArg(args, 6); candidatePid = getPidArg(args, 6);
if (candidatePid < 0) { if (candidatePid < 0) {
break; break;
} }
int returnCode = client.getProcessReturn(candidatePid); int returnCode = client.getProcessReturn(candidatePid);
@ -314,15 +313,15 @@ public class JobServClient {
* returns -1 (an invalid PID) if bad index or unparsable int * returns -1 (an invalid PID) if bad index or unparsable int
*/ */
private static int getPidArg(String[] args, int index) { private static int getPidArg(String[] args, int index) {
if (args.length < index) { if (args.length < index) {
System.out.println("Improper formatting, try client --help"); System.out.println("Improper formatting, try client --help");
return -1; return -1;
} }
try { try {
return Integer.parseInt(args[6]); return Integer.parseInt(args[6]);
} catch (InputMismatchException e) { } catch (InputMismatchException e) {
System.out.println(args[6] + " is not a valid int, much less a valid pid"); System.out.println(args[6] + " is not a valid int, much less a valid pid");
return -1; return -1;
} }

View file

@ -0,0 +1,101 @@
/*
* ProcessController
*
* v1.0
*
* May 22, 2019
*/
package JobServ;
/*
* ProcessController
* This class wraps a java Process object with metadata
* such as translated PID that exist for this specific API
* as well as general metadata like IO streams.
*/
class ProcessController {
// incremented in constructor
private static int nextPid = 0;
private int pid;
// TODO: add an api endpoint for streaming client input into
// interactive processes (out of scope for initial API)
private OutputStream output;
private InputStream input;
private Scanner outputScanner;
private Process process;
/*
* Constructor
* Takes a command and spawns it in a new process
* Redirects IO streams and assigns a fake PID
*/
public ProcessController(String command) throws IOException {
this.pid = ProcessController.nextPid;
ProcessController.nextPid += 1;
this.process = Runtime.exec(command);
this.output = this.process.getOutputStream();
this.input = this.process.getInputStream();
this.outputScanner = new Scanner(this.input);
this.outputScanner.useDelimieter("\\A");
}
/*
* getStatus()
* returns whether or not the process is running
* this isnt a very direct way of getting the information
* The alternative is to use reflection to get into the private UNIXProcess class
* for the PID and to check that against 'ps' or a similar command
*
* TODO: (for future release) return thread state
*/
public Boolean getStatus() {
try {
process.exitValue();
return true;
} catch (IllegalThreadStateException e) {
return false;
}
}
/*
* getReturn()
* returns the exit code of the process
* or 256 if process is still running
* (unix/posix defines an exit code as a uint8, so 256 is fair game)
*/
public int getReturn() {
try {
return process.exitValue();
} catch (IllegalThreadStateException e) {
return 256;
}
}
/*
* getOutput()
* gets new output from stream
* (TODO: investigate whether this would better be done by )
*/
public String getOutput() {
String out = "";
while(scanner.hasNext()) {
out += scanner.next();
}
return out;
}
/*
* kill()
* Cleans up resources and destroys process
*/
public void kill() {
this.input.close();
this.output.close();
process.destroy();
}
}