ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/filter/TCPReaderInit.java
Revision: 1.33
Committed: Mon Feb 24 20:18:49 2003 UTC (21 years, 2 months ago) by tdb
Branch: MAIN
CVS Tags: HEAD
Changes since 1.32: +2 -2 lines
State: FILE REMOVED
Log Message:
Fairly major commit. This will break the current version of ihost, but this
had to be done really to give Pete something to test the new ihost against.

The main change here is removal of the TCP Heartbeat functionality from the
filter. This meant the following features stopped working :-
  - Heartbeat testing
  - Configuration checking
  - Service checks

The heartbeat testing, specifically the monitor, now looks at the presence
of UDP packets instead. Before it just looked for the presence of a TCP
heartbeat packet, so the change their is fairly negligible. Of course this
means heartbeat testing now relies on the UDP working... but I don't see
this as a problem.

Configuration checking has been repositioned in to the filtermanager. This
is a backwards compatible change - the filtermanager should still perform
as it should for older hosts. But now there's an extra command to check the
configuration is up-to-date, with a similar format to the old TCP protocol
in the filter. (although we may optimise this soon)

The service checks are broken. This isn't a major issue for us as they were
pretty useless in the first place. The concept is good, but the checks are
just far too primitive. I expect at some point I'll work on a seperate
component that just monitors services, which will replace this function.

Further changes in the server include removal of the key checking code,
as this relied on a bolt on to the TCP heartbeat protocol to ship the
key. This got more akward than originally planned, so I'm happy to drop the
idea. In the long term we hope to replace this with a public key systems
for signing and even encryption.

