File Coverage

blib/lib/Clustericious.pm
Criterion Covered Total %
statement 58 58 100.0
branch 6 6 100.0
condition 5 8 62.5
subroutine 14 14 100.0
pod n/a
total 83 86 96.5


line stmt bran cond sub pod time code
1             package Clustericious;
2              
3 57     57   551523 use strict;
  57         182  
  57         1653  
4 57     57   314 use warnings;
  57         101  
  57         1340  
5 57     57   881 use 5.010;
  57         195  
6 57     57   309 use File::Spec;
  57         112  
  57         1513  
7 57     57   286 use File::Glob qw( bsd_glob );
  57         97  
  57         3461  
8 57     57   349 use File::Path qw( mkpath );
  57         110  
  57         10997  
9              
10             # ABSTRACT: A framework for RESTful processing systems.
11             our $VERSION = '1.27'; # VERSION
12              
13              
14             sub _testing
15             {
16 113     113   252 state $test = 0;
17 113         361 my($class, $new) = @_;
18 113 100       379 $test = $new if defined $new;
19 113         13304 $test;
20             }
21              
22             sub _config_path
23             {
24 215         1835 grep { -d $_ }
25 215         1716 map { File::Spec->catdir(@$_) }
26 276         797 grep { defined $_->[0] }
27             (
28 93 100   93   497 [ $ENV{CLUSTERICIOUS_CONF_DIR} ],
29             (!_testing) ? (
30             [ bsd_glob('~'), 'etc' ],
31             [ bsd_glob('~/.config/Perl/Clustericious') ],
32             [ '', 'etc' ],
33             ) : (),
34             );
35             }
36              
37             sub _slurp_pid ($)
38             {
39 57     57   9309 use autodie;
  57         352993  
  57         478  
40 2     2   1684 my($fn) = @_;
41 2         13 open my $fh, '<', $fn;
42 2         3130 my $pid = <$fh>;
43 2         15 close $fh;
44 2         794 chomp $pid;
45 2         18 $pid;
46             }
47              
48             sub _dist_dir
49             {
50 33     33   605 state $dir;
51 33   66     152 $dir //= do {
52 25         556 require Path::Class::Dir;
53 25         30248 require File::ShareDir::Dist;
54 25   50     20958 Path::Class::Dir->new(
55             File::ShareDir::Dist::dist_share('Clustericious') or die "unable to find share directory",
56             );
57             };
58             }
59              
60             sub _generate_port
61             {
62 10     10   431 require IO::Socket::INET;
63             # this code is duplicated in Test::Clustericious::Command,
64             # don't want to move it just FYI
65 10         14506 IO::Socket::INET->new(Listen => 5, LocalAddr => "127.0.0.1")->sockport
66             }
67              
68             sub _my_dist_data
69             {
70 11     11   302 my $dir = bsd_glob '~/.local/share/Perl/dist/Clustericious';
71 11         3167 mkpath $dir, 0, 0700;
72 11         107 $dir;
73             }
74              
75             sub _default_url
76             {
77 11     11   32 my(undef, $app_name) = @_;
78 11         69 require Path::Class::File;
79 11         46 require JSON::MaybeXS;
80 11         41 require Mojo::URL;
81 11         43 my $file = Path::Class::File->new(_my_dist_data(), 'default_ports.json');
82              
83 11         1514 $app_name =~ s{::}{-};
84            
85 11 100       55 my $data = -f $file ? JSON::MaybeXS::decode_json(scalar $file->slurp) : {};
86            
87 11   66     1349 $data->{$app_name} // do {
88 9         87 my $url = Mojo::URL->new('http://127.0.0.1');
89 9         2793 $url->port(__PACKAGE__->_generate_port);
90 9         3234 $url = $url->to_string;
91              
92 9         3606 $data->{$app_name} = $url;
93 9         135 $file->spew(JSON::MaybeXS::encode_json($data));
94              
95 9         2520 $url;
96             };
97             }
98              
99             # Note sub _config_uncache also gets placed
100             # in this package, but it is defined in
101             # Clustericious::Config.
102              
103             1;
104              
105             __END__
106              
107             =pod
108              
109             =encoding UTF-8
110              
111             =head1 NAME
112              
113             Clustericious - A framework for RESTful processing systems.
114              
115             =head1 VERSION
116              
117             version 1.27
118              
119             =head1 SYNOPSIS
120              
121             Generate a new Clustericious application:
122              
123             % clustericious generate app MyApp
124              
125             Basic application layout:
126              
127             package MyApp;
128            
129             use Mojo::Base qw( Clustericious::App );
130            
131             sub startup
132             {
133             my($self) = @_;
134             $self->SUPER::startup;
135             # app startup
136             }
137            
138             package MyApp::Routes;
139            
140             use Clustericious::RouteBuilder;
141            
142             # Mojolicious::Lite style routing
143             get '/' => sub { shift->render(text => 'welcome to myapp') };
144              
145             Basic testing for Clustericious application:
146              
147             use Test::Clustericious::Cluster;
148             use Test::More tests => 4;
149            
150             # see Test::Clustericious::Cluster for more details
151             # and examples.
152             my $cluster = Test::Clustericious::Cluster->new;
153             $cluster->create_cluster_ok('MyApp'); # 1
154            
155             my $url = $cluster->url;
156             my $t = $cluster->t; # Test::Mojo object
157            
158             $t->get_ok("$url/") # 2
159             ->status_is(200) # 3
160             ->content_is('welcome to myapp'); # 4
161            
162             __DATA__
163            
164             @ etc/MyApp.conf
165             ---
166             url: <%= cluster->url %>
167              
168             =head1 DESCRIPTION
169              
170             Clustericious is a web application framework designed to create HTTP/RESTful
171             web services that operate on a cluster, where each service does one thing
172             and ideally does it well. The design goal is to allow for easy deployment
173             of applications. Clustericious is based on the L<Mojolicious> and borrows
174             some ideas from L<Mojolicious::Lite> (L<Clustericious::RouteBuilder> is
175             based on L<Mojolicious::Lite> routing).
176              
177             Two examples of Clustericious applications on CPAN are L<Yars> the archive
178             server and L<PlugAuth> the authentication server.
179              
180             =head1 FEATURES
181              
182             Here are some of the distinctive aspects of Clustericious :
183              
184             =over 4
185              
186             =item *
187              
188             Simplified route builder based on L<Mojolicious::Lite> (see L<Clustericious::RouteBuilder>).
189              
190             =item *
191              
192             Provides a set of default routes (e.g. /status, /version, /api) for consistent
193             interaction with Clustericious services (see L<Clustericious::Plugin::CommonRoutes>).
194              
195             =item *
196              
197             Introspects the routes available and publishes the API as /api.
198              
199             =item *
200              
201             Automatically handle different formats (YAML or JSON) depending on request
202             (see L<Clustericious::Plugin::AutodataHandler>).
203              
204             =item *
205              
206             Interfaces with L<Clustericious::Client> to allow easy creation of
207             clients.
208              
209             =item *
210              
211             Uses L<Clustericious::Config> for configuration.
212              
213             =item *
214              
215             Uses L<Clustericious::Log> for logging.
216              
217             =item *
218              
219             Integrates with L<Module::Build::Database> and L<Rose::Planter>
220             to provide a basic RESTful CRUD interface to a database.
221              
222             =item *
223              
224             Provides 'stop' and 'start' commands, and high-level configuration
225             facilities for a variety of deployment options.
226              
227             =back
228              
229             =head1 AUTHOR
230              
231             Original author: Brian Duggan
232              
233             Current maintainer: Graham Ollis E<lt>plicease@cpan.orgE<gt>
234              
235             Contributors:
236              
237             Curt Tilmes
238              
239             Yanick Champoux
240              
241             =head1 COPYRIGHT AND LICENSE
242              
243             This software is copyright (c) 2013 by NASA GSFC.
244              
245             This is free software; you can redistribute it and/or modify it under
246             the same terms as the Perl 5 programming language system itself.
247              
248             =cut