# # Copyright (c) 2014 NetApp, Inc., All Rights Reserved. # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # package NACL::Service; use strict; use warnings; use parent qw(NATE::Service); use Params::Validate qw(validate_with BOOLEAN HASHREF OBJECT ARRAYREF SCALAR UNDEF); use Storable qw(nfreeze thaw); sub new { my ($proto, %opts) = @_; my $class = ref($proto) || $proto; $opts{admin_email} //= 'dl-nacl-dev@netapp.com'; return $class->SUPER::new(%opts); } use constant public_api => (); sub init { my $self = shift; my %opts = @_; $self->SUPER::init(%opts); my $class = ref($self); if (my %api = $self->public_api()) { foreach my $k (keys(%api)) { my $worker = $api{$k}->{worker_type} // next; if ($worker) { if ($worker eq "1") { # generic worker class $api{$k}->{worker_type} = $class.'::Worker'; } else { # this is a custom worker class } } else { # no worker defined, this is a passive API delete($api{$k}->{worker_type}); } } $self->api_register_bulk(namespace => $class, structure => \%api); } } #for now this is just in a hash...but in the future, a db, or...? sub _store { my $self = shift; my %opts = validate_with( params => \@_, spec => { 'name' => { 'type' => SCALAR }, 'value' => { 'type' => SCALAR }, }, ); #TODO - collision danger here... $self->{_object_store}->{$opts{name}} = $opts{value}; } sub store { my $self = shift; my %opts = validate_with( params => \@_, spec => { 'name' => { 'type' => SCALAR }, 'value' => { 'type' => SCALAR }, }, 'allow_extra' => 1, ); $self->_store( name => $opts{name}, value => $opts{value} ); #use Data::Dumper; print 'store!:' . Dumper {$self->_thaw_if_can(%{$self->{_object_store}})}; } sub _retrieve { my $self = shift; my %opts = validate_with( params => \@_, spec => { 'name' => { 'type' => SCALAR }, }, ); #should we throw exception if no value? Or fail silently... #TODO - collision danger here... return $self->{_object_store}->{$opts{name}}; } sub retrieve { my $self = shift; my %opts = validate_with( params => \@_, spec => { 'name' => { 'type' => SCALAR }, }, 'allow_extra' => 1, ); return $self->_retrieve( name => $opts{name}, ); } #used only on server sub _retrieve_as_object { my $self = shift; my %opts = validate_with( params => \@_, spec => { 'name' => { 'type' => SCALAR }, }, ); my $val = $self->_retrieve( name => $opts{name}, ); return $self->_thaw($val); } sub _freeze_if_can { my $self = shift; return map { ref $_ ? $self->_freeze($_) : $_ } @_; } sub _thaw_if_can { my $self = shift; return map { Storable::read_magic($_) ? $self->_thaw($_) : $_ } @_; } sub _freeze { my $self = shift; return nfreeze(shift); } sub _thaw { my $self = shift; return thaw(shift); } 1; __END__