TT#50974 ama: ccs "direct forwarder" scenario

Change-Id: Ifa6cba9d8429dcb1c72569dd12ba7f59aaef975e
changes/55/26755/4
Rene Krenn 7 years ago
parent 6d36444184
commit f00fbe2873

@ -34,6 +34,7 @@ our @EXPORT_OK = qw(
datetime_from_string
set_timezone
current_local
from_epoch
);
my $is_fake_time = 0;
@ -79,6 +80,12 @@ sub _current_local {
}
}
sub from_epoch {
my ($time,$tz) = @_;
$tz //= $LOCAL;
return DateTime->from_epoch(epoch => $time, time_zone => $tz);
}
sub current_local {
return DateTime->now(time_zone => $LOCAL);
}

@ -43,6 +43,8 @@ our @EXPORT_OK = qw(
get_callidprefix
$OK_CALL_STATUS
);
#process_records
#delete_ids
@ -140,11 +142,13 @@ my $expected_fieldnames = [
];
my @callid_suffixes = ();
our $PBXSUFFIX = '_pbx-1';
my $PBXSUFFIX = '_pbx-1';
push(@callid_suffixes,$PBXSUFFIX);
our $XFERSUFFIX = '_xfer-1';
my $XFERSUFFIX = '_xfer-1';
push(@callid_suffixes,$XFERSUFFIX);
our $OK_CALL_STATUS = 'ok';
my $indexes = {};
my $insert_unique_fields = [];

