| 1 18 19 package org.apache.beehive.netui.tools.testrecorder.server; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.Writer ; 24 import java.io.FileReader ; 25 import java.io.InputStream ; 26 import java.io.InputStreamReader ; 27 import javax.servlet.http.HttpServlet ; 28 import javax.servlet.http.HttpServletRequest ; 29 import javax.servlet.http.HttpServletResponse ; 30 import javax.servlet.ServletException ; 31 import javax.servlet.RequestDispatcher ; 32 33 import org.apache.beehive.netui.tools.testrecorder.shared.Logger; 34 import org.apache.beehive.netui.tools.testrecorder.shared.Constants; 35 import org.apache.beehive.netui.tools.testrecorder.shared.Reporter; 36 import org.apache.beehive.netui.tools.testrecorder.shared.RecordSessionBean; 37 import org.apache.beehive.netui.tools.testrecorder.shared.RequestData; 38 import org.apache.beehive.netui.tools.testrecorder.shared.SessionXMLException; 39 import org.apache.beehive.netui.tools.testrecorder.shared.xmlbeans.XMLHelper; 40 import org.apache.beehive.netui.tools.testrecorder.shared.config.TestDefinition; 41 import org.apache.beehive.netui.tools.testrecorder.shared.config.ConfigException; 42 import org.apache.beehive.netui.tools.testrecorder.shared.config.Category; 43 import org.apache.beehive.netui.tools.testrecorder.shared.config.WebappConfig; 44 import org.apache.beehive.netui.tools.testrecorder.server.state.PlaybackSession; 45 import org.apache.beehive.netui.tools.testrecorder.server.state.RecordSession; 46 import org.apache.beehive.netui.tools.testrecorder.server.state.State; 47 import org.apache.beehive.netui.tools.testrecorder.server.state.SessionFailedException; 48 49 50 public class TestRecorderServlet extends HttpServlet { 51 52 private static final Logger log = Logger.getInstance( TestRecorderServlet.class ); 53 54 public TestRecorderServlet() { 55 } 56 57 public void init() { 58 if ( log.isInfoEnabled() ) { 59 log.warn( "initializing ..." ); 60 } 61 } 62 63 public void destroy() { 64 if ( log.isInfoEnabled() ) { 65 log.warn( "destroying ..." ); 66 } 67 super.destroy(); 68 } 69 70 public void doPost( HttpServletRequest request, HttpServletResponse response ) 71 throws ServletException , IOException { 72 doGet( request, response ); 73 } 74 75 public void doGet( HttpServletRequest request, HttpServletResponse response ) 76 throws ServletException , IOException { 77 String mode = null; 78 try { 79 mode = request.getParameter( Constants.MODE ); 80 if ( mode == null ) { 81 String msg = "mode( " + mode + " ) may not be null."; 83 forward( request, response, msg, Constants.ERROR_PAGE, true ); 84 return; 85 } 86 else if ( mode.equalsIgnoreCase( Constants.RECORD ) ) { 87 doRecord( request, response ); 88 } 89 else if ( mode.equalsIgnoreCase( Constants.PLAYBACK ) ) { 90 doPlayback( request, response ); 91 } 92 else if ( mode.equalsIgnoreCase( Constants.DPY_DIFF ) ) { 93 doDiff( request, response ); 94 } 95 else if ( mode.equalsIgnoreCase( Constants.DPY_DETAILS ) ) { 96 doDetails( request, response ); 97 } 98 else if ( mode.equalsIgnoreCase( Constants.DPY_LINK ) ) { 99 doLink( request, response ); 100 } 101 else if ( mode.equalsIgnoreCase( Constants.ADMIN ) ) { 102 doAdmin( request, response ); 103 } 104 else if ( mode.equalsIgnoreCase( Constants.XML_MODE ) ) { 105 doXml( request, response ); 106 } 107 else { 108 String msg = "unknown mode( " + mode + " )."; 110 forward( request, response, msg, Constants.ERROR_PAGE, true ); 111 return; 112 } 113 } 114 catch ( Exception ex ) { 115 String msg = "ERROR: encountered exception handling test recorder control request, mode( " + mode + 116 ", exception( " + ex.getMessage() + " )"; 117 forward( request, response, msg, Constants.ERROR_PAGE, true, ex ); 118 } 119 } 120 121 public void doRecord( HttpServletRequest request, HttpServletResponse response ) 122 throws ServletException , IOException , ConfigException { 123 String cmd = request.getParameter( Constants.CMD ); 124 String testName = getTestName( request ); 125 String testUser = request.getParameter( Constants.TEST_USER ); 126 String description = request.getParameter( Constants.DESCRIPTION ); 127 boolean overwrite = Boolean.valueOf( request.getParameter( Constants.OVERWRITE ) ).booleanValue(); 128 if ( log.isInfoEnabled() ) { 129 log.debug( "record cmd( " + cmd + " )" ); 130 log.debug( "testName( " + testName + " )" ); 131 } 132 if ( log.isDebugEnabled() ) { 133 log.debug( "testUser( " + testUser + " )" ); 134 log.debug( "overwrite( " + overwrite + " )" ); 135 log.debug( "description( " + description + " )" ); 136 } 137 if ( cmd == null ) { 138 String msg = "ERROR: unable to handle record request, '" + Constants.CMD + "' may not be null."; 140 forward( request, response, msg, Constants.ERROR_PAGE, true ); 141 return; 142 } 143 if ( cmd.equalsIgnoreCase( Constants.START ) ) { 144 doRecordStart( testName, request, response, overwrite, testUser, description ); 145 } 146 else if ( cmd.equalsIgnoreCase( Constants.STOP ) ) { 147 doRecordStop( request, response ); 148 } 149 else { 150 String msg = "ERROR: unable to handle record request: '" + Constants.CMD + "'( " + cmd + 152 " ) is not recognized."; 153 forward( request, response, msg, Constants.ERROR_PAGE, true ); 154 return; 155 } 156 } 157 158 private void doRecordStop( HttpServletRequest request, HttpServletResponse response ) throws IOException , 159 ServletException { 160 TestRecorderFilter filter = TestRecorderFilter.instance(); 161 RecordSession session = filter.getState().getRecordingSession(); 162 String msg = "ERROR: failed stopping recording session"; 163 if ( log.isDebugEnabled() ) { 164 log.debug( "STOPPING: recording session( " + session + " )" ); 165 } 166 try { 167 session = filter.getState().recordStop(); 169 if ( session == null ) { 170 msg = "ERROR: no recording session is currently started"; 172 if ( log.isWarnEnabled() ) { 173 log.warn( msg ); 174 } 175 } 176 else { 177 request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, session ); 178 msg = "Recording session( " + session.getSessionName() + " ) stopped"; 179 if ( log.isInfoEnabled() ) { 180 log.info( msg ); 181 } 182 } 183 forward( request, response, msg, Constants.RECORD_PAGE, false ); 184 185 } 186 catch ( Exception ex ) { 187 msg = "ERROR: failed while stopping recording"; 188 request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, session ); 189 forward( request, response, msg, Constants.RECORD_PAGE, true, ex ); 190 } 191 if ( log.isDebugEnabled() ) { 192 log.debug( "STOPPED: recording session( " + session + " )" ); 193 } 194 } 195 196 private void doRecordStart( String testName, HttpServletRequest request, HttpServletResponse response, 197 boolean overwrite, String testUser, String description ) throws IOException , ServletException { 198 TestDefinition test = getTest( testName ); 199 if ( test == null ) { 200 test = new TestDefinition( testName, description, TestRecorderFilter.instance().getWebapp(), null ); 201 } 202 if ( test.getWebapp() != TestRecorderFilter.instance().getWebapp() ) { 203 String msg = "ERROR: unable to start recording, the webapp of the test( " + 204 test.getWebapp().getName() + " ) is not the same as this webapp( " + 205 TestRecorderFilter.instance().getWebapp() + " )"; 206 forward( request, response, msg, Constants.RECORD_PAGE, true ); 207 return; 208 } 209 RecordSession session = null; 211 try { 212 session = getRecordSession( test, overwrite, testUser, description ); 213 if ( description != null ) { 214 test.setDescription( description ); 215 } 216 TestRecorderFilter.instance().getTestDefinitions().add( test ); 217 } 218 catch ( Exception ex ) { 219 String msg = "ERROR: unable to start recording, unable to obtain session, exception( " + 220 ex.getMessage() + " )"; 221 forward( request, response, msg, Constants.RECORD_PAGE, true, ex ); 222 return; 223 } 224 if ( log.isDebugEnabled() ) { 225 log.debug( "attempting to start recording session( " + session + " )" ); 226 } 227 TestRecorderFilter filter = TestRecorderFilter.instance(); 228 boolean start = false; 229 try { 230 start = filter.getState().recordStart( session ); 232 } 233 catch ( Exception ex ) { 234 String msg = "ERROR: failed to start recording, exception( " + ex.getMessage() + " )"; 235 forward( request, response, msg, Constants.RECORD_PAGE, true, ex ); 236 return; 237 } 238 if ( log.isInfoEnabled() ) { 239 log.info( "start( " + start + " )" ); 240 } 241 if ( start ) { 242 String msg = "recording session( " + session.getSessionName() + " ) started."; 243 request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, session ); 244 if ( log.isInfoEnabled() ) { 245 log.info( msg ); 246 } 247 forward( request, response, msg, Constants.RECORD_PAGE, false ); 248 } 249 else { 250 String msg = "ERROR: recording session( " + 251 session.getSessionName() + " ) already started."; 252 request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, filter.getState().getRecordingSession() ); 253 forward( request, response, msg, Constants.RECORD_PAGE, true ); 254 } 255 } 256 257 public void doPlayback( HttpServletRequest request, HttpServletResponse response ) 258 throws ServletException , IOException , ConfigException { 259 String cmd = request.getParameter( Constants.CMD ); 260 if ( log.isInfoEnabled() ) { 261 log.info( "playback cmd( " + cmd + " )" ); 262 } 263 request.setAttribute( Constants.FILTER_SKIP_PARAM, Boolean.TRUE ); 265 if ( cmd != null ) { 266 if ( cmd.equalsIgnoreCase( Constants.START ) ) { 267 doPlaybackStart( request, response ); 268 } 269 if ( cmd.equalsIgnoreCase( Constants.STOP ) ) { 270 doPlaybackStop( request, response ); 271 } 272 } 273 else { 274 String msg = "ERROR: playback '" + Constants.CMD + "'( " + cmd + " ) is not recognized."; 276 forward( request, response, msg, Constants.ERROR_PAGE, true ); 277 return; 278 } 279 forward( request, response, Constants.RECORD_PAGE ); 280 } 281 282 private void doPlaybackStop( HttpServletRequest request, 283 HttpServletResponse response ) throws IOException { 284 String testId = request.getParameter( Constants.TEST_ID_HEADER ); 285 if ( log.isInfoEnabled() ) { 286 log.info( "playback stop testId( " + testId + " )" ); 287 } 288 TestRecorderFilter filter = TestRecorderFilter.instance(); 289 PlaybackSession session = null; 290 try { 291 session = filter.getState().playbackStop( testId ); 294 } 295 catch ( Exception ex ) { 296 String msg = "ERROR: unable to stop playback session for testId( " + testId + " ), exception( " + 297 ex.getMessage() + " )"; 298 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 299 response.setHeader( Constants.OUTCOME_HEADER, Constants.ERROR ); 300 log.error( msg, ex ); 301 if ( ex instanceof IOException ) { 302 throw (IOException ) ex; 303 } 304 else if ( ex instanceof RuntimeException ) { 305 throw (RuntimeException ) ex; 306 } 307 else { 308 throw new RuntimeException ( msg, ex ); 309 } 310 } 311 if ( log.isInfoEnabled() ) { 312 log.info( "STOP: playback session( " + session + " )" ); 313 } 314 if ( session == null ) { 315 String msg = "ERROR: no playback session exists for testId( " + testId + " )"; 317 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 318 response.setHeader( Constants.OUTCOME_HEADER, Constants.ERROR ); 320 response.setHeader( Constants.MSG_ATTRIBUTE, msg ); 321 log.error( msg ); 322 } 323 else { 324 String outcome = session.getStatus(); 328 String msg = "playback session( " + session.getSessionName() + " ) stopped with status( " + outcome + 329 " )."; 330 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 331 request.setAttribute( Constants.PLAYBACK_SESSION_ATTRIBUTE, session ); 332 if ( log.isInfoEnabled() ) { 333 log.info( msg ); 334 } 335 response.setHeader( Constants.OUTCOME_HEADER, outcome ); 337 response.setHeader( Constants.MSG_ATTRIBUTE, msg ); 338 response.setHeader( Constants.RESULTS_FILE_HEADER, session.getPlaybackFile().getAbsolutePath() ); 339 File diffFile = session.getDiffFile(); 340 if ( diffFile != null ) { 341 response.setHeader( Constants.RESULTS_DIFF_HEADER, diffFile.getAbsolutePath() ); 342 } 343 } 344 } 345 346 private void doPlaybackStart( HttpServletRequest request, HttpServletResponse response ) 347 throws IOException , ConfigException { 348 String testName = getTestName( request ); 349 TestDefinition test = getTest( testName ); 350 if ( test == null ) { 351 throw new ConfigException( 352 "ERROR: playback start failed, unable to find a test for test name( " + testName + " )" ); 353 } 354 if ( log.isInfoEnabled() ) { 355 log.info( "playback start test( " + test.getName() + " )" ); 356 } 357 PlaybackSession session = null; 358 try { 359 session = getPlaybackSession( test ); 360 } 361 catch ( Exception ex ) { 362 String msg = "ERROR: unable to start playback, unable to obtain session, exception( " + 363 ex.getMessage() + " )"; 364 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 365 log.error( msg, ex ); 366 System.err.println( "\nPLAYBACK ERROR:\n" + msg ); 367 if ( ex instanceof IOException ) { 368 throw (IOException ) ex; 369 } 370 else if ( ex instanceof RuntimeException ) { 371 throw (RuntimeException ) ex; 372 } 373 else { 374 throw new RuntimeException ( msg, ex ); 375 } 376 } 377 TestRecorderFilter filter = TestRecorderFilter.instance(); 378 boolean start = false; 379 try { 380 start = filter.getState().playbackStart( session ); 382 } 383 catch ( Exception ex ) { 384 String msg = "ERROR: failed to start playback session( " + session + " ), exception( " + 385 ex.getMessage() + " )"; 386 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 387 log.error( msg, ex ); 388 System.err.println( "\nPLAYBACK ERROR:\n" + msg ); 389 if ( ex instanceof IOException ) { 390 throw (IOException ) ex; 391 } 392 else if ( ex instanceof RuntimeException ) { 393 throw (RuntimeException ) ex; 394 } 395 else { 396 throw new RuntimeException ( msg, ex ); 397 } 398 } 399 if ( log.isInfoEnabled() ) { 400 log.info( "playback start( " + start + " )" ); 401 } 402 if ( start ) { 403 String msg = "playback session( " + 404 session.getSessionName() + " ) started."; 405 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 406 request.setAttribute( Constants.PLAYBACK_SESSION_ATTRIBUTE, session ); 407 if ( log.isInfoEnabled() ) { 408 log.info( msg ); 409 } 410 response.setHeader( Constants.OUTCOME_HEADER, 412 Constants.PASS ); 413 response.setHeader( Constants.TEST_ID_HEADER, 414 session.getStringUID() ); 415 response.setHeader( Constants.RECORD_FILE_HEADER, 416 session.getRecordFile().getAbsolutePath() ); 417 } 418 else { 419 String msg = "ERROR: failed to start playback session( " + 421 session.getSessionName() + " )"; 422 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 423 request.setAttribute( Constants.PLAYBACK_SESSION_ATTRIBUTE, session ); 424 log.error( msg ); 425 response.setHeader( Constants.OUTCOME_HEADER, 427 Constants.FAIL ); 428 response.setHeader( Constants.MSG_ATTRIBUTE, msg ); 429 } 430 } 431 432 public void doDiff( HttpServletRequest request, HttpServletResponse response ) 433 throws IOException , ServletException , ConfigException { 434 String sessionName = request.getParameter( Constants.FILE ); 436 TestDefinition test = getTest( sessionName ); 437 if ( test == null ) { 438 String msg = "ERROR: unable to display diff output, no test was found for name( " + sessionName + 439 " )"; 440 forward( request, response, msg, Constants.ERROR_PAGE, true ); 441 return; 442 } 443 try { 444 Writer wrtr = response.getWriter(); 445 File diffFile = getDiffFile( test ); 446 if ( !diffFile.exists() ) { 447 String msg = "ERROR: unable to display diff output, no file was found for test( " + 448 test.getName() + " ), file( " + diffFile.getAbsolutePath() + " )"; 449 forward( request, response, msg, Constants.ERROR_PAGE, true ); 450 return; 451 } 452 wrtr.write( "<html><head><title>Test Diffs of " ); 454 wrtr.write( test.getName() ); 455 wrtr.write( "</title></head>\n" ); 456 wrtr.write( "<body>\n" ); 457 wrtr.write( "<h4>Test Diffs: " ); 458 wrtr.write( test.getName() ); 459 wrtr.write( "</h4>\n" ); 460 wrtr.write( "<pre>" ); 461 wrtr.write( Reporter.genDiffDetails( diffFile ) ); 462 wrtr.write( "</pre>" ); 463 wrtr.write( "</body></html>" ); 464 } 465 catch ( Exception e ) { 466 String msg = "ERROR: failed to display diff file, exception( " + e.getMessage() + 467 " ), test( " + test.getName() + " )"; 468 forward( request, response, msg, Constants.ERROR_PAGE, true ); 469 return; 470 } 471 } 472 473 public void doLink( HttpServletRequest request, HttpServletResponse response ) 474 throws IOException , ServletException , ConfigException { 475 String sessionName = request.getParameter( Constants.FILE ); 476 TestDefinition test = getTest( sessionName ); 477 WebappConfig config = TestRecorderFilter.instance().getWebapp(); 478 try { 479 if ( test == null ) { 480 String msg = "No test was found for name( " + sessionName + " )"; 481 forward( request, response, msg, Constants.ERROR_PAGE, true ); 482 return; 483 } 484 485 File recFile = getRecordSessionFile( test ); 486 if ( !recFile.exists() ) { 487 String msg = "No file was found for test( " + test.getName() + " ), file( " + 488 recFile.getAbsolutePath() + " )"; 489 forward( request, response, msg, Constants.ERROR_PAGE, true ); 490 return; 491 } 492 493 RecordSessionBean bean = null; 494 try { 495 bean = XMLHelper.getRecordSessionBean( recFile ); 496 } 497 catch ( SessionXMLException e ) { 498 String msg = "Failed processing file for record session( " + test.getName() + " ), file( " + 499 recFile.getAbsolutePath() + " )"; 500 forward( request, response, msg, Constants.ERROR_PAGE, true ); 501 return; 502 } 503 RequestData rd = bean.getRequestData( 0 ); 504 if ( rd == null ) { 505 String msg = "Unable to find the first request in the test ( " + test.getName() + " ), file( " + 506 recFile.getAbsolutePath() + " )"; 507 forward( request, response, msg, Constants.ERROR_PAGE, true ); 508 return; 509 } 510 String host = config.getServer().getHostname(); 511 if ( host.equals( "localhost" ) ) 512 { 513 host = request.getServerName(); 514 } 515 response.sendRedirect( rd.getUri( host, config.getServer().getPort() ) ); 516 return; 517 } 518 catch ( Exception e ) { 519 String msg = "ERROR: failed to display test details, exception( " + e.getMessage() + 520 " ), test( " + test.getName() + " )"; 521 forward( request, response, msg, Constants.ERROR_PAGE, true, e ); 522 } 523 } 524 525 public void doDetails( HttpServletRequest request, HttpServletResponse response ) 526 throws IOException , ServletException , ConfigException { 527 String sessionName = request.getParameter( Constants.FILE ); 529 TestDefinition test = getTest( sessionName ); 530 try { 531 if ( test == null ) { 532 String msg = "No test was found for name( " + sessionName + " )"; 533 forward( request, response, msg, Constants.ERROR_PAGE, true ); 534 return; 535 } 536 Writer wrtr = response.getWriter(); 537 File recFile = getRecordSessionFile( test ); 538 if ( !recFile.exists() ) { 539 String msg = "No file was found for test( " + test.getName() + " ), file( " + 540 recFile.getAbsolutePath() + " )"; 541 forward( request, response, msg, Constants.ERROR_PAGE, true ); 542 return; 543 } 544 RecordSessionBean bean = null; 545 try { 546 bean = XMLHelper.getRecordSessionBean( recFile ); 547 } 548 catch ( SessionXMLException e ) { 549 String msg = "Failed processing file for record session( " + test.getName() + " ), file( " + 550 recFile.getAbsolutePath() + " )"; 551 forward( request, response, msg, Constants.ERROR_PAGE, true ); 552 return; 553 } 554 wrtr.write( "<html><head><title>Test Details of " ); 556 wrtr.write( test.getName() ); 557 wrtr.write( "</title></head>\n" ); 558 wrtr.write( "<body>\n" ); 559 wrtr.write( "<h3>Test Details: " ); 560 wrtr.write( test.getName() ); 561 wrtr.write( "</h3>\n" ); 562 wrtr.write( Reporter.genDetails( bean ) ); 563 wrtr.write( "</body></html>" ); 564 } 565 catch ( Exception e ) { 566 String msg = "ERROR: failed to display test details, exception( " + e.getMessage() + 567 " ), test( " + test.getName() + " )"; 568 forward( request, response, msg, Constants.ERROR_PAGE, true, e ); 569 } 570 } 571 572 private void forward( HttpServletRequest request, HttpServletResponse response, String msg, 573 String page, boolean error ) throws ServletException , IOException { 574 forward( request, response, msg, page, error, null ); 575 } 576 577 private void forward( HttpServletRequest request, HttpServletResponse response, String msg, 578 String page, boolean error, Exception ex ) throws ServletException , IOException { 579 if ( request.getAttribute( Constants.MSG_ATTRIBUTE ) == null ) { 580 request.setAttribute( Constants.MSG_ATTRIBUTE, msg ); 581 } 582 if ( error ) { 583 if ( ex != null ) { 584 log.error( msg, ex ); 585 } 586 else { 587 log.error( msg ); 588 } 589 } 590 forward( request, response, page ); 591 } 592 593 private void forward( HttpServletRequest request, HttpServletResponse response, String page ) 594 throws ServletException , IOException { 595 RequestDispatcher dispatcher = request.getRequestDispatcher( page ); 596 dispatcher.forward( request, response ); 597 } 598 599 public void doAdmin( HttpServletRequest request, HttpServletResponse response ) 600 throws ServletException , |