TT#58688 CCS importer: set CFU for subs with "1:1" routing typ

Change-Id: Ifc4f2d4ca4e11770f3375c57d7c72443f9b830b1
changes/22/29722/4
Rene Krenn 6 years ago
parent 2d432d7c6b
commit 8a0c240282

@ -3,6 +3,12 @@ use strict;
## no critic
use NGCP::BulkProcessor::Logging qw(
getlogger
rowinserted
rowsdeleted
);
use NGCP::BulkProcessor::ConnectorPool qw(
get_provisioning_db
@ -28,6 +34,7 @@ our @EXPORT_OK = qw(
$CFNA_TYPE
insert_row
delete_cfmappings
);
my $tablename = 'voip_cf_mappings';
@ -89,6 +96,37 @@ sub countby_subscriberid_type {
}
sub delete_cfmappings {
my ($xa_db,$subscriber_id,$types) = @_;
check_table();
my $db = &$get_db();
$xa_db //= $db;
my $table = $db->tableidentifier($tablename);
my $stmt = 'DELETE FROM ' . $table . ' WHERE ' .
$db->columnidentifier('subscriber_id') . ' = ?';
my @params = ($subscriber_id);
if (defined $types and 'HASH' eq ref $types) {
foreach my $in (keys %$types) {
my @values = (defined $types->{$in} and 'ARRAY' eq ref $types->{$in} ? @{$types->{$in}} : ($types->{$in}));
$stmt .= ' AND ' . $db->columnidentifier('type') . ' ' . $in . ' (' . substr(',?' x scalar @values,1) . ')';
push(@params,@values);
}
}
my $count;
if ($count = $xa_db->db_do($stmt,@params)) {
rowsdeleted($db,$tablename,$count,$count,getlogger(__PACKAGE__));
return 1;
} else {
rowsdeleted($db,$tablename,0,0,getlogger(__PACKAGE__));
return 0;
}
}
sub insert_row {
my $db = &$get_db();

@ -36,6 +36,10 @@ use NGCP::BulkProcessor::Projects::Migration::UPCAT::Settings qw(
$ccs_sippassword_length
@css_trusted_source_ips
$cf_default_priority
$cf_default_timeout
$cft_default_ringtimeout
);
use NGCP::BulkProcessor::Logging qw (
@ -72,9 +76,9 @@ use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_usr_preferences qw();
#use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings qw();
#use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_destination_sets qw();
#use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_destinations qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_destination_sets qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_destinations qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_trusted_sources qw();
use NGCP::BulkProcessor::Dao::Trunk::kamailio::voicemail_users qw();
@ -111,6 +115,7 @@ our @EXPORT_OK = qw(
provision_mta_subscribers
provision_ccs_subscribers
$UPDATE_CCS_PREFERENCES_MODE
$SET_CCS_CF_MODE
);
my $split_ipnets_pattern = join('|',(
@ -127,6 +132,12 @@ my $default_barring = 'default';
my $ccs_contact_identifier_field = 'gpp9';
our $UPDATE_CCS_PREFERENCES_MODE = 'update_ccs_preferences';
our $SET_CCS_CF_MODE = 'set_ccs_cf';
my $cf_types_pattern = '^' . $NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings::CFB_TYPE . '|'
. $NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings::CFT_TYPE . '|'
. $NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings::CFU_TYPE . '|'
. $NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings::CFNA_TYPE . '$';
sub provision_mta_subscribers {
@ -1126,7 +1137,7 @@ sub _provision_ccs_susbcriber {
#}
_update_ccs_preferences($context);
_set_registrations($context);
##_set_callforwards($context);
_set_callforwards($context);
##todo: additional prefs, AllowedIPs, NCOS, Callforwards. still thinking wether to integrate it
##in this main provisioning loop, or align it in separate run-modes, according to the files given.
} else {
@ -1140,6 +1151,8 @@ sub _provision_ccs_susbcriber {
if (defined $context->{prov_subscriber}) {
if ($update_mode eq $UPDATE_CCS_PREFERENCES_MODE) {
_update_ccs_preferences($context);
} elsif ($update_mode eq $SET_CCS_CF_MODE) {
_set_callforwards($context);
} else {
_warn($context,$context->{prov_subscriber}->{username} . ': ' . (scalar @$existing_billing_voip_subscribers) . ' existing billing subscribers found, skipping');
}
@ -1334,6 +1347,28 @@ sub _provision_ccs_subscribers_checks {
processing_info(threadid(),"shared_buddylist_visibility attribute found",getlogger(__PACKAGE__));
}
foreach my $cf_attribute (@NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::CF_ATTRIBUTES) {
eval {
$context->{attributes}->{$cf_attribute} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::findby_attribute($cf_attribute);
};
if ($@ or not defined $context->{attributes}->{$cf_attribute}) {
rowprocessingerror(threadid(),"cannot find $cf_attribute attribute",getlogger(__PACKAGE__));
$result = 0; #even in skip-error mode..
} else {
processing_info(threadid(),"$cf_attribute attribute found",getlogger(__PACKAGE__));
}
}
eval {
$context->{attributes}->{ringtimeout} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::findby_attribute(
$NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::RINGTIMEOUT_ATTRIBUTE);
};
if ($@ or not defined $context->{attributes}->{ringtimeout}) {
rowprocessingerror(threadid(),'cannot find ringtimeout attribute',getlogger(__PACKAGE__));
$result = 0; #even in skip-error mode..
} else {
processing_info(threadid(),"ringtimeout attribute found",getlogger(__PACKAGE__));
}
return $result;
}
@ -1531,6 +1566,52 @@ sub _provision_ccs_susbcriber_init_context {
$context->{registrations} = \@registrations;
$context->{trusted_sources} = \@trusted_sources;
$context->{ringtimeout} = undef;
my %cfsimple = ();
my @callforwards = ();
push(@callforwards,{
type => 'cfu',
destination => $first->{target_number},
}) if $first->{routing_type} eq '1:1';
if ((scalar @callforwards) > 0) {
my %vmcf = ();
my %maxpriority = ();
foreach my $callforward (@callforwards) {
my $type = lc($callforward->{type});
if ($type =~ /$cf_types_pattern/) {
unless (defined $callforward->{destination} and length($callforward->{destination}) > 0) {
_warn($context,"empty callforward destination, ignoring");
next;
}
if ($callforward->{destination} =~ /voicemail/i) {
$callforward->{destination} = 'sip:vm' . ('cfb' eq $type ? 'b' : 'u') . $context->{numbers}->{primary}->{number} . '@voicebox.local';
$vmcf{$type} = 1 unless $vmcf{$type};
} elsif ($callforward->{destination} !~ /^\d+$/i) {
_warn($context,"invalid callforward destination '$callforward->{destination}', ignoring");
next;
} else { #todo: allow sip uri destinations
$callforward->{destination} = 'sip:' . $callforward->{destination} .'@' . $context->{domain}->{domain};
}
$callforward->{priority} //= $cf_default_priority;
$callforward->{timeout} //= $cf_default_timeout;
$callforward->{ringtimeout} //= $cft_default_ringtimeout if 'cft' eq $type;
$context->{ringtimeout} = $callforward->{ringtimeout} if ('cft' eq $type and (not defined $context->{ringtimeout} or $callforward->{ringtimeout} > $context->{ringtimeout}));
$cfsimple{$type} = [] unless exists $cfsimple{$type};
push(@{$cfsimple{$type}},{
destination => $callforward->{destination},
priority => $callforward->{priority},
timeout => $callforward->{timeout},
});
#$vmcf{$type} = ($callforward->{destination} =~ /voicemail/i) unless $vmcf{$type};
$maxpriority{$type} = $callforward->{priority} if (not defined $maxpriority{$type} or $callforward->{priority} > $maxpriority{$type});
} else {
_warn($context,"invalid callforward type '$type', ignoring");
}
}
}
$context->{callforwards} = \%cfsimple;
#$context->{preferences} = {};
#$context->{preferences}->{gpp} = [
@ -1677,6 +1758,56 @@ sub _set_registrations {
}
sub _set_callforwards {
my ($context) = @_;
my $result = 1;
foreach my $type (keys %{$context->{callforwards}}) {
NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings::delete_cfmappings($context->{db},
$context->{prov_subscriber}->{id},{ '=' => $type });
my $destination_set_id = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_destination_sets::insert_row($context->{db},{
subscriber_id => $context->{prov_subscriber}->{id},
name => "quickset_$type",
});
foreach my $callforward (@{$context->{callforwards}->{$type}}) {
$callforward->{id} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_destinations::insert_row($context->{db},{
%$callforward,
destination_set_id => $destination_set_id,
});
}
my $cf_mapping_id = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_cf_mappings::insert_row($context->{db},{
subscriber_id => $context->{prov_subscriber}->{id},
type => $type,
destination_set_id => $destination_set_id,
#time_set_id
});
$context->{preferences}->{$type} = { id => set_subscriber_preference($context,
$context->{prov_subscriber}->{id},
$context->{attributes}->{$type},
$cf_mapping_id), value => $cf_mapping_id };
if (defined $context->{ringtimeout}) {
$context->{preferences}->{ringtimeout} = { id => set_subscriber_preference($context,
$context->{prov_subscriber}->{id},
$context->{attributes}->{ringtimeout},
$context->{ringtimeout}), value => $context->{ringtimeout} };
}
_info($context,"$type created (destination(s) " . join(', ',(map { $_->{destination}; } @{$context->{callforwards}->{$type}})) . ")",1);
$context->{callforwards}->{$type} = {
destination_set => {
destinations => $context->{callforwards}->{$type},
id => $destination_set_id,
},
id => $cf_mapping_id,
};
}
return $result;
}
sub _error {
my ($context,$message) = @_;

@ -92,6 +92,10 @@ our @EXPORT_OK = qw(
$ccs_sippassword_length
@css_trusted_source_ips
$cf_default_priority
$cf_default_timeout
$cft_default_ringtimeout
);
#$default_channels_map
@ -150,6 +154,10 @@ our $ccs_sippassword_length = 16;
our @css_trusted_source_ips = ();
our $cf_default_priority = 1;
our $cf_default_timeout = 300;
our $cft_default_ringtimeout = 20;
sub update_settings {
my ($data,$configfile) = @_;
@ -238,6 +246,10 @@ sub update_settings {
}
}
$cf_default_priority = $data->{cf_default_priority} if exists $data->{cf_default_priority};
$cf_default_timeout = $data->{cf_default_timeout} if exists $data->{cf_default_timeout};
$cft_default_ringtimeout = $data->{cft_default_ringtimeout} if exists $data->{cft_default_ringtimeout};
return $result;
}

@ -94,6 +94,7 @@ use NGCP::BulkProcessor::Projects::Migration::UPCAT::Provisioning qw(
provision_mta_subscribers
provision_ccs_subscribers
$UPDATE_CCS_PREFERENCES_MODE
$SET_CCS_CF_MODE
);
scripterror(getscriptpath() . ' already running',getlogger(getscriptpath())) unless flock DATA, LOCK_EX | LOCK_NB; # not tested on windows yet
@ -129,6 +130,9 @@ push(@TASK_OPTS,$create_ccs_subscriber_task_opt);
my $update_ccs_subscriber_preferences_task_opt = 'update_ccs_subscriber_preferences';
push(@TASK_OPTS,$update_ccs_subscriber_preferences_task_opt);
my $set_ccs_subscriber_cf_task_opt = 'set_ccs_subscriber_cf';
push(@TASK_OPTS,$set_ccs_subscriber_cf_task_opt);
if (init()) {
main();
@ -213,6 +217,13 @@ sub main() {
$completion |= 1;
}
} elsif (lc($set_ccs_subscriber_cf_task_opt) eq lc($task)) {
if (taskinfo($set_ccs_subscriber_cf_task_opt,$result,1)) {
next unless check_dry();
$result &= set_ccs_subscriber_cf_task(\@messages);
$completion |= 1;
}
} else {
$result = 0;
scripterror("unknow task option '" . $task . "', must be one of " . join(', ',@TASK_OPTS),getlogger(getscriptpath()));
@ -523,6 +534,29 @@ sub update_ccs_subscriber_preferences_task {
return $result;
}
sub set_ccs_subscriber_cf_task {
my ($messages) = @_;
my ($result,$warning_count) = (0,0);
eval {
($result,$warning_count) = provision_ccs_subscribers($SET_CCS_CF_MODE);
};
my $err = $@;
my $stats = ": $warning_count warnings";
eval {
$stats .= "\n total contracts: " .
NGCP::BulkProcessor::Dao::Trunk::billing::contracts::countby_status_resellerid(undef,undef) . ' rows';
$stats .= "\n total subscribers: " .
NGCP::BulkProcessor::Dao::Trunk::billing::voip_subscribers::countby_status_resellerid(undef,undef) . ' rows';
};
if ($err or !$result) {
push(@$messages,"set ccs subscriber callforwards INCOMPLETE$stats");
} else {
push(@$messages,"set ccs subscribers callforwards completed$stats");
}
destroy_all_dbs();
return $result;
}
#END {
# # this should not be required explicitly, but prevents Log4Perl's
# # "rootlogger not initialized error upon exit..

@ -40,3 +40,7 @@ ccs_billing_profile_name = Default Billing UPC
ccs_domain = in-ivr.upc.at
ccs_sippassword_length = 16
css_trusted_source_ips = 80.110.2.228,80.110.2.229
cf_default_priority: 1
cf_default_timeout: 300
cft_default_ringtimeout: 20

@ -37,8 +37,13 @@ provision_ccs_subscriber_multithreading = 1
provision_ccs_subscriber_numofthreads = 2
ccs_reseller_name = default
ccs_billing_profile_name = Default Billing Profile
ccs_domain = 10.15.19.193
ccs_domain = 192.168.0.29
#10.15.19.193
#d20.upc.at
#in-ivr.upc.at
ccs_sippassword_length = 16
css_trusted_source_ips = 80.110.2.228,80.110.2.229
cf_default_priority: 1
cf_default_timeout: 300
cft_default_ringtimeout: 20
Loading…
Cancel
Save