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

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2 tdb 1.25 package uk.org.iscream.cms.server.filter;
3 tdb 1.1
4     //---IMPORTS---
5 tdb 1.25 import uk.org.iscream.cms.server.core.*;
6     import uk.org.iscream.cms.server.filter.*;
7     import uk.org.iscream.cms.server.componentmanager.*;
8 tdb 1.1 import java.net.Socket;
9     import java.io.*;
10 tdb 1.27 import java.util.Random;
11 tdb 1.25 import uk.org.iscream.cms.server.util.*;
12 tdb 1.1
13     /**
14 ajm 1.10 * This provides Host heartbeat functionality
15 tdb 1.1 *
16 tdb 1.26 * @author $Author: tdb $
17 tdb 1.29 * @version $Id: TCPReaderInit.java,v 1.28 2002/03/21 22:09:13 tdb Exp $
18 tdb 1.1 */
19     class TCPReaderInit extends Thread {
20    
21     //---FINAL ATTRIBUTES---
22    
23     /**
24     * The current CVS revision of this class
25     */
26 tdb 1.29 public final String REVISION = "$Revision: 1.28 $";
27 tdb 1.1
28     //---STATIC METHODS---
29    
30     //---CONSTRUCTORS---
31 tdb 1.13
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 tdb 1.11 public TCPReaderInit(Socket socket, Queue queue) throws IOException {
40 tdb 1.21 // set the Thread name
41     setName("filter.TCPReaderInit");
42    
43 tdb 1.1 _socket = socket;
44 tdb 1.11 _queue = queue;
45 tdb 1.13 // setup the reader & writer
46 tdb 1.1 _socketIn = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
47 tdb 1.15 _socketOut = new PrintWriter(_socket.getOutputStream(), true);
48 tdb 1.8 _logger.write(toString(), Logger.SYSINIT, "created");
49 tdb 1.1 }
50    
51     //---PUBLIC METHODS---
52 tdb 1.13
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 tdb 1.1 public void run() {
59     try {
60 tdb 1.27 // 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 tdb 1.2
67 tdb 1.22 // try for HEARTBEAT
68 tdb 1.23 getInBound("HEARTBEAT");
69 tdb 1.22 _socketOut.println("OK");
70 tdb 1.3
71 tdb 1.27 // 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 tdb 1.29 // send key to host
103     _socketOut.println(key);
104 tdb 1.27 // 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 tdb 1.3 }
113    
114 tdb 1.27 // respond to ENDHEARTBEAT
115 tdb 1.22 _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 tdb 1.6
120 ajm 1.16 // run the service checks for this host
121 ajm 1.17 _logger.write(toString(), Logger.DEBUG, "Running service checks");
122 ajm 1.16 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 tdb 1.11 _queue.add(xml);
129 tdb 1.1
130     } catch (Exception e) {
131 tdb 1.20 _logger.write(toString(), Logger.ERROR, "ERROR: " + e);
132 tdb 1.1 }
133    
134     // Disconnect streams & socket
135     try {
136     _socketIn.close();
137     _socketOut.close();
138     _socket.close();
139     } catch (IOException e) {
140 tdb 1.8 _logger.write(toString(), Logger.ERROR, "exception on socket close");
141 tdb 1.1 }
142 tdb 1.14 _logger.write(toString(), Logger.DEBUG, "finished");
143 tdb 1.1 }
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 tdb 1.25 * This uses the uk.org.iscream.cms.server.util.NameFormat class
150 ajm 1.10 * to format the toString()
151     *
152 tdb 1.1 * @return the name of this class and its CVS revision
153     */
154     public String toString() {
155 ajm 1.10 return FormatName.getName(
156     _name,
157     getClass().getName(),
158     REVISION);
159 tdb 1.1 }
160    
161     //---PRIVATE METHODS---
162 tdb 1.22
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 tdb 1.26 throw new IOException("protocol error from "+_socket.getInetAddress().getHostName()+" - expected:"+expected+" got:" + inBound);
169 tdb 1.22 }
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 tdb 1.27
185 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
186    
187     //---ATTRIBUTES---
188    
189 ajm 1.10 /**
190     * A reference to the configuration manager
191     */
192 tdb 1.8 ConfigurationManager _configManager = ReferenceManager.getInstance().getCM();
193 ajm 1.10
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 tdb 1.1 Socket _socket;
215 ajm 1.10
216     /**
217     * The input from the socket
218     */
219 tdb 1.1 BufferedReader _socketIn;
220 ajm 1.10
221     /**
222     * The output from the socket
223     */
224 tdb 1.1 PrintWriter _socketOut;
225 ajm 1.10
226     /**
227 tdb 1.11 * A reference to our Queue
228 ajm 1.10 */
229 tdb 1.11 Queue _queue;
230 tdb 1.27
231 tdb 1.1 //---STATIC ATTRIBUTES---
232    
233     }