Source code for /engineering/autohit-2003/src/autohit/server/service/CommandService.javaOriginal file CommandService.java
   1 /**
   2  * AUTOHIT 2003
   3  * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
   4  * 
   5  * This program is free software; you can redistribute it and/or modify 
   6  * it under the terms of the GNU General Public License as published by 
   7  * the Free Software Foundation; either version 2 of the License, or (at
   8  * your option) any later version.
   9  * This program is distributed in the hope that it will be useful, but
  10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12  * more details.
  13  * 
  14  * You should have received a copy of the GNU General Public License along
  15  * with this program; if not, write to the Free Software Foundation, Inc.,
  16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17  *
  18  * Additional license information can be found in the documentation.
  19  * @author Erich P Gatejen
  20  */
  21 package autohit.server.service;
  22 
  23 import java.util.Enumeration;
  24 
  25 import autohit.common.AutohitProperties;
  26 import autohit.common.channels.Atom;
  27 import autohit.common.channels.Channel;
  28 import autohit.common.channels.ChannelException;
  29 import autohit.common.channels.Controller;
  30 import autohit.common.channels.QueuedDrain;
  31 import autohit.common.channels.SimpleChannel;
  32 import autohit.server.ServerException;
  33 import autohit.server.command.CommandAtom;
  34 import autohit.server.command.CommandServerLocal;
  35 
  36 /**
  37  * Command service.
  38  * <p>
  39  * 
  40  * @author Erich P. Gatejen
  41  * @version 1.0 <i>Version History</i><code>EPG - Initial - 16SEP03</code>
  42  */
  43 public class CommandService extends Service {
  44 
  45 	final private static int ACCEPT_TIMEOUT = 1000;
  46 	final private static int CLEANUP_THRESHOLD = 200;
  47 
  48 	/**
  49 	 *  Channel stuff */
  50 	private Channel commandChannel;
  51 	private QueuedDrain queue;
  52 
  53 	/**
  54 	 *  Server stuff */
  55 	CommandServerLocal cserver;
  56 
  57 	/**
  58 	 *  Default constructor */
  59 	public CommandService() {
  60 		super();
  61 	}
  62 
  63 	/**
  64 	 * Complete construction. This will be called when the VM is initialized. */
  65 	public void construct() throws ServiceException {
  66 
  67 		try {
  68 			// Build the drain queue
  69 			queue = new QueuedDrain();
  70 			queue.init(AutohitProperties.COMMAND_SERVER_DRAIN_NAME);
  71 
  72 			// Build the command channel
  73 			commandChannel = new SimpleChannel();
  74 			commandChannel.register(AutohitProperties.COMMAND_SERVER_DRAIN, queue);
  75 			commandChannel.requestLevel(AutohitProperties.COMMAND_SERVER_DRAIN, Atom.P_ALL);
  76 			commandChannel.requestType(AutohitProperties.COMMAND_SERVER_DRAIN, Atom.TYPE_CONTROL);
  77 
  78 			// Register it
  79 			Controller.register(AutohitProperties.COMMAND_SERVER_STATION, commandChannel);
  80 
  81 			// command server
  82 			cserver = new CommandServerLocal();
  83 			cserver.init(sc);
  84 
  85 		} catch (Exception ee) {
  86 			throw new ServiceException(
  87 				"Failed constructing CommandService.  message=" + ee.getMessage(),
  88 				ServiceException.CODE_SERVICE_STARTUP_FAULT);
  89 		}
  90 	}
  91 
  92 	/**
  93 	 * Fast loop. We spend most of our time waiting for connections. Cycle back
  94 	 * to VM only after an accept or a timeout.
  95 	 * 
  96 	 * @see autohit.vm.VMException
  97 	 */
  98 	public void execute() throws ServiceException {
  99 
 100 		CommandAtom ca = null;
 101 		boolean go = true;
 102 		String response = "unknown";
 103 
 104 		// live until the command server throws an exception
 105 		while (go) {
 106 
 107 			try {
 108 
 109 				// Get command
 110 				ca = (CommandAtom) queue.block();
 111 
 112 				// Dispatch
 113 				response = cserver.execute(ca);
 114 
 115 				// Handle response
 116 				// burn the response for now
 117 
 118 			} catch (ChannelException ce) {
 119 				if (ce.numeric==ChannelException.CODE_CHANNEL_INTERRUPTED) {
 120 					throw new ServiceException(
 121 						"Service intterupted by channel.  Halting.  code["
 122 							+ ce.numeric
 123 							+ "] "
 124 							+ ce.getMessage(),
 125 						ServiceException.CODE_SERVICE_INTENTIONAL_HALT,
 126 						ce);	
 127 				} else {
 128 					throw new ServiceException(
 129 						"Service FAULT in CommandService caused by Channel problem.  code["
 130 							+ ce.numeric
 131 							+ "] "
 132 							+ ce.getMessage(),
 133 						ServiceException.CODE_SERVICE_GENERAL_FAULT,
 134 						ce);		
 135 				}
 136 			} catch (ServerException se) {
 137 				switch (se.numeric) {
 138 
 139 					case ServerException.CODE_COMMAND_FAULT :
 140 						sc.getRootLogger().error(
 141 							"Command Service FAULT.  The service is now defunct.  code["
 142 								+ se.numeric
 143 								+ "] "
 144 								+ se.getMessage(),
 145 							se.numeric);
 146 						throw new ServiceException(
 147 							"Service FAULT in CommandService.  code[" + se.numeric + "] " + se.getMessage(),
 148 							ServiceException.CODE_SERVICE_GENERAL_FAULT,
 149 							se);
 150 
 151 					case ServerException.CODE_COMMAND_ERROR :
 152 					default :
 153 						sc.getRootLogger().error(
 154 							"Command Service ERROR.  Trying to continue.  code[" + se.numeric + "] " + se.getMessage(),
 155 							se.numeric);
 156 						break;
 157 				}
 158 
 159 			} // end catch
 160 		} // end while
 161 
 162 	} // end execute()
 163 
 164 	/**
 165 	 * Complete destroy. This will be called when the VM is finalizing. */
 166 	public void destruct() throws ServiceException {
 167 
 168 		try {
 169 			// remove injectors and drains
 170 			commandChannel.removeDrain(AutohitProperties.COMMAND_SERVER_DRAIN);
 171 
 172 			Object thingthang;
 173 			for (Enumeration e = commandChannel.enumInjector(); e.hasMoreElements();) {
 174 				thingthang = e.nextElement();
 175 				commandChannel.removeInjector((String) thingthang);
 176 			}
 177 		} catch (Exception efc) { //dont care
 178 		}
 179 
 180 		// Unregister channel
 181 		try {
 182 			Controller.remove(AutohitProperties.COMMAND_SERVER_STATION);
 183 		} catch (Exception eee) {
 184 			// don't care. probably tearing down the server anyway
 185 		}
 186 	} // end destruct
 187 
 188 }