/* * JobServServer * * v1.0 * * May 18, 2019 */ package JobServ; import io.grpc.Server; import io.grpc.ServerBuilder; import io.grpc.netty.GrpcSslContexts; import io.grpc.netty.NettyServerBuilder; import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslProvider; import javax.net.ssl.SSLException; import java.util.InputMismatchException; import java.io.File; import java.io.IOException; import java.util.logging.Logger; /* * The JobServServer class implements the JobServ protobuf API * It does this by extending the gRPC stub code. * Additionally, JobServServer starts and manages a daemon * Which accepts incoming connections from client. */ public class JobServServer { private static final Logger logger = Logger.getLogger(JobServServer.class.getName()); private Server server; /* * Constructor * builds server object */ public JobServServer(SslContext ssl, int port) throws IOException { this.server = NettyServerBuilder.forPort(port) .addService(new ShellServerService()) .sslContext(ssl) .build() .start(); } /* * start() * this initializes the server */ private void start() throws IOException { // TODO: this should be passed in from a configuration manager server.start(); logger.info("Server initialized!"); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { logger.info("Shutting down server"); JobServServer.this.stop(); } }); } /* * stop() * This is called when ctrl+c is pressed */ private void stop() { if (server != null) { server.shutdown(); } } /* * blockUntilShutdown() * This is more or less the main loop of the server. * It spins until shutdown is called. */ private void blockUntilShutdown() throws InterruptedException { if (server != null) { server.awaitTermination(); } } /* * main() * Entrypoint of hte server * parses args and initializes a server object. * calls server main loop. */ public static void main(String[] args) throws IOException, InterruptedException { // TODO: port and key/cert files should be handled by a config manager if(args.length < 4) { System.out.println("Usage: ./jobserv-server port cert privatekey truststore"); return; } JobServServer server; try { SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(new File(args[1]), new File(args[2])); // Mutual TLS trust store and require client auth sslContextBuilder.trustManager(new File(args[3])); sslContextBuilder.clientAuth(ClientAuth.REQUIRE); server = new JobServServer(GrpcSslContexts.configure(sslContextBuilder).build(), Integer.parseInt(args[0])); } catch (InputMismatchException e) { System.out.println("Invalid port!"); return; } catch (SSLException e) { System.out.println(e.getMessage()); return; } catch (IOException e) { System.out.println(e.getMessage()); return; } server.blockUntilShutdown(); } }