MT#7771 Introduce @{...} for match in rewrite rule

It inflates to $(avp(s:xxx)[*]) and can then be used to match against
AVP lists.
gjungwirth/voicemail_number
Andreas Granig 12 years ago
parent fae332191a
commit 2d9be3f212

@ -327,6 +327,7 @@ sub rules_root :Chained('rules_list') :PathPart('') :Args(0) {
my $mp = $row->match_pattern;
my $rp = $row->replace_pattern;
$mp =~ s/\$avp\(s\:(\w+)\)/\${$1}/g;
$mp =~ s/\$\(avp\(s\:(\w+)\)\[\*\]\)/\@{$1}/g;
$rp =~ s/\$avp\(s\:(\w+)\)/\${$1}/g;
$row->match_pattern($mp);
$row->replace_pattern($rp);

@ -14,7 +14,7 @@ sub build_form_element_class {[qw(form-horizontal)]}
has_field 'match_pattern' => (
type => '+NGCP::Panel::Field::Regexp',
required => 1,
inflate_default_method => \&inflate_pattern,
inflate_default_method => \&inflate_match_pattern,
element_attr => {
rel => ['tooltip'],
title => ['Match pattern, a regular expression.'],
@ -25,7 +25,7 @@ has_field 'replace_pattern' => (
type => 'Text',
required => 1,
label => 'Replacement Pattern',
inflate_default_method => \&inflate_pattern,
inflate_default_method => \&inflate_replace_pattern,
element_attr => {
rel => ['tooltip'],
title => ['Replacement pattern.'],
@ -87,10 +87,19 @@ has_block 'actions' => (
before 'update_model' => sub {
my $self = shift;
$self->value->{match_pattern} =~ s/\$\{(\w+)\}/\$avp(s:$1)/g;
$self->value->{match_pattern} =~ s/\@\{(\w+)\}/\$(avp(s:$1)[*])/g;
$self->value->{replace_pattern} =~ s/\$\{(\w+)\}/\$avp(s:$1)/g;
};
sub inflate_pattern {
sub inflate_match_pattern {
my ($self, $value) = @_;
$value =~ s/\$avp\(s\:(\w+)\)/\${$1}/g;
$value =~ s/\$\(avp\(s\:(\w+)\)\[\*\]\)/\@{$1}/g;
return $value;
}
sub inflate_replace_pattern {
my ($self, $value) = @_;
$value =~ s/\$avp\(s\:(\w+)\)/\${$1}/g;
@ -103,6 +112,7 @@ sub validate {
my $r = $self->field('replace_pattern')->value // "";
my $_ = "";
my $re = "s/$s/$r/";
eval { use warnings FATAL => qw(all); m/$re/; };
if( $@ && $self->field('match_pattern')->num_errors < 1 ) {
@ -114,12 +124,23 @@ sub validate {
if ( $r =~ m/\$$/ ) {
$self->field('replace_pattern')->add_error('Cannot end with "$"');
}
if ( my ($found) = $r =~ m/^([*?])/ ) {
$self->field('replace_pattern')->add_error("Cannot start with \"$found\"");
}
if ( $r =~ m/\s/ ) {
$self->field('replace_pattern')->add_error("Spaces are not allowed in replacement pattern");
}
my @acount;
@acount = $s =~ /(\@\{\w+\})/g;
if(@acount > 1) {
$self->field('match_pattern')->add_error("Cannot use more than one array variable in match pattern");
}
@acount = $r =~ /(\@\{\w+\})/g;
if(@acount > 0) {
$self->field('match_pattern')->add_error("Cannot use array variable in replacement pattern");
}
}
1;

@ -861,6 +861,7 @@ sub apply_rewrite {
});
my $cache = {};
foreach my $r($rule_rs->all) {
my @entries = ();
my $match = $r->match_pattern;
my $replace = $r->replace_pattern;
@ -868,38 +869,79 @@ sub apply_rewrite {
for my $field($match, $replace) {
#print ">>>>>>>>>>> normalizing $field\n";
my @avps = ();
@avps = ($field =~ /\$avp\(s:calle(?:r|e)_([^\)]+)\)/g);
@avps = ($field =~ /\$\(?avp\(s:calle(?:r|e)_([^\)]+)\)/g);
@avps = keys %{{ map { $_ => 1 } @avps }};
for my $avp(@avps) {
#print ">>>>>>>>>> checking avp $avp\n";
if(!exists $cache->{$avp}) {
my $pref_rs = NGCP::Panel::Utils::Preferences::get_usr_preference_rs(
c => $c, attribute => $avp,
prov_subscriber => $subscriber->provisioning_voip_subscriber,
);
unless($pref_rs && $pref_rs->count) {
$pref_rs = NGCP::Panel::Utils::Preferences::get_dom_preference_rs(
if($avp eq "pbx_account_cli_list") {
$cache->{$avp} = [];
foreach my $sub($subscriber->contract->voip_subscribers->all) {
foreach my $num($sub->voip_numbers->search({ status => 'active' })->all) {
my $v = $num->cc . ($num->ac // '') . $num->sn;
unless($v ~~ $cache->{$avp}) {
push @{ $cache->{$avp} }, $v;
}
}
}
} else {
my $pref_rs = NGCP::Panel::Utils::Preferences::get_usr_preference_rs(
c => $c, attribute => $avp,
prov_domain => $subscriber->provisioning_voip_subscriber->domain,
prov_subscriber => $subscriber->provisioning_voip_subscriber,
);
unless($pref_rs && $pref_rs->count) {
$pref_rs = NGCP::Panel::Utils::Preferences::get_dom_preference_rs(
c => $c, attribute => $avp,
prov_domain => $subscriber->provisioning_voip_subscriber->domain,
);
}
next unless($pref_rs);
if($field =~ /\$\(avp/) { # $(avp(s:xxx)[*])
$cache->{$avp} = [ $pref_rs->get_column('value')->all ];
} else {
$cache->{$avp} = $pref_rs->first ? $pref_rs->first->value : '';
}
}
next unless($pref_rs);
$cache->{$avp} = $pref_rs->first ? $pref_rs->first->value : '';
}
my $val = $cache->{$avp};
$field =~ s/\$avp\(s:calle(?:r|e)_$avp\)/$val/g;
if(ref $val eq "ARRAY") {
my $orig = $field; $field = [];
$orig = shift @{ $orig } if(ref $orig eq "ARRAY");
foreach my $v(@{ $val }) {
my $tmporig = $orig;
$tmporig =~ s/\$avp\(s:calle(?:r|e)_$avp\)/$v/g;
$tmporig =~ s/\$\(avp\(s:calle(?:r|e)_$avp\)\[\*\]\)/$v/g;
push @{ $field }, $tmporig;
}
} else {
my $orig = $field;
$orig = shift @{ $orig } if(ref $orig eq "ARRAY");
$orig =~ s/\$avp\(s:calle(?:r|e)_$avp\)/$val/g;
$field = [] unless(ref $field eq "ARRAY");
push @{ $field }, $orig;
}
#print ">>>>>>>>>>> normalized $field\n";
}
}
$match = [ $match ] if(ref $match ne "ARRAY");
$replace = shift @{ $replace } if(ref $replace eq "ARRAY");
$replace =~ s/\\(\d{1})/\$$1/g;
#print ">>>>>>>>>>> final match=$match, replace=$replace, applying to $callee\n";
$replace =~ s/\"/\\"/g;
$replace = qq{"$replace"};
if($callee =~ s/$match/$replace/eeg) {
# we only process one match
last;
my $found;
foreach my $m(@{ $match }) {
if($callee =~ s/$m/$replace/eeg) {
# we only process one match
$found = 1;
last;
}
}
last if $found;
#print ">>>>>>>>>>> done, match=$match, replace=$replace, callee is $callee\n";
}

Loading…
Cancel
Save