View Javadoc
1   /*
2    * Copyright 2010-2013 Capgemini Licensed under the Apache License, Version 2.0 (the
3    * "License"); you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11   * License for the specific language governing permissions and limitations under
12   * the License.
13   */package net.sf.appstatus.web.pages;
14  
15  import static java.lang.Math.round;
16  import static net.sf.appstatus.web.HtmlUtils.applyLayout;
17  import static net.sf.appstatus.web.HtmlUtils.countAndDetail;
18  import static net.sf.appstatus.web.HtmlUtils.generateBeginTable;
19  import static net.sf.appstatus.web.HtmlUtils.generateEndTable;
20  import static net.sf.appstatus.web.HtmlUtils.generateHeaders;
21  import static net.sf.appstatus.web.HtmlUtils.generateRow;
22  import static org.apache.commons.collections.CollectionUtils.isEmpty;
23  import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
24  
25  import java.io.IOException;
26  import java.io.UnsupportedEncodingException;
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  import javax.servlet.ServletOutputStream;
33  import javax.servlet.http.HttpServletRequest;
34  import javax.servlet.http.HttpServletResponse;
35  
36  import org.apache.commons.lang3.text.StrBuilder;
37  
38  import net.sf.appstatus.core.batch.IBatch;
39  import net.sf.appstatus.core.batch.IBatchConfiguration;
40  import net.sf.appstatus.core.batch.IBatchManager;
41  import net.sf.appstatus.core.batch.IBatchScheduleManager;
42  import net.sf.appstatus.web.HtmlUtils;
43  import net.sf.appstatus.web.StatusWebHandler;
44  
45  public class BatchPage extends AbstractPage {
46  	private static final String CLEAR_ITEM = "clear-item";
47  	private static final String CLEAR_OLD = "clear-old";
48  	private static final String CLEAR_SUCCESS = "clear-success";
49  	private static final String ENCODING = "UTF-8";
50  	private static final String ITEM_UUID = "item-uuid";
51  	private static final String PAGECONTENTLAYOUT = "batchesContentLayout.html";
52  
53  	/**
54  	 * Adding execution expressions informations from a list of IBatch.
55  	 *
56  	 * @param conf
57  	 * @param listBatchs
58  	 */
59  	private void addExecutionInformations(IBatchConfiguration conf, List<? extends IBatch> listBatchs) {
60  
61  		if (isEmpty(listBatchs)) {
62  			return;
63  		}
64  
65  		IBatch latestExecution = null;
66  
67  		for (IBatch batch : listBatchs) {
68  			if (latestExecution == null || latestExecution.getStartDate().before(batch.getEndDate())) {
69  				latestExecution = batch;
70  			}
71  
72  		}
73  		conf.setLastExecution(latestExecution.getStartDate());
74  	}
75  
76  	@Override
77  	public void doGet(StatusWebHandler webHandler, HttpServletRequest req, HttpServletResponse resp)
78  			throws UnsupportedEncodingException, IOException {
79  
80  		setup(resp, "text/html");
81  		ServletOutputStream os = resp.getOutputStream();
82  		Map<String, String> valuesMap = new HashMap<String, String>();
83  		StrBuilder sbRunningBatchesBatchesTable = new StrBuilder();
84  		StrBuilder sbFinishedBatchesBatchesTable = new StrBuilder();
85  		StrBuilder sbErrorsBatchesBatchesTable = new StrBuilder();
86  		StrBuilder sbConfBatchesBatchesTable = new StrBuilder();
87  
88  		IBatchManager manager = webHandler.getAppStatus().getBatchManager();
89  		List<IBatch> runningBatches = manager.getRunningBatches();
90  		if (generateBeginTable(sbRunningBatchesBatchesTable, runningBatches.size())) {
91  
92  			generateHeaders(sbRunningBatchesBatchesTable, "", "Id", "Group", "Name", "Start", "Progress", //
93  					"End (est.)", "Status", "Task", "Last Msg", "Items", "Rejected", "Last Update");
94  
95  			for (IBatch batch : runningBatches) {
96  				generateRow(sbRunningBatchesBatchesTable, getIcon(batch), generateId(resp, batch.getUuid()), //
97  						escapeHtml4(batch.getGroup()), escapeHtml4(batch.getName()), batch.getStartDate(),
98  						getProgressBar(batch), //
99  						batch.getEndDate(), batch.getStatus(), batch.getCurrentTask(), //
100 						escapeHtml4(batch.getLastMessage()), batch.getItemCount(),
101 						HtmlUtils.countAndDetail(batch.getRejectedItemsId()), //
102 						batch.getLastUpdate(), //
103 						batch.getStatus() != IBatch.STATUS_ZOMBIE ? "" //
104 								: "<form action='?p=batch' method='post'><input type='submit' name='" + CLEAR_ITEM //
105 										+ "' value='Delete'  class='btn btn-small' /><input type=hidden name='" //
106 										+ ITEM_UUID + "' value='" + escapeHtml4(batch.getUuid()) + "'/></form>");
107 			}
108 
109 			generateEndTable(sbRunningBatchesBatchesTable, runningBatches.size());
110 		}
111 
112 		// Batch Schedule
113 		List<IBatchConfiguration> batchConfigurations = new ArrayList<IBatchConfiguration>();
114 
115 		IBatchScheduleManager scheduleManager = webHandler.getAppStatus().getBatchScheduleManager();
116 		if (scheduleManager != null) {
117 			batchConfigurations.addAll(scheduleManager.getBatchConfigurations());
118 		}
119 
120 		if (HtmlUtils.generateBeginTable(sbConfBatchesBatchesTable, batchConfigurations.size())) {
121 			HtmlUtils.generateHeaders(sbConfBatchesBatchesTable, "", "Group", "Name", "Last run", "Next", "Exec. expr");
122 
123 			for (IBatchConfiguration batch : batchConfigurations) {
124 				addExecutionInformations(batch, manager.getBatches(batch.getGroup(), batch.getName()));
125 				generateRow(sbConfBatchesBatchesTable, Resources.STATUS_JOB, escapeHtml4(batch.getGroup()),
126 						escapeHtml4(batch.getName()), batch.getLastExecution(), batch.getNextExecution(),
127 						batch.getSchedule());
128 			}
129 
130 			generateEndTable(sbConfBatchesBatchesTable, runningBatches.size());
131 		}
132 
133 		List<IBatch> finishedBatches = manager.getFinishedBatches();
134 
135 		if (generateBeginTable(sbFinishedBatchesBatchesTable, finishedBatches.size())) {
136 
137 			generateHeaders(sbFinishedBatchesBatchesTable, "", "Id", "Group", "Name", "Start", "Progress", //
138 					"End", "Status", "Task", "Last Msg", "Items", "Rejected", "Last Update", "");
139 			for (IBatch batch : finishedBatches) {
140 				generateRow(sbFinishedBatchesBatchesTable, getIcon(batch), generateId(resp, batch.getUuid()), //
141 						escapeHtml4(batch.getGroup()), escapeHtml4(batch.getName()), batch.getStartDate(),
142 						getProgressBar(batch), //
143 						batch.getEndDate(), batch.getStatus(), batch.getCurrentTask(),
144 						escapeHtml4(batch.getLastMessage()), //
145 						batch.getItemCount(), countAndDetail(batch.getRejectedItemsId()), //
146 						batch.getLastUpdate(), //
147 						"<form action='?p=batch' method='post'><input type='submit' name='" //
148 								+ CLEAR_ITEM + "' value='Delete'  class='btn btn-small' /><input type=hidden name='" //
149 								+ ITEM_UUID + "' value='" + escapeHtml4(batch.getUuid()) + "'/></form>");
150 			}
151 
152 			generateEndTable(sbFinishedBatchesBatchesTable, finishedBatches.size());
153 		}
154 
155 		List<IBatch> errorBatches = manager.getErrorBatches();
156 
157 		if (generateBeginTable(sbErrorsBatchesBatchesTable, errorBatches.size())) {
158 
159 			generateHeaders(sbErrorsBatchesBatchesTable, "", "Id", "Group", "Name", "Start", "Progress", //
160 					"End", "Status", "Task", "Last Msg", "Items", "Rejected", "Last Update", "");
161 
162 			for (IBatch batch : errorBatches) {
163 				generateRow(sbErrorsBatchesBatchesTable, getIcon(batch), generateId(resp, batch.getUuid()), //
164 						escapeHtml4(batch.getGroup()), escapeHtml4(batch.getName()), batch.getStartDate(),
165 						getProgressBar(batch), //
166 						batch.getEndDate(), batch.getStatus(), batch.getCurrentTask(),
167 						escapeHtml4(batch.getLastMessage()), //
168 						batch.getItemCount(), HtmlUtils.countAndDetail(batch.getRejectedItemsId()), //
169 						batch.getLastUpdate(), //
170 						"<form action='?p=batch' method='post'><input type='submit' name='" //
171 								+ CLEAR_ITEM + "' value='Delete' class='btn btn-small'/><input type=hidden name='" //
172 								+ ITEM_UUID + "' value='" + escapeHtml4(batch.getUuid()) + "'/></form>");
173 			}
174 			generateEndTable(sbErrorsBatchesBatchesTable, errorBatches.size());
175 		}
176 
177 		valuesMap.put("confBatchesBatchesTable", sbConfBatchesBatchesTable.toString());
178 		valuesMap.put("runningBatchesBatchesTable", sbRunningBatchesBatchesTable.toString());
179 		valuesMap.put("finishedBatchesBatchesTable", sbFinishedBatchesBatchesTable.toString());
180 		valuesMap.put("errorsBatchesBatchesTable", sbErrorsBatchesBatchesTable.toString());
181 		valuesMap.put("clearActions", generateClearActions());
182 
183 		String content = applyLayout(valuesMap, PAGECONTENTLAYOUT);
184 
185 		valuesMap.clear();
186 		valuesMap.put("content", content);
187 
188 		os.write(getPage(webHandler, valuesMap).getBytes(ENCODING));
189 	}
190 
191 	@Override
192 	public void doPost(StatusWebHandler webHandler, HttpServletRequest req, HttpServletResponse resp) {
193 		if (req.getParameter(CLEAR_OLD) != null) {
194 			webHandler.getAppStatus().getBatchManager().removeAllBatches(IBatchManager.REMOVE_OLD);
195 		} else if (req.getParameter(CLEAR_SUCCESS) != null) {
196 			webHandler.getAppStatus().getBatchManager().removeAllBatches(IBatchManager.REMOVE_SUCCESS);
197 		} else if (req.getParameter(CLEAR_ITEM) != null) {
198 			webHandler.getAppStatus().getBatchManager().removeBatch(req.getParameter(ITEM_UUID));
199 		}
200 
201 	}
202 
203 	private String generateClearActions() throws IOException {
204 		StrBuilder sb = new StrBuilder();
205 		sb.append("<p>Actions :</p><form action='?p=batch' method='post'><input type='submit' name='" + CLEAR_OLD //
206 				+ "' value='Delete old (6 months)' class='btn'/> <input type='submit' name='" + CLEAR_SUCCESS //
207 				+ "' value='Delete Success w/o rejected' class='btn'/></form>");
208 		return sb.toString();
209 	}
210 
211 	private String generateId(HttpServletResponse resp, String id) throws IOException {
212 
213 		if (id == null) {
214 			return "";
215 		}
216 
217 		if (id.length() < 15) {
218 			return id;
219 		} else {
220 			return "<span title='" + escapeHtml4(id) + "'>" + escapeHtml4(id.substring(0, 10)) + "...</span";
221 		}
222 
223 	}
224 
225 	private String getIcon(IBatch b) {
226 
227 		if (IBatch.STATUS_FAILURE.equals(b.getStatus())) {
228 			return Resources.STATUS_JOB_ERROR;
229 		}
230 
231 		if (IBatch.STATUS_SUCCESS.equals(b.getStatus()) && b.getRejectedItemsId() != null //
232 				&& b.getRejectedItemsId().size() > 0) {
233 			return Resources.STATUS_JOB_WARNING;
234 		}
235 
236 		return Resources.STATUS_JOB;
237 
238 	}
239 
240 	@Override
241 	public String getId() {
242 		return "batch";
243 	}
244 
245 	@Override
246 	public String getName() {
247 		return "Batch";
248 	}
249 
250 	String getProgressBar(IBatch batch) {
251 
252 		String color = "success";
253 		if (batch.getRejectedItemsId() != null && batch.getRejectedItemsId().size() > 0) {
254 			color = "warning";
255 		}
256 
257 		if (IBatch.STATUS_ZOMBIE.equals(batch.getStatus())) {
258 			color = "warning";
259 		}
260 
261 		if (IBatch.STATUS_FAILURE.equals(batch.getStatus())) {
262 			color = "danger";
263 		}
264 
265 		int percent = round(batch.getProgressStatus());
266 
267 		String status = "progress-" + color;
268 		String active = "active";
269 		String striped = "progress-striped";
270 		// progress is animated if job is running (not complete and still
271 		// updated)
272 		if (IBatch.STATUS_ZOMBIE.equals(batch.getStatus()) || IBatch.STATUS_FAILURE.equals(batch.getStatus()) //
273 				|| IBatch.STATUS_SUCCESS.equals(batch.getStatus())) {
274 			active = "";
275 		}
276 
277 		if (IBatch.STATUS_FAILURE.equals(batch.getStatus()) || IBatch.STATUS_SUCCESS.equals(batch.getStatus())) {
278 			striped = "";
279 		}
280 
281 		if (percent == -1) {
282 			percent = 100;
283 		}
284 
285 		return "<div class=\"progress " + striped + " " + active + " " + status + "\">" //
286 				+ "<div class=\"bar\" style=\"width: " + percent + "%;\"></div>" + "</div>";
287 	}
288 }