Finally, general tidy up to remove other bits of code that check for
TCP heartbeat packets when they don't need to any more.

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org.uk
4 * Copyright (C) 2000-2002 i-scream
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 //---PACKAGE DECLARATION---
22 package uk.org.iscream.cms.server.filter;
23
24 //---IMPORTS---
25 import uk.org.iscream.cms.server.core.*;
26 import uk.org.iscream.cms.server.filter.*;
27 import uk.org.iscream.cms.server.componentmanager.*;
28 import java.net.Socket;
29 import java.io.*;
30 import java.util.Random;
31 import uk.org.iscream.cms.util.*;
32
33 /**
34 * This provides Host heartbeat functionality
35 *
36 * @author $Author: tdb $
37 * @version $Id: TCPReaderInit.java,v 1.32 2003/02/05 16:43:47 tdb Exp $
38 */
39 class TCPReaderInit extends Thread {
40
41 //---FINAL ATTRIBUTES---
42
43 /**
44 * The current CVS revision of this class
45 */
46 public final String REVISION = "$Revision: 1.32 $";
47
48 //---STATIC METHODS---
49
50 //---CONSTRUCTORS---
51
52 /**
53 * Construct a new TCPReaderInit.
54 *
55 * @param socket the Socket to which the host is connected
56 * @param queue the Queue to which we'll add data
57 * @throws IOException if something goes badly wrong
58 */
59 public TCPReaderInit(Socket socket, Queue queue) throws IOException {
60 // set the Thread name
61 setName("filter.TCPReaderInit");
62
63 _socket = socket;
64 _queue = queue;
65 // setup the reader & writer
66 _socketIn = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
67 _socketOut = new PrintWriter(_socket.getOutputStream(), true);
68 _logger.write(toString(), Logger.SYSINIT, "created");
69 }
70
71 //---PUBLIC METHODS---
72
73 /**
74 * Main run method. Will communicate with the host, inform it
75 * if any updates to it's configuration are needed, and send
76 * a heartbeat packet into the system.
77 */
78 public void run() {
79 try {
80 // get an instance of the KeyManager
81 KeyManager keyman = KeyManager.getInstance();
82
83 // get some information about the host
84 String hostname = _socket.getInetAddress().getHostName().toLowerCase();
85 String ipadd = _socket.getInetAddress().getHostAddress();
86
87 // try for HEARTBEAT
88 getInBound("HEARTBEAT");
89 _socketOut.println("OK");
90
91 // look for a command:
92 // CONFIG - to check config
93 // KEY - to get the key
94 // ENDHEARTBEAT - to finish
95 String cmd = getInBound();
96 while(!cmd.equals("ENDHEARTBEAT")) {
97 if(cmd.equals("CONFIG")) {
98 // respond to CONFIG
99 _socketOut.println("OK");
100
101 // try for {filelist}
102 String filelist = getInBound();
103 _socketOut.println("OK");
104
105 // try for {lastModified}
106 String lastModified = getInBound();
107 // check to see if a config update has happen
108 boolean newConfig = _configManager.isModified(filelist, Long.parseLong(lastModified));
109 if(newConfig) {
110 // new config !
111 _socketOut.println("ERROR");
112 }
113 else {
114 // nothing has changed
115 _socketOut.println("OK");
116 }
117 }
118 else if(cmd.equals("KEY")) {
119 // repsond to KEY
120 // generate a key
121 String key = keyman.genKey();
122 // send key to host
123 _socketOut.println(key);
124 // add it to the key manager
125 keyman.addKey(hostname, key);
126 }
127 else {
128 _socketOut.println("ERROR");
129 }
130 // get the next command
131 cmd = getInBound();
132 }
133
134 // respond to ENDHEARTBEAT
135 _socketOut.println("OK");
136
137 // work out some information for our heartbeat packet
138 String date = new Long(System.currentTimeMillis()/((long) 1000)).toString(); //seconds
139
140 // run the service checks for this host
141 _logger.write(toString(), Logger.DEBUG, "Running service checks");
142 String checks = PluginServiceCheckManager.getInstance().runServiceChecks(hostname);
143
144 // build the heartbeat packet
145 String xml = "<packet type=\"heartbeat\" machine_name=\""+hostname+"\" date=\""+date+"\" ip=\""+ipadd+"\">" + checks + "</packet>";
146
147 // get it to be sent on
148 _queue.add(xml);
149
150 } catch (Exception e) {
151 _logger.write(toString(), Logger.ERROR, "ERROR: " + e);
152 }
153
154 // Disconnect streams & socket
155 try {
156 _socketIn.close();
157 _socketOut.close();
158 _socket.close();
159 } catch (IOException e) {
160 _logger.write(toString(), Logger.ERROR, "exception on socket close");
161 }
162 _logger.write(toString(), Logger.DEBUG, "finished");
163 }
164
165 /**
166 * Overrides the {@link java.lang.Object#toString() Object.toString()}
167 * method to provide clean logging (every class should have this).
168 *
169 * This uses the uk.org.iscream.cms.util.NameFormat class
170 * to format the toString()
171 *
172 * @return the name of this class and its CVS revision
173 */
174 public String toString() {
175 return FormatName.getName(
176 _name,
177 getClass().getName(),
178 REVISION);
179 }
180
181 //---PRIVATE METHODS---
182
183 private String getInBound(String expected) throws IOException {
184 // grab the input
185 String inBound = getInBound();
186 // check if it's what we're expecting
187 if(!inBound.equals(expected)) {
188 throw new IOException("protocol error from "+_socket.getInetAddress().getHostName()+" - expected:"+expected+" got:" + inBound);
189 }
190 // it should be ok then
191 return inBound;
192 }
193
194 private String getInBound() throws IOException {
195 // grab the input
196 String inBound = _socketIn.readLine();
197 // check for null's, likely disconnection
198 if(inBound == null) {
199 throw new IOException("got null from host, maybe it died");
200 }
201 // it's a valid message it seems
202 return inBound;
203 }
204
205 //---ACCESSOR/MUTATOR METHODS---
206
207 //---ATTRIBUTES---
208
209 /**
210 * A reference to the configuration manager
211 */
212 ConfigurationManager _configManager = ReferenceManager.getInstance().getCM();
213
214 /**
215 * This is the friendly identifier of the
216 * component this class is running in.
217 * eg, a Filter may be called "filter1",
218 * If this class does not have an owning
219 * component, a name from the configuration
220 * can be placed here. This name could also
221 * be changed to null for utility classes.
222 */
223 private String _name = FilterMain.NAME;
224
225 /**
226 * This holds a reference to the
227 * system logger that is being used.
228 */
229 private Logger _logger = ReferenceManager.getInstance().getLogger();
230
231 /**
232 * The socket we are talking on
233 */
234 Socket _socket;
235
236 /**
237 * The input from the socket
238 */
239 BufferedReader _socketIn;
240
241 /**
242 * The output from the socket
243 */
244 PrintWriter _socketOut;
245
246 /**
247 * A reference to our Queue
248 */
249 Queue _queue;
250
251 //---STATIC ATTRIBUTES---
252
253 }