001/* 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030/* A thread for executing the lidar processing. 031 */ 032 033package org.geon; 034 035import java.io.BufferedReader; 036import java.io.BufferedWriter; 037import java.io.File; 038import java.io.FileInputStream; 039import java.io.FileOutputStream; 040import java.io.FileWriter; 041import java.io.IOException; 042import java.io.InputStream; 043import java.io.InputStreamReader; 044import java.io.OutputStream; 045import java.io.RandomAccessFile; 046import java.io.Reader; 047import java.net.URL; 048import java.util.Date; 049import java.util.HashMap; 050import java.util.Map; 051import java.util.Properties; 052import java.util.TreeMap; 053import java.util.Vector; 054 055import javax.mail.Message; 056import javax.mail.MessagingException; 057import javax.mail.Session; 058import javax.mail.Transport; 059import javax.mail.internet.InternetAddress; 060import javax.mail.internet.MimeMessage; 061import javax.servlet.http.HttpServletRequest; 062 063////////////////////////////////////////////////////////////////////////// 064//// ExecutionThread 065/** 066 * Thread for executing the Lidar processing. 067 * 068 * @author Efrat Jaeger 069 */ 070public class ExecutionThread extends Thread { 071 072 public ExecutionThread() { 073 } 074 075 public ExecutionThread(HttpServletRequest request, StringBuffer threadResp, 076 String appPath, String uniqueId, String host, String port) { 077 super(); 078 this.request = request; 079 this.appPath = appPath; 080 this.uniqueId = uniqueId; 081 this.threadResp = threadResp; 082 this.host = host; 083 this.port = port; 084 } 085 086 private HttpServletRequest request; 087 private String appPath; 088 private String uniqueId; 089 private String host; 090 private String port; 091 public StringBuffer threadResp; 092 private String header; 093 private String footer; 094 095 public void run() { 096 097 header = "<TABLE>\n"; 098 header += "<TR>\n"; 099 header += "<TD><A HREF=\"http://activetectonics.la.asu.edu/GEONatASU/index.htm\" target=\"_new\"><IMG SRC=\"http://agassiz.la.asu.edu/logos/GEONASUWebBanner.jpg\" alt=\"GEON at ASU homepage\"></A></TD>\n"; 100 header += "<TD><a href=\"http://www.sdsc.edu\" target=\"_new\"><img src=\"http://www.sdsc.edu/logos/SDSClogo-plusname-red.gif\" alt=\"San Diego Supercomputer Center\" height=\"60\" width=\"216\"></a></TD>\n"; 101 header += "</TR>\n"; 102 header += "</TABLE>\n"; 103 header += "<table cellpadding=2>\n"; 104 105 footer = "</table>\n"; 106 107 String configFile = (String) request.getAttribute("configFile"); 108 if (configFile == null || configFile.equals("")) { 109 System.out 110 .println("unable to connect to lidar db - missing configuration file"); 111 112 threadResp.append(header); 113 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 114 threadResp 115 .append("<tr><td>Unable to connect to the LiDAR database."); 116 threadResp.append("</td></tr>"); 117 threadResp.append(footer); 118 return; 119 } 120 LidarJobDB lidarJobDB = new LidarJobDB(configFile, new Date() 121 .toString()); 122 try { 123 lidarJobDB.createNewEntry(request); 124 } catch (Exception ex) { 125 ex.printStackTrace(); 126 threadResp.append(header); 127 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 128 threadResp.append("<tr><td>Unable to submit job."); 129 threadResp.append("</td></tr>"); 130 threadResp.append(footer); 131 return; 132 133 } 134 // For logging purposes. 135 String log = ""; 136 137 // For recording execution times. 138 Map timings = new HashMap(); 139 140 // get parameters. 141 Map inputs = new TreeMap(); 142 inputs.put("id", uniqueId); 143 System.out.println("uniqueId ==> " + uniqueId + "\n"); 144 log += uniqueId + " "; 145 146 // use username instead of email. 147 String email = request.getParameter("email"); 148 // System.out.println("email ==> " + email); 149 inputs.put("email", email); 150 151 String user = request.getParameter("username"); 152 153 String ip = request.getRemoteAddr(); 154 log += ip + " "; 155 156 if (email == null || email.equals("")) { 157 email = "noEmail"; 158 } 159 log += email + " "; 160 161 String srid = request.getParameter("srid"); 162 log += srid + " "; 163 164 String rawdata = request.getParameter("rawdata"); 165 if (rawdata == null) 166 rawdata = "0"; 167 inputs.put("rawdata", rawdata); 168 169 String download = request.getParameter("download"); 170 System.out.println("download = " + download); 171 172 // Read processing parameters. 173 StringBuffer sb = new StringBuffer(); 174 StringBuffer xmlParams = new StringBuffer(); 175 xmlParams 176 .append("<command><dataset><filename name=\"/export/downloads/kepler/rawData/"); 177 xmlParams.append(uniqueId + "\"/></dataset>\n"); 178 xmlParams.append("<query>\n"); 179 180 String algs[] = { "elev", "slope", "aspect", "pcurv" }; 181 String formats[] = { "view", "arc", "ascii", "tiff" }; 182 String logAlgs = ""; 183 184 for (int i = 0; i < 4; i++) { 185 for (int j = 0; j < 4; j++) { 186 String type = algs[i] + formats[j]; 187 String typeVal = request.getParameter(type); 188 if (j == 0) { 189 inputs.put(type, typeVal); 190 logAlgs += (i == 0 ? "spline" : algs[i]) + "=" 191 + (typeVal.equals("") ? "0" : "1") + " "; 192 } 193 System.out.println(type + "=" + typeVal); 194 if (typeVal != null && !typeVal.equals("")) { 195 sb.append(type + "=" + typeVal + "\n"); 196 xmlParams 197 .append("<attribute name=\"" + algs[i] 198 + "\" type=\"" + formats[j] 199 + "\" value=\"1\" />\n"); 200 } 201 } 202 } 203 String resolution = request.getParameter("resolution"); 204 if (resolution != null && !resolution.equals("")) { 205 sb.append("res=" + resolution + "\n"); 206 xmlParams.append("<attribute name=\"res\" type=\"\" value=\"" 207 + resolution + "\" />\n"); 208 logAlgs += "res=" + resolution + " "; 209 } else 210 logAlgs += "res=6 "; 211 212 String dmin = request.getParameter("dmin"); 213 String tension = request.getParameter("spline_tension"); 214 String smooth = request.getParameter("spline_smoothing"); 215 216 if (dmin != null && !dmin.equals("")) { 217 sb.append("dmin=" + dmin + "\n"); 218 xmlParams.append("<attribute name=\"dmin\" type=\"\" value=\"" 219 + dmin + "\" />\n"); 220 logAlgs += "dmin=" + dmin + " "; 221 } else 222 logAlgs += "dmin=1 "; 223 if (tension != null && !tension.equals("")) { 224 sb.append("tension=" + tension + "\n"); 225 xmlParams.append("<attribute name=\"tension\" type=\"\" value=\"" 226 + tension + "\" />\n"); 227 logAlgs += "tension=" + tension + " "; 228 } else 229 logAlgs += "tension=40 "; 230 if (smooth != null && !smooth.equals("")) { 231 sb.append("smooth=" + smooth + "\n"); 232 xmlParams.append("<attribute name=\"smooth\" type=\"\" value=\"" 233 + smooth + "\" />\n"); 234 logAlgs += "smooth=" + smooth + " "; 235 } else 236 logAlgs += "smooth=0.1 "; 237 238 String projection = request.getParameter("projection"); 239 String units = request.getParameter("units"); 240 sb.append("projection=" + projection + "\n"); 241 sb.append("units=" + units + "\n"); 242 243 xmlParams.append("<attribute name=\"id\" type=\"\" value=\"" + uniqueId 244 + "\" />\n"); 245 xmlParams 246 .append("<attribute name=\"path\" type=\"\" value=\"./\" />\n"); 247 xmlParams.append("</query></command>"); 248 System.out.println("xmlParams:\n" + xmlParams.toString()); 249 250 String MinX = request.getParameter("MinX"); 251 String MaxX = request.getParameter("MaxX"); 252 String MinY = request.getParameter("MinY"); 253 String MaxY = request.getParameter("MaxY"); 254 System.out.println("MinX ==> " + MinX); 255 System.out.println("MinY ==> " + MinY); 256 System.out.println("MaxX ==> " + MaxX); 257 System.out.println("MaxY ==> " + MaxY); 258 log += MinX + " " + MaxX + " " + MinY + " " + MaxY + " "; 259 260 String[] classification = request.getParameterValues("c"); 261 log += "{"; 262 // log += classification.toString() + " "; 263 if (classification != null) { 264 for (int i = 0; i < classification.length - 1; i++) { 265 log += classification[i] + ","; 266 // System.out.println("clasification (Execution thread) ==> " + 267 // classification[i]); 268 } 269 log += classification[classification.length - 1]; 270 } 271 log += "} "; 272 273 LidarUtilities lutil = new LidarUtilities(threadResp, header, footer, 274 srid); 275 boolean propSet = lutil.setProperties(configFile); 276 if (!propSet) { 277 lidarJobDB.setJobStatus(uniqueId, "query failure", 278 "Unable to setup database connection properties."); 279 log += "query failure "; 280 _logExecution(log + "\n", "errorLog"); 281 return; 282 } 283 284 StringBuffer constraint = new StringBuffer(); 285 constraint = lutil.createConstraint(classification, MinX, MinY, MaxX, 286 MaxY); 287 288 // count the number of matching ROWS - TEMPORARILY DONE HERE!!! 289 String numRows = request.getParameter("numRows"); 290 long queryCount = Long.parseLong(numRows); 291 System.out.println("inside exec thread queryCount/rowNum = " 292 + queryCount); 293 Vector tableNames = new Vector(); 294 if (queryCount == -1) {// calculate num rows only if it wasn't 295 // calculated yet. 296 queryCount = lutil.calculateNumRows(MinX, MinY, MaxX, MaxY, 297 classification, download); 298 299 tableNames = lutil.tableNames; 300 System.out.println("query returned " + queryCount + "rows."); 301 } else { 302 tableNames = lutil.getTableNames(MinX, MinY, MaxX, MaxY); 303 } 304 timings.put("NUMROWS", String.valueOf(queryCount)); 305 lidarJobDB.updateJobEntry(uniqueId, timings); 306 timings.clear(); 307 log += queryCount + " "; 308 if (queryCount == -1) { 309 lidarJobDB.setJobStatus(uniqueId, "query failure", ""); 310 log += "query failure "; 311 _logExecution(log + "\n", "errorLog"); 312 return; 313 } 314 if (tableNames.size() == 0) { 315 lidarJobDB.setJobStatus(uniqueId, "query failure", 316 "Empty query response."); 317 log += "empty query response "; 318 _logExecution(log + "\n", "errorLog"); 319 return; 320 } 321 322 String cStr = ""; 323 if (classification != null) { 324 if (classification.length > 0 && classification.length < 4) {// something 325 // was 326 // selected 327 // but 328 // not 329 // all 330 cStr = "classification = " + classification[0]; 331 for (int i = 1; i < classification.length; i++) { 332 // if (classification.length > 1) { 333 cStr += "," + classification[i]; 334 } 335 cStr += " and "; 336 } 337 } 338 // System.out.println("cstr = " + cStr); 339 if (queryCount == 0) { 340 lidarJobDB.setJobStatus(uniqueId, "query failure", 341 "Empty query response."); 342 threadResp.append(header); 343 threadResp 344 .append("<tr><td><h2>Empty Query Response!<h2></td></tr>"); 345 threadResp.append("<tr><td>Querying for " + cStr); 346 threadResp.append("bounding box selection: MinX = " + MinX 347 + ", MaxX = " + MaxX + ", "); 348 threadResp.append("MinY = " + MinY + ", MaxY = " + MaxY 349 + " returned no result!</td></tr>"); 350 threadResp.append(footer); 351 log += "empty query response "; 352 _logExecution(log + "\n", "errorLog"); 353 return; 354 } 355 356 long PROCESSLIMIT = lutil.PROCESSLIMIT; 357 long QUERYLIMIT = lutil.QUERYLIMIT; 358 boolean hasAccess = lidarJobDB.verifyUser(user); 359 if (!hasAccess) { 360 PROCESSLIMIT = lutil.PROCESSLIMITNOACC; 361 QUERYLIMIT = lutil.QUERYLIMITNOACC; 362 } 363 364 if (queryCount > PROCESSLIMIT) { 365 if (download.equals("1")) { 366 // if exceeding the process limit and a processing algorithm was 367 // selected then return a warning. 368 // else return the rawdata. 369 threadResp.append(header); 370 threadResp 371 .append("<tr><td><h3>Sorry, unable to process your request.<h3></td></tr>"); 372 threadResp.append("<tr><td>Querying for " + cStr); 373 threadResp.append("bounding box selection: MinX = " + MinX 374 + ", MaxX = " + MaxX + ", "); 375 threadResp.append("MinY = " + MinY + ", MaxY = " + MaxY 376 + " returned more than the maximum capacity. "); 377 threadResp 378 .append("Currently the process is limited to 1,600,000 points, please modify your query or "); 379 threadResp.append("try again in the future.</td></tr>"); 380 threadResp.append(footer); 381 lidarJobDB.setJobStatus(uniqueId, "process failure", 382 "Processing exceeds maximum points limit."); 383 384 String fromAddress = "GLW Support <efrat@geon01.sdsc.edu>"; 385 386 String messageBody = "Thank you for using the GEON LiDAR Workflow running on the GEONgrid.\n\n"; 387 messageBody += "We were unable to process your request as bounding box selection: "; 388 messageBody += "MinX = " + MinX + ", MaxX = " + MaxX + ", " 389 + "MinY = " + MinY + ", MaxY = " + MaxY; 390 messageBody += "exceeds maximum processing limits. Please modify your selection and try again.\n\n"; 391 if (!hasAccess) 392 messageBody += "To be able to process larger amounts of data please requst access on the LiDAR main page.\n\n"; 393 messageBody += "---------------\nThe GEON project"; 394 String messageSubject = "GEON LiDAR Workflow processing error notification"; 395 String[] toAddress = { email }; 396 lutil.sendEmail(fromAddress, toAddress, null, null, 397 messageSubject, messageBody); 398 399 log += "query returned more than 1600000 points "; 400 _logExecution(log + "\n", "errorLog"); 401 return; 402 } 403 } 404 405 if (queryCount > QUERYLIMIT) { 406 // if exceeding the query limit (20,000,000 rows). 407 threadResp.append(header); 408 threadResp 409 .append("<tr><td><h3>Sorry, unable to process your request.<h3></td></tr>"); 410 threadResp.append("<tr><td>Querying for " + cStr); 411 threadResp.append("bounding box selection: MinX = " + MinX 412 + ", MaxX = " + MaxX + ", "); 413 threadResp.append("MinY = " + MinY + ", MaxY = " + MaxY 414 + " returned more than the maximum capacity. "); 415 threadResp 416 .append("and is unsupported. Please modify your bounding box selection and/or attributes "); 417 threadResp.append("and try again.</td></tr>"); 418 threadResp.append(footer); 419 lidarJobDB.setJobStatus(uniqueId, "query failure", 420 "Query exceeds maximum points limits."); 421 422 String fromAddress = "GLW Support <efrat@geon01.sdsc.edu>"; 423 424 String messageBody = "Thank you for using the GEON LiDAR Workflow running on the GEONgrid.\n\n"; 425 messageBody += "We were unable to process your request as bounding box selection: "; 426 messageBody += "MinX = " + MinX + ", MaxX = " + MaxX + ", " 427 + "MinY = " + MinY + ", MaxY = " + MaxY; 428 messageBody += "exceeds maximum download quota and cannot be processed. Please modify your selection and try again.\n\n"; 429 if (!hasAccess) 430 messageBody += "To be able to download more data please requst access on the LiDAR main page.\n\n"; 431 messageBody += "---------------\nThe GEON project"; 432 433 String messageSubject = "GEON LiDAR Workflow processing error notification"; 434 String[] toAddress = { email }; 435 lutil.sendEmail(fromAddress, toAddress, null, null, messageSubject, 436 messageBody); 437 438 log += "query returned more than 20000000 points "; 439 _logExecution(log + "\n", "errorLog"); 440 return; 441 } 442 443 log += logAlgs; 444 // call query template 445 446 int i; 447 String tableNamesStr = "{"; 448 for (i = 0; i < tableNames.size() - 1; i++) { 449 tableNamesStr += "\"" + (String) tableNames.get(i) + "\"" + ","; 450 } 451 tableNamesStr += "\"" + tableNames.get(i) + "\"" + "}"; 452 System.out.println("tableNamesStr ==> " + tableNamesStr); 453 454 String columnNames = request.getParameter("columnNames"); 455 System.out.println("columnNames = " + columnNames); 456 String columnExpression = request.getParameter("columnExpression"); 457 System.out.println("columnExpression = " + columnExpression); 458 459 Map queryInputs = new TreeMap(); 460 queryInputs.put("uniqueId", uniqueId); 461 queryInputs.put("appPath", appPath); // NO LONGER NECESSARY?? 462 queryInputs.put("tableNames", tableNamesStr); 463 queryInputs.put("constraint", constraint.toString()); 464 queryInputs.put("columnExpression", columnExpression); 465 queryInputs.put("columnNames", columnNames); 466 467 String qtemplate = appPath + "data/queryAcrossTemplate.xml"; 468 File qtemplateFile = new File(qtemplate); 469 // System.out.println("original query template ==> " + qtemplate); 470 471 // copy the template. 472 String queryTemplate = appPath + "data/tmp/queryAcrossTemplate" 473 + uniqueId + ".xml"; 474 File qwftemplateFile = new File(queryTemplate); 475 queryTemplate = "file:///" + queryTemplate; 476 // System.out.println("unique id query template ==> " + queryTemplate); 477 478 try { 479 InputStream is = new FileInputStream(qtemplateFile); 480 OutputStream os = new FileOutputStream(qwftemplateFile); 481 482 // Transfer bytes from in to out 483 byte[] buf = new byte[1024]; 484 int len; 485 while ((len = is.read(buf)) > 0) { 486 os.write(buf, 0, len); 487 } 488 is.close(); 489 os.close(); 490 491 } catch (Exception ex) { 492 lidarJobDB.setJobStatus(uniqueId, "query failure", ex.getMessage()); 493 System.out.println("unable to create query template for " 494 + uniqueId + ex.getMessage()); 495 496 threadResp.append(header); 497 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 498 threadResp.append("<tr><td>Unable to create query template for " 499 + uniqueId + ":\n" + ex.getMessage()); 500 threadResp.append("</td></tr>"); 501 threadResp.append(footer); 502 log += "unable to query the lidar db "; 503 _logExecution(log + "\n", "errorLog"); 504 return; 505 } 506 507 // System.out.println("query template url ==> " + queryTemplate); 508 System.out.println("BEFORE executing query!!"); 509 510 lidarJobDB.setJobStatus(uniqueId, "querying", ""); // set the job status 511 // in the monitoring 512 // DB. 513 514 LidarWorkflowExecute lwfe = new LidarWorkflowExecute(); 515 String res = ""; 516 try { 517 long begin = new Date().getTime(); 518 res = lwfe.executeQuery(queryTemplate, queryInputs); 519 long end = new Date().getTime(); 520 long queryTime = end - begin; 521 String queryTimeSec = queryTime / 1000 + ""; 522 timings.put("QUERYTIME", queryTimeSec); 523 log += queryTimeSec + " "; 524 System.out.println("query response url ==> " + res 525 + "\n queryTime = " + queryTimeSec); 526 if (res.equals("")) 527 throw new Exception("res is empty"); 528 } catch (Exception ex) { 529 lidarJobDB.setJobStatus(uniqueId, "query failure", 530 "Unable to query LiDAR database."); 531 ex.printStackTrace(); 532 threadResp.append(header); 533 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 534 threadResp.append("<tr><td>Unable to query the LiDAR database."); 535 threadResp.append("</td></tr>"); 536 threadResp.append(footer); 537 log += "unable to query the lidar db "; 538 _logExecution(log + "\n", "errorLog"); 539 return; 540 // ADD EXCEPTION NOTIFICATION TO USER AND STOP EXECUTION!!!! 541 } 542 543 // /TODO! this test is no longer necessary 544 if (res.equals("0")) { 545 lidarJobDB.setJobStatus(uniqueId, "query failure", 546 "No available data for user selection."); 547 threadResp.append(header); 548 threadResp 549 .append("<tr><td><h2>Empty Query Response!<h2></td></tr>"); 550 threadResp.append("<tr><td>Querying for " + cStr); 551 threadResp.append("bounding box selection: MinX = " + MinX 552 + ", MaxX = " + MaxX + ", "); 553 threadResp.append("MinY = " + MinY + ", MaxY = " + MaxY 554 + " returned no result!</td></tr>"); 555 threadResp.append(footer); 556 log += "empty query response "; 557 _logExecution(log + "\n", "errorLog"); 558 return; 559 } 560 inputs.put("rawdataURL", res); 561 562 // remove query file - TODO! 563 564 inputs.put("appPath", appPath); 565 inputs.put("host", host); 566 inputs.put("port", port); 567 inputs.put("download", download); 568 // inputs.put("xmlParams",xmlParams.toString()); 569 570 // if only download raw data was selected 571 if (download.equals("0")) { 572 // The user is only interested in raw data. 573 lidarJobDB.setJobStatus(uniqueId, "done", ""); 574 timings.put("COMPLETIONDATE", new Date().toString()); 575 lidarJobDB.updateJobEntry(uniqueId, timings); 576 StringBuffer queryResp = new StringBuffer(); 577 queryResp.append("Raw data for " + cStr); 578 queryResp.append("bounding box selection: MinX = " + MinX 579 + ", MaxX = " + MaxX + ", "); 580 queryResp.append("MinY = " + MinY + ", MaxY = " + MaxY 581 + " is available at "); 582 583 threadResp.append(header); 584 threadResp.append("<tr><td>"); 585 threadResp.append(queryResp.toString()); 586 threadResp.append("<A href=\"" + res + "\">queryResult</A> (" 587 + queryCount + " points).</td></tr>"); 588 threadResp.append(footer); 589 threadResp.append("<br><table><tr><td>Download "); 590 threadResp 591 .append("<A href=\"http://activetectonics.la.asu.edu/GEONatASU/LViz.html\">"); 592 threadResp.append("LViz</A>"); 593 threadResp 594 .append(" - A free application for visualization of LiDAR point cloud and interpolated surface "); 595 threadResp 596 .append("data developed in the Active Tectonics Research Group at Arizona State University."); 597 threadResp.append("</td></tr></table>"); 598 599 // Email results. 600 if (email != null && !email.equals("")) { 601 emailQueryResp(queryResp.toString(), res, email, queryCount); 602 } 603 _logExecution(log + "\n", "rawDataLog"); 604 return; 605 } 606 // else.. 607 inputs.put("queryCount", String.valueOf(queryCount)); 608 if (rawdata.equals("1")) { 609 // send bounding box for printout. 610 inputs.put("MinX", MinX); 611 inputs.put("MinY", MinY); 612 inputs.put("MaxX", MaxX); 613 inputs.put("MaxY", MaxY); 614 inputs.put("classification", cStr); 615 } 616 617 // Create parameters file from string buffer. 618 try { 619 String filePath = appPath + "data/tmp/params" + uniqueId + ".txt"; 620 File paramsFile = new File(filePath); 621 String paramsFileURL = paramsFile.getAbsolutePath(); 622 System.out.println("Writing to parameter file " + paramsFileURL); 623 BufferedWriter bw = new BufferedWriter(new FileWriter( 624 paramsFileURL, false)); 625 626 bw.write(sb.toString()); 627 bw.close(); 628 629 } catch (Exception ex) { 630 lidarJobDB.setJobStatus(uniqueId, "process failure", ex 631 .getMessage()); 632 System.out.println("unable to create params file " + uniqueId 633 + ": " + ex.getMessage()); 634 threadResp.append(header); 635 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 636 threadResp.append("<tr><td>Unable to create params file " 637 + uniqueId + ": " + ex.getMessage()); 638 threadResp.append("</td></tr>"); 639 threadResp.append(footer); 640 log += "unable to process user selections "; 641 _logExecution(log + "\n", "errorLog"); 642 return; 643 } 644 645 // String template = "file:///" + appPath + "data/processTemplate.xml"; 646 // String template = appPath + "data/processTemplate.xml"; 647 String template = appPath + "data/processTemplateWS.xml"; 648 System.out.println("process template ==> " + template); 649 File templateFile = new File(template); 650 651 // copy the template. 652 // String workflowTemplate = "file:///" + appPath + 653 // "data/processTemplate" + uniqueId + ".xml"; 654 String workflowTemplate = appPath + "data/tmp/processTemplate" 655 + uniqueId + ".xml"; 656 File wftemplateFile = new File(workflowTemplate); 657 workflowTemplate = "file:///" + workflowTemplate; 658 659 try { 660 InputStream is = new FileInputStream(templateFile); 661 OutputStream os = new FileOutputStream(wftemplateFile); 662 663 // Transfer bytes from in to out 664 byte[] buf = new byte[1024]; 665 int len; 666 while ((len = is.read(buf)) > 0) { 667 os.write(buf, 0, len); 668 } 669 is.close(); 670 os.close(); 671 672 } catch (Exception ex) { 673 lidarJobDB.setJobStatus(uniqueId, "process failure", ex 674 .getMessage()); 675 System.out.println("unable to create process template for " 676 + uniqueId + ex.getMessage()); 677 678 threadResp.append(header); 679 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 680 threadResp.append("<tr><td>Unable to create process template for " 681 + uniqueId + ":\n" + ex.getMessage()); 682 threadResp.append("</td></tr>"); 683 threadResp.append(footer); 684 log += "unable to process user selections "; 685 _logExecution(log + "\n", "errorLog"); 686 return; 687 } 688 689 System.out.println("workflow url ==> " + workflowTemplate); 690 System.out.println("BEFORE!!"); 691 lidarJobDB.setJobStatus(uniqueId, "processing", ""); // set the job 692 // status in the 693 // monitoring 694 // DB. 695 // LidarWorkflowExecute lwfe = new LidarWorkflowExecute(); 696 try { 697 long begin = new Date().getTime(); 698 res = lwfe.executeProcess(workflowTemplate, inputs); 699 long end = new Date().getTime(); 700 long processTime = end - begin; 701 String processTimeSec = processTime / 1000 + ""; 702 timings.put("PROCESSTIME", processTimeSec); 703 log += processTimeSec + " "; 704 System.out.println("process result url ==> " + res 705 + "\n processTime = " + processTimeSec); 706 // response.sendRedirect(res); 707 System.out.println("RES = " + res); 708 if (res.equals("0")) { 709 lidarJobDB.setJobStatus(uniqueId, "process failure", 710 "GRASS processing error"); 711 threadResp.append(header); 712 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 713 threadResp 714 .append("<tr><td>GRASS processing error for bounding box selection: "); 715 threadResp.append("MinX = " + MinX + ", MaxX = " + MaxX 716 + ", MinY = " + MinY + ", MaxY = " + MaxY); 717 threadResp 718 .append(". Please modify selection area and try again."); 719 threadResp.append("</td></tr>"); 720 threadResp.append(footer); 721 log += "GRASS processing error "; 722 _logExecution(log + "\n", "errorLog"); 723 724 String fromAddress = "GLW Support <efrat@geon01.sdsc.edu>"; 725 726 String messageBody = "Thank you for using the GEON LiDAR Workflow running on the GEONgrid.\n\n"; 727 messageBody += "We were unable to process your request for bounding box selection: "; 728 messageBody += "MinX = " + MinX + ", MaxX = " + MaxX + ", " 729 + "MinY = " + MinY + ", MaxY = " + MaxY; 730 messageBody += "due to a GRASS processing error. Please modify your selection and try again.\n\n"; 731 messageBody += "---------------\nThe GEON project"; 732 String messageSubject = "GEON LiDAR Workflow processing error notification"; 733 String[] toAddress = { email }; 734 lutil.sendEmail(fromAddress, toAddress, null, null, 735 messageSubject, messageBody); 736 737 return; 738 739 } 740 URL url = new URL(res); 741 Reader in = new InputStreamReader(url.openStream()); 742 BufferedReader br = new BufferedReader(in); 743 String line; 744 745 while ((line = br.readLine()) != null) { 746 threadResp.append(line + "\n"); 747 } 748 749 } catch (Exception ex) { 750 lidarJobDB.setJobStatus(uniqueId, "process failure", ex 751 .getMessage()); 752 ex.printStackTrace(); 753 threadResp.append(header); 754 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 755 threadResp.append("<tr><td>Workflow exception please try again."); 756 threadResp.append("</td></tr>"); 757 threadResp.append("<tr><td>" + ex.getMessage() + "."); 758 threadResp.append("</td></tr>"); 759 threadResp.append(footer); 760 log += "workflow execution error "; 761 _logExecution(log + "\n", "errorLog"); 762 return; 763 } 764 String completeDate = new Date().toString(); 765 log += completeDate; 766 lidarJobDB.setJobStatus(uniqueId, "done", ""); 767 timings.put("COMPLETIONDATE", completeDate); 768 lidarJobDB.updateJobEntry(uniqueId, timings); 769 _logExecution(log + "\n", "lidarLog"); 770 } 771 772 public void getProcessResponse(String configFile) { 773 774 LidarJobDB lidarJobDB = new LidarJobDB(configFile); 775 LidarJobConfig jobConfig = lidarJobDB.getJobConfig(uniqueId); 776 777 Map inputs = new TreeMap(); 778 inputs.put("id", uniqueId); 779 inputs.put("rawdata", "0"); 780 inputs.put("download", "1"); 781 inputs.put("appPath", appPath); 782 inputs.put("host", host); 783 inputs.put("port", port); 784 785 String[] processings = jobConfig.getProcessings(); 786 for (int i = 0; i < processings.length; i++) { 787 inputs.put(processings[i], "1"); 788 } 789 790 String template = appPath + "data/gmTemplate.xml"; 791 System.out.println("global mapper template ==> " + template); 792 File templateFile = new File(template); 793 794 // copy the template. 795 String workflowTemplate = appPath + "data/tmp/gmTemplate" + uniqueId 796 + ".xml"; 797 File wftemplateFile = new File(workflowTemplate); 798 workflowTemplate = "file:///" + workflowTemplate; 799 800 try { 801 InputStream is = new FileInputStream(templateFile); 802 OutputStream os = new FileOutputStream(wftemplateFile); 803 804 // Transfer bytes from in to out 805 byte[] buf = new byte[1024]; 806 int len; 807 while ((len = is.read(buf)) > 0) { 808 os.write(buf, 0, len); 809 } 810 is.close(); 811 os.close(); 812 813 System.out.println("workflow url ==> " + workflowTemplate); 814 System.out.println("BEFORE!!"); 815 816 LidarWorkflowExecute lwfe = new LidarWorkflowExecute(); 817 String res = lwfe.executeProcess(workflowTemplate, inputs); 818 819 URL url = new URL(res); 820 Reader in = new InputStreamReader(url.openStream()); 821 BufferedReader br = new BufferedReader(in); 822 String line; 823 824 while ((line = br.readLine()) != null) { 825 threadResp.append(line + "\n"); 826 } 827 828 } catch (Exception ex) { 829 ex.printStackTrace(); 830 threadResp.append(header); 831 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 832 threadResp.append("<tr><td>Unable to obtain process response:\n" 833 + ex.getMessage()); 834 threadResp.append("</td></tr>"); 835 threadResp.append("<tr><td>" + ex.getMessage() + "."); 836 threadResp.append("</td></tr>"); 837 threadResp.append(footer); 838 return; 839 } 840 } 841 842 public void getQueryResponse(String configFile) { 843 844 LidarJobDB lidarJobDB = new LidarJobDB(configFile); 845 LidarJobConfig jobConfig = lidarJobDB.getJobConfig(uniqueId); 846 847 String MinX = jobConfig.getXmin(); 848 String MaxX = jobConfig.getXmax(); 849 String MinY = jobConfig.getYmin(); 850 String MaxY = jobConfig.getYmax(); 851 String[] classification = jobConfig.getClassifications(); 852 String srid = jobConfig.getSrid(); 853 String queryCount = jobConfig.getNumRows(); 854 855 try { 856 LidarUtilities lutil = new LidarUtilities(threadResp, header, 857 footer, srid); 858 boolean propSet = lutil.setProperties(configFile); 859 if (!propSet) { 860 throw new Exception( 861 "unable to setup database connection properties"); 862 } 863 864 StringBuffer constraint = new StringBuffer(); 865 constraint = lutil.createConstraint(classification, MinX, MinY, 866 MaxX, MaxY); 867 868 Vector tableNames = new Vector(); 869 tableNames = lutil.getTableNames(MinX, MinY, MaxX, MaxY); 870 871 String cStr = ""; 872 if (classification != null) { 873 if (classification.length > 0 && classification.length < 4) {// something 874 // was 875 // selected 876 // but 877 // not 878 // all 879 cStr = "classification = " + classification[0]; 880 for (int i = 1; i < classification.length; i++) { 881 // if (classification.length > 1) { 882 cStr += "," + classification[i]; 883 } 884 cStr += " and "; 885 } 886 } 887 888 int i; 889 String tableNamesStr = "{"; 890 for (i = 0; i < tableNames.size() - 1; i++) { 891 tableNamesStr += "\"" + (String) tableNames.get(i) + "\"" + ","; 892 } 893 tableNamesStr += "\"" + tableNames.get(i) + "\"" + "}"; 894 895 Map queryInputs = new TreeMap(); 896 queryInputs.put("uniqueId", uniqueId); // check that 897 queryInputs.put("appPath", appPath); // check that 898 queryInputs.put("tableNames", tableNamesStr); 899 queryInputs.put("constraint", constraint.toString()); 900 901 String queryTemplate = appPath + "data/tmp/queryAcrossTemplate" 902 + uniqueId + ".xml"; // replace jobId with generated id 903 File qwftemplateFile = new File(queryTemplate); 904 queryTemplate = "file:///" + queryTemplate; 905 906 String qtemplate = appPath + "data/queryAcrossTemplate.xml"; 907 File qtemplateFile = new File(qtemplate); 908 909 InputStream is = new FileInputStream(qtemplateFile); 910 OutputStream os = new FileOutputStream(qwftemplateFile); 911 912 // Transfer bytes from in to out 913 byte[] buf = new byte[1024]; 914 int len; 915 while ((len = is.read(buf)) > 0) { 916 os.write(buf, 0, len); 917 } 918 is.close(); 919 os.close(); 920 921 LidarWorkflowExecute lwfe = new LidarWorkflowExecute(); 922 String res = ""; 923 res = lwfe.executeQuery(queryTemplate, queryInputs); 924 925 StringBuffer queryResp = new StringBuffer(); 926 queryResp.append("Raw data for " + cStr); 927 queryResp.append("bounding box selection: MinX = " + MinX 928 + ", MaxX = " + MaxX + ", "); 929 queryResp.append("MinY = " + MinY + ", MaxY = " + MaxY 930 + " is available at "); 931 932 threadResp.append("<table><tr><td>"); 933 threadResp.append(queryResp.toString()); 934 threadResp.append("<A href=\"" + res + "\">queryResult</A>"); 935 if (queryCount != null) { 936 if (!queryCount.equals("-1")) { 937 threadResp.append(" (" + queryCount + " points)."); 938 } 939 } 940 threadResp.append(".</td></tr></table>"); 941 threadResp.append("<br><table><tr><td>Download "); 942 threadResp 943 .append("<A href=\"http://activetectonics.la.asu.edu/GEONatASU/LViz.html\">"); 944 threadResp.append("LViz</A>"); 945 threadResp 946 .append(" - A free application for visualization of LiDAR point cloud and interpolated surface "); 947 threadResp 948 .append("data developed in the Active Tectonics Research Group at Arizona State University."); 949 threadResp.append("</td></tr></table>"); 950 951 } catch (Exception ex) { 952 ex.printStackTrace(); 953 threadResp.append(header); 954 threadResp.append("<tr><td><h2>Error!<h2></td></tr>"); 955 threadResp.append("<tr><td>Unable to obtain query response:\n" 956 + ex.getMessage()); 957 threadResp.append("</td></tr>"); 958 threadResp.append(footer); 959 return; 960 } 961 } 962 963 private void emailQueryResp(String queryResp, String URL, String email, 964 long queryCount) { 965 String messageBody = "Thank you for using the GEON LiDAR Workflow running on the GEONgrid.\n\n"; 966 messageBody += queryResp + URL + " (" + queryCount + " points).\n\n"; 967 messageBody += "Please note that the results will expire after 48 hours.\n\n"; 968 messageBody += "---------------\nThe GEON project"; 969 970 String messageSubject = "GEON LiDAR Workflow processing results"; 971 972 String host = "localhost"; 973 String fromAddress = "GEON LiDAR Workflow Processing Notification <efrat@geon01.sdsc.edu>"; 974 975 Properties props = new Properties(); 976 props.put("mail.smtp.host", host); 977 props.put("mail.debug", "false"); 978 979 Session session = Session.getInstance(props); 980 981 try { 982 Message msg = new MimeMessage(session); 983 msg.setFrom(new InternetAddress(fromAddress)); 984 InternetAddress[] address = { new InternetAddress(email) }; 985 msg.setRecipients(Message.RecipientType.TO, address); 986 msg.setSubject(messageSubject); 987 msg.setSentDate(new java.util.Date()); 988 msg.setText(messageBody); 989 990 Transport.send(msg); 991 } catch (MessagingException mex) { 992 mex.printStackTrace(); 993 } 994 } 995 996 public void _logExecution(String log, String fileName) { 997 String logURL = System.getProperty("user.home") + File.separator 998 + ".lidar" + File.separator + fileName; 999 try { 1000 File logFile = new File(logURL); 1001 FileWriter fw = new FileWriter(logFile, true); 1002 1003 RandomAccessFile raf = new RandomAccessFile(logFile, "r"); 1004 if (raf.length() == 0) {// write header 1005 logFile.createNewFile(); 1006 fw 1007 .write("id ip email dataset minX maxX minY maxY classification munberOfPoints " 1008 + "spline slope aspect pcurv res dmin tension smooth queryTime processTime\n"); 1009 } 1010 fw.write(log); 1011 fw.flush(); 1012 fw.close(); 1013 } catch (IOException ioex) { 1014 System.out.println("Unable to write " + log + " to " + logURL 1015 + ".\n" + ioex.getMessage()); 1016 } 1017 } 1018}