1818
1919from __future__ import print_function
2020
21- from ssm .brokers import StompBrokerGetter , STOMP_SERVICE , STOMP_SSL_SERVICE
22- from ssm .ssm2 import Ssm2 , Ssm2Exception
23- from ssm import __version__ , set_up_logging , LOG_BREAK
21+ import ssm .agents
22+ from ssm import __version__ , LOG_BREAK
2423
25- from stomp .exception import NotConnectedException
26- try :
27- from argo_ams_library import AmsConnectionException
28- except ImportError :
29- # ImportError is raised when Ssm2 initialised if AMS is requested but lib
30- # not installed.
31- AmsConnectionException = None
32-
33- import time
34- import logging .config
35- import ldap
24+ import logging
3625import os
3726import sys
3827from optparse import OptionParser
39- from daemon import DaemonContext
4028
4129try :
4230 import ConfigParser
4331except ImportError :
4432 import configparser as ConfigParser
4533
46- # How often (in seconds) to read the list of valid DNs.
47- REFRESH_DNS = 600
48- log = None
49-
50-
51- def get_dns (dn_file ):
52- """Retrieve a list of DNs from a file."""
53- dns = []
54- f = None
55- try :
56- f = open (dn_file , 'r' )
57- lines = f .readlines ()
58- for line in lines :
59- if line .isspace () or line .strip ().startswith ('#' ):
60- continue
61- elif line .strip ().startswith ('/' ):
62- dns .append (line .strip ())
63- else :
64- log .warn ('DN in incorrect format: %s' , line )
65- finally :
66- if f is not None :
67- f .close ()
68- # If no valid DNs, SSM cannot receive any messages.
69- if len (dns ) == 0 :
70- raise Ssm2Exception ('No valid DNs found in %s. SSM will not start' % dn_file )
71-
72- log .debug ('%s DNs found.' , len (dns ))
73- return dns
74-
7534
7635def main ():
7736 """Set up connection, and listen for messages."""
@@ -97,192 +56,21 @@ def main():
9756 print ('Cannot start SSM. Pidfile %s already exists.' % pidfile )
9857 sys .exit (1 )
9958
100- # set up logging
101- try :
102- if os .path .exists (options .log_config ):
103- logging .config .fileConfig (options .log_config )
104- else :
105- set_up_logging (cp .get ('logging' , 'logfile' ),
106- cp .get ('logging' , 'level' ),
107- cp .getboolean ('logging' , 'console' ))
108- except (ConfigParser .Error , ValueError , IOError ) as err :
109- print ('Error configuring logging: %s' % err )
110- print ('SSM will exit.' )
111- sys .exit (1 )
59+ ssm .agents .logging_helper (cp , options .log_config )
11260
113- global log
11461 log = logging .getLogger ('ssmreceive' )
11562
11663 log .info (LOG_BREAK )
11764 log .info ('Starting receiving SSM version %s.%s.%s.' , * __version__ )
11865
119- # Determine the protocol for the SSM to use.
120- try :
121- protocol = cp .get ('receiver' , 'protocol' )
122-
123- except (ConfigParser .NoSectionError , ConfigParser .NoOptionError ):
124- # If the newer configuration setting 'protocol' is not set, use 'STOMP'
125- # for backwards compatability.
126- protocol = Ssm2 .STOMP_MESSAGING
127- log .debug ("No option set for 'protocol'. Defaulting to %s." , protocol )
66+ protocol = ssm .agents .get_protocol (cp , log )
12867
12968 log .info ('Setting up SSM with protocol: %s' , protocol )
13069
131- if protocol == Ssm2 .STOMP_MESSAGING :
132- # Set defaults for AMS variables that Ssm2 constructor requires below.
133- project = None
134- token = ''
135-
136- use_ssl = cp .getboolean ('broker' , 'use_ssl' )
137- if use_ssl :
138- service = STOMP_SSL_SERVICE
139- else :
140- service = STOMP_SERVICE
141-
142- # If we can't get a broker to connect to, we have to give up.
143- try :
144- bg = StompBrokerGetter (cp .get ('broker' , 'bdii' ))
145- brokers = bg .get_broker_hosts_and_ports (service , cp .get ('broker' ,
146- 'network' ))
147- except ConfigParser .NoOptionError as e :
148- try :
149- host = cp .get ('broker' , 'host' )
150- port = cp .get ('broker' , 'port' )
151- brokers = [(host , int (port ))]
152- except ConfigParser .NoOptionError :
153- log .error ('Options incorrectly supplied for either single '
154- 'broker or broker network. '
155- 'Please check configuration' )
156- log .error ('System will exit.' )
157- log .info (LOG_BREAK )
158- sys .exit (1 )
159- except ldap .SERVER_DOWN as e :
160- log .error ('Could not connect to LDAP server: %s' , e )
161- log .error ('System will exit.' )
162- log .info (LOG_BREAK )
163- sys .exit (1 )
164-
165- elif protocol == Ssm2 .AMS_MESSAGING :
166- # Then we are setting up an SSM to connect to a AMS.
167-
168- # 'use_ssl' isn't checked when using AMS (SSL is always used), but it
169- # is needed for the call to the Ssm2 constructor below.
170- use_ssl = None
171- try :
172- # We only need a hostname, not a port
173- host = cp .get ('broker' , 'host' )
174- # Use brokers variable so subsequent code is not dependant on
175- # the exact destination type.
176- brokers = [host ]
177-
178- except ConfigParser .NoOptionError :
179- log .error ('The host must be specified when connecting to AMS, '
180- 'please check your configuration' )
181- log .error ('System will exit.' )
182- log .info (LOG_BREAK )
183- print ('SSM failed to start. See log file for details.' )
184- sys .exit (1 )
185-
186- # Attempt to configure AMS specific variables.
187- try :
188- token = cp .get ('messaging' , 'token' )
189- project = cp .get ('messaging' , 'ams_project' )
190-
191- except (ConfigParser .Error , ValueError , IOError ) as err :
192- # A token and project are needed to successfully receive from an
193- # AMS instance, so log and then exit on an error.
194- log .error ('Error configuring AMS values: %s' , err )
195- log .error ('SSM will exit.' )
196- print ('SSM failed to start. See log file for details.' )
197- sys .exit (1 )
70+ brokers , project , token = ssm .agents .get_ssm_args (protocol , cp , log )
19871
199- if len (brokers ) == 0 :
200- log .error ('No brokers available.' )
201- log .error ('System will exit.' )
202- log .info (LOG_BREAK )
203- sys .exit (1 )
204-
205- log .info ('The SSM will run as a daemon.' )
206-
207- # We need to preserve the file descriptor for any log files.
208- rootlog = logging .getLogger ()
209- log_files = [x .stream for x in rootlog .handlers ]
210- dc = DaemonContext (files_preserve = log_files )
211-
212- try :
213- ssm = Ssm2 (brokers ,
214- cp .get ('messaging' , 'path' ),
215- cert = cp .get ('certificates' , 'certificate' ),
216- key = cp .get ('certificates' , 'key' ),
217- listen = cp .get ('messaging' , 'destination' ),
218- use_ssl = use_ssl ,
219- capath = cp .get ('certificates' , 'capath' ),
220- check_crls = cp .getboolean ('certificates' , 'check_crls' ),
221- pidfile = pidfile ,
222- protocol = protocol ,
223- project = project ,
224- token = token )
225-
226- log .info ('Fetching valid DNs.' )
227- dns = get_dns (options .dn_file )
228- ssm .set_dns (dns )
229-
230- except Exception as e :
231- log .fatal ('Failed to initialise SSM: %s' , e )
232- log .info (LOG_BREAK )
233- sys .exit (1 )
234-
235- try :
236- # Note: because we need to be compatible with python 2.4, we can't use
237- # with dc:
238- # here - we need to call the open() and close() methods
239- # manually.
240- dc .open ()
241- ssm .startup ()
242- i = 0
243- # The message listening loop.
244- while True :
245- try :
246- time .sleep (0.1 )
247- if protocol == Ssm2 .AMS_MESSAGING :
248- # We need to pull down messages as part of
249- # this loop when using AMS.
250- ssm .pull_msg_ams ()
251-
252- if i % (REFRESH_DNS * 10 ) == 0 :
253- log .info ('Refreshing valid DNs and then sending ping.' )
254- dns = get_dns (options .dn_file )
255- ssm .set_dns (dns )
256-
257- if protocol == Ssm2 .STOMP_MESSAGING :
258- ssm .send_ping ()
259-
260- except (NotConnectedException , AmsConnectionException ) as error :
261- log .warn ('Connection lost.' )
262- log .debug (error )
263- ssm .shutdown ()
264- dc .close ()
265- log .info ("Waiting for 10 minutes before restarting..." )
266- time .sleep (10 * 60 )
267- log .info ('Restarting SSM.' )
268- dc .open ()
269- ssm .startup ()
270-
271- i += 1
272-
273- except SystemExit as e :
274- log .info ('Received the shutdown signal: %s' , e )
275- ssm .shutdown ()
276- dc .close ()
277- except Exception as e :
278- log .error ('Unexpected exception: %s' , e )
279- log .error ('Exception type: %s' , e .__class__ )
280- log .error ('The SSM will exit.' )
281- ssm .shutdown ()
282- dc .close ()
283-
284- log .info ('Receiving SSM has shut down.' )
285- log .info (LOG_BREAK )
72+ ssm .agents .run_receiver (protocol , brokers , project , token ,
73+ cp , log , options .dn_file )
28674
28775
28876if __name__ == '__main__' :
0 commit comments