blob: 5bdf8e880a6ea57e68f5360def7331f722dc3f22 [file] [log] [blame]
package Kalamar::Plugin::QueryReference;
use Mojo::Base 'Mojolicious::Plugin';
# This is a plugin to support query references.
# It currently only mocks endpoints for development purposes.
sub register {
my ($plugin, $mojo) = @_;
# Namespace not yet established
if ($ENV{QUERY_REF_MOCKUP}) {
unless (exists $mojo->renderer->helpers->{chi} &&
$mojo->chi('queryref')) {
$mojo->plugin(CHI => {
queryref => {
driver => 'Memory',
global => 1
}
});
};
};
# Establishes routes under '/query'
my $r = $mojo->routes;
$r->add_type('qname' => qr![-_\.a-zA-Z0-9]+!);
# List queries
$r->get('/query')->to(
cb => sub {
my $c = shift;
# Use mock up
if ($ENV{QUERY_REF_MOCKUP}) {
my $chi = $c->chi('queryref');
my $qs = $chi->get('~queries') // [];
my @queries = ();
foreach (@$qs) {
push @queries, $chi->get($_);
};
return $c->render(json => \@queries);
};
# Get user handle
my $user = $c->user_handle;
if ($user eq 'not_logged_in') {
return $c->render(
json => {
errors => [
message => 'User not logged in'
]
}, status => 400
);
};
$c->render_later;
# API for query adding
my $url = Mojo::URL->new($c->korap->api);
$url->path->merge(
Mojo::Path->new->parts(['query', '~' . $user])
)->trailing_slash(0);
# Issue backend request
$c->korap_request('get', $url)->then(
sub {
my $tx = shift;
# Catch errors and warnings
if ($c->catch_errors_and_warnings($tx)) {
my $json = $tx->res->json;
if ($json) {
$c->notify_on_warnings($json);
$c->stash(api_response => $json);
};
return $c->render(
status => $tx->res->code,
json => $json
);
};
Mojo::Promise->reject;
}
)->catch(
sub {
my $err_msg = shift;
# Only raised in case of connection errors
if ($err_msg) {
$c->notify(error => { src => 'Backend' } => $err_msg)
};
return $c->render(
status => 400,
json => $c->notifications(json => {})
);
}
);
}
);
# Create query
$r->put('/query/<qname:qname>')->to(
cb => sub {
my $c = shift;
my $v = $c->validation;
# Missing: definition
$v->required('q');
$v->optional('ql');
$v->optional('desc');
my $qname = $c->stash('qname');
if ($v->has_error()) {
return $c->render(
json => {
errors => [
{
message => 'Unable to store query reference'
}
]
}, status => 400
);
};
# Use mock up
if ($ENV{QUERY_REF_MOCKUP}) {
my $chi = $c->chi('queryref');
if ($chi->is_valid($qname)) {
return $c->render(
json => {
errors => [
{
message => 'Unable to store query reference'
}
]
}, status => 400
);
};
my $json = {
name => $qname,
# TODO: Actually this is KQ - not pq or similar
koralQuery => $v->param('q'),
q => $v->param('q'),
ql => ($v->param('ql') // 'poliqarp')
};
if ($v->param('desc')) {
$json->{description} = $v->param('desc');
};
# Set query reference
$chi->set($qname => $json);
my $queries = $chi->get('~queries') // [];
push @$queries, $qname;
$chi->set('~queries' => $queries);
return $c->render(
status => 201,
text => ''
);
};
# Get user handle
my $user = $c->user_handle;
if ($user eq 'not_logged_in') {
return $c->render(
json => {
errors => [
message => 'User not logged in'
]
}, status => 400
);
};
# API for query adding
my $url = Mojo::URL->new($c->korap->api);
$url->path->merge(
Mojo::Path->new->parts(['query', '~' . $user, $qname])
)->trailing_slash(0);
my $json = {
type => 'PRIVATE',
queryType => 'QUERY',
queryLanguage => ($v->param('ql') // 'poliqarp'),
query => $v->param('q')
};
if ($v->param('desc')) {
$json->{description} = $v->param('desc');
};
$c->render_later;
# Issue backend request
$c->korap_request('put', $url => json => $json)->then(
sub {
my $tx = shift;
if ($tx->res->is_error) {
my $json = $tx->res->json;
$c->notify_on_warnings($json);
$c->stash(api_response => $json);
return $c->render(
status => $tx->res->code,
json => $json
);
};
return $c->render(
status => 201,
text => ''
);
}
)->catch(
sub {
my $err_msg = shift;
# Only raised in case of connection errors
if ($err_msg) {
$c->notify(error => { src => 'Backend' } => $err_msg)
};
return $c->render(
status => 400,
json => $c->notifications(json => {})
);
}
);
}
);
# Delete query
$r->delete('/query/<qname:qname>')->to(
cb => sub {
my $c = shift;
my $qname = $c->stash('qname');
# Use mock up
if ($ENV{QUERY_REF_MOCKUP}) {
my $chi = $c->chi('queryref');
$chi->remove($qname);
my $queries = $chi->get('~queries') // [];
my @clean = ();
foreach (@$queries) {
push @clean, $_ unless $_ eq $qname
};
$chi->set('~queries' => \@clean);
return $c->render(
status => 200,
text => ''
);
};
# Get user handle
my $user = $c->user_handle;
if ($user eq 'not_logged_in') {
return $c->render(
json => {
errors => [
message => 'User not logged in'
]
}, status => 400
);
};
$c->render_later;
# API for query adding
my $url = Mojo::URL->new($c->korap->api);
$url->path->merge(
Mojo::Path->new->parts(['query', '~' . $user, $qname])
)->trailing_slash(0);
# Issue backend request
$c->korap_request('delete', $url)->then(
sub {
my $tx = shift;
if ($tx->res->is_error) {
my $json = $tx->res->json;
$c->notify_on_warnings($json);
$c->stash(api_response => $json);
return $c->render(
status => $tx->res->code,
json => $json
);
};
return $c->render(
status => 200,
text => ''
);
}
)->catch(
sub {
my $err_msg = shift;
# Only raised in case of connection errors
if ($err_msg) {
$c->notify(error => { src => 'Backend' } => $err_msg)
};
return $c->render(
status => 400,
json => $c->notifications(json => {})
);
}
);
}
);
# Retrieve query
$r->get('/query/<qname:qname>')->to(
cb => sub {
my $c = shift;
my $qname = $c->stash('qname');
# Use mock up
if ($ENV{QUERY_REF_MOCKUP}) {
my $chi = $c->chi('queryref');
my $json = $chi->get($qname);
if ($json) {
return $c->render(
json => $json
);
};
return $c->render(
json => {
errors => [
{
message => 'Query reference not found'
}
]
}, status => 404
);
};
# Get user handle
my $user = $c->user_handle;
if ($user eq 'not_logged_in') {
return $c->render(
json => {
errors => [
message => 'User not logged in'
]
}, status => 400
);
};
# API for query adding
my $url = Mojo::URL->new($c->korap->api);
$url->path->merge(
Mojo::Path->new->parts(['query', '~' . $user, $qname])
)->trailing_slash(0);
# Issue backend request
$c->korap_request('get', $url)->then(
sub {
my $tx = shift;
if ($tx->res->code == 404) {
return $c->render(
status => 404,
json => $tx->res->json
);
};
# Catch errors and warnings
if ($c->catch_errors_and_warnings($tx)) {
my $json = $tx->res->json;
if ($json) {
$c->notify_on_warnings($json);
$c->stash(api_response => $json);
};
return $c->render(
status => $tx->res->code,
json => $json
);
};
Mojo::Promise->reject;
}
)->catch(
sub {
my $err_msg = shift;
# Only raised in case of connection errors
if ($err_msg) {
$c->notify(error => { src => 'Backend' } => $err_msg)
};
return $c->render(
status => 400,
json => $c->notifications(json => {})
);
}
);
}
);
};
1;