MT#59662 enhance subscriber assigned header rules/sets handling

* POST /api/headerrules now supports either 'set_id' or 'subscriber_id'.
  When 'subsriber_id' is specified, a subscriber assigned header rule
  set is automatically created if it does not exist, as well as
  automatically removed when its last header rule is deleted.
* It is now possible to directly GET and DELETE /api/headerrules/:id
  where :id is a subscriber assigned header rule.
* It is now possible to directly GET and DELETE /api/headerrulesets/:id
  where :id is a subscriber assigned header rule set.
* Improve /api/headerrules data validation and duplicate header rule
  detection.
* It is now possible to expand by /api/headerrules/?expand=set_id field

Change-Id: I681bc61c2eed47a8e54847f07f31134f643930c2
mr12.3
Kirill Solomko 1 year ago
parent 1fb8d04136
commit aef4c89197

@ -39,7 +39,7 @@ sub query_params {
},
{
param => 'subscriber_id',
description => 'Filter for header rule sets of a specific subscriber',
description => 'Filter for header rules of a specific subscriber',
}
];
}
@ -49,10 +49,46 @@ sub create_item {
my $item;
my $schema = $c->model('DB');
try {
my $header_actions = delete $resource->{actions};
my $header_conditions = delete $resource->{conditions};
my $subscriber_id = delete $resource->{subscriber_id};
my $set;
if ($subscriber_id) {
my $sub = $schema->resultset('voip_subscribers')->find($subscriber_id);
my $prov_sub = $sub->provisioning_voip_subscriber;
my $reseller_id = $sub->contract->contact->reseller_id;
$set = $schema->resultset('voip_header_rule_sets')->search({
subscriber_id => $prov_sub->id,
})->first;
unless ($set) {
$set = $schema->resultset('voip_header_rule_sets')->create({
name => 'subscriber_'.$subscriber_id,
subscriber_id => $prov_sub->id,
reseller_id => $reseller_id,
description => '',
});
}
$resource->{set_id} = $set->id;
} else {
$set = $schema->resultset('voip_header_rule_sets')->find($resource->{set_id});
}
my $existing_item = $schema->resultset('voip_header_rules')->search({
name => $resource->{name},
set_id => $set->id,
})->first;
if ($existing_item) {
$c->log->error("header rule with name '$$resource{name}' already exists");
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Header rule with this name already exists");
return;
}
$item = $schema->resultset('voip_header_rules')->create($resource);
if ($header_actions) {
foreach my $action (@$header_actions) {
$action->{rule_id} = $item->id;
@ -65,6 +101,7 @@ sub create_item {
my $action_result = $schema->resultset('voip_header_rule_actions')->create($action);
}
}
if ($header_conditions) {
foreach my $condition (@$header_conditions) {
$condition->{rule_id} = $item->id;
@ -77,6 +114,7 @@ sub create_item {
my $condition_result = $schema->resultset('voip_header_rule_conditions')->create($condition);
}
}
NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset(
c => $c, set_id => $item->ruleset->id
);

@ -32,9 +32,18 @@ sub get_journal_methods {
sub delete_item {
my ($self, $c, $item) = @_;
my $set_id = $item->ruleset->id;
my $ruleset = $item->ruleset;
my $set_id = $ruleset->id;
my $subscriber_id = $ruleset->subscriber_id;
my $res = $self->SUPER::delete_item($c, $item);
if ($ruleset->subscriber_id) {
$ruleset->discard_changes;
if (!$ruleset->voip_header_rules->count()) {
$ruleset->delete;
}
}
NGCP::Panel::Utils::HeaderManipulations::invalidate_ruleset(
c => $c, set_id => $set_id
);

@ -5,10 +5,23 @@ extends 'NGCP::Panel::Form::Header::Rule';
has_field 'set_id' => (
type => 'PosInteger',
required => 1,
required => 0,
element_attr => {
rel => ['tooltip'],
title => ['Header rule set id, one the rule must belong to.'],
expand => {
class => 'NGCP::Panel::Role::API::HeaderRuleSets',
allowed_roles => [qw(admin reseller)],
},
},
);
has_field 'subscriber_id' => (
type => 'PosInteger',
required => 0,
element_attr => {
rel => ['tooltip'],
title => ['Subscriber id, to create a subscriber assigned header rule.'],
},
);

@ -28,7 +28,7 @@ sub get_form {
}
sub _item_rs {
my ($self, $c, $type) = @_;
my ($self, $c, $by_id) = @_;
my $item_rs;
if ($c->user->roles eq "admin") {
@ -43,20 +43,26 @@ sub _item_rs {
);
$item_rs = $item_rs->search_rs(
{ subscriber_id => $prov_subscriber_id });
} else {
} elsif (!$by_id) {
$item_rs = $item_rs->search_rs(
{ subscriber_id => undef });
}
return $item_rs;
}
sub item_by_id {
my ($self, $c, $id) = @_;
my $item_rs = $self->item_rs($c, 1);
return $item_rs->find($id);
}
sub post_process_hal_resource {
my ($self, $c, $item, $resource, $form) = @_;
if ($resource->{subscriber_id}) {
my $subscriber_id = NGCP::Panel::Utils::Subscriber::prov_to_billing_subscriber_id(
c => $c, subscriber_id => $resource->{subscriber_id}
);
$resource->{subscriber_id} = $subscriber_id // 0;
$resource->{subscriber_id} = $subscriber_id // undef;
}
return $resource;
}

@ -21,13 +21,12 @@ sub config_allowed_roles {
}
sub _item_rs {
my ($self, $c, $type) = @_;
my ($self, $c, $by_id) = @_;
my $item_rs = $c->model('DB')->resultset('voip_header_rules')->search_rs(undef, {
join => 'ruleset'
});
if ($c->user->roles eq "reseller") {
$item_rs = $c->model('DB')->resultset('voip_header_rules')->search_rs({
'ruleset.reseller_id' => $c->user->reseller_id,
@ -40,7 +39,7 @@ sub _item_rs {
);
$item_rs = $item_rs->search_rs(
{ 'ruleset.subscriber_id' => $prov_subscriber_id });
} else {
} elsif (!$by_id) {
$item_rs = $item_rs->search_rs(
{ 'ruleset.subscriber_id' => undef });
}
@ -48,6 +47,12 @@ sub _item_rs {
return $item_rs;
}
sub item_by_id {
my ($self, $c, $id) = @_;
my $item_rs = $self->item_rs($c, 1);
return $item_rs->find($id);
}
sub get_form {
my ($self, $c) = @_;
return ( NGCP::Panel::Form::get("NGCP::Panel::Form::Header::RuleAPI", $c) );
@ -64,8 +69,8 @@ sub check_resource {
my ($self, $c, $item, $old_resource, $resource, $form, $process_extras) = @_;
my $schema = $c->model('DB');
unless (defined $resource->{set_id}) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required: 'set_id'");
unless ($resource->{set_id} || $resource->{subscriber_id}) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Required: 'set_id' or 'subscriber_id'");
return;
}
@ -74,16 +79,33 @@ sub check_resource {
$reseller_id = $c->user->reseller_id;
}
my $ruleset = $schema->resultset('voip_header_rule_sets')->find({
id => $resource->{set_id},
($reseller_id ? (reseller_id => $reseller_id) : ()),
});
unless ($ruleset) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'set_id'.");
return;
if ($resource->{set_id}) {
my $ruleset = $schema->resultset('voip_header_rule_sets')->find({
id => $resource->{set_id},
($reseller_id ? (reseller_id => $reseller_id) : ()),
});
unless ($ruleset) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'set_id'.");
return;
}
$c->stash->{checked}->{ruleset} = $ruleset;
}
$c->stash->{checked}->{ruleset} = $ruleset;
if ($resource->{subscriber_id}) {
my $sub = $schema->resultset('voip_subscribers')->find({
id => $resource->{subscriber_id},
status => { '!=' => 'terminated' },
($reseller_id
? ('contract.contact.reseller_id' => $reseller_id)
: ()),
},{
join => { 'contract' => 'contact' },
});
unless ($sub) {
$self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Invalid 'subscriber_id'");
return;
}
}
return 1;
}

Loading…
Cancel
Save