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.29
Committed: Sun May 12 15:49:50 2002 UTC (22 years ago) by tdb
Branch: MAIN
Changes since 1.28: +4 -3 lines
Log Message:
Send key *before* we add it to the key manager. The thinking behind this is
that if the connection to the host fails, for whatever reason, we won't put
the new key in the keymanager. This seems safer. But, as these two
operations can't be fully atomic, it's inevitable that at some point a
packet will arrive with an older or newer key than that in the key manager.

File Contents

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