@ -181,11 +181,11 @@ sub update_export_status {
' WHERE ' . $db->columnidentifier('status_id') . ' = ? AND ' . $db->columnidentifier('export_status') . ' != ?';
my @params = ($export_status,$status_id,$export_status);
if (defined $start_time_from) {
$stmt .= ' AND ' . $db->columnidentifier('start_time') . ' >= UNIX_TIMESTAMP(?)';
$stmt .= ' AND ' . $db->columnidentifier('cdr_start_time') . ' >= UNIX_TIMESTAMP(?)';
push(@params,$start_time_from);
}
if (defined $start_time_to) {
$stmt .= ' AND ' . $db->columnidentifier('start_time') . ' < UNIX_TIMESTAMP(?)';
$stmt .= ' AND ' . $db->columnidentifier('cdr_start_time') . ' < UNIX_TIMESTAMP(?)';
push(@params,$start_time_to);
}

@ -118,7 +118,7 @@ sub findby_subscriberidisprimary {
my @params = ($subscriber_id,$is_primary);
my $rows = $db->db_get_all_arrayref($stmt,@params);
return buildrecords_fromrows($rows,$load_recursive)->[0];
return buildrecords_fromrows($rows,$load_recursive);
}

@ -76,7 +76,7 @@ our @EXPORT_OK = qw(
fix_free_cash
);
my $create_sample_cdr = 0;
my $create_sample_cdr = 0;
sub fix_contract_balance_gaps {
@ -539,7 +539,7 @@ sub _generate_cdr_init_context {
$source_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($source_subscriber->{contract_id});
$source_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($source_subscriber->{contract}->{contact_id});
$source_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$source_subscriber->{uuid});
$source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1);
$source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1)->[0];
$source_subscriber->{domain} = $context->{domain_map}->{$source_subscriber->{domain_id}}->{domain};
$source_reseller = $context->{reseller_map}->{$source_subscriber->{contract}->{contact}->{reseller_id}};
} else {
@ -552,7 +552,7 @@ sub _generate_cdr_init_context {
$dest_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($dest_subscriber->{contract_id});
$dest_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($dest_subscriber->{contract}->{contact_id});
$dest_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$dest_subscriber->{uuid});
$dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1);
$dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1)->[0];
$dest_subscriber->{domain} = $context->{domain_map}->{$dest_subscriber->{domain_id}}->{domain};
$dest_reseller = $context->{reseller_map}->{$dest_subscriber->{contract}->{contact}->{reseller_id}};
} else {

@ -17,6 +17,13 @@ use NGCP::BulkProcessor::Projects::Export::Ama::Ccs::Settings qw(
$export_cdr_limit
$export_cdr_stream
$export_cdr_rollover_fsn
$ama_sensor_id
$ama_recording_office_id
$ama_incoming_trunk_group_number
$ama_outgoing_trunk_group_number
$ama_originating_digits_cdr_field
$ama_terminating_digits_cdr_field
);
use NGCP::BulkProcessor::Logging qw (
@ -35,6 +42,9 @@ use NGCP::BulkProcessor::Dao::Trunk::accounting::cdr_export_status qw();
use NGCP::BulkProcessor::Dao::Trunk::accounting::cdr_export_status_data qw();
use NGCP::BulkProcessor::Dao::Trunk::accounting::mark qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers qw();
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases qw();
use NGCP::BulkProcessor::Projects::Export::Ama::Format::File qw();
use NGCP::BulkProcessor::Projects::Export::Ama::Format::Record qw();
use NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure0510 qw();
@ -66,7 +76,7 @@ use NGCP::BulkProcessor::ConnectorPool qw(
use NGCP::BulkProcessor::Utils qw(threadid kbytes2gigs); # stringtobool check_ipnet trim);
use NGCP::BulkProcessor::Calendar qw(current_local);
use NGCP::BulkProcessor::Calendar qw(from_epoch);
require Exporter;
our @ISA = qw(Exporter);
@ -76,6 +86,8 @@ our @EXPORT_OK = qw(
reset_export_status
);
my $DIRECT_FORWARDER_SCENARIO = 1;
my $file_sequence_number : shared = 0;
my $rowcount : shared = 0;
@ -274,6 +286,8 @@ sub _export_cdrs_init_context {
my $result = 0;
$context->{cdrs} = [];
$context->{call_id} = $call_id;
my $scenario = { code => 0, };
$context->{scenario} = $scenario;
if (not exists $context->{file_cdr_id_map}->{$cdr_id}) {
my $call_id_prefix = NGCP::BulkProcessor::Dao::Trunk::accounting::cdr::get_callidprefix($call_id);
@ -285,10 +299,13 @@ sub _export_cdrs_init_context {
if ((scalar @{$context->{cdrs}}) == 2
and not $context->{cdrs}->[0]->is_xfer()
and $context->{cdrs}->[1]->is_xfer()
and ($scenario->{ccs_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$context->{cdrs}->[0]->{destination_user_id}))
and ($scenario->{ccs_subscriber}->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($scenario->{ccs_subscriber}->{id},1)->[0])
) {
$scenario->{code} = $DIRECT_FORWARDER_SCENARIO;
$result = 1;
} else {
print "blah";
#} else {
# print "blah";
}
foreach my $cdr (@{$context->{cdrs}}) {
if ($result) {
@ -304,12 +321,19 @@ sub _export_cdrs_init_context {
}
}
# todo: prepare the fields from the call's CDRs:
$context->{dt} = current_local();
$context->{source} = "43011001";
$context->{destination} = "43011002";
$context->{duration} = 123.456;
if ($scenario->{code} == $DIRECT_FORWARDER_SCENARIO) {
$scenario->{start_time} = $context->{cdrs}->[0]->{start_time};
$scenario->{duration} = $context->{cdrs}->[0]->{duration};
$scenario->{originating} = $context->{cdrs}->[0]->{$ama_originating_digits_cdr_field};
$scenario->{terminating} = $context->{cdrs}->[1]->{$ama_terminating_digits_cdr_field};
$scenario->{unanswered} = ($context->{cdrs}->[1]->{call_status} != $NGCP::BulkProcessor::Dao::Trunk::accounting::cdr::OK_CALL_STATUS ? 1 : 0);
$scenario->{correlation_id} = substr($context->{cdrs}->[0]->{id},-7);
$scenario->{nod} = {
originating_digits => $scenario->{originating},
switch_number_digits => $scenario->{ccs_subscriber}->{primary_alias}->{username},
mode => '0001',
};
}
return $result;
@ -385,16 +409,13 @@ sub _get_transfer_in {
NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9013->new(
rewritten => 0,
sensor_id => '438716', # Graz
sensor_id => $ama_sensor_id,
padding => 0,
recording_office_id => '438716',
date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt}),
connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt}), # adjacent
recording_office_id => $ama_recording_office_id,
dt => $context->{dt},
#date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt_transfer_in}),
#connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt_transfer_in}), # adjacent?
file_sequence_number => $context->{file_sequence_number},
)
@ -410,65 +431,72 @@ sub _get_record {
) = @params{qw/
context
/};
return NGCP::BulkProcessor::Projects::Export::Ama::Format::Record->new(
NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure0510->new(
call_type => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::CallType::STATION_PAID,
rewritten => 0,
sensor_id => '438716', # Graz
padding => 0,
recording_office_id => '438716', #008708
call_type => '970',
#call code 970c
#timing ind 000
#seervice observed 0c
#called party off-hook setzen
#unanswered =>
date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt}),
service_feature => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ServiceFeature::OTHER,
#mit 43
originating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{source}),
originating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{source}),
originating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{source}),
domestic_international => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::DomesticInternational::INTERNATIONAL, #get_number_domestic_international($context->{destination}),
#2c
#destination number mit 43
#dialed_in , 0er wegstreichen
terminating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{destination}),
terminating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{destination}),
terminating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{destination}),
connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt}),
elapsed_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ElapsedTime::get_elapsed_time($context->{duration}),
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module611->new(
generic_context_identifier => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericContextIdentifier::IN_CORRELATION_ID,
parsing_rules => '7',
additional_digits_dialed => ((scalar @{$context->{cdrs}}) > 0 ? substr($context->{cdrs}->[0]->{id},-7) : undef),
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module199->new(
network_operator_data => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::NetworkOperatorData::get_network_operator_data($context->{source},'123456'),
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new(
direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::INCOMING,
trunk_group_number => '2999',
trunk_member_number => '0000',
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new(
direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::OUTGOING,
trunk_group_number => '2014',
trunk_member_number => '0000',
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module000->new(
),
);
if ($context->{scenario}->{code} == $DIRECT_FORWARDER_SCENARIO) {
$context->{file}->update_start_end_time($context->{scenario}->{start_time},$context->{scenario}->{start_time} + $context->{scenario}->{duration});
my $record = NGCP::BulkProcessor::Projects::Export::Ama::Format::Record->new(
NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure0510->new(
call_type => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::CallType::STATION_PAID,
rewritten => 0,
sensor_id => $ama_sensor_id,
padding => 0,
recording_office_id => $ama_recording_office_id,
call_type => '970',
#timing ind 000
#seervice observed 0c
unanswered => $context->{scenario}->{unanswered}, #called party off-hook setzen
date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date(from_epoch($context->{scenario}->{start_time})),
service_feature => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ServiceFeature::OTHER,
originating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{scenario}->{originating}),
originating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{scenario}->{originating}),
originating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{scenario}->{originating}),
domestic_international => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::DomesticInternational::INTERNATIONAL, #get_number_domestic_international($context->{destination}),
terminating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{scenario}->{terminating}),
terminating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{scenario}->{terminating}),
terminating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{scenario}->{terminating}),
connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time(from_epoch($context->{scenario}->{start_time})),
elapsed_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ElapsedTime::get_elapsed_time($context->{scenario}->{duration}),
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module611->new(
generic_context_identifier => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericContextIdentifier::IN_CORRELATION_ID,
parsing_rules => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericContextIdentifier::IN_CORRELATION_ID_PARSING_RULES,
additional_digits_dialed => $context->{scenario}->{correlation_id},
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module199->new(
network_operator_data => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::NetworkOperatorData::get_network_operator_data(
$context->{scenario}->{nod}->{originating_digits},
$context->{scenario}->{nod}->{switch_number_digits},
$context->{scenario}->{nod}->{mode},
),
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new(
direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::INCOMING,
trunk_group_number => $ama_incoming_trunk_group_number,
trunk_member_number => '0000',
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new(
direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::OUTGOING,
trunk_group_number => $ama_outgoing_trunk_group_number,
trunk_member_number => '0000',
),
NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module000->new(
),
);
_info($context,"ama record from cdr ids " . join(', ',map { $_->{id}; } @{$context->{cdrs}}) . ':' . $record->to_string(),1);
return $record;
} else {
_error($context,"unknown scenario $context->{scenario}->{code} for cdr ids " . join(', ',map { $_->{id}; } @{$context->{cdrs}}) );
}
}
@ -480,26 +508,21 @@ sub _get_transfer_out {
) = @params{qw/
context
/};
return NGCP::BulkProcessor::Projects::Export::Ama::Format::Record->new(
NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9014->new(
@_,
rewritten => 0,
sensor_id => '008708', # Graz
sensor_id => $ama_sensor_id,
padding => 0,
recording_office_id => '008708',
date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt}),
recording_office_id => $ama_recording_office_id,
connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt}),
#date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt_transfer_out}),
#connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt_transfer_out}),
file_sequence_number => $context->{file_sequence_number},
dt => $context->{dt},
#=> (scalar @records),
)
);

