The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::Stomp::Producer - helper object to send messages via Net::Stomp

VERSION

version 1.001

SYNOPSIS

  my $ser = JSON::XS->new->utf8;

  my $p = Net::Stomp::Producer->new({
    servers => [ { hostname => 'localhost', port => 61613 } ],
    serializer => sub { $ser->encode($_[0]) },
    default_headers => { 'content-type' => 'json' },
  });

  $p->send('/queue/somewhere',
           { type => 'my_message' },
           { a => [ 'data', 'structure' ] });

Also:

  package My::Message::Transformer {
    use Moose;
    sub transform {
      my ($self,@elems) = @_;

      return { destination => '/queue/somewhere',
               type => 'my_message', },
             { a => \@elems };
    }
  }

  $p->transform_and_send('My::Message::Transformer',
                         'data','structure');

Or even:

  my $t = My::Message::Transformer->new();
  $p->transform_and_send($t,
                         'data','structure');

They all send the same message.

DESCRIPTION

This class sends messages via a STOMP connection (see Net::Stomp::MooseHelpers::CanConnect). It provides facilities for serialisation and validation. You can have an instance of this class as a singleton / global in your process, and use it to send all your messages: this is recommended, as it will prevent flooding the broker with many connections (each instance would connect independently, and if you create many instances per second, the broker or your process may run out of file descriptiors and stop working).

You can use it at several levels:

Raw sending

  my $p = Net::Stomp::Producer->new({
    servers => [ { hostname => 'localhost', port => 61613 } ],
  });

  $p->send($destination,\%headers,$body_byte_string);

This will just wrap the parameters in a Net::Stomp::Frame and send it. $destination can be undef, if you have set it in the %headers.

Serialisation support

  my $p = Net::Stomp::Producer->new({
    servers => [ { hostname => 'localhost', port => 61613 } ],
    serializer => sub { encode_json($_[0]) },
  });

  $p->send($destination,\%headers,$body_hashref);

The body will be passed through the serializer, and the resulting string will be used as above.

Transformer instance

  $p->transform_and_send($transformer_obj,@args);

This will call $transformer_obj->transform(@args). That function should return a list (with an even number of elements). Each pair of elements is interpreted as \%headers, $body_ref and passed to "send" as above (with no destination, so the transformer should set it in the headers). It's not an error for the transformer to return an empty list: it just means that nothing will be sent.

Transformer class

  my $p = Net::Stomp::Producer->new({
    servers => [ { hostname => 'localhost', port => 61613 } ],
    transformer_args => { some => 'param' },
  });

  $p->transform_and_send($transformer_class,@args);

The transformer will be instantiated like $transformer_class->new($p->transformer_args), then the object will be called as above.

Transform & validate

If the transformer class / object supports the validate method, it will be called before sending each message, like:

  $transformer_obj->validate(\%headers,$body_ref);

This method is expected to return a true value if the message is valid, and throw a meaningful exception if it is not. The exception will be wrapped in a Net::Stomp::Producer::Exceptions::Invalid. If the validate method returns false without throwing any exception, Net::Stomp::Producer::Exceptions::Invalid will still be throw, but the previous_exception slot will be undef.

ATTRIBUTES

serializer

A coderef that, passed the body parameter from "send", returns a byte string to use as the frame body. The default coderef will just pass non-refs through, and die (with a Net::Stomp::Producer::Exceptions::CantSerialize exception) if passed a ref.

default_headers

Hashref of STOMP headers to use for every frame we send. Headers passed in to "send" take precedence. There is no support for removing a default header for a single send.

transformer_args

Hashref to pass to the transformer constructor when "make_transformer" instantiates a transformer class.

METHODS

connect

Since the connection is set up automatically, this method (usually provided by Net::Stomp::MooseHelpers::CanConnect) is overridden to be a no-op and warn. Don't call it.

send

  $p->send($destination,\%headers,$body);

Serializes the $body via the "serializer", merges the %headers with the "default_headers", setting the content-length to the byte length of the serialized body. Overrides the destination in the headers with $destination if it's defined.

Finally, sends the frame.

make_transformer

  $p->make_transformer($class);

If passed a reference, this function just returns it (it assumes it's a transformer object ready to use).

If passed a string, tries to load the class with Class::Load::load_class. If the class has a new method, it's invoked with the value of "transformer_args" to obtain an object that is then returned. If the class does not have a new, the class name is returned.

transform_and_send

  $p->transform_and_send($transformer,@data);

Uses "make_transformer" to (optionally) instantiate a transformer object, then tries to call transform on it. If there is no such method, a Net::Stomp::Producer::Exceptions::BadTransformer is thrown.

The transformer is expected to return a list of (header,body) pairs (that is, a list with an even number of elements; not a list of arrayrefs!).

Each message in the returned list is optionally validated, then sent (via the "send" method).

The optional validation happens if the transformer ->can('validate'). IF it can, that method is called like:

  $transformer->validate($header,$body_ref);

The method is expected to return a true value if the message is valid, and throw a meaningful exception if it is not. The exception will be wrapped in a Net::Stomp::Producer::Exceptions::Invalid. If the validate method returns false without throwing any exception, Net::Stomp::Producer::Exceptions::Invalid will still be throw, but the previous_exception slot will be undef.

It's not an error for the transformer to return an empty list: it just means that nothing will be sent.

EXAMPLES

You can find examples of use in the tests, or at https://github.com/dakkar/CatalystX-StompSampleApps

AUTHOR

Gianni Ceccarelli <gianni.ceccarelli@net-a-porter.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Net-a-porter.com.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.