001/* 002 * Stallion Core: A Modern Web Framework 003 * 004 * Copyright (C) 2015 - 2016 Stallion Software LLC. 005 * 006 * This program is free software: you can redistribute it and/or modify it under the terms of the 007 * GNU General Public License as published by the Free Software Foundation, either version 2 of 008 * the License, or (at your option) any later version. This program is distributed in the hope that 009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 011 * License for more details. You should have received a copy of the GNU General Public License 012 * along with this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>. 013 * 014 * 015 * 016 */ 017 018package io.stallion.boot; 019 020import io.stallion.Context; 021import io.stallion.asyncTasks.AsyncCoordinator; 022import io.stallion.plugins.PluginRegistry; 023import io.stallion.restfulEndpoints.EndpointsRegistry; 024import io.stallion.requests.RequestHandler; 025import io.stallion.restfulEndpoints.RestEndpointBase; 026import io.stallion.restfulEndpoints.SlugRegistry; 027import io.stallion.services.Log; 028import io.stallion.settings.Settings; 029 030import org.eclipse.jetty.server.Server; 031import sun.misc.Signal; 032import sun.misc.SignalHandler; 033 034import javax.servlet.MultipartConfigElement; 035import java.text.MessageFormat; 036import java.util.Map; 037 038 039public class StallionServer implements StallionRunAction<ServeCommandOptions> { 040 041 @Override 042 public String getActionName() { 043 return "serve"; 044 } 045 046 @Override 047 public String getHelp() { 048 return "run the Stallion HTTP server"; 049 } 050 051 @Override 052 public void loadApp(ServeCommandOptions options) { 053 AppContextLoader.loadCompletely(options); 054 AppContextLoader.instance().startAllServices(); 055 } 056 057 @Override 058 public ServeCommandOptions newCommandOptions() { 059 return new ServeCommandOptions(); 060 } 061 062 @Override 063 public void execute(ServeCommandOptions options) throws Exception { 064 065 066 067 068 // Start the server 069 Server server = new Server(Settings.instance().getPort()); 070 server.setHandler(RequestHandler.instance()); 071 072 073 server.start(); 074 075 System.out.print("-------------------------------------------------------\n"); 076 System.out.print(MessageFormat.format( 077 "Final registration count: {1} controllers. {2} plugins. {3} endpoints. {4} slugs. V=3\n", 078 Settings.instance().getPort(), 079 Context.dal().size(), 080 PluginRegistry.instance().getJavaPluginByName().size(), 081 EndpointsRegistry.instance().getEndpoints().size(), 082 SlugRegistry.instance().getSlugMap().size() 083 )); 084 085 086 // If we are in debug mode, file system changes will send a signal, which 087 // will then be caught, triggering a reload. 088 if (MainRunner.isIsDebugRunner()) { 089 sun.misc.Signal.handle(new Signal("INT"), new InterruptHandler(server)); 090 sun.misc.Signal.handle(new Signal("USR2"), new ReloadHandler(server)); 091 MainRunner.setupWatchers(Settings.instance().getTargetFolder()); 092 } 093 094 095 System.out.print("-------------------------------------------------------\n"); 096 String art = "" + 097 " _,_\n" + 098 " ;'._\\\n" + 099 " ';) \\._, Stallion server now running on port " + Settings.instance().getPort() + ".\n" + 100 " / /`-'\n" + 101 " ~~( )/\n" + 102 " )))\n" + 103 " \\\\\\"; 104 System.out.print(art); 105 System.out.print("\n-------------------------------------------------------\n"); 106 107 108 server.join(); 109 110 System.out.println("Shutting down async coordinator"); 111 AsyncCoordinator.gracefulShutdown(); 112 113 } 114 115 public class ReloadHandler implements SignalHandler { 116 private Server server; 117 118 public ReloadHandler(Server server) { 119 this.server = server; 120 } 121 122 @Override 123 public void handle(sun.misc.Signal signal) { 124 if (server.isStopped()) { 125 return; 126 } 127 try { 128 MainRunner.setDoReload(true); 129 AsyncCoordinator.gracefulShutdown(); 130 server.stop(); 131 } catch (Exception e) { 132 throw new RuntimeException(e); 133 } 134 } 135 136 } 137 138 139 public class InterruptHandler implements SignalHandler { 140 private Server server; 141 142 public InterruptHandler(Server server) { 143 this.server = server; 144 } 145 146 @Override 147 public void handle(sun.misc.Signal signal) { 148 System.out.println("Interrupted!"); 149 if (server.isStopped()) { 150 System.exit(0); 151 } 152 try { 153 AsyncCoordinator.gracefulShutdown(); 154 server.stop(); 155 } catch (Exception e) { 156 throw new RuntimeException(e); 157 } 158 } 159 } 160}