ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/filtermanager/HostInit.java
Revision: 1.35
Committed: Mon Feb 24 20:18:50 2003 UTC (21 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.34: +103 -71 lines
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

# User Rev Content
1 tdb 1.30 /*
2     * i-scream central monitoring system
3 tdb 1.32 * http://www.i-scream.org.uk
4 tdb 1.30 * 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 tdb 1.1 //---PACKAGE DECLARATION---
22 tdb 1.28 package uk.org.iscream.cms.server.filtermanager;
23 tdb 1.1
24     //---IMPORTS---
25 tdb 1.28 import uk.org.iscream.cms.server.core.*;
26     import uk.org.iscream.cms.server.filter.*;
27 tdb 1.34 import uk.org.iscream.cms.util.*;
28 tdb 1.28 import uk.org.iscream.cms.server.componentmanager.*;
29 tdb 1.18 import java.net.*;
30 tdb 1.1 import java.io.*;
31 tdb 1.22 import java.util.*;
32 tdb 1.1
33     /**
34 tdb 1.11 * Handles setting up a host.
35 ajm 1.12 * This class provides a host with appropriate configuration
36     * and a reference to a Filter to which it should pass data.
37 tdb 1.1 *
38 tdb 1.29 * @author $Author: tdb $
39 tdb 1.35 * @version $Id: HostInit.java,v 1.34 2003/02/05 16:43:47 tdb Exp $
40 tdb 1.1 */
41     class HostInit extends Thread {
42    
43     //---FINAL ATTRIBUTES---
44    
45     /**
46     * The current CVS revision of this class
47     */
48 tdb 1.35 public final String REVISION = "$Revision: 1.34 $";
49 tdb 1.1
50     //---STATIC METHODS---
51    
52     //---CONSTRUCTORS---
53    
54 tdb 1.15 /**
55     * Construct a new HostInit.
56     *
57     * @param socket The socket to which the host is connected
58     */
59 tdb 1.11 public HostInit(Socket socket) throws IOException {
60 tdb 1.25 // set the Thread name
61     setName("filtermanager.HostInit");
62    
63 tdb 1.1 _socket = socket;
64 tdb 1.15 // setup reader & writer
65 tdb 1.1 _socketIn = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
66 tdb 1.16 _socketOut = new PrintWriter(_socket.getOutputStream(), true);
67 tdb 1.11 _logger.write(toString(), Logger.SYSINIT, "created");
68 tdb 1.1 }
69    
70     //---PUBLIC METHODS---
71    
72 tdb 1.15 /**
73     * Main method in this class, which handles communicating with
74     * the host to determine it's setup.
75     */
76 tdb 1.1 public void run() {
77 tdb 1.26 // get a hook on the config proxy
78     ConfigurationProxy cp = ConfigurationProxy.getInstance();
79     // this is our config name
80     String configName = "Host." + _socket.getInetAddress().getHostName().toLowerCase();
81 tdb 1.1 try {
82 tdb 1.35 // look for a command:
83     // STARTCONFIG - to get a configuration
84     // CHECKCONFIG - to check a configuration
85     // END - to finish
86     String cmd = getInBound();
87     while(!cmd.equals("END")) {
88     if(cmd.equals("STARTCONFIG")) {
89     // respond to STARTCONFIG
90     _socketOut.println("OK");
91    
92     // try for LASTMODIFIED
93     getInBound("LASTMODIFIED");
94     _socketOut.println(cp.getLastModified(configName));
95    
96     // try for FILELIST
97     getInBound("FILELIST");
98     _socketOut.println(cp.getFileList(configName));
99    
100     // try for FQDN
101     getInBound("FQDN");
102     _socketOut.println(_socket.getInetAddress().getHostName().toLowerCase());
103    
104     // get properties
105     String reqProperty = getInBound();
106     while(!reqProperty.equals("ENDCONFIG")) {
107     // get the property
108     try {
109     String returnedProperty = cp.getProperty(configName, "Host."+reqProperty);
110     _socketOut.println(returnedProperty);
111     } catch (PropertyNotFoundException e) {
112     _socketOut.println("ERROR");
113     }
114     // get the next request
115     reqProperty = _socketIn.readLine();
116     }
117     _logger.write(toString(), Logger.SYSMSG, "configured host");
118     _socketOut.println("OK");
119    
120     // get filter reference
121     getInBound("FILTER");
122     // send info
123     String filterList = cp.getProperty(configName, "Host.filter");
124     FilterInfo filterInfoRef = null;
125     String filter = null;
126     StringTokenizer st = new StringTokenizer(filterList, ";");
127     while (filterInfoRef==null && st.hasMoreTokens()) {
128     filter = st.nextToken();
129     _logger.write(toString(), Logger.DEBUG, " looking for filter- " + filter);
130     try {
131     filterInfoRef = FilterInfoHelper.narrow(ReferenceManager.getInstance().getCORBARef("iscream.FilterInfo\\." + filter));
132     } catch (ComponentCORBAException e) {
133     _logger.write(toString(), Logger.DEBUG, " unable to find filter- " + filter);
134     }
135     }
136    
137     // hopefully we found a filter
138     if(filterInfoRef != null) {
139     _logger.write(toString(), Logger.DEBUG, " found filter- " + filter);
140     try {
141     // tell the host about it...
142     _socketOut.println(filterInfoRef.getHostName() + ";"
143     + filterInfoRef.getUDPPort());
144     }
145     catch(org.omg.CORBA.COMM_FAILURE e) {
146     // failed to talk to filter, lets signal an error
147     _socketOut.println("ERROR");
148     throw new IOException("error communicating with filter - " + e);
149     }
150     }
151     else {
152     // ...or throw a wobbly (and tell the host!)
153     _socketOut.println("ERROR");
154     throw new IOException("unable to find filter for host");
155     }
156    
157     }
158     else if(cmd.equals("CHECKCONFIG")) {
159     // respond to CHECKCONFIG
160     _socketOut.println("OK");
161    
162     // try for {filelist}
163     String filelist = getInBound();
164     _socketOut.println("OK");
165    
166     // try for {lastModified}
167     String lastModified = getInBound();
168     // check to see if a config update has happen
169     boolean newConfig = _configManager.isModified(filelist, Long.parseLong(lastModified));
170     if(newConfig) {
171     // new config !
172     _socketOut.println("ERROR");
173     }
174     else {
175     // nothing has changed
176     _socketOut.println("OK");
177     }
178     }
179     else {
180 tdb 1.2 _socketOut.println("ERROR");
181 tdb 1.4 }
182 tdb 1.35 // get the next command
183     cmd = getInBound();
184 tdb 1.1 }
185 tdb 1.35 // respond to END
186 tdb 1.26 _socketOut.println("OK");
187 tdb 1.1
188     } catch (Exception e) {
189 tdb 1.17 _logger.write(toString(), Logger.ERROR, "ERROR - " + e);
190 tdb 1.1 }
191    
192     // Disconnect streams & socket
193     try {
194     _socketIn.close();
195     _socketOut.close();
196     _socket.close();
197     } catch (IOException e) {
198 tdb 1.11 _logger.write(toString(), Logger.ERROR, "exception on socket close");
199 tdb 1.1 }
200 tdb 1.11 _logger.write(toString(), Logger.SYSMSG, "finished");
201 tdb 1.1 }
202    
203     /**
204     * Overrides the {@link java.lang.Object#toString() Object.toString()}
205     * method to provide clean logging (every class should have this).
206     *
207 tdb 1.34 * This uses the uk.org.iscream.cms.util.NameFormat class
208 ajm 1.12 * to format the toString()
209     *
210 tdb 1.1 * @return the name of this class and its CVS revision
211     */
212     public String toString() {
213 ajm 1.12 return FormatName.getName(
214     _name,
215 ajm 1.13 getClass().getName(),
216 ajm 1.12 REVISION);
217 tdb 1.1 }
218    
219     //---PRIVATE METHODS---
220 tdb 1.26
221     private String getInBound(String expected) throws IOException {
222     // grab the input
223     String inBound = getInBound();
224     // check if it's what we're expecting
225     if(!inBound.equals(expected)) {
226     throw new IOException("protocol error - expected:"+expected+" got:" + inBound);
227     }
228     // it should be ok then
229     return inBound;
230     }
231    
232     private String getInBound() throws IOException {
233     // grab the input
234     String inBound = _socketIn.readLine();
235     // check for null's, likely disconnection
236     if(inBound == null) {
237     throw new IOException("got null from host, maybe it died");
238     }
239     // it's a valid message it seems
240     return inBound;
241     }
242 tdb 1.1
243     //---ACCESSOR/MUTATOR METHODS---
244    
245     //---ATTRIBUTES---
246    
247 tdb 1.11 /**
248 ajm 1.12 * This holds a reference to the
249     * system logger that is being used.
250 tdb 1.11 */
251 ajm 1.12 private Logger _logger = ReferenceManager.getInstance().getLogger();
252 tdb 1.11
253     /**
254     * A reference to the Configuration Manager the system is using
255     */
256 ajm 1.12 private ConfigurationManager _configManager = ReferenceManager.getInstance().getCM();
257    
258     /**
259     * This is the friendly identifier of the
260     * component this class is running in.
261     * eg, a Filter may be called "filter1",
262     * If this class does not have an owning
263     * component, a name from the configuration
264     * can be placed here. This name could also
265     * be changed to null for utility classes.
266     */
267     private String _name = FilterManager.NAME;
268    
269     /**
270     * The socket this class uses
271     */
272     private Socket _socket;
273    
274     /**
275     * Used for the input stream of this socket
276     */
277     private BufferedReader _socketIn;
278 tdb 1.11
279 ajm 1.12 /**
280     * Used for the output stream of this socket
281     */
282     private PrintWriter _socketOut;
283 tdb 1.11
284 tdb 1.1 //---STATIC ATTRIBUTES---
285    
286     }