View Javadoc

1   /*
2    * Copyright 2010-2012 Capgemini
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   *
15   */
16  package net.sf.appstatus.web;
17  
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.util.Map;
21  import java.util.Properties;
22  
23  import javax.servlet.http.HttpServletRequest;
24  import javax.servlet.http.HttpServletResponse;
25  
26  import org.apache.commons.lang3.StringUtils;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  
30  import net.sf.appstatus.core.AppStatus;
31  import net.sf.appstatus.core.AppStatusStatic;
32  import net.sf.appstatus.web.pages.Resources;
33  
34  /**
35   * Handle the Web UI of AppStatus.
36   *
37   * @author Olivier Lafon
38   * @author Nicolas Richeton
39   */
40  public class StatusWebHandler {
41  	private static Logger logger = LoggerFactory.getLogger(StatusWebHandler.class);
42  	private String allowIp = null;
43  	private String applicationName = StringUtils.EMPTY;
44  	private AppStatus appStatus = null;
45  	private String cssLocation = null;
46  	private Map<String, IPage> pages = null;
47  
48  	/**
49  	 * Handle a GET request.
50  	 *
51  	 * @param req
52  	 * @param resp
53  	 * @throws IOException
54  	 */
55  	public void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
56  
57  		if (allowIp != null) {
58  			if (!req.getRemoteAddr().equals(allowIp)) {
59  				resp.sendError(401, "IP not authorized");
60  				return;
61  			}
62  		}
63  
64  		if (req.getParameter("icon") != null || req.getParameter("resource") != null) {
65  			Resources.doGet(this, req, resp);
66  			return;
67  		}
68  
69  		if (req.getParameter("p") != null && pages.containsKey(req.getParameter("p"))) {
70  			pages.get(req.getParameter("p")).doGet(this, req, resp);
71  
72  		} else {
73  			pages.get("status").doGet(this, req, resp);
74  		}
75  	}
76  
77  	/**
78  	 * Handle a POST request.
79  	 *
80  	 * @param req
81  	 * @param resp
82  	 * @throws IOException
83  	 */
84  	public void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
85  		if (allowIp != null) {
86  			if (!req.getRemoteAddr().equals(allowIp)) {
87  				resp.sendError(401, "IP not authorized");
88  				return;
89  			}
90  		}
91  
92  		if (req.getParameter("p") != null && pages.containsKey(req.getParameter("p"))) {
93  			pages.get(req.getParameter("p")).doPost(this, req, resp);
94  
95  		} else {
96  			pages.get("status").doPost(this, req, resp);
97  		}
98  
99  		doGet(req, resp);
100 	}
101 
102 	public String getApplicationName() {
103 		return applicationName;
104 	}
105 
106 	public AppStatus getAppStatus() {
107 		return appStatus;
108 	}
109 
110 	public String getCssLocation() {
111 		return cssLocation;
112 	}
113 
114 	public Map<String, IPage> getPages() {
115 		return pages;
116 	}
117 
118 	/**
119 	 * Does the initialization work.
120 	 * <p>
121 	 * Read configuration from /status-web-conf.properties
122 	 * <p>
123 	 * If you need to inject custom objects using these methods, please do it
124 	 * before calling init.
125 	 * <ul>
126 	 * <li>{@link #setPages(Map)}</li>
127 	 * <li>{@link #setAppStatus(AppStatus)}</li>
128 	 * <li>{@link #setCssLocation(String)}</li>
129 	 * </ul>
130 	 */
131 	public void init() {
132 
133 		// init AppStatus
134 		if (appStatus == null) {
135 			// Use default instance if not set
136 			appStatus = AppStatusStatic.getInstance();
137 		}
138 
139 		appStatus.init();
140 
141 		// Load specific configuration
142 		try {
143 			final InputStream is = Thread.currentThread().getContextClassLoader()
144 					.getResourceAsStream("/status-web-conf.properties");
145 
146 			if (is == null) {
147 				logger.warn("/status-web-conf.properties not found in classpath. Using default configuration");
148 			} else {
149 				final Properties p = new Properties();
150 				p.load(is);
151 				is.close();
152 
153 				if (allowIp == null) {
154 					allowIp = (String) p.get("ip.allow");
155 				}
156 			}
157 		} catch (final Exception e) {
158 			logger.error("Error loading configuration from /status-web-conf.properties.", e);
159 		}
160 
161 		// Init css & js
162 		if (cssLocation == null) {
163 			cssLocation = "?resource=appstatus.css";
164 			Resources.addResource("appstatus.css", "/assets/css/appstatus.css", "text/css");
165 			Resources.addResource("bootstrap.js", "/assets/js/bootstrap.js", "application/javascript");
166 			Resources.addResource("jquery.js", "/assets/js/jquery-2.0.1.min.js", "application/javascript");
167 			Resources.addResource("glyphicons-halflings.png", "/assets/img/glyphicons-halflings.png", "image/png");
168 			Resources.addResource("glyphicons-halflings-white.png", "/assets/img/glyphicons-halflings-white.png",
169 					"image/png");
170 		}
171 	}
172 
173 	/**
174 	 * Restrict access to a single IP.
175 	 *
176 	 * @param allowIp
177 	 */
178 	public void setAllowIp(final String allowIp) {
179 		this.allowIp = allowIp;
180 	}
181 
182 	public void setApplicationName(final String servletContextName) {
183 		this.applicationName = servletContextName;
184 	}
185 
186 	/**
187 	 * Set the AppStatus object to use in the web interface.
188 	 *
189 	 * @param appStatus
190 	 */
191 	public void setAppStatus(final AppStatus appStatus) {
192 		this.appStatus = appStatus;
193 	}
194 
195 	/**
196 	 * Set the location of the css to use.
197 	 *
198 	 * @param cssLocation
199 	 */
200 	public void setCssLocation(final String cssLocation) {
201 		this.cssLocation = cssLocation;
202 	}
203 
204 	/**
205 	 * Set the available pages in the web interface.
206 	 *
207 	 * @param pages
208 	 */
209 	public void setPages(final Map<String, IPage> pages) {
210 		this.pages = pages;
211 	}
212 }