File Coverage

blib/lib/Mojo/WebSocketProxy/Backend.pm
Criterion Covered Total %
statement 55 66 83.3
branch 13 20 65.0
condition 10 12 83.3
subroutine 13 14 92.8
pod 8 8 100.0
total 99 120 82.5


line stmt bran cond sub pod time code
1             package Mojo::WebSocketProxy::Backend;
2              
3 17     17   441 use strict;
  17         32  
  17         417  
4 17     17   72 use warnings;
  17         33  
  17         379  
5              
6 17     17   6131 no indirect;
  17         15548  
  17         70  
7              
8 17     17   845 use Mojo::Util qw(class_to_path);
  17         36  
  17         16513  
9              
10             our $VERSION = '0.12'; ## VERSION
11              
12             our %CLASSES = ();
13              
14             =head1 NAME
15              
16             Mojo::WebSocketProxy::Backend
17              
18             =head1 DESCRIPTION
19              
20             Abstract base class for RPC dispatch backends. See
21             L for the original JSON::RPC backend.
22              
23             =cut
24              
25             =head1 CLASS METHODS
26              
27             =cut
28              
29             =head2 register_type
30              
31             $class->register_type($type)
32              
33             Registers that the invoking subclass implements an RPC backend of the given type.
34              
35             =cut
36              
37             sub register_type {
38 18     18 1 69 my ($class, $type) = @_;
39 18         53 $CLASSES{$type} = $class;
40 18         52 return;
41             }
42              
43             =head2 backend_instance
44              
45             $backend = Mojo::WebSocketProxy::Backend->new($type, %args)
46              
47             Constructs a new instance of the subclass previously registered as handling
48             the given type. Throws an exception of no such class exists.
49              
50             =cut
51              
52             sub backend_instance {
53 24     24 1 99 my ($class, $type, %args) = @_;
54 24 50       122 my $backend_class = $CLASSES{$type} or die 'unknown backend type ' . $type;
55 24         162 return $backend_class->new(%args);
56             }
57              
58             =head2 METHODS - For backend classes
59              
60             These will be inherited by backend implementations and can be used
61             for some common actions when processing requests and responses.
62              
63             =cut
64              
65             =head2 new
66              
67             $backend = $class->new(%args)
68              
69             Returns a new blessed HASH reference containing the given arguments.
70              
71             =cut
72              
73             sub new {
74 23     23 1 78 my ($class, %args) = @_;
75 23         134 return bless \%args, $class;
76             }
77              
78             =head2 make_call_params
79              
80             Make RPC call params.
81              
82             $backend->make_call_params($c, $req_storage)
83              
84             Method params:
85             stash_params - it contains params to forward from server storage.
86              
87             =cut
88              
89             sub make_call_params {
90 23     23 1 63 my ($self, $c, $req_storage) = @_;
91              
92 23         49 my $args = $req_storage->{args};
93 23         50 my $stash_params = $req_storage->{stash_params};
94              
95 23         71 my $call_params = $req_storage->{call_params};
96 23         60 $call_params->{args} = $args;
97              
98 23 100       73 if (defined $stash_params) {
99 3         15 $call_params->{$_} = $c->stash($_) for @$stash_params;
100             }
101              
102 23         154 return $call_params;
103             }
104              
105             =head2 get_rpc_response_cb
106              
107             Returns the stored callback for this response if we have one, otherwise an empty list.
108              
109             =cut
110              
111             sub get_rpc_response_cb {
112 23     23 1 63 my ($self, $c, $req_storage) = @_;
113              
114 23         60 my $success_handler = delete $req_storage->{success};
115 23         50 my $error_handler = delete $req_storage->{error};
116              
117 23 100       78 if (my $rpc_response_cb = delete $req_storage->{rpc_response_cb}) {
118             return sub {
119 2     2   58 my $rpc_response = shift;
120 2         9 return $rpc_response_cb->($c, $rpc_response, $req_storage);
121 2         12 };
122             } else {
123             return sub {
124 20     20   483 my $rpc_response = shift;
125 20 50 66     105 if (ref($rpc_response) eq 'HASH' and exists $rpc_response->{error}) {
126 0 0       0 $error_handler->($c, $rpc_response, $req_storage) if defined $error_handler;
127 0         0 return error_api_response($c, $rpc_response, $req_storage);
128             } else {
129 20 50       79 $success_handler->($c, $rpc_response, $req_storage) if defined $success_handler;
130 20         78 store_response($c, $rpc_response);
131 20         81 return success_api_response($c, $rpc_response, $req_storage);
132             }
133 0         0 return;
134 21         132 };
135             }
136 0         0 return;
137             }
138              
139             =head2 store_response
140              
141             Save RPC response to storage.
142              
143             =cut
144              
145             sub store_response {
146 20     20 1 50 my ($c, $rpc_response) = @_;
147              
148 20 100 100     103 if (ref($rpc_response) eq 'HASH' && $rpc_response->{stash}) {
149 1         3 $c->stash(%{delete $rpc_response->{stash}});
  1         5  
150             }
151 20         63 return;
152             }
153              
154             =head2 success_api_response
155              
156             Make wsapi proxy server response from RPC response.
157              
158             =cut
159              
160             sub success_api_response {
161 20     20 1 50 my ($c, $rpc_response, $req_storage) = @_;
162              
163 20         52 my $msg_type = $req_storage->{msg_type};
164 20         40 my $rpc_response_handler = $req_storage->{response};
165              
166 20         64 my $api_response = {
167             msg_type => $msg_type,
168             $msg_type => $rpc_response,
169             };
170              
171 20 100 66     152 if (ref($rpc_response) eq 'HASH' and keys %$rpc_response == 1 and exists $rpc_response->{status}) {
      100        
172 1         3 $api_response->{$msg_type} = $rpc_response->{status};
173             }
174              
175 20 100       58 if ($rpc_response_handler) {
176 2         8 return $rpc_response_handler->($rpc_response, $api_response, $req_storage);
177             }
178              
179 18         50 return $api_response;
180             }
181              
182             =head2 error_api_response
183              
184             Make wsapi proxy server response from RPC response.
185              
186             =cut
187              
188             sub error_api_response {
189 0     0 1   my ($c, $rpc_response, $req_storage) = @_;
190              
191 0           my $msg_type = $req_storage->{msg_type};
192 0           my $rpc_response_handler = $req_storage->{response};
193             my $api_response =
194 0           $c->wsp_error($msg_type, $rpc_response->{error}->{code}, $rpc_response->{error}->{message_to_client}, $rpc_response->{error}->{details});
195              
196 0 0         if ($rpc_response_handler) {
197 0           return $rpc_response_handler->($rpc_response, $api_response, $req_storage);
198             }
199              
200 0           return $api_response;
201             }
202              
203             =head1 REQUIRED METHODS - subclasses must implement
204              
205             =cut
206              
207             =head2 call_rpc
208              
209             $f = $backend->call_rpc($c, $req_storage)
210              
211             Invoked to actually dispatch a given RPC method call to the backend.
212              
213             =cut
214              
215             1;