89d087ba18bc5738903a7f73d573055906c53613
[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                         ( ref($router->{services}) eq 'HASH' and 
102                             grep { $_ eq $self->{app} } @{$router->{services}->{service}} )  ||
103                         $router->{services}->{service} eq $self->{app}) {
104
105                     my $name = $router->{name};
106                     my $domain = $router->{domain};
107                     my $target = "$name\@$domain/router";
108                     push(@{$self->{routers}}, $target);
109                     $logger->info( $self->{app} . " connecting to router $target");
110                     $self->send( to => $target, body => "registering", router_command => "register" , router_class => $self->{app} );
111                 }
112             } else {
113                 my $target = "$router_name\@$router/router";
114                 push(@{$self->{routers}}, $target);
115                 $logger->info( $self->{app} . " connecting to router $target");
116                 $self->send( to => $target, body => "registering", router_command => "register" , router_class => $self->{app} );
117             }
118         }
119                 
120         } catch Error with {
121         my $err = shift;
122                 $logger->error($self->{app} . ": No routers defined: $err");
123                 # no routers defined
124         };
125
126
127         
128                         
129         $logger->transport( $self->{app} . " going into listen loop", INFO );
130
131         while(1) {
132         
133                 my $sock = $self->unix_sock();
134                 my $o;
135
136                 $logger->debug("Inbound listener calling process()");
137
138                 try {
139                         $o = $self->process(-1);
140
141                         if(!$o){
142                                 $logger->error(
143                                         "Inbound received no data from the Jabber socket in process()");
144                                 usleep(100000); # otherwise we loop and pound syslog logger with errors
145                         }
146
147                 } catch OpenSRF::EX::JabberDisconnected with {
148
149                         $logger->error("Inbound process lost its ".
150                                 "jabber connection.  Attempting to reconnect...");
151                         $self->initialize;
152                         $o = undef;
153                 };
154
155
156                 if($o) {
157                         my $socket = IO::Socket::UNIX->new( Peer => $sock  );
158                         throw OpenSRF::EX::Socket( 
159                                 "Unable to connect to UnixServer: socket-file: $sock \n :=> $! " )
160                                 unless ($socket->connected);
161                         print $socket freeze($o);
162                         $socket->close;
163                 } 
164         }
165
166         throw OpenSRF::EX::Socket( "How did we get here?!?!" );
167 }
168
169 1;
170