001/* 002 * AliveURL.java 003 * $Source: /cvsroot2/open/projects/WebARTS/ca/bc/webarts/tools/AliveURL.java,v $ 004 * $Revision: 563 $ $Date: 2012-11-03 19:28:37 -0700 (Sat, 03 Nov 2012) $ $Locker: $ 005 * Copyright 2002 (C) WebARTS Design. All rights reserved. 006 * 007 * This program is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU General Public License 009 * as published by the Free Software Foundation; either version 2 010 * of the License, or any later version. 011 * 012 * This program is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 015 * GNU General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * along with this program; if not, write to the Free Software 019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 020 */ 021package ca.bc.webarts.tools; 022 023import java.awt.Toolkit; 024import java.io.File; 025import java.io.FileOutputStream; 026import java.io.IOException; 027import java.io.InputStream; 028import java.io.OutputStream; 029import java.io.PrintStream; 030import java.net.Authenticator; 031import java.net.HttpURLConnection; 032import java.net.MalformedURLException; 033import java.net.PasswordAuthentication; 034import java.net.URL; 035import java.net.URLConnection; 036import java.util.Date; 037import java.util.Properties; 038import java.util.Vector; 039 040import javax.mail.Address; 041import javax.mail.Message; 042import javax.mail.MessagingException; 043import javax.mail.SendFailedException; 044import javax.mail.Session; 045import javax.mail.Transport; 046import javax.mail.internet.InternetAddress; 047import javax.mail.internet.MimeMessage; 048 049import javax.sound.sampled.AudioFormat; 050import javax.sound.sampled.AudioInputStream; 051import javax.sound.sampled.AudioSystem; 052import javax.sound.sampled.DataLine; 053import javax.sound.sampled.LineUnavailableException; 054import javax.sound.sampled.SourceDataLine; 055import javax.sound.sampled.UnsupportedAudioFileException; 056 057// not necessary but saves headaches later if classes move 058import ca.bc.webarts.tools.StreamGobbler; 059 060//import com.jpeterson.x10.SendX10; 061 062 063/** 064 * A simple commandline based app that periodically contacts some specified 065 * URLs and confirms connectivity. It alarms if it cannot connect a specified 066 * number of consequetive times. It also has 067 * built in capability of calling/running an external script and or sending off 068 * an email.<br><br>For Example... I use this as a watchdog for one of my 069 * webservers. The server is on a remote control power supply which allows me 070 * to reboot the server if, for some reason, it has hung and fails this AliveURL 071 * watchdog check 4 times in a row. It then sends off an email to my cell phone 072 * to let me kknow there has been a problem. 073 * 074 * <pre> 075 Usage: 076 java -DproxySet=true -DproxyHost=YourProxyServerHostname 077 -DproxyPort=YourProxyServerPort 078 -DproxyUser=YourProxyUsernameIFNEEDED 079 -DproxyPassword=YourProxyUserPasswordIFNEEDED 080 -DnonProxyHosts=CommaSeperatedlistOfNonProxiedSites 081 ca.bc.webarts.tools.AliveURL [URL location 1] [URL location 2]... 082 </pre> 083 * 084 * @author Tom Gutwin P.Eng 085 */ 086class AliveURL extends Authenticator 087{ 088 public Date currDate = new Date(); 089 static int checkDelay = 300000; // 5 minutes 090 private static URL errorMusic = null; 091 private static File errorMusicFile = null; 092 private static String errorMusicUrlStr = 093 "http://www-bcg.bcg.ada.com/~gutwint/Carbrake.wav"; 094 private static String errorMusicFileStr = 095 "/usr/lib/openoffice.org2.0/share/gallery/sounds/cow.wav"; 096 private static boolean useURL = false; 097 Playback playback = null; 098 Toolkit tk = Toolkit.getDefaultToolkit(); 099 100 public static final String DEFAULT_PROXY_SET = "false"; 101 public static final String DEFAULT_PROXY_HOST = "bchrelay4"; 102 public static final String DEFAULT_PROXY_PORT = "80"; 103 public static final String DEFAULT_PROXY_NOPROXY = ""; 104 /** 105 * Constant Specifying that the logging output will go to System.out. 106 */ 107 public final static short CONSOLE = 50; 108 /** 109 * Constant Specifying that the logging output will go to a spec'd file. 110 */ 111 public final static short FILE = 51; 112 /** 113 * Constant Specifying that the logging output will go to a 114 * spec'd OutputStream. 115 */ 116 public final static short PIPE = 52; 117 118 /** 119 * The Standard OutputStream. 120 */ 121 private final static PrintStream STD_OUT = System.out; 122 123 /** 124 * Description of the Field 125 */ 126 static private String logFileName_ = "AliveUrlLog.txt"; 127 /** 128 * Description of the Field 129 */ 130 static private OutputStream userOut_ = STD_OUT; 131 /** 132 * The stream that ALL logging ends upo getting directed to. 133 */ 134 static private PrintStream logOut_ = null; 135 /** 136 * Description of the Field 137 */ 138 static private File logFile_ = null; 139 /** 140 * Description of the Field 141 */ 142 static private short outSpot_ = FILE; 143 /** 144 * A constant that tells us how many sequential errors to accept before 145 * calling the external Script. 146 **/ 147 static private final short ACCEPTABLE_NUMBER_ERRORS = 3; 148 /** 149 * An extra Delay after a script execution to wait before checking again. 150 **/ 151 static private final int EXTRA_DELAY_TIME = 600000; //10min 152 /** 153 * A class varthat tells us how many sequential errors have occured. 154 **/ 155 static private short numSequentialErrors_ = 0; 156 /** 157 * This is the supervisor flag that toggles running the external script 158 * execution. 159 **/ 160 static private boolean enableExecScript_ = false; 161 static private boolean enableJavaX10_ = true; 162 static private boolean externalScriptWasExecuted_ = false; 163 static private boolean areWePlayingMusic = true; 164 static private boolean areWeSendingEmail_ = true; 165 static private boolean areWeUsingProxy_ = false; 166 static private boolean useProxyAuthentication_ = true; 167 /** 168 * A class var to record and error message to print out if any of the 169 * validation checks on the properties fail. 170 **/ 171 private static String errorMsg_ = ""; 172 173 /** The email addr to send notifications to if a recycle happens **/ 174 private static String emailTo_ = "tgutwin@webarts.bc.ca"; 175 176 /** the class Proxy Username to authenticate with. **/ 177 static private String proxyUsername_ = "YourProxyUserName"; 178 179 /** the class Proxy Password to authenticate with. **/ 180 static private String proxyPassword_ = "GetYourOwnPassword"; 181 182 /** the Proxy hostname. **/ 183 static private String proxyHost_ = DEFAULT_PROXY_HOST; 184 185 /** the Proxy port. **/ 186 static private String proxyPort_ = DEFAULT_PROXY_PORT; 187 188 /** The X10 Commands to send to the X10 engine **/ 189 190 private static String [] x10Cmd1_ = {"off","a","2"}; 191 private static String [] x10Cmd2_ = {"on","a","2"}; 192 193 194 195 /** 196 * 197 * A simple/useless constructor for the sole purpose of providing the 198 * Authenticator impl to the net authentication mechanism. Both the passed 199 * params can be null or "" - if they are the default class username and 200 * pass are used. 201 * 202 * @param String proxyUser is the usernamer to pass to the proxy 203 * @param String proxyPass is the password to pass to the proxy 204 */ 205 public AliveURL(String proxyUser, String proxyPass) 206 { 207 if (proxyUser != null && !proxyUser.equals("")) 208 proxyUsername_ = proxyUser; 209 if (proxyPass != null && !proxyPass.equals("")) 210 proxyPassword_ = proxyPass; 211 } 212 213 214 /** 215 * Constructor for the AliveURL object 216 * 217 * @param url Description of the Parameter 218 */ 219 public AliveURL(URL url) 220 { 221 if (url != null) 222 { 223 StringBuffer outStr = new StringBuffer(); 224 try 225 { 226 int respCode = 200; 227 //initProxy(); 228 currDate.setTime(System.currentTimeMillis()); 229 outStr.append(currDate.toString()); 230 outStr.append(" "); 231 outStr.append(url.getHost()); 232 outStr.append(url.getPath()); 233 Properties systemProperties = System.getProperties(); 234 if (systemProperties.getProperty("http.proxyHost") != null && 235 !systemProperties.getProperty("http.proxyHost").equals("")) 236 { 237 outStr.append(" proxy "); 238 outStr.append(systemProperties.getProperty("http.proxyHost")); 239 outStr.append(":"); 240 outStr.append(systemProperties.getProperty("http.proxyPort")); 241 } 242 System.out.print(outStr.toString()); 243 if (url.getProtocol().equals("http")) 244 { 245 HttpURLConnection connection = 246 (HttpURLConnection) url.openConnection(); 247 248 respCode = connection.getResponseCode(); 249 outStr.append(" --> ResponseCode: " ); 250 outStr.append(respCode); 251 outStr.append(" = "); 252 outStr.append(connection.getResponseMessage()); 253 System.out.print(" --> ResponseCode: " + respCode); 254 System.out.println(" = " + connection.getResponseMessage()); 255 if (respCode == HttpURLConnection.HTTP_NOT_FOUND ) 256 { 257 int headerCount = 1; 258 while (connection.getHeaderFieldKey(headerCount) != null) 259 { 260 System.out.print(" "+connection.getHeaderFieldKey(headerCount)); 261 System.out.println(" = "+connection.getHeaderField(headerCount++)); 262 } 263 } 264 265 if (respCode != 200) 266 { 267 if(areWePlayingMusic) 268 { 269 playErrorMusic(); 270 } 271 numSequentialErrors_++; 272 if (numSequentialErrors_ > ACCEPTABLE_NUMBER_ERRORS) 273 callExternalScript(); 274 } 275 else 276 { 277 unsetExternalScriptWasExecuted_(); 278 numSequentialErrors_ = 0; 279 } 280 } 281 else 282 { 283 URLConnection connection = url.openConnection(); 284 outStr.append(" --> Successful"); 285 System.out.println(" --> Successful"); 286 unsetExternalScriptWasExecuted_(); 287 numSequentialErrors_ = 0; 288 } 289 } 290 catch (IOException ex) 291 { 292 String args = ex.getMessage(); 293 numSequentialErrors_++; 294 System.out.println(" --> Unsuccessful ("+numSequentialErrors_+")"); 295 System.out.println(args); 296 outStr.append(" --> Unsuccessful("+numSequentialErrors_+")"); 297 outStr.append(args); 298 if(areWePlayingMusic) 299 { 300 playErrorMusic(); 301 } 302 if (numSequentialErrors_ > ACCEPTABLE_NUMBER_ERRORS) 303 callExternalScript(); 304 } 305 logEntry(outStr.toString()); 306 } 307 } 308 309 310 /** 311 * Sets the to email address for email notice of the no-connection. 312 * 313 * @param emailTo the email addr to use 314 **/ 315 public void setEmailTo(String emailTo) 316 { 317 this.emailTo_ = emailTo; 318 } 319 320 321 /** 322 * emailTo_ Getter. 323 * 324 * @return the emailTo_ field. 325 **/ 326 public String getEmailTo() 327 { 328 return emailTo_; 329 } 330 331 332/** 333 * The public set method to set the enableExecScript_ class field. 334 * 335 * @param enableExecScript is the value to use to set the class field to. 336 * 337 **/ 338public void setEnableExecScript(boolean enableExecScript) 339{ 340 this.enableExecScript_ = enableExecScript; 341} 342 343 344/** 345 * The public get method to return the enableExecScript_ class field. 346 * 347 * @return the class field: enableExecScript_ 348 * 349 **/ 350public boolean getEnableExecScript() 351{ 352 return enableExecScript_; 353} 354 355 356public void setExternalScriptWasExecuted_() 357{ 358 this.externalScriptWasExecuted_ = true; 359} 360 361 362public void unsetExternalScriptWasExecuted_() 363{ 364 this.externalScriptWasExecuted_ = false; 365} 366 367 368public void setExternalScriptWasExecuted_(boolean externalScriptWasExecuted_) 369{ 370 this.externalScriptWasExecuted_ = externalScriptWasExecuted_; 371} 372 373 374public boolean getExternalScriptWasExecuted_() 375{ 376 return externalScriptWasExecuted_; 377} 378 379 380 /** 381 * Does the gruntwork to get the proxy properties set. 382 **/ 383 384 public static void initProxy() 385 { 386 // Set up the proxy settings if needed 387 Properties sysProps = System.getProperties(); 388 String tmpUseproxy = sysProps.getProperty("proxySet"); 389 // System.out.println("tmpUseproxy="+tmpUseproxy); 390 if (tmpUseproxy != null && !tmpUseproxy.equals("null") && !tmpUseproxy.equals("")) 391 areWeUsingProxy_ = (tmpUseproxy.toLowerCase().equals("true")?true:false); 392 393 394 if (areWeUsingProxy_) 395 { 396 System.out.println("Initializing the proxy settings"); 397 // check if the user had something defined in the Sys Props via the cmdline. 398 String tmpUser = sysProps.getProperty("http.proxyUser"); 399 String tmpPass = sysProps.getProperty("http.proxyPassword"); 400 String tmpHost = sysProps.getProperty("http.proxyHost"); 401 String tmpPort = sysProps.getProperty("http.proxyPort"); 402 403 if (tmpUser != null && !tmpUser.equals("")) 404 proxyUsername_ = tmpUser; 405 if (tmpPass != null && !tmpPass.equals("")) 406 proxyPassword_ = tmpPass; 407 if (tmpHost != null && !tmpHost.equals("")) 408 proxyHost_ = tmpHost; 409 if (tmpPort != null && !tmpPort.equals("")) 410 proxyPort_ = tmpHost; 411 412 if (useProxyAuthentication_) 413 { 414 System.out.println("Authenticating the proxy."); 415 Authenticator.setDefault(new AliveURL(proxyUsername_, proxyPassword_)); 416 } 417 sysProps.put("proxySet", "true"); 418 sysProps.put("http.proxyHost", proxyHost_); 419 sysProps.put("http.proxyPort", proxyPort_); 420 sysProps.put("noProxy", 421 "www-bcg.bcg.ada.com,*.ada.com,149.154.64.245,149.154.64.245:8080"); 422 } 423 424 } 425 426 427 /** 428 * Impl for Authenticator so an authorizing proxy will work. 429 **/ 430 431 protected PasswordAuthentication getPasswordAuthentication() 432 { 433 return new PasswordAuthentication( 434 proxyUsername_, proxyPassword_.toCharArray()); 435 } 436 437 438 /** 439 * Execs an external script/application when an error occurs.. 440 */ 441 private void callExternalScript() 442 { 443 boolean testingOnly = false; 444 445 // 1st cycle the server power OFF 446 String cmdScript = "nice.exe"; 447 Vector v = new Vector(); 448 v.add("/D"); 449 v.add("G:\\apps\\x10\\X10_cmd.cmd"); 450 v.add("B2"); 451 v.add("OFF"); 452 if (enableExecScript_) 453 { 454 executeNativeApp(cmdScript, v); 455 setExternalScriptWasExecuted_(); 456 } 457 if (enableJavaX10_) 458 { 459 //System.out.println("Calling Java X10 Command Off"); 460 //SendX10 sendX10 = new SendX10("com.jpeterson.x10.module.CM17A"); 461 //sendX10.transmit(0, x10Cmd1_); 462 String x10HouseCode = "B"; 463 String x10DeviceNumber = "1"; 464 String x10Command = "off"; 465 if (!testingOnly) (new ca.bc.webarts.tools.X10FireCracker()).sendX10Command(x10HouseCode, x10DeviceNumber, x10Command ); 466 if (areWeSendingEmail_) 467 sendAnEmail(emailTo_, "AliveURL Notification", "AliveURL Sent X10 Command ( "+ 468 x10HouseCode + x10DeviceNumber +" "+x10Command +") - "+(new Date()).toString()); 469 setExternalScriptWasExecuted_(); 470 } 471 472 // wait for the command to execute 473 mySleep(15000); 474 475 // The cycle the server power back On 476 v= new Vector(); 477 v.add("/D"); 478 v.add("G:\\apps\\x10\\X10_cmd.cmd"); 479 v.add("B2"); 480 v.add("ON"); 481 if (enableExecScript_) 482 executeNativeApp(cmdScript, v); 483 if (enableJavaX10_) 484 { 485 try 486 { 487 //System.out.println("Calling Java X10 Command On"); 488 //SendX10 sendX10 = new SendX10("com.jpeterson.x10.module.CM17A"); 489 //sendX10.transmit(0, x10Cmd2_); 490 String x10HouseCode = "B"; 491 String x10DeviceNumber = "1"; 492 String x10Command = "on"; 493 if (!testingOnly) (new ca.bc.webarts.tools.X10FireCracker()).sendX10Command(x10HouseCode, x10DeviceNumber, x10Command ); 494 if (areWeSendingEmail_) 495 sendAnEmail(emailTo_, "AliveURL Notification", "AliveURL Sent X10 Command ( "+ 496 x10HouseCode + x10DeviceNumber +" "+x10Command +") - "+(new Date()).toString()); 497 } 498 catch (java.lang.UnsatisfiedLinkError x10Ex) 499 { 500 System.out.println("Exception thrown... trying again after 60 seconds."); 501 // wait for the command to execute 502 mySleep(60000); 503 //SendX10 sendX10 = new SendX10("com.jpeterson.x10.module.CM17A"); 504 //sendX10.transmit(0, x10Cmd2_); 505 String x10HouseCode = "A"; 506 String x10DeviceNumber = "2"; 507 String x10Command = "off"; 508 if (!testingOnly) (new ca.bc.webarts.tools.X10FireCracker()).sendX10Command(x10HouseCode, x10DeviceNumber, x10Command ); 509 if (areWeSendingEmail_) 510 sendAnEmail(emailTo_, "AliveURL Notification", "AliveURL Sent X10 Command ( "+ 511 x10HouseCode + x10DeviceNumber +" "+x10Command +") - "+(new Date()).toString()); 512 513 } 514 } 515 } 516 517 518 /** 519 * Executes the Specified Native OS application with the provided commandline 520 * parameters. This method blocks until the Executed app is complete. It also 521 * cleans up its sub-process and garbage collects. 522 * 523 * @param executableLocation is the path to the executable to run 524 * 525 * @param appParms and extra commandline parameters to tag onto the end of the 526 * commandline that gets executed. 527 * 528 * @return returns the return code from the executed app/process 529 * 530 * @see StreamGobbler 531 * @see java.lang.Runtime#getRuntime 532 **/ 533 private static int executeNativeApp(String executableLocation, 534 Vector appParms) 535 { 536 int retVal = -1; 537 int cmdParms = 0; 538 if (appParms != null) 539 cmdParms = appParms.size(); 540 String [] cmds = new String [cmdParms+1]; 541 cmds[0] = executableLocation; 542 System.out.print("AutoUpdateApp: Executing: "+ cmds[0]); 543 for (int i=1; i <= cmdParms; i++) 544 { 545 cmds[i] = (String) appParms.elementAt(i-1); 546 System.out.print(" " + cmds[i]); 547 } 548 System.out.println(""); 549 550 // Start the app... This starts a new process 551 try 552 { 553 Runtime runtime = Runtime.getRuntime(); 554 Process p = runtime.exec(cmds); 555 556 // capture any output we get 557 // any error message? 558 StreamGobbler errorGobbler = new 559 StreamGobbler(p.getErrorStream(), "RMT APP ERR:"); 560 561 // any output? 562 StreamGobbler outputGobbler = new 563 StreamGobbler(p.getInputStream(), "RMT APP OUT:"); 564 565 // kick them off 566 errorGobbler.start(); 567 outputGobbler.start(); 568 569 // now wait for the process to end 570 try 571 { 572 p.waitFor(); 573 } 574 catch (InterruptedException intEx) 575 { 576 // no biggie 577 } 578 retVal = p.exitValue(); 579 errorGobbler.finishedGobbling_ = true; 580 outputGobbler.finishedGobbling_ = true; 581 p.destroy(); 582 p = null; 583 runtime.gc(); 584 } 585 catch (IOException ioEx) 586 { 587 errorMsg_ = "ERROR: An IO exception occured while attempting " + 588 "execution of the " + executableLocation + " application."; 589 } 590 catch (SecurityException securityEx) 591 { 592 errorMsg_ = "ERROR: A Java Security Manager is in use and is " + 593 "restricting execution of the " + executableLocation + " application."; 594 } 595 596 return retVal; 597 } 598 599 600 /** 601 * Send a cycle email out to the existing class email addr. 602 **/ 603 private void sendAnEmail() 604 { 605 sendAnEmail(getEmailTo()); 606 } 607 608 609 /** 610 * Send a cycle email out. 611 **/ 612 private void sendAnEmail(String to) 613 { 614 sendAnEmail(to, "AliveURL Notification", "X10 Command Sent - "+currDate.toString()); 615 } 616 617 618 /** 619 * Send a cycle email out. 620 **/ 621 private void sendAnEmail(String to, String subjectToSend, String msgToSend) 622 { 623 boolean debug = false; 624 //String to = "tgutwin_sms@webarts.bc.ca"; 625 //String to = "tgutwin@webarts.bc.ca"; 626 String from = "tgutwin@webarts.bc.ca"; 627 String host = "aurora1.webarts.bc.ca"; 628 String msgText = msgToSend; 629 630 // create some properties and get the default Session 631 Properties props = new Properties(); 632 props.put("mail.smtp.host", host); 633 if (debug) 634 { 635 props.put("mail.debug", "true"); 636 } 637 638 Session session = Session.getDefaultInstance(props, null); 639 session.setDebug(debug); 640 641 try 642 { 643 // create a message 644 Message msg = new MimeMessage(session); 645 msg.setFrom(new InternetAddress(from)); 646 InternetAddress[] address = {new InternetAddress(to)}; 647 msg.setRecipients(Message.RecipientType.TO, address); 648 msg.setSubject(subjectToSend); 649 msg.setSentDate(new Date()); 650 // If the desired charset is known, you can use 651 // setText(text, charset) 652 msg.setText(msgText); 653 654 Transport.send(msg); 655 } 656 catch (MessagingException mex) 657 { 658 System.out.println("\n--Exception handling in AliveURL.java"); 659 660 mex.printStackTrace(); 661 System.out.println(); 662 Exception ex = mex; 663 do 664 { 665 if (ex instanceof SendFailedException) 666 { 667 SendFailedException sfex = (SendFailedException) ex; 668 Address[] invalid = sfex.getInvalidAddresses(); 669 if (invalid != null) 670 { 671 System.out.println(" ** Invalid Addresses"); 672 if (invalid != null) 673 { 674 for (int i = 0; i < invalid.length; i++) 675 { 676 System.out.println(" " + invalid[i]); 677 } 678 } 679 } 680 Address[] validUnsent = sfex.getValidUnsentAddresses(); 681 if (validUnsent != null) 682 { 683 System.out.println(" ** ValidUnsent Addresses"); 684 if (validUnsent != null) 685 { 686 for (int i = 0; i < validUnsent.length; i++) 687 { 688 System.out.println(" " + validUnsent[i]); 689 } 690 } 691 } 692 Address[] validSent = sfex.getValidSentAddresses(); 693 if (validSent != null) 694 { 695 System.out.println(" ** ValidSent Addresses"); 696 if (validSent != null) 697 { 698 for (int i = 0; i < validSent.length; i++) 699 { 700 System.out.println(" " + validSent[i]); 701 } 702 } 703 } 704 } 705 System.out.println(); 706 } while ((ex = ((MessagingException) ex).getNextException()) 707 != null); 708 } 709 710 } 711 712 /** 713 * Initializes the logOut_ Stream based on the outSpot specifired by the user. 714 */ 715 static private void initLogOut() 716 { 717 switch (outSpot_) 718 { 719 case FILE: 720 if (logFile_ != null) 721 { 722 try 723 { 724 logOut_ = new PrintStream(new FileOutputStream(logFile_), true); 725 } 726 catch (IOException ioEx) 727 { 728 STD_OUT.println("Error Creating Logfile:\n " + ioEx.getMessage()); 729 outSpot_ = CONSOLE; 730 initLogOut(); 731 } 732 } 733 else 734 { 735 outSpot_ = CONSOLE; 736 initLogOut(); 737 } 738 break; 739 case PIPE: 740 logOut_ = new PrintStream(userOut_, true); 741 break; 742 default: // default is CONSOLE 743 logOut_ = new PrintStream(STD_OUT, true); 744 } 745 } 746 747 /** 748 * Generic uncategorized log entry. 749 * 750 * @param value The String to dump into the Log. 751 */ 752 static private void logEntry(String value) 753 { 754 if (logOut_ != null ) 755 { 756 //value = createCurrentTimeStamp() + ":" + msgSpacing_ + value; 757 logOut_.println(value); 758 } 759 } 760 761 762 /** Plays the error music file */ 763 private void playErrorMusic() 764 { 765 tk.beep(); 766 tk.beep(); 767 if (errorMusic != null) 768 { 769 // System.out.println(" --> Nice Music URL"); 770 // play error music 771 playback = new Playback(errorMusic); 772 playback.start(); 773 } 774 else if (errorMusicFile != null) 775 { 776 // System.out.println(" --> Nice Music File"); 777 // play error music 778 playback = new Playback(errorMusicFile); 779 playback.start(); 780 } 781 } 782 783 784 /** 785 * A method to simply abstract the Try/Catch required to put the current 786 * thread to sleep for the specified time in ms. 787 * 788 * @param waitTime the sleep time in milli seconds (ms). 789 * @return boolean value specifying if the sleep completed (true) or 790 * was interupted (false). 791 */ 792 private static boolean mySleep(long waitTime) 793 { 794 boolean retVal = true; 795 796 /* 797 * BLOCK for the spec'd time 798 */ 799 try 800 { 801 Thread.sleep(waitTime); 802 } 803 catch (InterruptedException iex) 804 { 805 retVal = false; 806 } 807 return retVal; 808 } 809 810 811 /** 812 * The main program for the AliveURL class 813 * 814 * @param args The command line arguments 815 */ 816 public static void main(String[] args) 817 { 818 String emailAddr = null; 819 try 820 { 821 if (args.length > 0) 822 { 823 short options = 0; 824 logFile_ = new File(logFileName_); 825 initLogOut(); 826 827 // set up the proxy ONCE here for evermore. 828 AliveURL.initProxy(); 829 830 831 while (true) 832 { 833 emailAddr = null; 834 if (args[0].toUpperCase().startsWith("-M")) 835 { 836 // A music file was spec'd 837 options = 1; 838 if (args[0].substring(2).startsWith("http") || 839 args[0].substring(2).startsWith("ftp") || 840 args[0].substring(2).startsWith("file:/")) 841 { 842 try 843 { 844 errorMusic = new URL(args[0].substring(2)); 845 errorMusicFile = null; 846 // System.out.println("Got Our Error Music URL: " + 847 // errorMusic.toString()); 848 } 849 catch (MalformedURLException badUrl) 850 { 851 System.out.println("Can't Get ERROR MUSIC URL"); 852 errorMusic = null; 853 } 854 } 855 else 856 { 857 // assume it is a file path 858 try 859 { 860 errorMusicFile = new File(args[0].substring(2)); 861 } 862 catch (NullPointerException badUrl) 863 { 864 System.out.println("Can't Get ERROR MUSIC FILE"); 865 errorMusicFile = null; 866 } 867 } 868 } 869 else if (args[0].toUpperCase().startsWith("-E")) 870 { 871 options = 1; 872 emailAddr = args[0].substring(2); 873 } 874 else if (args.length >1 && args[1].toUpperCase().startsWith("-M")) 875 { 876 // A music file was spec'd 877 options = 2; 878 if (args[1].substring(2).startsWith("http") || 879 args[1].substring(2).startsWith("ftp") || 880 args[1].substring(2).startsWith("file:/")) 881 { 882 try 883 { 884 errorMusic = new URL(args[1].substring(2)); 885 errorMusicFile = null; 886 // System.out.println("Got Our Error Music URL: " + 887 // errorMusic.toString()); 888 } 889 catch (MalformedURLException badUrl) 890 { 891 System.out.println("Can't Get ERROR MUSIC URL"); 892 errorMusic = null; 893 } 894 } 895 else 896 { 897 // assume it is a file path 898 try 899 { 900 errorMusicFile = new File(args[1].substring(2)); 901 } 902 catch (NullPointerException badUrl) 903 { 904 System.out.println("Can't Get ERROR MUSIC FILE"); 905 errorMusicFile = null; 906 } 907 } 908 } 909 else if (args.length >1 && args[1].toUpperCase().startsWith("-E")) 910 { 911 options = 2; 912 emailAddr = args[1].substring(2); 913 } 914 else 915 { 916 // it was not the error music... so use it as a URL to check 917 try 918 { 919 if (useURL) 920 { 921 errorMusic = new URL(errorMusicUrlStr); 922 } 923 else 924 { 925 errorMusicFile = new File(errorMusicFileStr); 926 } 927 // System.out.println("Got Our Error Music URL."); 928 } 929 catch (MalformedURLException badUrl) 930 { 931 System.out.println("Can't Get ERROR MUSIC URL"); 932 errorMusic = null; 933 } 934 catch (NullPointerException badUrl) 935 { 936 System.out.println("Can't Get ERROR MUSIC FILE"); 937 errorMusicFile = null; 938 } 939 } 940 941 942 // now do the check! 943 int extraDelay = 0; 944 AliveURL checker = null; 945 URL url = null; 946 for (int i = options; i < args.length; i++) 947 { 948 url = new URL(args[i]); 949 checker = new AliveURL(url); 950 if (checker.getExternalScriptWasExecuted_() ) 951 // add an extra 10 minutes before checking again 952 extraDelay = EXTRA_DELAY_TIME; 953 } 954 System.out.println("----------------------------------------"+ 955 (extraDelay>0?" ExtraDelay="+extraDelay/1000:"")); 956 mySleep(checkDelay + extraDelay); 957 if (extraDelay>0 && checker != null) 958 { 959 if (emailAddr != null) 960 checker.sendAnEmail(emailAddr, "AliveURL Notification", "AliveURL Resuming Checking - "+(new Date()).toString()); 961 else if (areWeSendingEmail_) 962 checker.sendAnEmail(emailTo_, "AliveURL Notification", "AliveURL Resuming Checking - "+(new Date()).toString()); 963 checker.unsetExternalScriptWasExecuted_(); 964 } 965 extraDelay = 0; 966 checker = null; 967 System.gc(); 968 } 969 } 970 else 971 { 972 URL url = new URL("http://www.webarts.bc.ca"); 973 while (true) 974 { 975 try 976 { 977 if (useURL) 978 { 979 errorMusic = new URL(errorMusicUrlStr); 980 } 981 else 982 { 983 errorMusicFile = new File(errorMusicFileStr); 984 } 985 // System.out.println("Got Our Error Music URL."); 986 } 987 catch (MalformedURLException badUrl) 988 { 989 System.out.println("Can't Get ERROR MUSIC URL"); 990 errorMusic = null; 991 } 992 catch (NullPointerException badUrl) 993 { 994 System.out.println("Can't Get ERROR MUSIC FILE"); 995 errorMusicFile = null; 996 } 997 AliveURL checker = new AliveURL(url); 998 int extraDelay = 0; 999 if (checker.getExternalScriptWasExecuted_() ) 1000 extraDelay = EXTRA_DELAY_TIME; // add an extra 10 minutes before checking again 1001 System.out.println("----------------------------------------"); 1002 mySleep(checkDelay+extraDelay); 1003 if (extraDelay>0 && checker != null) 1004 { 1005 if (emailAddr != null) 1006 checker.sendAnEmail(emailAddr, "AliveURL Notification", "AliveURL Resuming Checking - "+(new Date()).toString()); 1007 else if (areWeSendingEmail_) 1008 checker.sendAnEmail(emailTo_, "AliveURL Notification", "AliveURL Resuming Checking - "+(new Date()).toString()); 1009 checker.unsetExternalScriptWasExecuted_(); 1010 } 1011 checker = null; 1012 extraDelay = 0; 1013 System.gc(); 1014 1015 } 1016 } 1017 } 1018 catch (MalformedURLException ex) 1019 { 1020 String msg = ex.getMessage(); 1021 System.out.println(msg); 1022 } 1023 } 1024 1025/* 1026 private static void initProxy2() 1027 { 1028 1029 boolean httpEnabled = areWeUsingProxy_; 1030 Properties sysProps = System.getProperties(); 1031 if (!httpEnabled) 1032 { 1033 sysProps.remove("proxySet"); 1034 sysProps.remove("proxyHost"); 1035 sysProps.remove("proxyPort"); 1036 sysProps.remove("http.proxyHost"); 1037 sysProps.remove("http.proxyPort"); 1038 sysProps.remove("http.nonProxyHosts"); 1039 Authenticator.setDefault(null); 1040 } 1041 else 1042 { 1043 if (sysProps.getProperty("http.proxySet") == null || 1044 sysProps.getProperty("http.proxySet").equals("")) 1045 System.setProperty("http.proxySet", DEFAULT_PROXY_SET); 1046 1047 if (sysProps.getProperty("http.proxyHost") == null || 1048 sysProps.getProperty("http.proxyHost").equals("")) 1049 System.setProperty("http.proxyHost", DEFAULT_PROXY_HOST); 1050 1051 if (sysProps.getProperty("http.proxyPort") == null || 1052 sysProps.getProperty("http.proxyPort").equals("")) 1053 System.setProperty("http.proxyPort", DEFAULT_PROXY_PORT); 1054 1055 if (sysProps.getProperty("http.nonProxyHosts") == null || 1056 sysProps.getProperty("http.nonProxyHosts").equals("")) 1057 System.setProperty("http.nonProxyHosts", DEFAULT_PROXY_NOPROXY); 1058 1059 // set proxy authentication 1060 String username = sysProps.getProperty("http.proxyUser"); 1061 String password = sysProps.getProperty("http.proxyPassword"); 1062 if (username == null || 1063 username.equals("")) 1064 username = ""; 1065 1066 if (password == null || 1067 password.equals("")) 1068 password = ""; 1069 1070 if(username == null || username.length()==0) 1071 { 1072 Authenticator.setDefault(new FirewallAuthenticator(null)); 1073 } 1074 else 1075 { 1076 PasswordAuthentication pw = new PasswordAuthentication( 1077 username,password.toCharArray() 1078 ); 1079 Authenticator.setDefault(new FirewallAuthenticator(pw)); 1080 } 1081 } 1082 } 1083 1084 1085 // FirewallAuthenticator class 1086 static class FirewallAuthenticator extends Authenticator 1087 { 1088 PasswordAuthentication pw; 1089 1090 public FirewallAuthenticator(PasswordAuthentication pw) 1091 { 1092 this.pw = pw; 1093 } 1094 1095 protected PasswordAuthentication getPasswordAuthentication() 1096 { 1097 return pw; 1098 } 1099 } 1100*/ 1101 1102 /** 1103 * Write data to the OutputChannel. 1104 * 1105 * @author unknowntgutwin 1106 */ 1107 public class Playback implements Runnable 1108 { 1109 1110 final static int BUFFER_SIZE = 16384; 1111 SourceDataLine line; 1112 Thread thread; 1113 URL urlToPlay = null; 1114 File fileToPlay = null; 1115 AudioInputStream audioInputStream = null; 1116 1117 1118 /** 1119 * Constructor for the Playback object 1120 * 1121 * @param url Description of the Parameter 1122 */ 1123 public Playback(URL url) 1124 { 1125 urlToPlay = url; 1126 } 1127 1128 1129 /** 1130 * Constructor for the Playback object 1131 * 1132 * @param f Description of the Parameter 1133 */ 1134 public Playback(File f) 1135 { 1136 fileToPlay = f; 1137 } 1138 1139 1140 /** 1141 * Description of the Method 1142 * 1143 * @param msg Description of the Parameter 1144 */ 1145 private void reportStatus(String msg) 1146 { 1147 if (msg != null) 1148 { 1149 System.out.println(msg); 1150 } 1151 } 1152 1153 1154 /** 1155 * Description of the Method 1156 * 1157 * @param file Description of the Parameter 1158 */ 1159 public void createAudioInputStream(File file) 1160 { 1161 if (file != null && file.isFile()) 1162 { 1163 try 1164 { 1165 createAudioInputStream(file.toURL()); 1166 } 1167 catch (MalformedURLException ex) 1168 { 1169 audioInputStream = null; 1170 } 1171 } 1172 else 1173 { 1174 reportStatus("Audio file required."); 1175 } 1176 } 1177 1178 1179 /** 1180 * Description of the Method 1181 * 1182 * @param url Description of the Parameter 1183 */ 1184 public void createAudioInputStream(URL url) 1185 { 1186 if (url != null) 1187 { 1188 try 1189 { 1190 // reportStatus("\nLoading AudioURL Stream " + url); 1191 InputStream urlStream = url.openStream(); 1192 // reportStatus(" InputStream is " + (urlStream==null?"null":"Valid")); 1193 audioInputStream = AudioSystem.getAudioInputStream(urlStream); 1194 } 1195 catch (UnsupportedAudioFileException ex) 1196 { 1197 reportStatus(ex.toString()); 1198 } 1199 catch (IOException ex) 1200 { 1201 ex.printStackTrace(); 1202 } 1203 } 1204 else 1205 { 1206 reportStatus("Audio file required."); 1207 } 1208 } 1209 1210 1211 /** Description of the Method */ 1212 public void start() 1213 { 1214 thread = new Thread(this); 1215 thread.setName("Playback"); 1216 thread.start(); 1217 } 1218 1219 1220 /** Description of the Method */ 1221 public void stop() 1222 { 1223 thread = null; 1224 } 1225 1226 1227 /** 1228 * Description of the Method 1229 * 1230 * @param message Description of the Parameter 1231 */ 1232 private void shutDown(String message) 1233 { 1234 if (message != null) 1235 { 1236 System.err.println(message); 1237 } 1238 } 1239 1240 1241 /** Main processing method for the Playback object */ 1242 public void run() 1243 { 1244 1245 // reload the file if loaded by file 1246 if (fileToPlay != null) 1247 { 1248 createAudioInputStream(fileToPlay); 1249 } 1250 1251 // reload the file if loaded by file 1252 if (urlToPlay != null) 1253 { 1254 createAudioInputStream(urlToPlay); 1255 } 1256 1257 // make sure we have something to play 1258 if (audioInputStream == null) 1259 { 1260 shutDown("No loaded audio to play back"); 1261 return; 1262 } 1263 // reset to the beginnning of the stream 1264 try 1265 { 1266 audioInputStream.reset(); 1267 } 1268 catch (Exception e) 1269 { 1270 shutDown("Unable to reset the stream\n" + e); 1271 return; 1272 } 1273 1274 // get an AudioInputStream of the desired format for playback 1275 AudioFormat format = audioInputStream.getFormat(); 1276 AudioInputStream playbackInputStream = AudioSystem.getAudioInputStream(format, audioInputStream); 1277 1278 if (playbackInputStream == null) 1279 { 1280 shutDown("Unable to convert stream of format " + audioInputStream + " to format " + format); 1281 return; 1282 } 1283 1284 // define the required attributes for our line, 1285 // and make sure a compatible line is supported. 1286 1287 DataLine.Info info = new DataLine.Info(SourceDataLine.class, 1288 format); 1289 if (!AudioSystem.isLineSupported(info)) 1290 { 1291 shutDown("Line matching " + info + " not supported."); 1292 return; 1293 } 1294 1295 // get and open the source data line for playback. 1296 1297 try 1298 { 1299 line = (SourceDataLine) AudioSystem.getLine(info); 1300 line.open(format, BUFFER_SIZE); 1301 } 1302 catch (LineUnavailableException ex) 1303 { 1304 shutDown("Unable to open the line: " + ex); 1305 return; 1306 } 1307 1308 // play back the captured audio data 1309 1310 int frameSizeInBytes = format.getFrameSize(); 1311 int bufferLengthInFrames = line.getBufferSize() / 8; 1312 int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes; 1313 byte[] data = new byte[bufferLengthInBytes]; 1314 int numBytesRead = 0; 1315 1316 // start the source data line 1317 line.start(); 1318 1319 while (thread != null) 1320 { 1321 try 1322 { 1323 if ((numBytesRead = playbackInputStream.read(data)) == -1) 1324 { 1325 break; 1326 } 1327 int numBytesRemaining = numBytesRead; 1328 while (numBytesRemaining > 0) 1329 { 1330 numBytesRemaining -= line.write(data, 0, numBytesRemaining); 1331 } 1332 } 1333 catch (Exception e) 1334 { 1335 shutDown("Error during playback: " + e); 1336 break; 1337 } 1338 } 1339 // we reached the end of the stream. let the data play out, then 1340 // stop and close the line. 1341 if (thread != null) 1342 { 1343 line.drain(); 1344 } 1345 line.stop(); 1346 line.close(); 1347 line = null; 1348 shutDown(null); 1349 } 1350 1351 } 1352 // End class Playback 1353} 1354 1355