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 }
|