1 package OpenSRF::Application;
3 use OpenSRF::AppSession;
4 use OpenSRF::DomainObject::oilsMethod;
5 use OpenSRF::DomainObject::oilsResponse qw/:status/;
6 use OpenSRF::Utils::Logger qw/:level/;
7 use Time::HiRes qw/time/;
8 use vars qw/$_app $log/;
9 use OpenSRF::EX qw/:try/;
13 $log = 'OpenSRF::Utils::Logger';
16 our @pending_requests;
18 sub application_implementation {
26 $log->error( "Error loading application_implementation: $app -> $@", ERROR);
35 my ($self, $session, $app_msg) = @_;
37 $log->debug( "In Application::handler()", DEBUG );
39 my $app = $self->application_implementation;
42 $log->debug( "Application is $app", DEBUG);
44 $log->debug( "Message is ".$app_msg->toString(1), INTERNAL);
47 if ($session->last_message_type eq 'REQUEST') {
48 $log->debug( "We got a REQUEST: ". $app_msg->method, INFO );
50 my $method_name = $app_msg->method;
51 $log->debug( " * Looking up $method_name inside $app", DEBUG);
53 my $method_proto = $session->last_message_protocol;
54 $log->debug( " * Method API Level [$method_proto]", DEBUG);
56 my $coderef = $app->method_lookup( $method_name, $method_proto );
59 $session->status( OpenSRF::DomainObject::oilsMethodException->new() );
63 #if ( $session->client_auth->username || $session->client_auth->userid ) {
64 # unless ( $coderef->is_action ) {
66 # OpenSRF::DomainObject::oilsMethodException->new(
67 # statusCode => STATUS_NOTALLOWED(),
68 # status => "User cannot use [$method_name]" ) );
74 $log->debug( " (we got coderef $coderef", DEBUG);
76 unless ($session->continue_request) {
78 OpenSRF::DomainObject::oilsConnectStatus->new(
79 statusCode => STATUS_REDIRECTED(),
80 status => 'Disconnect on max requests' ) );
86 my @args = $app_msg->params;
87 my $appreq = OpenSRF::AppRequest->new( $session );
89 $log->debug( "in_request = $in_request : [" . $appreq->threadTrace."]", DEBUG );
91 $log->debug( "Pushing onto pending requests: " . $appreq->threadTrace, DEBUG );
92 push @pending_requests, [ $appreq, \@args, $coderef ];
99 $log->debug( "Executing coderef for {$method_name -> ".join(', ', @args)."}", INTERNAL );
104 $resp = $coderef->run( $appreq, @args);
105 my $time = sprintf '%.3f', time() - $start;
106 $log->debug( "Method duration for {$method_name -> ".join(', ', @args)."}: ". $time, DEBUG );
108 $log->debug( "Calling respond_complete: ". $resp->toString(), INTERNAL );
109 $appreq->respond_complete( $resp );
111 $appreq->status( OpenSRF::DomainObject::oilsConnectStatus->new(
112 statusCode => STATUS_COMPLETE(),
113 status => 'Request Complete' ) );
117 $e = $e->{-text} || $e->message if (ref $e);
118 my $sess_id = $session->session_id;
120 OpenSRF::DomainObject::oilsMethodException->new(
121 statusCode => STATUS_INTERNALSERVERERROR(),
122 status => " *** Call to [$method_name] failed for session ".
123 "[$sess_id], thread trace [".$appreq->threadTrace."]:\n".$e
130 # ----------------------------------------------
133 # XXX may need this later
134 # $_->[1] = 1 for (@OpenSRF::AppSession::_CLIENT_CACHE);
138 $log->debug( "Pending Requests: " . scalar(@pending_requests), INTERNAL );
140 # cycle through queued requests
141 while( my $aref = shift @pending_requests ) {
146 my $response = $aref->[2]->run( $aref->[0], @{$aref->[1]} );
147 my $time = sprintf '%.3f', time - $start;
148 $log->debug( "Method duration for {[".$aref->[2]->name." -> ".join(', ',@{$aref->[1]}).'}: '.$time, DEBUG );
150 $appreq = $aref->[0];
151 if( ref( $response ) ) {
152 $log->debug( "Calling respond_complete: ". $response->toString(), INTERNAL );
153 $appreq->respond_complete( $response );
155 $appreq->status( OpenSRF::DomainObject::oilsConnectStatus->new(
156 statusCode => STATUS_COMPLETE(),
157 status => 'Request Complete' ) );
159 $log->debug( "Executed: " . $appreq->threadTrace, DEBUG );
163 OpenSRF::DomainObject::oilsMethodException->new(
164 statusCode => STATUS_INTERNALSERVERERROR(),
165 status => "Call to [".$aref->[2]->name."] faild: ".$e->{-text}
174 my $res = OpenSRF::DomainObject::oilsMethodException->new;
175 $session->send('ERROR', $res);
180 $log->debug( "Pushing ". $app_msg->toString ." onto queue", INTERNAL );
181 $session->push_queue([ $app_msg, $session->last_threadTrace ]);
184 $session->last_message_type('');
185 $session->last_message_protocol('');
195 my $class = ref($self) || $self;
197 $log->debug("Looking up [$method] in [$self]", INTERNAL);
199 my $obj = bless {} => $self;
200 if (my $coderef = $self->can("${method}_${proto}")) {
201 $$obj{code} = $coderef;
202 $$obj{name} = "${method}_${proto}";
215 if (my $can = $self->can($self->{name} . '_action')) {