001/* 002 * $Id: McIDASVMonitor.java,v 1.8 2011/03/24 16:06:31 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2011 007 * Space Science and Engineering Center (SSEC) 008 * University of Wisconsin - Madison 009 * 1225 W. Dayton Street, Madison, WI 53706, USA 010 * https://www.ssec.wisc.edu/mcidas 011 * 012 * All Rights Reserved 013 * 014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 015 * some McIDAS-V source code is based on IDV and VisAD source code. 016 * 017 * McIDAS-V is free software; you can redistribute it and/or modify 018 * it under the terms of the GNU Lesser Public License as published by 019 * the Free Software Foundation; either version 3 of the License, or 020 * (at your option) any later version. 021 * 022 * McIDAS-V is distributed in the hope that it will be useful, 023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 025 * GNU Lesser Public License for more details. 026 * 027 * You should have received a copy of the GNU Lesser Public License 028 * along with this program. If not, see http://www.gnu.org/licenses. 029 */ 030package edu.wisc.ssec.mcidasv; 031 032import ucar.unidata.idv.IntegratedDataViewer; 033import ucar.unidata.util.HttpServer; 034import ucar.unidata.util.LogUtil; 035 036import java.util.Hashtable; 037 038 039import java.net.InetAddress; 040import java.net.Socket; 041 042 043 044/** 045 * This provides http based access to a stack trace and enables the user to shut down McIDAS-V. 046 * This only is responsive to incoming requests from localhost 047 * the urls this provides are: 048 * http://localhost:<port>/stack.html 049 * http://localhost:<port>/info.html 050 * http://localhost:<port>/shutdown.html 051 * 052 * @author IDV development team 053 */ 054public class McIDASVMonitor extends HttpServer { 055 056 private IntegratedDataViewer idv; 057 058 /** The localhost */ 059 private InetAddress localHost; 060 061 public McIDASVMonitor(IntegratedDataViewer idv, int port) { 062 super(port); 063 this.idv = idv; 064 } 065 066 /** 067 * Make the handler for this request. Check if the client is coming from localhost 068 * if not then return null. 069 * 070 * @param socket incoming socket 071 * @return handler or null 072 */ 073 protected RequestHandler doMakeRequestHandler(Socket socket) 074 throws Exception { 075 if (localHost == null) { 076 localHost = InetAddress.getLocalHost(); 077 } 078 InetAddress inet = socket.getInetAddress(); 079 if (! (inet.getHostAddress().equals("127.0.0.1") || inet.getHostName().equals("localhost"))) { 080 return null; 081 } 082 return new MonitorRequestHandler(idv, this, socket); 083 } 084 085 /** 086 * Class OneInstanceRequestHandler the handler 087 * 088 * 089 * @author IDV Development Team 090 * @version $Revision: 1.8 $ 091 */ 092 public class MonitorRequestHandler extends HttpServer.RequestHandler { 093 094 /** The idv */ 095 IntegratedDataViewer idv; 096 097 /** The socket */ 098 Socket mysocket; 099 100 /** 101 * ctor 102 * 103 * @param idv the idv 104 * @param server the server 105 * @param socket the socket we handle the connection of 106 * 107 * @throws Exception On badness 108 */ 109 public MonitorRequestHandler(IntegratedDataViewer idv, 110 HttpServer server, Socket socket) 111 throws Exception { 112 super(server, socket); 113 this.idv = idv; 114 this.mysocket = socket; 115 } 116 117 /** 118 * Try to trap the case where the socket doesn't contain any bytes 119 * This can happen when mcservl connects to ping 120 * Prevents an infinite loop in HttpServer 121 */ 122 public void run() { 123 try { 124 int availableBytes = mysocket.getInputStream().available(); 125 if (availableBytes != 0) { 126 super.run(); 127 } 128 mysocket.close(); 129 } catch (Exception e) { 130 System.err.println("HTTP server error"); 131 } 132 } 133 134 private void decorateHtml(StringBuffer sb) throws Exception { 135 String header = "<h1>McIDAS-V HTTP monitor</h1><hr>" + 136 "<a href=stack.html>Stack Trace</a> | " + 137 "<a href=info.html>System Information</a> | " + 138 "<a href=shutdown.html>Shut Down</a><hr>"; 139 writeResult(true, header+sb.toString(),"text/html"); 140 } 141 142 /** 143 * 144 * @param path url path. ignored. 145 * @param formArgs form args 146 * @param httpArgs http args 147 * @param content content. unused. 148 * 149 * @throws Exception On badness 150 */ 151 protected void handleRequest(String path, Hashtable formArgs, 152 Hashtable httpArgs, String content) 153 throws Exception { 154 if (path.equals("/stack.html")) { 155 StringBuffer stack = LogUtil.getStackDump(true); 156 decorateHtml(stack); 157 } 158 else if (path.equals("/info.html")) { 159 StringBuffer extra = idv.getIdvUIManager().getSystemInfo(); 160 extra.append("<H3>Data Sources</H3>"); 161 extra.append("<div style=\"margin-left:20px;\">"); 162 extra.append(idv.getDataManager().getDataSourceHtml()); 163 extra.append("</div>"); 164 extra.append(idv.getPluginManager().getPluginHtml()); 165 extra.append(idv.getResourceManager().getHtmlView()); 166 decorateHtml(extra); 167 } 168 else if (path.equals("/shutdown.html")) { 169 decorateHtml(new StringBuffer("<a href=\"reallyshutdown.html\">Shut down McIDAS-V</a>")); 170 } 171 else if (path.equals("/reallyshutdown.html")) { 172 writeResult(true, "McIDAS-V is shutting down","text/html"); 173 System.exit(0); 174 } 175 else if (path.equals("/") || path.equals("/index.html")) { 176 decorateHtml(new StringBuffer("")); 177 } 178 else { 179 decorateHtml(new StringBuffer("Unknown url:" + path)); 180 } 181 } 182 } 183 184}