From 55f178ee7c54120db6447fe91c5cbcaa77494f70 Mon Sep 17 00:00:00 2001 From: jeff Date: Fri, 21 Nov 2008 03:36:16 +0000 Subject: [PATCH] initial somanetworks support --- FS/FS/part_export/soma.pm | 401 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 401 insertions(+) create mode 100644 FS/FS/part_export/soma.pm diff --git a/FS/FS/part_export/soma.pm b/FS/FS/part_export/soma.pm new file mode 100644 index 000000000..c57fc7ff1 --- /dev/null +++ b/FS/FS/part_export/soma.pm @@ -0,0 +1,401 @@ +package FS::part_export::soma; + +use vars qw(@ISA %info %options $DEBUG); +use Tie::IxHash; +use FS::Record qw(fields dbh); +use FS::part_export; + +@ISA = qw(FS::part_export); +$DEBUG = 1; + +tie %options, 'Tie::IxHash', + 'url' => { label => 'Soma OSS-API url', default=>'https://localhost:8088/ossapi/services' }, + 'data_app_id' => { label => 'SOMA Data Application Id', default => '' }, +; + +my $notes = <<'EOT'; +Real-time export of svc_external and svc_broadband record data +to SOMA Networks platform via the +OSS-API.

+ +Freeside will attempt to create/delete a cpe for the ESN provided in +svc_external. If a data application id is provided then freeside will +use the values provided in svc_broadband to manage the attributes and +features of that cpe. + +EOT + +%info = ( + 'svc' => [ qw ( svc_broadband svc_external ) ], + 'desc' => 'Real-time export to SOMA platform', + 'options' => \%options, + 'nodomain' => 'Y', + 'notes' => $notes, +); + +sub _export_insert { + my( $self, $svc ) = ( shift, shift ); + + warn "_export_insert called for service ". $svc->svcnum + if $DEBUG; + + my %args = ( url => $self->option('url'), method => '_queueable_insert' ); + + $args{esn} = $self->esn($svc) or return 'No ESN found!'; + + my $svcdb = $svc->cust_svc->part_svc->svcdb; + $args{svcdb} = $svcdb; + if ( $svcdb eq 'svc_external' ) { + #do nothing + } elsif ( $svcdb eq 'svc_broadband' ){ + $args{data_app_id} = $self->option('data_app_id') + } else { + return "Don't know how to provision $svcdb"; + } + + warn "dispatching statuschange" if $DEBUG; + + eval { statuschange(%args) }; + return $@ if $@; + + ''; +} + +sub _export_delete { + my( $self, $svc ) = ( shift, shift ); + + my %args = ( url => $self->option('url'), method => '_queueable_delete' ); + + $args{esn} = $self->esn($svc) or return 'No ESN found!'; + + my $svcdb = $svc->cust_svc->part_svc->svcdb; + $args{svcdb} = $svcdb; + if ( $svcdb eq 'svc_external' ) { + #do nothing + } elsif ( $svcdb eq 'svc_broadband' ){ + $args{data_app_id} = $self->option('data_app_id') + } else { + return "Don't know how to provision $svcdb"; + } + + eval { statuschange(%args) }; + return $@ if $@; + + ''; +} + +sub _export_replace { + my( $self, $new, $old ) = ( shift, shift, shift ); + + my %args = ( url => $self->option('url'), method => '_queueable_replace' ); + + $args{esn} = $self->esn($old) or return 'No old ESN found!'; + $args{new_esn} = $self->esn($new) or return 'No new ESN found!'; + + my $svcdb = $old->cust_svc->part_svc->svcdb; + $args{svcdb} = $svcdb; + if ( $svcdb eq 'svc_external' ) { + #do nothing + } elsif ( $svcdb eq 'svc_broadband' ){ + $args{data_app_id} = $self->option('data_app_id') + } else { + return "Don't know how to provision $svcdb"; + } + + eval { statuschange(%args) }; + return $@ if $@; + + ''; +} + +sub _export_suspend { + my( $self, $svc ) = ( shift, shift ); + + $self->queue_statuschange('_queueable_suspend', $svc); +} + +sub _export_unsuspend { + my( $self, $svc ) = ( shift, shift ); + + $self->queue_statuschange('_queueable_unsuspend', $svc); +} + +sub queue_statuschange { + my( $self, $method, $svc ) = @_; + + my %args = ( url => $self->option('url'), method => $method ); + + my $svcdb = $svc->cust_svc->part_svc->svcdb; + $args{svcdb} = $svcdb; + if ( $svcdb eq 'svc_external' ) { + #do absolutely nothing + return ''; + } elsif ( $svcdb eq 'svc_broadband' ){ + $args{data_app_id} = $self->option('data_app_id') + } else { + return "Don't know how to provision $svcdb"; + } + + $args{esn} = $self->esn($svc); + + my $queue = new FS::queue { + 'svcnum' => $svc->svcnum, + 'job' => 'FS::part_export::soma::$method', + }; + my $error = $queue->insert( $self->option('url'), %args ); + + return $error if $error; + + ''; + +} + +sub statuschange { # subroutine + my( %options ) = @_; + + warn "statuschange called with options ". + join (', ', map { "$_ => $options{$_}" } keys(%options)) + if $DEBUG; + + my $method = $options{method}; + + eval "use Net::Soma 0.01 qw(ApplicationDef ApplicationInstance + AttributeDef AttributeInstance);"; + die $@ if $@; + + my %soma_objects = (); + foreach my $service ( qw ( CPECollection CPEAccess AppCatalog Applications ) ) + { + $soma_objects{$service} = new Net::Soma ( namespace => $service."Service", + url => $options{'url'}, + die_on_fault => 1, + ); + } + + my $cpeid = eval {$soma_objects{CPECollection}->getCPEByESN( $options{esn} )}; + warn "failed to find CPE with ESN $options{esn}" + if ($DEBUG && !$cpeid); + + if ( $method eq '_queueable_insert' && $options{svcdb} eq 'svc_external' ) { + if ( !$cpeid ) { + # only type 1 is used at this time + $cpeid = $soma_objects{CPECollection}->createCPE( $options{esn}, 1 ); + } else { + $soma_objects{CPECollection}->releaseCPE( $cpeid ); + die "Soma element for $options{esn} already exists"; + } + } + + die "Can't find soma element for $options{esn}" + unless $cpeid; + + warn "dispatching $method from statuschange" if $DEBUG; + &{$method}( \%soma_objects, $cpeid, %options ); + +} + +sub _queueable_insert { + my( $soma_objects, $cpeid, %options ) = @_; + + warn "_queueable_insert called for $cpeid with options ". + join (', ', map { "$_ => $options{$_}" } keys(%options)) + if $DEBUG; + + my $appid = $options{data_app_id}; + if ($appid) { + my $application = + $soma_objects->{AppCatalog} + ->getDefaultApplicationInstance($appid, $cpeid); + + my $attribute = + $soma_objects->{AppCatalog} + ->getDefaultApplicationAttributeInstance(2, 1, $cpeid); + $attribute->value('G'); + + my $i = 0; + foreach my $instance (@{$application->attributes}) { + unless ($instance->definitionId == $attribute->definitionId) { + $i++; next; + } + $application->attributes->[$i] = $attribute; + last; + } + + $soma_objects->{Applications}->subscribeApp( $cpeid, $application ); + } + + $soma_objects->{CPECollection}->releaseCPE( $cpeid ); + + ''; +} + +sub _queueable_delete { + my( $soma_objects, $cpeid, %options ) = @_; + + my $appid = $options{data_app_id}; + my $norelease; + + if ($appid) { + my $applications = + $soma_objects->{Applications}->getSubscribedApplications( $cpeid ); + + my $instance_id; + foreach $application (@$applications) { + next unless $application->definitionId == $appid; + $instance_id = $application->instanceId; + } + + $soma_objects->{Applications}->unsubscribeApp( $cpeid, $instance_id ); + + } else { + + $soma_objects->{CPECollection}->deleteCPE($cpeid); + $norelease = 1; + + } + + $soma_objects->{CPECollection}->releaseCPE( $cpeid ) unless $norelease; + + ''; +} + +sub _queueable_replace { + my( $soma_objects, $cpeid, %options ) = @_; + + my $appid = $options{data_app_id} || ''; + + if (exists($options{data_app_id})) { + my $applications = + $soma_objects->{Applications}->getSubscribedApplications( $cpeid ); + + my $instance_id; + foreach $application (@$applications) { + next unless $application->internalName eq 'dataApplication'; + if ($application->definitionId != $options{data_app_id}) { + $instance_id = $application->instanceId; + $soma_objects->{Applications}->unsubscribeApp( $cpeid, $instance_id ); + } + } + + if ($appid && !$instance_id ) { + my $application = + $soma_objects->{AppCatalog} + ->getDefaultApplicationInstance($appid, $cpeid); + + $soma_objects->{Applications}->subscribeApp( $cpeid, $application ); + } + + } else { + + $soma_objects->{CPEAccess}->switchCPE($cpeid, $options{new_esn}) + unless( $options{new_esn} eq $options{esn}); + + } + + $soma_objects->{CPECollection}->releaseCPE( $cpeid ); + + ''; +} + +sub _queueable_suspend { + my( $soma_objects, $cpeid, %options ) = @_; + + my $appid = $options{data_app_id}; + + if ($appid) { + my $applications = + $soma_objects->{Applications}->getSubscribedApplications( $cpeid ); + + my $instance_id; + foreach $application (@$applications) { + next unless $application->definitionId == $appid; + + $instance_id = $application->instanceId; + $app_def = $app_catalog->getApplicationDef($appid, $cpeid); + @attr_def = grep { $_->internalName eq 'status' } @{$app_def->attributes}; + + foreach my $attribute ( @{$application->attributes} ) { + next unless $attibute->definitionId == $attr_def[0]->definitionId; + $attribute->{value} = 'S'; + + $soma_objects->{Applications}->setAppAttribute( $cpeid, + $instance_id, + $attribute + ); + } + + } + + } else { + + #do nothing + + } + + $soma_objects->{CPECollection}->releaseCPE( $cpeid ); + + ''; +} + +sub _queueable_unsuspend { + my( $soma_objects, $cpeid, %options ) = @_; + + my $appid = $options{data_app_id}; + + if ($appid) { + my $applications = + $soma_objects->{Applications}->getSubscribedApplications( $cpeid ); + + my $instance_id; + foreach $application (@$applications) { + next unless $application->definitionId == $appid; + + $instance_id = $application->instanceId; + $app_def = $app_catalog->getApplicationDef($appid, $cpeid); + @attr_def = grep { $_->internalName eq 'status' } @{$app_def->attributes}; + + foreach my $attribute ( @{$applicate->attributes} ) { + next unless $attibute->definitionId == $attr_def[0]->definitionId; + $attribute->{value} = 'E'; + + $soma_objects->{Applications}->setAppAttribute( $cpeid, + $instance_id, + $attribute + ); + } + + } + + } else { + + #do nothing + + } + + $soma_objects->{CPECollection}->releaseCPE( $cpeid ); + + ''; +} + +sub esn { + my ( $self, $svc ) = @_; + my $svcdb = $svc->cust_svc->part_svc->svcdb; + + return sprintf( '%016d', $svc->id ) if $svcdb eq 'svc_external'; + + my $cust_pkg = $svc->cust_svc->cust_pkg; + return '' unless $cust_pkg; + + my @cust_svc = grep { $_->part_svc->svcdb eq 'svc_external' && + scalar( $_->part_svc->part_export('soma') ) + } + $cust_pkg->cust_svc; + return '' unless scalar(@cust_svc); + warn "part_export::soma found multiple ESNs for cust_svc ". $svc->svcnum + if scalar( @cust_svc ) > 1; + + sprintf( '%016d', $cust_svc[0]->svc_x->id ); +} + + +1; -- 2.11.0