make config parsing more tolerant
[OpenSRF.git] / src / perl / lib / OpenSRF / Transport / SlimJabber / Inbound.pm
1 package OpenSRF::Transport::SlimJabber::Inbound;
2 use strict;use warnings;
3 use base qw/OpenSRF::Transport::SlimJabber::Client/;
4 use OpenSRF::EX qw(:try);
5 use OpenSRF::Utils::Logger qw(:level);
6 use OpenSRF::Utils::SettingsClient;
7 use OpenSRF::Utils::Config;
8 use Time::HiRes qw/usleep/;
9 use FreezeThaw qw/freeze/;
10
11 my $logger = "OpenSRF::Utils::Logger";
12
13 =head1 Description
14
15 This is the jabber connection where all incoming client requests will be accepted.
16 This connection takes the data, passes it off to the system then returns to take
17 more data.  Connection params are all taken from the config file and the values
18 retreived are based on the $app name passed into new().
19
20 This service should be loaded at system startup.
21
22 =cut
23
24 {
25         my $unix_sock;
26         sub unix_sock { return $unix_sock; }
27         my $instance;
28
29         sub new {
30                 my( $class, $app ) = @_;
31                 $class = ref( $class ) || $class;
32                 if( ! $instance ) {
33
34                         my $conf = OpenSRF::Utils::Config->current;
35                         my $domain = $conf->bootstrap->domain;
36             $logger->error("use of <domains/> is deprecated") if $conf->bootstrap->domains;
37
38                         my $username    = $conf->bootstrap->username;
39                         my $password    = $conf->bootstrap->passwd;
40                         my $port                        = $conf->bootstrap->port;
41                         my $host                        = $domain;
42                         my $resource    = $app . '_listener_at_' . $conf->env->hostname;
43
44             my $no_router = 0; # make this a config entry if we want to use it
45                         if($no_router) { 
46                             # no router, only one listener running..
47                                 $username = "router";
48                                 $resource = $app; 
49                         }
50
51                         OpenSRF::Utils::Logger->transport("Inbound as $username, $password, $resource, $host, $port\n", INTERNAL );
52
53                         my $self = __PACKAGE__->SUPER::new( 
54                                         username                => $username,
55                                         resource                => $resource,
56                                         password                => $password,
57                                         host                    => $host,
58                                         port                    => $port,
59                                         );
60
61                         $self->{app} = $app;
62                                         
63                         my $client = OpenSRF::Utils::SettingsClient->new();
64                         my $f = $client->config_value("dirs", "sock");
65                         $unix_sock = join( "/", $f, 
66                                         $client->config_value("apps", $app, "unix_config", "unix_sock" ));
67                         bless( $self, $class );
68                         $instance = $self;
69                 }
70                 return $instance;
71         }
72
73 }
74
75 sub DESTROY {
76         my $self = shift;
77         for my $router (@{$self->{routers}}) {
78                 if($self->tcp_connected()) {
79             $logger->info("disconnecting from router $router");
80                         $self->send( to => $router, body => "registering", 
81                                 router_command => "unregister" , router_class => $self->{app} );
82                 }
83         }
84 }
85         
86 sub listen {
87         my $self = shift;
88         
89     $self->{routers} = [];
90
91         try {
92
93                 my $conf = OpenSRF::Utils::Config->current;
94         my $router_name = $conf->bootstrap->router_name;
95                 my $routers = $conf->bootstrap->routers;
96         $logger->info("loading router info $routers");
97
98         for my $router (@$routers) {
99             if(ref $router) {
100                 if( !$router->{services} || 
101                     !$router->{services}->{service} || 
102                     ( 
103                         ref($router->{services}->{service}) eq 'ARRAY' and 
104                         grep { $_ eq $self->{app} } @{$router->{services}->{service}} )  ||
105                     $router->{services}->{service} eq $self->{app}) {
106
107                     my $name = $router->{name};
108                     my $domain = $router->{domain};
109                     my $target = "$name\@$domain/router";
110                     push(@{$self->{routers}}, $target);
111                     $logger->info( $self->{app} . " connecting to router $target");
112                     $self->send( to => $target, body => "registering", router_command => "register" , router_class => $self->{app} );
113                 }
114             } else {
115                 my $target = "$router_name\@$router/router";
116                 push(@{$self->{routers}}, $target);
117                 $logger->info( $self->{app} . " connecting to router $target");
118                 $self->send( to => $target, body => "registering", router_command => "register" , router_class => $self->{app} );
119             }
120         }
121                 
122         } catch Error with {
123         my $err = shift;
124                 $logger->error($self->{app} . ": No routers defined: $err");
125                 # no routers defined
126         };
127
128
129         
130                         
131         $logger->transport( $self->{app} . " going into listen loop", INFO );
132
133         while(1) {
134         
135                 my $sock = $self->unix_sock();
136                 my $o;
137
138                 $logger->debug("Inbound listener calling process()");
139
140                 try {
141                         $o = $self->process(-1);
142
143                         if(!$o){
144                                 $logger->error(
145                                         "Inbound received no data from the Jabber socket in process()");
146                                 usleep(100000); # otherwise we loop and pound syslog logger with errors
147                         }
148
149                 } catch OpenSRF::EX::JabberDisconnected with {
150
151                         $logger->error("Inbound process lost its ".
152                                 "jabber connection.  Attempting to reconnect...");
153                         $self->initialize;
154                         $o = undef;
155                 };
156
157
158                 if($o) {
159                         my $socket = IO::Socket::UNIX->new( Peer => $sock  );
160                         throw OpenSRF::EX::Socket( 
161                                 "Unable to connect to UnixServer: socket-file: $sock \n :=> $! " )
162                                 unless ($socket->connected);
163                         print $socket freeze($o);
164                         $socket->close;
165                 } 
166         }
167
168         throw OpenSRF::EX::Socket( "How did we get here?!?!" );
169 }
170
171 1;
172