1 package Catalyst::Controller::MessageDriven;
4 use Moose::Util::TypeConstraints;
5 use MooseX::Types::Moose qw/Str/;
6 use namespace::autoclean;
8 BEGIN { extends 'Catalyst::Controller' }
12 Catalyst::Controller::MessageDriven
16 package MyApp::Controller::Queue;
18 BEGIN { extends 'Catalyst::Controller::MessageDriven' }
20 sub some_action : Local {
21 my ($self, $c, $message) = @_;
25 # Reply with a minimal response message
26 my $response = { type => 'testaction_response' };
27 $c->stash->{response} = $response;
32 A Catalyst controller base class for use with Catalyst::Engine::Stomp,
33 which handles YAML-serialized messages. A top-level "type" key in the
34 YAML determines the action dispatched to.
40 Deserializes the request into C<< $c->stash->{request} >>
44 Dispatches to method named by the key C<< $c->stash->{request}->{type} >>
48 Serializes the response from C<< $c->stash->{response} >>
52 In the configuration file add the following to set the value for a parameter
60 The hash key the module will try to pull out the received message to call
61 within the controller. This defaults to 'type'.
65 The serializer used to serialiser/deserialise. See Data::Serializer to see
66 what is available. Defaults to YAML. JSON is anotther that is available.
71 class_type 'Data::Serializer';
72 my $serializer_t = subtype 'Data::Serializer', where { 1 };
73 coerce $serializer_t, from 'Str',
74 via { Data::Serializer->new( serializer => $_ ) };
77 isa => $serializer_t, is => 'ro', required => 1,
78 default => 'YAML', coerce => 1,
82 is => 'ro', required =>1,
90 # Deserialize the request message
92 my $s = $self->serializer;
94 my $body = $c->request->body;
95 open my $IN, "$body" or die "can't open temp file $body";
96 $message = $s->raw_deserialize(do { local $/; <$IN> });
99 # can't reply - reply_to is embedded in the message
100 $c->error("exception in deserialize: $@");
103 $c->stash->{request} = $message;
110 # Engine will send our reply based on the value of this header.
111 $c->response->headers->header( 'X-Reply-Address' => $c->stash->{request}->{reply_to} );
117 my $s = $self->serializer;
119 # Custom error handler - steal errors from catalyst and dump them into
120 # the stash, to get them serialized out as the reply.
121 if (scalar @{$c->error}) {
122 $c->log->error($_) for @{$c->error}; # Log errors in Catalyst
123 my $error = join "\n", @{$c->error};
124 $c->stash->{response} = { status => 'ERROR', error => $error };
125 $output = $s->serialize( $c->stash->{response} );
127 $c->response->status(400);
130 # Serialize the response
132 $output = $s->raw_serialize( $c->stash->{response} );
135 my $error = "exception in serialize: $@";
136 $c->stash->{response} = { status => 'ERROR', error => $error };
137 $output = $s->serialize( $c->stash->{response} );
138 $c->response->status(400);
141 $c->response->output( $output );
144 sub default : Private {
147 # Forward the request to the appropriate action, based on the
149 my $action = $c->stash->{request}->{ $self->type_key };
150 if (defined $action) {
151 $c->forward($action, [$c->stash->{request}]);
154 $c->error('no message type specified');
158 __PACKAGE__->meta->make_immutable;