[Bps-public-commit] r16778 - in Prophet/trunk/lib/Prophet: Replica Server

jesse at bestpractical.com jesse at bestpractical.com
Sun Nov 9 05:32:38 EST 2008


Author: jesse
Date: Sun Nov  9 05:32:35 2008
New Revision: 16778

Added:
   Prophet/trunk/lib/Prophet/Server/Dispatcher.pm
Modified:
   Prophet/trunk/lib/Prophet/Replica/prophet.pm
   Prophet/trunk/lib/Prophet/Server.pm

Log:
* First cut of a Prophet Serverdispatcher

Modified: Prophet/trunk/lib/Prophet/Replica/prophet.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Replica/prophet.pm	(original)
+++ Prophet/trunk/lib/Prophet/Replica/prophet.pm	Sun Nov  9 05:32:35 2008
@@ -601,6 +601,7 @@
         my ( $seq, $orig_uuid, $orig_seq, $key )
             = unpack( 'Na16NH40', $index_record );
 
+        $self->log(join(",", ( $seq, $orig_uuid, $orig_seq, $key )));
         $orig_uuid = Data::UUID->new->to_string($orig_uuid);
         $self->log( "REV: $rev - seq $seq - originally $orig_seq from "
                 . substr( $orig_uuid, 0, 6 )
@@ -637,6 +638,7 @@
     my $chgidx = $self->_read_changeset_index;
     $self->log("Traversing changesets between $first_rev and $latest");
     for my $rev ( $first_rev .. $latest ) {
+        $self->log("Fetching changeset $rev");
         my $changeset = $self->_get_changeset_index_entry(
             sequence_no => $rev,
             index_file  => $chgidx
@@ -648,6 +650,7 @@
 
 sub _read_changeset_index {
     my $self =shift;
+    $self->log("Reading changeset index file");
     my $chgidx    = $self->_read_file( $self->changeset_index );
     return \$chgidx;
 }

Modified: Prophet/trunk/lib/Prophet/Server.pm
==============================================================================
--- Prophet/trunk/lib/Prophet/Server.pm	(original)
+++ Prophet/trunk/lib/Prophet/Server.pm	Sun Nov  9 05:32:35 2008
@@ -3,6 +3,7 @@
 extends qw'HTTP::Server::Simple::CGI';
 
 use Prophet::Server::View;
+use Prophet::Server::Dispatcher;
 use Params::Validate qw/:all/;
 use JSON;
 
@@ -10,6 +11,7 @@
     handles => [ qw/handle/]
 );
 
+has cgi => (isa => 'Maybe[CGI]', is => 'rw');
 has read_only => ( is => 'rw', isa => 'Bool');
 
 before run => sub {
@@ -47,41 +49,33 @@
 
 override handle_request => sub {
     my ($self, $cgi) = validate_pos( @_, { isa => 'Prophet::Server'} ,  { isa => 'CGI' } );
-    my $http_status;
+    $self->cgi($cgi);
+    
+   
+    my $d = Prophet::Server::Dispatcher->new(server => $self);
+   my $http_status = $d->run($cgi->request_method."/". $cgi->path_info, $self);
+
+   unless ($http_status) {
     if ( my $sub = $self->can( 'handle_request_' . lc( $cgi->request_method ) ) ) {
-        $http_status = $sub->( $self, $cgi );
+        $http_status = $sub->( $self);
+    }
     }
     unless ($http_status) {
         $self->_send_404;
     }
-};
-
-sub handle_request_get {
-    my $self = shift;
-    my ($cgi) = validate_pos( @_, { isa => 'CGI' } );
-    my $p = $cgi->path_info;
 
-    if ( $p =~ qr|^/+replica| ) {
-        $self->_handle_request_get_replica($cgi);
-    }
-    elsif ( $p =~ m|^/+records| ) {
-        $self->_handle_request_get_rest($cgi);
-    } else {
-        $self->_handle_request_get_template($cgi);
-    }
-}
+};
 
-sub _handle_request_get_template {
+sub handle_request_get_template {
    my $self = shift;
-    my ($cgi) = validate_pos( @_, { isa => 'CGI' } );
-    my $p = $cgi->path_info;
+    my $p = $self->cgi->path_info;
 
 
     if (Template::Declare->has_template($p)) {
         Prophet::Server::View->app_handle($self->app_handle);
         my $content = Template::Declare->show($p);
 
-        return $self->_send_content(
+        return $self->send_content(
             content_type => 'text/html',
             content      => $content,
         );
@@ -90,10 +84,9 @@
 
 };
 
-sub _handle_request_get_replica {
+sub handle_request_get_replica {
 	my $self = shift;
-    my ($cgi) = validate_pos( @_, { isa => 'CGI' } );
-    my $p = $cgi->path_info;
+    my $p = $self->cgi->path_info;
 
 
     if ($p =~ qr{^/+replica/+(.*)$}) {
@@ -102,56 +95,18 @@
 
        my $content = $self->handle->read_file($repo_file);
        return unless defined $content && length($content);
-       return $self->_send_content(
+       return $self->send_content(
             content_type => 'application/x-prophet',
             content      => $content
         );
     }
 }
 
-sub _handle_request_get_rest {
+sub handle_request_get_rest {
 	my $self = shift;
-    my ($cgi) = validate_pos( @_, { isa => 'CGI' } );
-    my $p = $cgi->path_info;
-
-    if ( $p =~ m|^/records\.json$| ) {
-        $self->_send_content(
-            content_type => 'text/x-json',
-            content      => to_json( $self->handle->list_types )
-        );
+    my $p = $self->cgi->path_info;
 
-    } elsif ( $p =~ m|^/records/(.*)/(.*)/(.*)| ) {
-        my $type   = $1;
-        my $uuid   = $2;
-        my $prop   = $3;
-        my $record = $self->load_record( type => $type, uuid => $uuid );
-        return $self->_send_404 unless ($record);
-        if ( my $val = $record->prop($prop) ) {
-            return $self->_send_content( content_type => 'text/plain', content => $val );
-        } else {
-            return $self->_send_404();
-        }
-    }
-
-    elsif ( $p =~ m|^/records/(.*)/(.*).json| ) {
-        my $type   = $1;
-        my $uuid   = $2;
-        my $record = $self->load_record( type => $type, uuid => $uuid );
-        return $self->_send_404 unless ($record);
-        return $self->_send_content( content_type => 'text/x-json', content => to_json( $record->get_props ) );
-    }
-
-    elsif ( $p =~ m|^/records/(.*).json| ) {
-        my $type = $1;
-        require Prophet::Collection;
-        my $col = Prophet::Collection->new( handle => $self->handle, type => $type );
-        $col->matching( sub {1} );
-        warn "Query language not implemented yet.";
-        return $self->_send_content(
-            content_type => 'text/x-json',
-            content      => to_json( { map { $_->uuid => "/records/$type/" . $_->uuid . ".json" } @$col } )
-            )
-    }
+    $p =~ s/^GET//i;
 }
 
 sub handle_request_post {
@@ -159,8 +114,7 @@
 
     return $self->_send_401 if ($self->read_only);
 
-    my ($cgi) = validate_pos( @_, { isa => 'CGI' } );
-    my $p = $cgi->path_info;
+    my $p = $self->cgi->path_info;
     if ( $p =~ m|^/records/(.*)/(.*)/(.*)| ) {
         my $type = $1;
         my $uuid = $2;
@@ -168,7 +122,7 @@
 
         my $record = $self->load_record( type => $type, uuid => $uuid );
         return $self->_send_404 unless ($record);
-        $record->set_props( props => { $prop => ( $cgi->param('value') || undef ) } );
+        $record->set_props( props => { $prop => ( $self->cgi->param('value') || undef ) } );
         return $self->_send_redirect( to => "/records/$type/$uuid/$prop" );
     } elsif ( $p =~ m|^/records/(.*)/(.*).json| ) {
         my $type   = $1;
@@ -177,12 +131,12 @@
 
         return $self->_send_404 unless ($record);
 
-        my $ret = $record->set_props( props => { map { $_ => $cgi->param($_) } $cgi->param() } );
+        my $ret = $record->set_props( props => { map { $_ => $self->cgi->param($_) } $self->cgi->param() } );
         $self->_send_redirect( to => "/records/$type/$uuid.json" );
     } elsif ( $p =~ m|^/records/(.*).json| ) {
         my $type   = $1;
         my $record = $self->load_record( type => $type );
-        my $uuid   = $record->create( props => { map { $_ => $cgi->param($_) } $cgi->param() } );
+        my $uuid   = $record->create( props => { map { $_ => $self->cgi->param($_) } $self->cgi->param() } );
         return $self->_send_redirect( to => "/records/$type/$uuid.json" );
     }
 }
@@ -199,9 +153,15 @@
     return $record;
 }
 
-sub _send_content {
+sub send_content {
     my $self = shift;
-    my %args = validate( @_, { content => 1, content_type => 1 } );
+    my %args = validate( @_, { content => 1, content_type => 0, encode_as => 0 } );
+
+    if ($args{'encode_as'} && $args{'encode_as'} eq 'json') {
+        $args{'content_type'} = 'text/x-json'; 
+        $args{'content'} = to_json($args{'content'});
+    }
+
     print "HTTP/1.0 200 OK\r\n";
     print "Content-Type: " . $args{'content_type'} . "\r\n";
     print "Content-Length: " . length( $args{'content'} ) . "\r\n\r\n";

Added: Prophet/trunk/lib/Prophet/Server/Dispatcher.pm
==============================================================================
--- (empty file)
+++ Prophet/trunk/lib/Prophet/Server/Dispatcher.pm	Sun Nov  9 05:32:35 2008
@@ -0,0 +1,89 @@
+package Prophet::Server::Dispatcher;
+use Moose;
+use Path::Dispatcher::Declarative -base;
+
+has server => ( isa => 'Prophet::Server', is => 'rw', weak_ref =>1);
+
+
+sub token_delimiter { '/' }
+sub case_sensitive_tokens { 0 }
+
+under 'GET' => sub {
+
+    on 'replica' => sub {
+        my $server = shift;
+        return $server->handle_request_get_replica();
+    };
+    on 'records.json' => sub {
+        my $server = shift;
+        return $server->send_content( encode_as => 'json',
+                                    content      =>  $server->handle->list_types );
+    };
+
+
+
+
+    under 'records' => sub {
+
+        on qr|(.*)/(.*)/(.*)| => sub {
+            my $server = shift;
+            my $type   = $1;
+            my $uuid   = $2;
+            my $prop   = $3;
+            my $record = $server->load_record( type => $type, uuid => $uuid );
+            return $server->_send_404 unless ($record);
+            if ( my $val = $record->prop($prop) ) {
+                return $server->send_content(
+                    content_type => 'text/plain',
+                    content      => $val
+                );
+            } else {
+                return $server->_send_404();
+            }
+        };
+        on qr|(.*)/(.*).json| => sub {
+            my $server = shift;
+            my $type   = $1;
+            my $uuid   = $2;
+            my $record = $server->load_record( type => $type, uuid => $uuid );
+            return $server->_send_404 unless ($record);
+            return $server->send_content(
+                encode_as =>'json',
+                content      =>  $record->get_props 
+            );
+        };
+
+        on qr|(.*).json| => sub {
+            my $server = shift;
+            my $type = $1;
+            require Prophet::Collection;
+            my $col = Prophet::Collection->new(
+                handle => $server->handle,
+                type   => $type
+            );
+            $col->matching( sub {1} );
+            warn "Query language not implemented yet.";
+            return $server->send_content(
+                encode_as => 'json',
+                content      => 
+                    {   map {
+                            $_->uuid => "/records/$type/" . $_->uuid . ".json"
+                            } @$col
+                    }
+                
+            );
+        };
+
+        on '*' => sub {
+            my $server = shift;
+            return $server->handle_request_get_template();
+        };
+    };
+
+};
+
+on '*' =>  sub {return undef};
+
+no Moose;
+
+1;



More information about the Bps-public-commit mailing list