@ -29,6 +29,7 @@ use NGCP::BulkProcessor::LoadConfig qw(
);
use NGCP::BulkProcessor::Utils qw(prompt timestampdigits); #stringtobool
#format_number check_ipnet
use NGCP::BulkProcessor::Array qw(contains);
require Exporter;
our @ISA = qw(Exporter);
@ -53,6 +54,13 @@ our @EXPORT_OK = qw(
$export_cdr_stream
$export_cdr_rollover_fsn
$ama_sensor_id
$ama_recording_office_id
$ama_incoming_trunk_group_number
$ama_outgoing_trunk_group_number
$ama_originating_digits_cdr_field
$ama_terminating_digits_cdr_field
);
our $defaultconfig = 'config.cfg';
@ -73,6 +81,13 @@ our $export_cdr_limit = undef;
our $export_cdr_stream = undef;
our $export_cdr_rollover_fsn = 0;
our $ama_sensor_id;
our $ama_recording_office_id;
our $ama_incoming_trunk_group_number;
our $ama_outgoing_trunk_group_number;
our $ama_originating_digits_cdr_field;
our $ama_terminating_digits_cdr_field;
sub update_settings {
my ($data,$configfile) = @_;
@ -99,6 +114,20 @@ sub update_settings {
$export_cdr_stream = $data->{export_cdr_stream} if exists $data->{export_cdr_stream};
$export_cdr_rollover_fsn = $data->{export_cdr_rollover_fsn} if exists $data->{export_cdr_rollover_fsn};
$ama_sensor_id = $data->{ama_sensor_id} if exists $data->{ama_sensor_id};
$ama_recording_office_id = $data->{ama_recording_office_id} if exists $data->{ama_recording_office_id};
$ama_incoming_trunk_group_number = $data->{ama_incoming_trunk_group_number} if exists $data->{ama_incoming_trunk_group_number};
$ama_outgoing_trunk_group_number = $data->{ama_outgoing_trunk_group_number} if exists $data->{ama_outgoing_trunk_group_number};
$ama_originating_digits_cdr_field = $data->{ama_originating_digits_cdr_field} if exists $data->{ama_originating_digits_cdr_field};
unless (contains($ama_originating_digits_cdr_field,[qw(source_user source_user_out source_cli)])) {
configurationerror($configfile,'unknown ama_originating_digits_cdr_field',getlogger(__PACKAGE__));
}
$ama_terminating_digits_cdr_field = $data->{ama_terminating_digits_cdr_field} if exists $data->{ama_terminating_digits_cdr_field};
unless (contains($ama_terminating_digits_cdr_field,[qw(destination_user destination_user_out destination_user_dialed destination_user_in)])) {
configurationerror($configfile,'unknown ama_terminating_digits_cdr_field',getlogger(__PACKAGE__));
}
return $result;
}
@ -123,7 +152,7 @@ sub _parse_export_joins {
my ($token,$file) = @_;
my @joins = ();
if (defined $token and length($token) > 0) {
foreach my $f (split_tuple($token)) {
foreach my $f (_split(\$token)) {
next unless($f);
$f =~ s/^\s*\{?\s*//;
$f =~ s/\}\s*\}\s*$/}/;
@ -146,7 +175,7 @@ sub _parse_export_conditions {
my ($token,$file) = @_;
my @conditions = ();
if (defined $token and length($token) > 0) {
foreach my $f (split_tuple($token)) {
foreach my $f (_split(\$token)) {
next unless($f);
$f =~ s/^\s*\{?\s*//;
$f =~ s/\}\s*\}\s*$/}/;
@ -173,4 +202,33 @@ sub _get_numofthreads {
return $_numofthreads;
}
sub _split {
my $buffer_ref = shift;
my $pos = 0;
my @tokens = ();
my $is_literal = 0;
my $token = '';
while ($pos < length($$buffer_ref)) {
if ("'" eq substr($$buffer_ref,$pos,length("'"))) {
$is_literal = not $is_literal;
$token .= "'";
$pos += length("'");
} elsif ("," eq substr($$buffer_ref,$pos,length(","))) {
if ($is_literal) {
$token .= ",";
} else {
push(@tokens,$token);
$token = '';
}
$pos += length(",");
} else {
$token .= substr($$buffer_ref,$pos,1);
$pos += 1;
}
}
push(@tokens,$token);
return @tokens;
}
1;

@ -57,7 +57,7 @@ completionemailrecipient = rkrenn@sipwise.com
doneemailrecipient =
##logging:
fileloglevel = INFO
fileloglevel = DEBUG
#DEBUG
screenloglevel = INFO
#INFO

@ -57,7 +57,7 @@ completionemailrecipient = rkrenn@sipwise.com
doneemailrecipient =
##logging:
fileloglevel = INFO
fileloglevel = DEBUG
#DEBUG
screenloglevel = INFO
#INFO

@ -3,12 +3,24 @@
export_cdr_multithreading = 1
export_cdr_numofthreads = 2
export_cdr_blocksize = 1000
export_cdr_joins = { 'billing.voip_subscribers source_voip_subscribers' => { 'source_voip_subscribers.uuid' => 'accounting.cdr.source_user_id' } }, { 'billing.voip_subscribers destination_voip_subscribers' => { 'destination_voip_subscribers.uuid' => 'accounting.cdr.destination_user_id' } }, { 'billing.billing_zones_history source_carrier_bbz' => { 'source_carrier_bbz.id' => 'accounting.cdr.source_carrier_billing_zone_id' } }, { 'billing.billing_zones_history source_reseller_bbz' => { 'source_reseller_bbz.id' => 'accounting.cdr.source_reseller_billing_zone_id' } }, { 'billing.billing_zones_history source_customer_bbz' => { 'source_customer_bbz.id' => 'accounting.cdr.source_customer_billing_zone_id' } }, { 'billing.billing_zones_history destination_carrier_bbz' => { 'destination_carrier_bbz.id' => 'accounting.cdr.destination_carrier_billing_zone_id' } }, { 'billing.billing_zones_history destination_reseller_bbz' => { 'destination_reseller_bbz.id' => 'accounting.cdr.destination_reseller_billing_zone_id' } }, { 'billing.billing_zones_history destination_customer_bbz' => { 'destination_customer_bbz.id' => 'accounting.cdr.destination_customer_billing_zone_id' } }
export_cdr_conditions =
#{ 'accounting.cdr.export_status' => { '=' => '"unexported"' } }, { 'accounting.cdr.call_status' => { '=' => '"ok"' } }, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } }
export_cdr_limit = 10000
export_cdr_stream = ama_ccs
export_cdr_rollover_fsn = 1
use_tempfiles = 1
export_cdr_conditions = { 'accounting.cdr.destination_domain' => { 'IN' => '("80.110.2.164","ccs.upc.at")' } }
#export_cdr_conditions = { 'accounting.cdr.destination_domain' => { '=' => '"ccs.upc.at"' } }
#{ 'accounting.cdr.export_status' => { '=' => '"unexported"' } }, { 'accounting.cdr.call_status' => { '=' => '"ok"' } }, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } }
#export_cdr_joins = { 'billing.voip_subscribers source_voip_subscribers' => { 'source_voip_subscribers.uuid' => 'accounting.cdr.source_user_id' } }, { 'billing.voip_subscribers destination_voip_subscribers' => { 'destination_voip_subscribers.uuid' => 'accounting.cdr.destination_user_id' } }, { 'billing.billing_zones_history source_carrier_bbz' => { 'source_carrier_bbz.id' => 'accounting.cdr.source_carrier_billing_zone_id' } }, { 'billing.billing_zones_history source_reseller_bbz' => { 'source_reseller_bbz.id' => 'accounting.cdr.source_reseller_billing_zone_id' } }, { 'billing.billing_zones_history source_customer_bbz' => { 'source_customer_bbz.id' => 'accounting.cdr.source_customer_billing_zone_id' } }, { 'billing.billing_zones_history destination_carrier_bbz' => { 'destination_carrier_bbz.id' => 'accounting.cdr.destination_carrier_billing_zone_id' } }, { 'billing.billing_zones_history destination_reseller_bbz' => { 'destination_reseller_bbz.id' => 'accounting.cdr.destination_reseller_billing_zone_id' } }, { 'billing.billing_zones_history destination_customer_bbz' => { 'destination_customer_bbz.id' => 'accounting.cdr.destination_customer_billing_zone_id' } }
use_tempfiles = 1
make_dir = 1
ama_filename_format = %1$sP%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA%10$s
ama_max_blocks = 1000
ama_sensor_id = 438716
ama_recording_office_id = 438716
ama_incoming_trunk_group_number = 2999
ama_outgoing_trunk_group_number = 2014
ama_originating_digits_cdr_field = source_user
ama_terminating_digits_cdr_field = destination_user

@ -3,15 +3,25 @@
export_cdr_multithreading = 1
export_cdr_numofthreads = 2
export_cdr_blocksize = 1000
#export_cdr_joins = { 'accounting.cdr_export_status_data esd' => { 'esd.cdr_id' => 'accounting.cdr.id' } }, { 'accounting.cdr_export_status es' => { 'es.id' => 'esd.status_id' } }
#export_cdr_conditions = { 'es.type' => { '=' => '"default"' } }, { 'esd.export_status' => { '=' => '"unexported"' } }, { 'accounting.cdr.call_status' => { '=' => '"ok"' } }
#, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } }
export_cdr_conditions =
#{ 'accounting.cdr.call_status' => { '=' => '"ok"' } }
export_cdr_stream = ama_ccs
#default
export_cdr_limit = 10000
export_cdr_rollover_fsn = 1
export_cdr_conditions = { 'accounting.cdr.destination_domain' => { 'IN' => '("80.110.2.164","ccs.upc.at")' } }
#export_cdr_conditions = { 'accounting.cdr.destination_domain' => { '=' => '"ccs.upc.at"' } }
#, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } }
#{ 'accounting.cdr.call_status' => { '=' => '"ok"' } }
#export_cdr_joins = { 'accounting.cdr_export_status_data esd' => { 'esd.cdr_id' => 'accounting.cdr.id' } }, { 'accounting.cdr_export_status es' => { 'es.id' => 'esd.status_id' } }
use_tempfiles = 1
make_dir = 1
ama_filename_format = %1$sdebug/P%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA.debug%10$s
ama_max_blocks = 1000
ama_filename_format = %1$sP%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA.debug%10$s
ama_sensor_id = 438716
ama_recording_office_id = 438716
ama_incoming_trunk_group_number = 2999
ama_outgoing_trunk_group_number = 2014
ama_originating_digits_cdr_field = source_user
ama_terminating_digits_cdr_field = destination_user

@ -10,11 +10,12 @@ use NGCP::BulkProcessor::LogError qw(
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
$line_terminator
);
my $field_separator = ": ";
my $line_terminator = "\n";
our $line_terminator = "\n";
my $indentation = " ";
my $padding = ' ';
sub new {
@ -78,7 +79,7 @@ sub to_string {
}
}
foreach my $field (@{$self->{fields}}) {
push(@lines,uc($field->get_name()) . $field_separator . ($maxlen > 0 ? ($padding x ($maxlen - length($field->get_name()))) : '') . uc($field->get_hex(@_)));
push(@lines,$indentation . uc($field->get_name()) . $field_separator . ($maxlen > 0 ? ($padding x ($maxlen - length($field->get_name()))) : '') . uc($field->get_hex(@_)));
}
return join($line_terminator,@lines);

@ -16,7 +16,7 @@ our @EXPORT_OK = qw(
my $field_name = "connect time";
my $length = 8;
my @param_names = qw/connect_time dt/;
my @param_names = qw/connect_time/;
sub new {
@ -43,7 +43,7 @@ sub _get_param_names {
sub get_hex {
my $self = shift;
my ($connect_time,$dt) = $self->_get_params(@_);
my ($connect_time) = $self->_get_params(@_);
die("invalid connect time '$connect_time'") unless length($connect_time) == 7;
return $connect_time . $TERMINATOR;

@ -16,7 +16,7 @@ our @EXPORT_OK = qw(
my $field_name = "date";
my $length = 6;
my @param_names = qw/date dt/;
my @param_names = qw/date/;
sub new {
@ -43,7 +43,7 @@ sub _get_param_names {
sub get_hex {
my $self = shift;
my ($date,$dt) = $self->_get_params(@_);
my ($date) = $self->_get_params(@_);
die("invalid date '$date'") unless length($date) == 5;
return $date . $TERMINATOR;

@ -23,6 +23,8 @@ our @EXPORT_OK = qw(
$NUMBER_PORTABILITY
$NPI
$CPS
$IN_CORRELATION_ID_PARSING_RULES
);
my $field_name = "generic context identifier";
@ -57,6 +59,8 @@ push(@generic_context_ids,$NPI);
our $CPS = '80080';
push(@generic_context_ids,$CPS);
our $IN_CORRELATION_ID_PARSING_RULES = 7;
sub new {
my $class = shift;

@ -14,7 +14,7 @@ our @EXPORT_OK = qw(
);
my $field_name = "network operator data";
my $length = 49;
my $length = 40;
my @param_names = qw/network_operator_data/;
sub new {
@ -41,20 +41,28 @@ sub get_hex {
my $self = shift;
my ($network_operator_data) = $self->_get_params(@_);
die("invalid network operator data '$network_operator_data'") if length($network_operator_data) != 39;
return $network_operator_data . '1'; #$TERMINATOR;
die("invalid network operator data '$network_operator_data'") if length($network_operator_data) != 40;
return $network_operator_data; # . '1'; #$TERMINATOR;
}
sub get_network_operator_data {
my ($originating_digits,$switch_number_digits) = @_;
my ($originating_digits,$switch_number_digits,$mode) = @_;
my $result = $originating_digits;
my $padlength = 16 - length($originating_digits);
$result .= 'f' x $padlength;
if ($padlength >= 0) {
$result .= 'f' x $padlength;
} else {
die("invalid network operator data/originating_digits '$originating_digits'");
}
$result .= $switch_number_digits;
$padlength = 20 - length($switch_number_digits);
$result .= 'f' x $padlength;
$result .= '800';
if ($padlength >= 0) {
$result .= 'f' x $padlength;
} else {
die("invalid network operator data/switch_number_digits '$switch_number_digits'");
}
$result .= $mode;
return $result;
}

@ -3,16 +3,23 @@ use strict;
## no critic
use File::Basename qw(fileparse);
use NGCP::BulkProcessor::Projects::Export::Ama::Format::Settings qw(
$output_path
$ama_filename_format
$use_tempfiles
$tempfile_path
$make_dir
$ama_max_blocks
);
use NGCP::BulkProcessor::Projects::Export::Ama::Format::Block qw();
use NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9014 qw();
use NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date qw();
use NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime qw();
use NGCP::BulkProcessor::Logging qw(
getlogger
);
@ -21,7 +28,8 @@ use NGCP::BulkProcessor::LogError qw(
fileerror
);
use NGCP::BulkProcessor::Utils qw(tempfilename);
use NGCP::BulkProcessor::Utils qw(tempfilename makepath);
use NGCP::BulkProcessor::Calendar qw(current_local from_epoch);
require Exporter;
our @ISA = qw(Exporter);
@ -29,7 +37,6 @@ our @EXPORT_OK = qw(
);
my $max_blocks = 99;
my $ama_file_extension = '.ama';
sub new {
@ -50,9 +57,20 @@ sub reset {
$self->_save_transfer_in(undef);
$self->_save_transfer_out(undef);
$self->{tempfilename} = tempfilename('XXXX',$tempfile_path,$ama_file_extension) if $use_tempfiles;
$self->{now} = current_local();
$self->{min_start_time} = undef;
$self->{max_end_time} = undef;
return;
}
sub update_start_end_time {
my $self = shift;
my ($start_time,$end_time) = @_;
#my $end_time = $start_time + $duration;
$self->{min_start_time} = $start_time if (not defined $self->{min_start_time} or $self->{min_start_time} > $start_time);
$self->{max_end_time} = $end_time if (not defined $self->{max_end_time} or $self->{max_end_time} < $end_time);
}
sub get_record_count {
my $self = shift;
return $self->{record_count};
@ -67,12 +85,12 @@ sub add_record {
my $self = shift;
my ($record,$pad) = @_;
my $result;
if (not $pad and (scalar @{$self->{blocks}}) >= $max_blocks and not $self->{current_block}->records_fit($record,
if (not $pad and (scalar @{$self->{blocks}}) >= $ama_max_blocks and not $self->{current_block}->records_fit($record,
$NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9014::length)) {
$result = 0;
} else {
if (not $self->{current_block}->add_record($record)) {
if ((scalar @{$self->{blocks}}) >= $max_blocks) {
if ((scalar @{$self->{blocks}}) >= $ama_max_blocks) {
$result = 0;
} else {
$self->{current_block}->set_padded(1);
@ -97,13 +115,13 @@ sub get_filename {
return $self->{tempfilename} if ($use_tempfiles and $show_tempfilename);
return sprintf($ama_filename_format,
$output_path,
$self->{transfer_in}->get_structure()->get_date_field()->{dt}->year,
substr($self->{transfer_in}->get_structure()->get_date_field()->{dt}->year,-2),
$self->{transfer_in}->get_structure()->get_date_field()->{dt}->month,
$self->{transfer_in}->get_structure()->get_date_field()->{dt}->day,
$self->{transfer_in}->get_structure()->get_connect_time_field()->{dt}->hour,
$self->{transfer_in}->get_structure()->get_connect_time_field()->{dt}->minute,
$self->{transfer_in}->get_structure()->get_connect_time_field()->{dt}->second,
$self->{now}->year,
substr($self->{now}->year,-2),
$self->{now}->month,
$self->{now}->day,
$self->{now}->hour,
$self->{now}->minute,
$self->{now}->second,
$self->{transfer_in}->get_structure()->get_file_sequence_number_field()->{file_sequence_number},
$ama_file_extension,
);
@ -120,6 +138,15 @@ sub _rename {
return rename($self->{tempfilename},$filename);
}
sub _makedir {
my ($filename) = @_;
my ($name,$path,$suffix) = fileparse($filename,$ama_file_extension);
makepath($path,\&fileerror,getlogger(__PACKAGE__)) if ($make_dir and length($path) > 0 and not -d $path);
return $filename;
}
sub flush {
my $self = shift;
my %params = @_;
@ -134,14 +161,14 @@ sub flush {
fileerror($filename . ' already exists',getlogger(__PACKAGE__));
return 0;
} else {
if (open(my $fh,">:raw",($use_tempfiles ? $self->{tempfilename} : $filename))) {
if (open(my $fh,">:raw",($use_tempfiles ? $self->{tempfilename} : _makedir($filename)))) {
foreach my $block (@{$self->{blocks}}) {
print $fh pack('H*',$block->get_hex());
}
close $fh;
if (defined $commit_cb) {
if (&$commit_cb(@_)) {
if (not $use_tempfiles or $self->_rename($filename)) {
if (not $use_tempfiles or $self->_rename(_makedir($filename))) {
return 1;
} else {
my $err = $!;
@ -193,9 +220,29 @@ sub close {
)),
1,
);
# update count fields:
# update transfer_in date/time:
my $min_start_dt;
$min_start_dt = from_epoch($self->{min_start_time}) if defined $self->{min_start_time};
$self->{transfer_in}->get_structure()->get_date_field()->_set_params(
date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($min_start_dt // $self->{now}),
);
$self->{transfer_in}->get_structure()->get_connect_time_field()->_set_params(
connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($min_start_dt // $self->{now}),
);
# update transfer_out date/time:
my $max_end_dt;
$max_end_dt = from_epoch($self->{max_end_time}) if defined $self->{max_end_time};
$self->{transfer_out}->get_structure()->get_date_field()->_set_params(
date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($max_end_dt // $self->{now}),
);
$self->{transfer_out}->get_structure()->get_connect_time_field()->_set_params(
connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($max_end_dt // $self->{now}),
);
# update transfer_out count fields:
$self->{transfer_out}->get_structure()->get_block_count_field()->_set_params(block_count => $self->get_block_count());
$self->{transfer_out}->get_structure()->get_record_count_field()->_set_params(record_count => $self->get_record_count());
$result |= $self->flush(
commit_cb => $commit_cb,
@_
@ -232,7 +279,6 @@ sub write_record {
my $result = 0;
my $record = &$get_record(@_);
if (not $self->add_record($record)) {
#my $blah="y";
$result |= $self->close(
get_transfer_out => $get_transfer_out,
commit_cb => $commit_cb,

@ -3,6 +3,8 @@ use strict;
## no critic
use NGCP::BulkProcessor::Projects::Export::Ama::Format::FieldSet qw($line_terminator);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
@ -40,6 +42,20 @@ sub get_hex {
return $result;
}
sub to_string {
my $self = shift;
my $result = $line_terminator . $line_terminator . "record data:$line_terminator" . $self->{structure}->to_string(@_);
foreach my $module (@{$self->{modules}}) {
next unless $module->get_enabled(@_);
$result .= $line_terminator . $line_terminator . "module data:$line_terminator" . $module->to_string(@_);
}
$result .= $line_terminator;
return $result;
}
sub get_length {
my $self = shift;
my $length = $record_descriptor_word_length;

@ -41,8 +41,11 @@ our @EXPORT_OK = qw(
$domestic_destination_pattern
$international_destination_pattern
$make_dir
$ama_filename_format
$use_tempfiles
$ama_max_blocks
);
our $output_path = $working_path . 'output/';
@ -53,6 +56,9 @@ our $use_tempfiles = 0;
our $domestic_destination_pattern = undef;
our $international_destination_pattern = undef;
our $ama_max_blocks = 1000;
our $make_dir = 0;
our $ama_filename_format = '%1$sP%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA%10$s';
sub update_settings {
@ -68,6 +74,7 @@ sub update_settings {
$result &= _prepare_working_paths(1);
$use_tempfiles = $data->{use_tempfiles} if exists $data->{use_tempfiles};
$make_dir = $data->{make_dir} if exists $data->{make_dir};
my $regexp_result;
$domestic_destination_pattern = $data->{domestic_destination_pattern} if exists $data->{domestic_destination_pattern};
@ -79,6 +86,8 @@ sub update_settings {
$ama_filename_format = $data->{ama_filename_format} if exists $data->{ama_filename_format};
$ama_max_blocks = $data->{ama_max_blocks} if exists $data->{ama_max_blocks};
return $result;
}

@ -60,12 +60,14 @@ sub new {
$self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::RecordingOfficeId->new(
@_,
));
$self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date->new(
$self->{date} = NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date->new(
@_,
));
$self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime->new(
);
$self->_add_field($self->{date});
$self->{connect_time} = NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime->new(
@_,
));
);
$self->_add_field($self->{connect_time});
$self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericIssue->new(
@_,
));
@ -112,6 +114,16 @@ sub get_block_count_field {
return $self->{block_count};
}
sub get_date_field {
my $self = shift;
return $self->{date};
}
sub get_connect_time_field {
my $self = shift;
return $self->{connect_time};
}
#sub get_instance {
# return
#}

@ -333,7 +333,7 @@ sub _generate_cdr_init_context {
$source_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($source_subscriber->{contract_id});
$source_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($source_subscriber->{contract}->{contact_id});
$source_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$source_subscriber->{uuid});
$source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1);
$source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1)->[0];
$source_subscriber->{domain} = $context->{domain_map}->{$source_subscriber->{domain_id}}->{domain};
$source_reseller = $context->{reseller_map}->{$source_subscriber->{contract}->{contact}->{reseller_id}};
} else {
@ -346,7 +346,7 @@ sub _generate_cdr_init_context {
$dest_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($dest_subscriber->{contract_id});
$dest_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($dest_subscriber->{contract}->{contact_id});
$dest_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$dest_subscriber->{uuid});
$dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1);
$dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1)->[0];
$dest_subscriber->{domain} = $context->{domain_map}->{$dest_subscriber->{domain_id}}->{domain};
$dest_reseller = $context->{reseller_map}->{$dest_subscriber->{contract}->{contact}->{reseller_id}};
} else {

Loading…
Cancel
Save