| 1 | # $Id$ |
|---|
| 2 | |
|---|
| 3 | package Mvalve::Message; |
|---|
| 4 | use Moose; |
|---|
| 5 | use Moose::Util::TypeConstraints; |
|---|
| 6 | use MooseX::ClassAttribute; |
|---|
| 7 | use Data::Serializer; |
|---|
| 8 | use Digest::SHA1 (); |
|---|
| 9 | use HTTP::Headers; |
|---|
| 10 | use POSIX(); |
|---|
| 11 | use Sys::Hostname(); |
|---|
| 12 | use Time::HiRes(); |
|---|
| 13 | |
|---|
| 14 | class_type 'HTTP::Headers'; |
|---|
| 15 | |
|---|
| 16 | coerce 'HTTP::Headers' |
|---|
| 17 | => from 'HashRef', |
|---|
| 18 | => via { HTTP::Headers->new(%$_) } |
|---|
| 19 | ; |
|---|
| 20 | |
|---|
| 21 | has 'id' => ( |
|---|
| 22 | is => 'ro', |
|---|
| 23 | isa => 'Str', |
|---|
| 24 | required => 1, |
|---|
| 25 | default => sub { |
|---|
| 26 | # XXX - hints as to about when this message was generated |
|---|
| 27 | my ($int_part, $float_part) = split(/\./, Time::HiRes::time()); |
|---|
| 28 | my $prefix = join('.', POSIX::strftime('%Y%m%d%H%M%S', localtime($int_part)), $float_part); |
|---|
| 29 | |
|---|
| 30 | return join('-', $prefix, Digest::SHA1::sha1_hex({}, $$, Time::HiRes::time(), rand(), Sys::Hostname::hostname())) |
|---|
| 31 | } |
|---|
| 32 | ); |
|---|
| 33 | |
|---|
| 34 | has 'headers' => ( |
|---|
| 35 | is => 'rw', |
|---|
| 36 | isa => 'HTTP::Headers', |
|---|
| 37 | coerce => 1, |
|---|
| 38 | default => sub { HTTP::Headers->new }, |
|---|
| 39 | handles => { |
|---|
| 40 | header => 'header', |
|---|
| 41 | header_add => 'push_header', |
|---|
| 42 | header_remove => 'remove_header' |
|---|
| 43 | }, |
|---|
| 44 | ); |
|---|
| 45 | |
|---|
| 46 | has 'content' => ( |
|---|
| 47 | is => 'rw', |
|---|
| 48 | ); |
|---|
| 49 | |
|---|
| 50 | class_has 'SERIALIZER' => ( |
|---|
| 51 | is => 'rw', |
|---|
| 52 | isa => 'Data::Serializer', |
|---|
| 53 | lazy => 1, |
|---|
| 54 | default => sub { |
|---|
| 55 | Data::Serializer->new( |
|---|
| 56 | serializer => 'Storable', |
|---|
| 57 | compress => 1, |
|---|
| 58 | ) |
|---|
| 59 | }, |
|---|
| 60 | ); |
|---|
| 61 | |
|---|
| 62 | __PACKAGE__->meta->make_immutable; |
|---|
| 63 | |
|---|
| 64 | no Moose; |
|---|
| 65 | no MooseX::ClassAttribute; |
|---|
| 66 | |
|---|
| 67 | sub serialize { |
|---|
| 68 | my $rv = eval { $_[0]->SERIALIZER->serialize($_[0]) }; |
|---|
| 69 | Carp::confess("Failed to serialize @_: $@") if $@; |
|---|
| 70 | return $rv; |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | sub deserialize { |
|---|
| 74 | my $rv = eval { shift->SERIALIZER->deserialize(@_) }; |
|---|
| 75 | Carp::confess("Failed to deserialize @_: $@") if $@; |
|---|
| 76 | return $rv; |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | |
|---|
| 80 | 1; |
|---|
| 81 | |
|---|
| 82 | __END__ |
|---|
| 83 | |
|---|
| 84 | =head1 NAME |
|---|
| 85 | |
|---|
| 86 | Mvalve::Message - A Message Object |
|---|
| 87 | |
|---|
| 88 | =head1 SYNOPSIS |
|---|
| 89 | |
|---|
| 90 | use Mvalve::Message; |
|---|
| 91 | |
|---|
| 92 | my $message = Mvalve::Message->new( |
|---|
| 93 | headers => { |
|---|
| 94 | from => 'me', |
|---|
| 95 | to => 'you', |
|---|
| 96 | }, |
|---|
| 97 | content => { |
|---|
| 98 | random => 'content', |
|---|
| 99 | } |
|---|
| 100 | ); |
|---|
| 101 | |
|---|
| 102 | my $serialized = $message->serialize; |
|---|
| 103 | my $materialized = Mvalve::Message->deserialize($serialized); |
|---|
| 104 | |
|---|
| 105 | =head1 METHODS |
|---|
| 106 | |
|---|
| 107 | =head2 BUILD |
|---|
| 108 | |
|---|
| 109 | Custom BUILD() for Moose |
|---|
| 110 | |
|---|
| 111 | =head2 SERIALIZER |
|---|
| 112 | |
|---|
| 113 | Returns the serializer object to use |
|---|
| 114 | |
|---|
| 115 | =head2 serialize |
|---|
| 116 | |
|---|
| 117 | Serializes the message |
|---|
| 118 | |
|---|
| 119 | =head2 deserialize |
|---|
| 120 | |
|---|
| 121 | Deserializes a packed structure to a message |
|---|
| 122 | |
|---|
| 123 | =cut |
|---|