MT#11917 include journal in generated API doc page

Change-Id: Iab13239e892823e2708f5b13b985db42be45d136
changes/74/1674/1
Rene Krenn 11 years ago
parent b5dca5e6e2
commit 83fdc85702

@ -22,16 +22,23 @@ class_has('resource_name', is => 'ro', default => 'cftimesets');
class_has('dispatch_path', is => 'ro', default => '/api/cftimesets/');
class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-cftimesets');
class_has(@{ __PACKAGE__->get_journal_query_params() });
__PACKAGE__->config(
action => {
map { $_ => {
(map { $_ => {
ACLDetachTo => '/api/root/invalid_user',
AllowedRole => [qw/admin reseller/],
Args => 1,
Does => [qw(ACL RequireSSL)],
Method => $_,
Path => __PACKAGE__->dispatch_path,
} } @{ __PACKAGE__->allowed_methods },
} } @{ __PACKAGE__->allowed_methods }),
@{ __PACKAGE__->get_journal_action_config(__PACKAGE__->resource_name,{
ACLDetachTo => '/api/root/invalid_user',
AllowedRole => [qw/admin reseller/],
Does => [qw(ACL RequireSSL)],
}) }
},
action_roles => [qw(HTTPMethods)],
);
@ -110,6 +117,9 @@ sub PATCH :Allow {
$tset = $self->update_item($c, $tset, $old_resource, $resource, $form);
last unless $tset;
my $hal = $self->hal_from_item($c, $tset, "timesets");
last unless $self->add_update_journal_item_hal($c,$hal);
$guard->commit;
if ('minimal' eq $preference) {
@ -117,7 +127,7 @@ sub PATCH :Allow {
$c->response->header(Preference_Applied => 'return=minimal');
$c->response->body(q());
} else {
my $hal = $self->hal_from_item($c, $tset, "timesets");
#my $hal = $self->hal_from_item($c, $tset, "timesets");
my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new(
$hal->http_headers,
), $hal->as_json);
@ -149,6 +159,9 @@ sub PUT :Allow {
my $form = $self->get_form($c);
$tset = $self->update_item($c, $tset, $old_resource, $resource, $form);
last unless $tset;
my $hal = $self->hal_from_item($c, $tset, "destinationsets");
last unless $self->add_update_journal_item_hal($c,$hal);
$guard->commit;
@ -157,7 +170,7 @@ sub PUT :Allow {
$c->response->header(Preference_Applied => 'return=minimal');
$c->response->body(q());
} else {
my $hal = $self->hal_from_item($c, $tset, "destinationsets");
#my $hal = $self->hal_from_item($c, $tset, "destinationsets");
my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new(
$hal->http_headers,
), $hal->as_json);
@ -190,6 +203,41 @@ sub DELETE :Allow {
return;
}
sub item_base_journal :Journal {
my $self = shift @_;
return $self->handle_item_base_journal(@_);
}
sub journals_get :Journal {
my $self = shift @_;
return $self->handle_journals_get(@_);
}
sub journalsitem_get :Journal {
my $self = shift @_;
return $self->handle_journalsitem_get(@_);
}
sub journals_options :Journal {
my $self = shift @_;
return $self->handle_journals_options(@_);
}
sub journalsitem_options :Journal {
my $self = shift @_;
return $self->handle_journalsitem_options(@_);
}
sub journals_head :Journal {
my $self = shift @_;
return $self->handle_journals_head(@_);
}
sub journalsitem_head :Journal {
my $self = shift @_;
return $self->handle_journalsitem_head(@_);
}
sub end : Private {
my ($self, $c) = @_;

@ -14,6 +14,8 @@ require Catalyst::ActionRole::CheckTrailingSlash;
require Catalyst::ActionRole::HTTPMethods;
require Catalyst::ActionRole::RequireSSL;
use NGCP::Panel::Utils::Journal qw();
with 'NGCP::Panel::Role::API';
class_has('dispatch_path', is => 'ro', default => '/api/');
@ -79,7 +81,9 @@ sub GET : Allow {
} else {
$actions = [ keys %{ $full_mod->config->{action} } ];
}
my $uri = "/api/$rel/";
my $item_actions = [];
my $journal_resource_config = {};
if($full_item_mod->can('config')) {
if($c->user->read_only) {
foreach my $m(keys %{ $full_item_mod->config->{action} }) {
@ -87,7 +91,50 @@ sub GET : Allow {
push @{ $item_actions }, $m;
}
} else {
$item_actions = [ keys %{ $full_item_mod->config->{action} } ];
foreach my $m(keys %{ $full_item_mod->config->{action} }) {
next unless $m =~ /^(GET|HEAD|OPTIONS|PUT|PATCH|DELETE)$/;
push @{ $item_actions }, $m;
}
}
if($full_item_mod->can('resource_name')) {
my @operations = ();
my $op_config = {};
my $resource_name = $full_item_mod->resource_name;
$journal_resource_config = NGCP::Panel::Utils::Journal::get_journal_resource_config($c->config,$resource_name);
if (exists $full_mod->config->{action}->{POST}) {
$op_config = NGCP::Panel::Utils::Journal::get_api_journal_op_config($c->config,$resource_name,NGCP::Panel::Utils::Journal::CREATE_JOURNAL_OP);
if ($op_config->{operation_enabled}) {
push(@operations,"create (<span>POST $uri</span>)");
}
}
my $item_action_config = $full_item_mod->config->{action};
if (exists $item_action_config->{PUT} || exists $item_action_config->{PATCH}) {
$op_config = NGCP::Panel::Utils::Journal::get_api_journal_op_config($c->config,$resource_name,NGCP::Panel::Utils::Journal::UPDATE_JOURNAL_OP);
if ($op_config->{operation_enabled}) {
if (exists $item_action_config->{PUT} && exists $item_action_config->{PATCH}) {
push(@operations,"update (<span>PUT/PATCH $uri"."id</span>)");
} elsif (exists $item_action_config->{PUT}) {
push(@operations,"update (<span>PUT $uri"."id</span>)");
} elsif (exists $item_action_config->{PATCH}) {
push(@operations,"update (<span>PATCH $uri"."id</span>)");
}
}
}
if (exists $item_action_config->{DELETE}) {
$op_config = NGCP::Panel::Utils::Journal::get_api_journal_op_config($c->config,$resource_name,NGCP::Panel::Utils::Journal::CREATE_JOURNAL_OP);
if ($op_config->{operation_enabled}) {
push(@operations,"delete (<span>DELETE $uri"."id</span>)");
}
}
$journal_resource_config->{operations} = \@operations;
$journal_resource_config->{format} = $op_config->{format};
$journal_resource_config->{uri} = 'api/' . $resource_name . '/id/' . NGCP::Panel::Utils::Journal::API_JOURNAL_RESOURCE_NAME . '/';
$journal_resource_config->{query_params} = ($full_item_mod->can('journal_query_params') ? $full_item_mod->journal_query_params : []);
$journal_resource_config->{sorting_cols} = NGCP::Panel::Utils::Journal::JOURNAL_FIELDS;
$journal_resource_config->{item_uri} = $journal_resource_config->{uri} . 'journalitemid';
if (length(NGCP::Panel::Utils::Journal::API_JOURNALITEMTOP_RESOURCE_NAME) > 0) {
$journal_resource_config->{recent_uri} = $journal_resource_config->{uri} . NGCP::Panel::Utils::Journal::API_JOURNALITEMTOP_RESOURCE_NAME;
}
}
}
@ -110,12 +157,13 @@ sub GET : Allow {
actions => $actions,
item_actions => $item_actions,
sorting_cols => $sorting_cols,
uri => "/api/$rel/",
uri => $uri,
sample => $full_mod->can('documentation_sample') # generate pretty json, but without outer brackets (this is tricky though)
? to_json($full_mod->documentation_sample, {pretty => 1}) =~ s/(^\s*{\s*)|(\s*}\s*$)//rg =~ s/\n /\n/rg
: undef,
journal_resource_config => $journal_resource_config,
};
}
$c->stash(template => 'api/root.tt');

@ -49,6 +49,7 @@ sub hal_from_item {
Data::HAL::Link->new(relation => 'self', href => sprintf("%s%d", $self->dispatch_path, $item->id)),
Data::HAL::Link->new(relation => "ngcp:$type", href => sprintf("/api/%s/%d", $type, $item->id)),
Data::HAL::Link->new(relation => "ngcp:subscribers", href => sprintf("/api/subscribers/%d", $b_subs_id)),
$self->get_journal_relation_link($item->id),
],
relation => 'ngcp:'.$self->resource_name,
);

@ -40,6 +40,8 @@ use constant CONTENT_DEFAULT_FORMAT => CONTENT_JSON_FORMAT;
use constant API_JOURNAL_RELATION => 'ngcp:'.API_JOURNAL_RESOURCE_NAME;
#use constant API_JOURNALITEM_RELATION => 'ngcp:journalitem';
use constant JOURNAL_FIELDS => ['id', 'operation', 'resource_name', 'resource_id', 'timestamp', 'username'];
sub add_journal_item_hal {
my ($controller,$c,$operation,@args) = @_;
my $cfg = _get_api_journal_op_config($c,$controller->resource_name,$operation);
@ -357,7 +359,7 @@ sub get_journal_rs {
'resource_name' => $controller->resource_name,
'resource_id' => $resource_id,
},($all_columns ? undef : {
columns => [qw(id operation resource_name resource_id timestamp username)],
columns => JOURNAL_FIELDS,
#alias => 'me',
}));

@ -418,4 +418,31 @@ Preference-Applied: return=minimal';
[% END -%]
</div>
[% IF col.journal_resource_config.journal_resource_enabled -%]
<h[% level + 1 %]>Journal</h[% level + 1%]>
A collection showing the history of modifications to a particular [% title %] collection item can be accessed using <span>OPTIONS/GET/HEAD [% col.journal_resource_config.uri %]</span>. By configuration, CRUD operations below will be recorded:
[% UNLESS col.journal_resource_config.operations.size -%]
<br/>None.
[% ELSE -%]
<ul id="[% id %]-journal_operations">
[% FOR o IN col.journal_resource_config.operations -%]
<li>[% o %]</li>
[% END -%]
</ul>
[% END -%]
Query parameters:
<ul id="[% id %]-journal_qparams">
[% FOREACH f IN col.journal_resource_config.query_params -%]
<li><b>[% f.param %]</b>: [% f.description %]</li>
[% END -%]
<li><b>order_by</b>: Order collection by a specific attribute. Possible values are: <i>[% col.journal_resource_config.sorting_cols.join(', ') %]</i></li>
<li><b>order_by_direction</b>: Direction which the collection should be ordered by. Possible values are: <i>asc (default), desc</i></li>
</ul>
The item's state after a completed operation is serialized and stored in [% col.journal_resource_config.format -%] format. It can be retrieved by requesting the corresponding journal record with <span>OPTIONS/GET/HEAD [% col.journal_resource_config.item_uri %]</span>.
[% IF col.journal_resource_config.recent_uri -%]
The most recent journal record is directly accessible using <span>OPTIONS/GET/HEAD [% col.journal_resource_config.recent_uri %]</span>.
[% END -%]
[% END -%]
[% # vim: set tabstop=4 syntax=html expandtab: -%]

@ -22,8 +22,8 @@ for my $path(qw#/etc/ngcp-panel/ngcp_panel.conf etc/ngcp_panel.conf ngcp_panel.c
}
}
$panel_config //= 'ngcp_panel.conf';
#my $catalyst_config = Config::General->new("../ngcp_panel.conf");
my $catalyst_config = Config::General->new($panel_config);
my $catalyst_config = Config::General->new("../ngcp_panel.conf");
#my $catalyst_config = Config::General->new($panel_config);
my %config = $catalyst_config->getall();
my $enable_journal_tests = 1;
@ -38,17 +38,17 @@ my $ssl_ca_cert = $ENV{API_SSL_CA_CERT} || "/etc/ngcp-panel/api_ssl/api_ca.crt";
my ($ua, $req, $res);
$ua = LWP::UserAgent->new;
$ua->ssl_opts(
SSL_cert_file => $valid_ssl_client_cert,
SSL_key_file => $valid_ssl_client_key,
SSL_ca_file => $ssl_ca_cert,
);
#$ua->ssl_opts(
# verify_hostname => 0,
# SSL_cert_file => $valid_ssl_client_cert,
# SSL_key_file => $valid_ssl_client_key,
# SSL_ca_file => $ssl_ca_cert,
#);
#$ua->credentials("127.0.0.1:4443", "api_admin_http", 'administrator', 'administrator');
##$ua->timeout(500); #useless, need to change the nginx timeout
$ua->ssl_opts(
verify_hostname => 0,
);
$ua->credentials("127.0.0.1:4443", "api_admin_http", 'administrator', 'administrator');
#$ua->timeout(500); #useless, need to change the nginx timeout
my $t = time;
my $default_reseller_id = 1;
@ -62,16 +62,16 @@ my $customercontact = test_customercontact($t,$reseller);
my $customer = test_customer($customercontact,$billingprofile);
my $customerpreferences = test_customerpreferences($customer);
my $subscriberprofileset = test_subscriberprofileset($t,$reseller);
my $subscriberprofile = test_subscriberprofile($t,$subscriberprofileset);
my $profilepreferences = test_profilepreferences($subscriberprofile);
#my $subscriberprofileset = test_subscriberprofileset($t,$reseller);
#my $subscriberprofile = test_subscriberprofile($t,$subscriberprofileset);
#my $profilepreferences = test_profilepreferences($subscriberprofile);
my $subscriber = test_subscriber($t,$customer,$domain);
my $cfdestinationset = test_cfdestinationset($t,$subscriber);
my $systemsoundset = test_soundset($t,$reseller);
my $customersoundset = test_soundset($t,$reseller,$customer);
my $subscriberpreferences = test_subscriberpreferences($subscriber,$customersoundset,$systemsoundset);
#my $systemsoundset = test_soundset($t,$reseller);
#my $customersoundset = test_soundset($t,$reseller,$customer);
#my $subscriberpreferences = test_subscriberpreferences($subscriber,$customersoundset,$systemsoundset);

Loading…
Cancel
Save