1
#!/usr/bin/perl -w
2
#
3
# Copyright (c) 2008 Klaas Freitag <freitag@suse.de>, Novell Inc.
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License version 2 as
7
# published by the Free Software Foundation.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program (see the file COPYING); if not, write to the
16
# Free Software Foundation, Inc.,
17
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18
#
19
################################################################
20
# Contributors:
21
#  Klaas Freitag <freitag@suse.de>
22
# 
23
# This script diggs through the hermes database and generates messages
24
# from the raw notifications stored through herminator
25
26
BEGIN {
27
  my ($wd) = $0 =~ m-(.*)/- ;
28
  $wd ||= '.';
29
  chdir "$wd";
30
  unshift @INC,  ".";
31
}
32
33
use strict;
34
use Getopt::Std;
35
use Data::Dumper;
36
37
use Hermes::Log;
38
use Hermes::DB;
39
use Hermes::Message;
40
use Hermes::Proxy;
41
42
use Time::HiRes qw( gettimeofday tv_interval );
43
44
use vars qw ( $opt_h $opt_s $opt_l $opt_w $opt_o $opt_t $opt_p $gotTermSignal);
45
46
47
sub usage()
48
{
49
  print<<END
50
51
  hermesgenerator.pl
52
53
  Script to generate hermes messages from raw notifications.
54
55
  This script runs forever, make sure it is started as weak user in an 
56
  environment that makes sure that this script is running.
57
  To stop it smoothly send it a TERM signal.
58
59
  -o:  process messages only one times and stop after that
60
  -h:  help text
61
  -s:  silent, no output is generated.
62
  -p url:   proxy: send raw data of each notification to another Hermes
63
            instance identified by url. 
64
	    Example: hermesgenerator.pl -p http://testhermes.suse.de/herminator
65
  -l limit: limit processing to limit notifications
66
  -w delay: sleeping time in seconds, default 10
67
  -t database name as of the Config.pm file
68
69
END
70
;
71
  exit;
72
}
73
74
sub gotSignalTerm
75
{
76
  $gotTermSignal = 1;
77
}
78
79
# ---------------------------------------------------------------------------
80
81
# Process the commandline arguments.
82
getopts('ohsl:w:t:p:');
83
84
usage() if ($opt_h );
85
86
print "Connecting to database $opt_t\n" if defined $opt_t;
87
setLogFileName('hermesgenerator');
88
connectDB( $opt_t );
89
90
my $silent = 0;
91
$silent = 1 if( $opt_s );
92
93
my $limit = 100;
94
$limit = 0+$opt_l if( $opt_l && $opt_l =~ /^\d+$/ );
95
96
my $delay = $opt_w || 10; # ten seconds default delay
97
98
$gotTermSignal = 0;
99
$SIG{TERM} = \&gotSignalTerm;
100
101
log( 'info', "#################################### generator rocks the show" );
102
103
my $sql = "SELECT n.*, msgt.msgtype FROM notifications n, msg_types msgt WHERE ";
104
$sql   .= "n.generated=0 AND n.msg_type_id=msgt.id order by n.received limit $limit";
105
log( 'info', "SQL: $sql " );
106
my $notiSth = dbh()->prepare( $sql );
107
108
$sql = "SELECT np.*, mtp.name FROM notification_parameters np, parameters mtp ";
109
$sql .= "WHERE np.parameter_id=mtp.id AND np.notification_id=?";
110
my $paramSth = dbh()->prepare( $sql );
111
112
$sql = "UPDATE notifications SET generated=NOW() WHERE id=?";
113
my $generatedSth = dbh()->prepare( $sql );
114
115
$sql = "INSERT INTO generated_notifications(notification_id, subscription_id, created_at) " .
116
       "VALUES (?, ?, ?)";
117
my $genSth = dbh()->prepare( $sql );
118
119
while( 1 ) {
120
    # my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
121
 
122
    my $t0 = [gettimeofday];
123
 
124
    $notiSth->execute();
125
126
    my $cnt = 0;
127
    while( my ($id, $msgTypeId, $received, $sender, $gen, $type ) = $notiSth->fetchrow_array() ) {
128
	print " [$type]" unless( $silent );
129
	$paramSth->execute( $id );
130
	my %params;
131
	my $pCount = 0;
132
	while( my ($nId, $notiId, $paramId, $val, $name) = $paramSth->fetchrow_array()) {
133
	    # print "$name = $val\n" unless( $silent );
134
	    $params{$name} = $val;
135
	    $pCount++;
136
	}
137
	print " with $pCount Arguments:" unless( $silent );
138
139
	# send to another herminator if configured
140
	sendToHermes( $opt_p, $type, \%params ) if( $opt_p );
141
	
142
	# generateNotification returns the count of generated notifications
143
	my $subsIdsRef = generateNotification( $type,  \%params );
144
	unless( $subsIdsRef ) {
145
	    print " no subscribers!\n";
146
	    next;
147
	}
148
149
	my $genCnt = @{$subsIdsRef}; # amount of entries
150
151
	if( $genCnt ) {
152
	    print ", $genCnt notifications generated!\n" unless( $silent );
153
	} elsif( $genCnt == 0 ) {
154
	    print ", no notifications created!\n" unless( $silent );
155
	} else {
156
	    print ", ERROR happened, check logfile!\n" unless( $silent );
157
	}
158
159
	# write records into generated_notifications table. This connects the 
160
	# notification and a subscription. 
161
	# Do that only if there are really subscriptions interested in this type.
162
	if( $genCnt > 0 ) {
163
	    foreach my $subsId ( @{$subsIdsRef} ) {
164
		$genSth->execute( $id, $subsId, $received );
165
	    }
166
	    $cnt++;
167
	}
168
	# Even if there were no subscriber, set the notification to sent.
169
	if( $genCnt >= 0 ) {
170
	    $generatedSth->execute( $id );
171
	}
172
    }
173
174
    my $elapsed = tv_interval ($t0);
175
    log 'info', "Generated $cnt notifications in $elapsed sec.\n";
176
    print "Generated $cnt notifications in $elapsed sec.\n" unless( $silent );
177
    
178
    if( $gotTermSignal ) {
179
      log 'info', "Got the term signal, I go outta here...";
180
      print "## Got the term signal, I go outta here...\n";
181
      exit 0;
182
    }
183
    
184
    sleep( $delay );
185
    if( $opt_o ) {
186
	log('info', "################################### generator exits" );
187
	exit;
188
    }
189
190
    log( 'info', ">>> Generator sleeping for $delay seconds" );
191
}
192
193
194
# the end