X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fpart_export%2Fprizm.pm;h=99644895165a330d3eac4c85d8ff6d31adec972b;hb=1586961f12c742e45a38bc9cea0fcc49d5b1dd2a;hp=438354263692f668732c4ca821b0901f2cf11b0f;hpb=2da31e8f5d4533c342d13ce7a2eb46ae80ced8da;p=freeside.git
diff --git a/FS/FS/part_export/prizm.pm b/FS/FS/part_export/prizm.pm
index 438354263..996448951 100644
--- a/FS/FS/part_export/prizm.pm
+++ b/FS/FS/part_export/prizm.pm
@@ -1,32 +1,96 @@
package FS::part_export::prizm;
-use vars qw(@ISA %info %options $DEBUG);
+use vars qw(@ISA %info %options $DEBUG $me);
use Tie::IxHash;
-use FS::Record qw(fields);
+use FS::Record qw(fields dbh);
use FS::part_export;
@ISA = qw(FS::part_export);
-$DEBUG = 1;
+$DEBUG = 0;
+$me = '[' . __PACKAGE__ . ']';
tie %options, 'Tie::IxHash',
'url' => { label => 'Northbound url', default=>'https://localhost:8443/prizm/nbi' },
'user' => { label => 'Northbound username', default=>'nbi' },
'password' => { label => 'Password', default => '' },
'ems' => { label => 'Full EMS', type => 'checkbox' },
+ 'always_bam' => { label => 'Always activate/suspend authentication', type => 'checkbox' },
+ 'element_name_length' => { label => 'Size of siteName (best left blank)' },
;
+my $notes = <<'EOT';
+Real-time export of svc_broadband, cust_pkg, and cust_main
+record data to Motorola
+Canopy Prizm
+software via the Northbound interface.
+
+Freeside will attempt to create an element in an existing network with the
+values provided in svc_broadband. Of particular interest are
+
+ - mac address - used to identify the element
+
- vlan profile - an exact match for a vlan profiles defined in prizm
+
- ip address - defines the management ip address of the prizm element
+
- latitude - GPS latitude
+
- longitude - GPS longitude
+
- altitude - GPS altitude
+
+
+In addition freeside attempts to set the service plan name in prizm to the
+name of the package in which the service resides.
+
+The service is associated with a customer in prizm as well, and freeside
+will create the customer should none already exist with import id matching
+the freeside customer number. The following fields are set.
+
+
+ - importId - the freeside customer number
+
- customerType - freeside
+
- customerName - the name associated with the freeside shipping address
+
- address1 - the shipping address
+
- address2
+
- city
+
- state
+
- zipCode
+
- country
+
- workPhone - the daytime phone number
+
- homePhone - the night phone number
+
- freesideId - the freeside customer number
+
+
+ Additionally set on the element are
+
+ - Site Name - The shipping name followed by the service broadband description field
+
- Site Location - the shipping address
+
- Site Contact - the daytime and night phone numbers
+
+
+Freeside provisions, suspends, and unsuspends elements BAM only unless the
+'Full EMS' checkbox is checked.
+
+When freeside provisions an element the siteName is copied internally by
+prizm in such a manner that it is possible for the value to exceed the size
+of the column used in the prizm database. Therefore freeside truncates
+by default this value to 50 characters. It is thought that this
+column is the account_name column of the element_user_account table. It
+may be possible to lift this limit by modifying the prizm database and
+setting a new appropriate value on this export. This is untested and
+possibly harmful.
+
+EOT
+
%info = (
- 'svc' => 'svc_broadband',
- 'desc' => 'Real-time export to Northbound Interface',
- 'options' => \%options,
- 'nodomain' => 'Y',
- 'notes' => 'These are notes.'
+ 'svc' => 'svc_broadband',
+ 'desc' => 'Real-time export to Northbound Interface',
+ 'options' => \%options,
+ 'nodomain' => 'Y',
+ 'no_machine' => 1,
+ 'notes' => $notes,
);
sub prizm_command {
my ($self,$namespace,$method) = (shift,shift,shift);
- eval "use Net::Prizm qw(CustomerInfo PrizmElement);";
+ eval "use Net::Prizm 0.04 qw(CustomerInfo PrizmElement);";
die $@ if $@;
my $prizm = new Net::Prizm (
@@ -42,7 +106,7 @@ sub prizm_command {
sub queued_prizm_command { # subroutine
my( $url, $user, $password, $namespace, $method, @args ) = @_;
- eval "use Net::Prizm qw(CustomerInfo PrizmElement);";
+ eval "use Net::Prizm 0.04 qw(CustomerInfo PrizmElement);";
die $@ if $@;
my $prizm = new Net::Prizm (
@@ -63,6 +127,9 @@ sub queued_prizm_command { # subroutine
sub _export_insert {
my( $self, $svc ) = ( shift, shift );
+ warn "$me: _export_insert called for export ". $self->exportnum.
+ " on service ". $svc->svcnum. "\n"
+ if $DEBUG;
my $cust_main = $svc->cust_svc->cust_pkg->cust_main;
@@ -89,6 +156,7 @@ sub _export_insert {
my $pcustomer;
if ($err_or_som->result->[0]) {
$pcustomer = $err_or_som->result->[0]->customerId;
+ warn "$me: found customer $pcustomer in prizm\n" if $DEBUG;
}else{
my $chashref = $cust_main->hashref;
my $customerinfo = {
@@ -115,6 +183,7 @@ sub _export_insert {
unless ref($err_or_som);
$pcustomer = $err_or_som->result;
+ warn "$me: added customer $pcustomer to prizm\n" if $DEBUG;
}
warn "multiple prizm customers found for $cust_main->custnum"
if scalar(@$pcustomer) > 1;
@@ -138,19 +207,50 @@ sub _export_insert {
# }
# }
+# here we cope with a problem of prizm failing to insert for reason
+# of duplicate mac addr, but doing so inconsistently... a race in prizm?
+
+ $self->prizm_command( 'CustomerIfService', 'removeElementFromCustomer',
+ 0,
+ $cust_main->custnum,
+ 0,
+ $svc->mac_addr,
+ );
+
+ $err_or_som = $self->prizm_command( 'NetworkIfService', 'getPrizmElements',
+ [ 'MAC Address' ],
+ [ $svc->mac_addr ],
+ [ '=' ],
+ );
+ if ( ref($err_or_som) && $err_or_som->result->[0] ) { # ignore errors
+ $self->prizm_command( 'NetworkIfService', 'deleteElement',
+ $err_or_som->result->[0],
+ 1,
+ );
+ }
+# end of coping
+
+ my $performance_profile = $svc->performance_profile;
+ $performance_profile ||= $svc->cust_svc->cust_pkg->part_pkg->pkg;
+
+ my $element_name_length = 50;
+ $element_name_length = $1
+ if $self->option('element_name_length') =~ /^\s*(\d+)\s*$/;
$err_or_som = $self->prizm_command('NetworkIfService', 'addProvisionedElement',
$networkid,
$svc->mac_addr,
- $name, # we fix this below (bug in prizm?)
+ substr($name . " " . $svc->description,
+ 0, $element_name_length),
$location,
$contact,
- sprintf("%032X", $svc->authkey),
- $svc->cust_svc->cust_pkg->part_pkg->pkg,
+ sprintf("%032X", $svc->authkey || 0),
+ $performance_profile,
$svc->vlan_profile,
- $self->option('ems') == 1,
+ ($self->option('ems') ? 1 : 0 ),
);
return $err_or_som
unless ref($err_or_som);
+ warn "$me: added provisioned element to prizm\n" if $DEBUG;
my (@names) = ('Management IP',
'GPS Latitude',
@@ -178,6 +278,7 @@ sub _export_insert {
);
return $err_or_som
unless ref($err_or_som);
+ warn "$me: set element configuration\n" if $DEBUG;
$err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet',
[ $element ],
@@ -187,25 +288,28 @@ sub _export_insert {
);
return $err_or_som
unless ref($err_or_som);
+ warn "$me: set element vlan profile\n" if $DEBUG;
$err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet',
[ $element ],
- $svc->cust_svc->cust_pkg->part_pkg->pkg,
+ $performance_profile,
0,
1,
);
return $err_or_som
unless ref($err_or_som);
+ warn "$me: set element configset (performance profile)\n" if $DEBUG;
$err_or_som = $self->prizm_command('NetworkIfService',
'activateNetworkElements',
[ $element ],
1,
- $self->option('ems') == 1,
+ ( $self->option('ems') ? 1 : 0 ),
);
return $err_or_som
unless ref($err_or_som);
+ warn "$me: activated element\n" if $DEBUG;
$err_or_som = $self->prizm_command('CustomerIfService',
'addElementToCustomer',
@@ -217,6 +321,7 @@ sub _export_insert {
return $err_or_som
unless ref($err_or_som);
+ warn "$me: added element to customer\n" if $DEBUG;
'';
}
@@ -224,6 +329,10 @@ sub _export_insert {
sub _export_delete {
my( $self, $svc ) = ( shift, shift );
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
my $cust_pkg = $svc->cust_svc->cust_pkg;
my $depend = [];
@@ -233,7 +342,7 @@ sub _export_delete {
'svcnum' => $svc->svcnum,
'job' => 'FS::part_export::prizm::queued_prizm_command',
};
- $queue->insert(
+ my $error = $queue->insert(
( map { $self->option($_) }
qw( url user password ) ),
'CustomerIfService',
@@ -242,10 +351,27 @@ sub _export_delete {
$cust_pkg->custnum,
0,
$svc->mac_addr,
- ) && push @$depend, $queue->jobnum;
+ );
+
+ if ($error) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ push @$depend, $queue->jobnum;
}
- $self->queue_statuschange('deleteElement', $depend, $svc, 1);
+ my $err_or_queue =
+ $self->queue_statuschange('deleteElement', $depend, $svc, 1);
+
+ unless (ref($err_or_queue)) {
+ $dbh->rollback if $oldAutoCommit;
+ return $err_or_queue;
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+ '';
}
sub _export_replace {
@@ -308,20 +434,93 @@ sub _export_replace {
return $err_or_som
unless ref($err_or_som);
+ my $performance_profile = $new->performance_profile;
+ $performance_profile ||= $new->cust_svc->cust_pkg->part_pkg->pkg;
+
+ $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet',
+ [ $element ],
+ $performance_profile,
+ 0,
+ 1,
+ );
+ return $err_or_som
+ unless ref($err_or_som);
+
'';
}
sub _export_suspend {
my( $self, $svc ) = ( shift, shift );
- my $ems = $self->option('ems') == 1;
- $self->queue_statuschange('suspendNetworkElements', [], $svc, 1, $ems);
+ my $depend = [];
+ my $ems = $self->option('ems') ? 1 : 0;
+ my $err_or_queue = '';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ $err_or_queue =
+ $self->queue_statuschange('suspendNetworkElements', [], $svc, 1, $ems);
+ unless (ref($err_or_queue)) {
+ $dbh->rollback if $oldAutoCommit;
+ return $err_or_queue;
+ }
+ push @$depend, $err_or_queue->jobnum;
+
+ if ($ems && $self->option('always_bam')) {
+ $err_or_queue =
+ $self->queue_statuschange('suspendNetworkElements', $depend, $svc, 1, 0);
+ unless (ref($err_or_queue)) {
+ $dbh->rollback if $oldAutoCommit;
+ return $err_or_queue;
+ }
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+ '';
}
sub _export_unsuspend {
my( $self, $svc ) = ( shift, shift );
- my $ems = $self->option('ems') == 1;
- $self->queue_statuschange('activateNetworkElements', [], $svc, 1, $ems);
+ my $depend = [];
+ my $ems = $self->option('ems') ? 1 : 0;
+ my $err_or_queue = '';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ if ($ems && $self->option('always_bam')) {
+ $err_or_queue =
+ $self->queue_statuschange('activateNetworkElements', [], $svc, 1, 0);
+ unless (ref($err_or_queue)) {
+ $dbh->rollback if $oldAutoCommit;
+ return $err_or_queue;
+ }
+ push @$depend, $err_or_queue->jobnum;
+ }
+
+ $err_or_queue =
+ $self->queue_statuschange('activateNetworkElements', $depend, $svc, 1, $ems);
+ unless (ref($err_or_queue)) {
+ $dbh->rollback if $oldAutoCommit;
+ return $err_or_queue;
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+ '';
+}
+
+sub export_links {
+ my( $self, $svc, $arrayref ) = ( shift, shift, shift );
+
+ push @$arrayref,
+ 'SM';
+
+ '';
}
sub queue_statuschange {
@@ -333,7 +532,7 @@ sub queue_statuschange {
'svcnum' => $svc->svcnum,
'job' => 'FS::part_export::prizm::statuschange',
};
- $queue->insert(
+ my $error = $queue->insert(
( map { $self->option($_) }
qw( url user password ) ),
$method,
@@ -341,18 +540,19 @@ sub queue_statuschange {
@args,
);
- if ($queue->jobnum) { # successful insertion
+ unless ($error) { # successful insertion
foreach my $job ( @$jobs ) {
- $queue->depend_insert($job);
+ $error ||= $queue->depend_insert($job);
}
}
+ $error or $queue;
}
sub statuschange { # subroutine
my( $url, $user, $password, $method, $mac_addr, @args) = @_;
- eval "use Net::Prizm qw(CustomerInfo PrizmElement);";
+ eval "use Net::Prizm 0.04 qw(CustomerInfo PrizmElement);";
die $@ if $@;
my $prizm = new Net::Prizm (