From 9d6666ceb6836fd40e493407eac272fd9634d9ce Mon Sep 17 00:00:00 2001 From: Gerhard Jungwirth Date: Thu, 12 Oct 2017 15:49:32 +0200 Subject: [PATCH] TT#23280 proper domain reload xmlrpc tries multiple times to reload domain on all proxies and fails if unsuccessful. adapted conflicts to previous Moose way of XMLDispatcher Change-Id: I7a08df97243d0389232a0c0c7ad95652f87c7eb7 (cherry picked from commit acade2e5997ec7c485055169915f055185e0bf3c) --- lib/NGCP/Panel/Controller/API/Domains.pm | 8 +- lib/NGCP/Panel/Controller/API/DomainsItem.pm | 3 +- lib/NGCP/Panel/Controller/Domain.pm | 52 +++++++------ lib/NGCP/Panel/Role/API/Domains.pm | 15 ---- lib/NGCP/Panel/Utils/XMLDispatcher.pm | 81 ++++++++++++++++---- 5 files changed, 98 insertions(+), 61 deletions(-) diff --git a/lib/NGCP/Panel/Controller/API/Domains.pm b/lib/NGCP/Panel/Controller/API/Domains.pm index 8bcbeb30e7..b422cbd662 100644 --- a/lib/NGCP/Panel/Controller/API/Domains.pm +++ b/lib/NGCP/Panel/Controller/API/Domains.pm @@ -13,6 +13,7 @@ require Catalyst::ActionRole::ACL; require Catalyst::ActionRole::CheckTrailingSlash; require NGCP::Panel::Role::HTTPMethods; require Catalyst::ActionRole::RequireSSL; +use NGCP::Panel::Utils::XMLDispatcher; sub allowed_methods{ return [qw/GET POST OPTIONS HEAD/]; @@ -229,12 +230,7 @@ sub POST :Allow { try { $self->xmpp_domain_reload($c, $resource->{domain}) if $xmpp_reload; - if ($sip_reload) { - my (undef, $xmlrpc_res) = $self->sip_domain_reload($c); - if (!defined $xmlrpc_res || $xmlrpc_res < 1) { - die "XMLRPC failed"; - } - } + NGCP::Panel::Utils::XMLDispatcher::sip_domain_reload($c, $resource->{domain}) if ($sip_reload); } catch($e) { $c->log->error("failed to activate domain: $e. Domain created"); # TODO: user, message, trace, ... $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to activate domain. Domain was created"); diff --git a/lib/NGCP/Panel/Controller/API/DomainsItem.pm b/lib/NGCP/Panel/Controller/API/DomainsItem.pm index 3f6cb63577..b360c8b1a4 100644 --- a/lib/NGCP/Panel/Controller/API/DomainsItem.pm +++ b/lib/NGCP/Panel/Controller/API/DomainsItem.pm @@ -13,6 +13,7 @@ use NGCP::Panel::Utils::ValidateJSON qw(); require Catalyst::ActionRole::ACL; require NGCP::Panel::Role::HTTPMethods; require Catalyst::ActionRole::RequireSSL; +use NGCP::Panel::Utils::XMLDispatcher; sub allowed_methods{ return [qw/GET OPTIONS HEAD DELETE/]; @@ -145,7 +146,7 @@ sub DELETE :Allow { try { $self->xmpp_domain_disable($c, $domain) if $xmpp_reload; - $self->sip_domain_reload($c) if $sip_reload; + NGCP::Panel::Utils::XMLDispatcher::sip_domain_reload($c) if $sip_reload; } catch($e) { $c->log->error("failed to deactivate domain: $e"); # TODO: user, message, trace, ... $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to deactivate domain."); diff --git a/lib/NGCP/Panel/Controller/Domain.pm b/lib/NGCP/Panel/Controller/Domain.pm index 382b868a67..90b0ffcddc 100644 --- a/lib/NGCP/Panel/Controller/Domain.pm +++ b/lib/NGCP/Panel/Controller/Domain.pm @@ -143,11 +143,13 @@ sub create :Chained('dom_list') :PathPart('create') :Args() { NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/domain')); } - my (undef, $xmlrpc_res) = $self->_sip_domain_reload($c); - if (!defined $xmlrpc_res || $xmlrpc_res < 1) { + try { + NGCP::Panel::Utils::XMLDispatcher::sip_domain_reload($c, $form->value->{domain}); + } catch ($e) { NGCP::Panel::Utils::Message::error( c => $c, desc => $c->loc('Failed to activate domain. Domain was created.'), + error => $e, ); NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/domain')); } @@ -231,7 +233,17 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) { return; } - $self->_sip_domain_reload($c); + try { + NGCP::Panel::Utils::XMLDispatcher::sip_domain_reload($c, $form->value->{domain}); + } catch ($e) { + NGCP::Panel::Utils::Message::error( + c => $c, + desc => $c->loc('Failed to reload proxy. Domain was modified.'), + error => $e, + ); + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/domain')); + return; + } NGCP::Panel::Utils::Message::info( c => $c, desc => $c->loc('Domain successfully updated'), @@ -270,13 +282,24 @@ sub delete :Chained('base') :PathPart('delete') :Args(0) { return; } - $self->_sip_domain_reload($c); + try { + NGCP::Panel::Utils::XMLDispatcher::sip_domain_reload($c); + } catch ($e) { + NGCP::Panel::Utils::Message::error( + c => $c, + desc => $c->loc('Failed to reload proxy. Domain was deleted.'), + error => $e, + ); + NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/domain')); + return; + } NGCP::Panel::Utils::Message::info( c => $c, data => { $c->stash->{domain_result}->get_inflated_columns }, desc => $c->loc('Domain successfully deleted!'), ); $c->response->redirect($c->uri_for()); + return; } sub ajax :Chained('dom_list') :PathPart('ajax') :Args(0) { @@ -400,21 +423,6 @@ sub load_preference_list :Private { ); } -sub _sip_domain_reload { - my ($self, $c) = @_; - my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new; - my ($res) = $dispatcher->dispatch($c, "proxy-ng", 1, 1, < - -domain.reload - - -EOF - - return ref $res ? @{ $res } : (); -} - - 1; __END__ @@ -483,12 +491,6 @@ Retrieves and processes a datastructure containing preference groups, preference Data that is put on stash: pref_groups -=head2 _sip_domain_reload - -Ported from ossbss - -reloads domain cache of sip proxies - =head1 AUTHOR Andreas Granig,,, diff --git a/lib/NGCP/Panel/Role/API/Domains.pm b/lib/NGCP/Panel/Role/API/Domains.pm index 8cac6db157..19d9d5639e 100644 --- a/lib/NGCP/Panel/Role/API/Domains.pm +++ b/lib/NGCP/Panel/Role/API/Domains.pm @@ -10,7 +10,6 @@ use NGCP::Panel::Utils::DataHal qw(); use NGCP::Panel::Utils::DataHalLink qw(); use HTTP::Status qw(:constants); use JSON::Types; -use NGCP::Panel::Utils::XMLDispatcher; use NGCP::Panel::Utils::Prosody; sub get_form { @@ -138,20 +137,6 @@ sub item_by_id { return $item_rs->find($id); } -sub sip_domain_reload { - my ($self, $c) = @_; - my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new; - my ($res) = $dispatcher->dispatch($c, "proxy-ng", 1, 1, < - -domain.reload - - -EOF - - return ref $res ? @{ $res } : (); -} - sub xmpp_domain_reload { my ($self, $c, $domain) = @_; NGCP::Panel::Utils::Prosody::activate_domain($c, $domain); diff --git a/lib/NGCP/Panel/Utils/XMLDispatcher.pm b/lib/NGCP/Panel/Utils/XMLDispatcher.pm index 1d5cf45e58..ef1062fe4f 100644 --- a/lib/NGCP/Panel/Utils/XMLDispatcher.pm +++ b/lib/NGCP/Panel/Utils/XMLDispatcher.pm @@ -20,18 +20,18 @@ sub dispatch { $c->log->info("dispatching to target $target, all=$all, sync=$sync"); $c->log->debug("dispatching body $body"); - my $hosts; - if ($target =~ /^%TG%/) { - my @t = split(/::/, $target); - $hosts = [{ip => $t[2], port => $t[3], path => $t[4], id => $t[5]}]; - } - else { - my $host_rs = $schema->resultset('xmlgroups') - ->search_rs({name => $target}) - ->search_related('xmlhostgroups')->search_related('host', {}, { order_by => 'id' }); - $hosts = [map +{ip => $_->ip, port => $_->port, path => $_->path, - id => $_->id}, $host_rs->all]; - } + my $hosts; + if ($target =~ /^%TG%/) { + my @t = split(/::/, $target); + $hosts = [{ip => $t[2], port => $t[3], path => $t[4], id => $t[5]}]; + } + else { + my $host_rs = $schema->resultset('xmlgroups') + ->search_rs({name => $target}) + ->search_related('xmlhostgroups')->search_related('host', {}, { order_by => 'id' }); + $hosts = [map +{ip => $_->ip, port => $_->port, path => $_->path, + id => $_->id}, $host_rs->all]; + } use Data::Dumper; $c->log->info("dispatching to hosts: " . Dumper $hosts); @@ -133,7 +133,7 @@ sub _dequeue { },{ order_by => 'id' })->first; - $row or return; + $row or return; $row->update({ tries => \'tries+1', @@ -141,7 +141,7 @@ sub _dequeue { next_try => \['unix_timestamp() + ?', [{} => 5 + $row->tries * 30]], }); - return $row; + return $row; } sub _unqueue { @@ -150,6 +150,59 @@ sub _unqueue { $self->schema->resultset('xmlqueue')->find($id)->delete; } +# dies if unsuccessful +# not an object method +sub sip_domain_reload { + my ($c, $domain_name) = @_; + + my $NUM_TRIES = 3; + my $SLEEP_BEFORE_RETRY = 1; + my $res; + my $dispatcher = NGCP::Panel::Utils::XMLDispatcher->new; + + my $reload_command = < + +domain.reload + + +EOF + + my $dump_command = < + +domain.dump + + +EOF + + for (my $i = 0; $i < $NUM_TRIES; $i++) { + sleep $SLEEP_BEFORE_RETRY if ($i > 0); + + ($res) = $dispatcher->dispatch($c, "proxy-ng", 1, 1, $reload_command); # we're only checking first host here + if ($res->[1] < 1) { + die "couldn't reload domains"; + } + return () unless $domain_name; + my @replies = $dispatcher->dispatch($c, "proxy-ng", 1, 1, $dump_command); + my $all_successful = 1; + for my $reply (@replies) { + if ($reply->[1] && $reply->[2] =~ m/$domain_name/) { + # successful + } else { + $c->log->debug("Domain not loaded. Retrying..."); + $all_successful = 0; + } + } + if ($all_successful) { + $c->log->debug("Domain successfully loaded in all proxies"); + return; + } + } + + die "couldn't load domain into all proxies. Tried $NUM_TRIES times."; +} + no Moose; 1;