From 94af18840467c7e1c1b591cba2c391e47e912a5c Mon Sep 17 00:00:00 2001 From: jeff Date: Fri, 21 Nov 2008 04:37:14 +0000 Subject: [PATCH 1/1] Net::Soma --- Changes | 5 ++ MANIFEST | 7 ++ META.yml | 11 +++ Makefile.PL | 10 +++ README | 31 +++++++ Soma.pm | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ t/Net-Soma.t | 19 ++++ 7 files changed, 371 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 META.yml create mode 100644 Makefile.PL create mode 100644 README create mode 100644 Soma.pm create mode 100644 t/Net-Soma.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..e0390ed --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ + +Revision history for Perl extension Net::Soma + +0.01 Fri Nov 14 04:12:39 EST 2008 + -original version; created by jeff diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..1c805d0 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,7 @@ +Changes +Makefile.PL +MANIFEST +README +Soma.pm +t/Net-Soma.t +META.yml Module meta-data (added by MakeMaker) diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..a836aeb --- /dev/null +++ b/META.yml @@ -0,0 +1,11 @@ +# http://module-build.sourceforge.net/META-spec.html +#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# +name: Net-Soma +version: 0.01 +version_from: Soma.pm +installdirs: site +requires: + SOAP::Lite: 0.71 + +distribution_type: module +generated_by: ExtUtils::MakeMaker version 6.17 diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..5305cbc --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,10 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'Net::Soma', + 'ABSTRACT_FROM' => 'Soma.pm', + 'AUTHOR' => 'Jeff Finucane ', + 'VERSION_FROM' => 'Soma.pm', # finds $VERSION + 'PREREQ_PM' => { SOAP::Lite => 0.71 }, +); diff --git a/README b/README new file mode 100644 index 0000000..24f793b --- /dev/null +++ b/README @@ -0,0 +1,31 @@ +Net-Soma version 0.01 +==================== + +THis module implements a client to SOMA Network's iWireless OSS-API +SOAP interface enabling a perl application to talk to a SOMA platform. + +This module is not sponsored or endorsed by SOMA Networks. + +INSTALLATION + +To install this module type the following: + + perl Makefile.PL + make + make test + make install + +DEPENDENCIES + +This module requires these other modules and libraries: + + SOAP::Lite + OSS-API WSDL files supplied by SOMA Networks + +COPYRIGHT AND LICENCE + +Copyright (C) 2008 Jeff Finucane + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + diff --git a/Soma.pm b/Soma.pm new file mode 100644 index 0000000..9dd63dd --- /dev/null +++ b/Soma.pm @@ -0,0 +1,288 @@ +package Net::Soma; + +use strict; +use vars qw($DEBUG $VERSION @uris $AUTOLOAD %schemas); +use SOAP::Lite 0.71 #+trace => debug, objects +; + +$VERSION = '0.01'; + +$DEBUG = 0; + +@uris = qw( CPECollection AppCatalog AdminService CPESearch Version Applications + CPEAccess ApplicationsV2 + ); + +=head1 NAME + +Net::Soma - Perl client interface to SOMA iWireless platform + +=head1 SYNOPSIS + +use Net::Soma; +use Net::Soma qw( AttributeInstance FeatureInstance ApplicationInstance + ChoiceItem AttributeDef FeatureDef ApplicationDef + ApplicationDefV2 FeatureDefV2 AttributeDefV2 CPEInfoDefV2 + CPESearchStruct CPESearchResult CPEInfo CPEInfoDef + HardwarePort + NoSuchCPEException DataAccessException InternalFault + BadAppParameterException BadAppParameterExceptionV2 + NoSuchAppException NoSuchFeatureException + NoSuchAttributeException BadCPEParameterException + ActiveApplicationsException ); + +$soma = new Net::Soma { url => 'https://soma.example.net:8088/ossapi/services', + namespace => 'AppCatalog', + } + +$err_or_som = $soma->getApplicationDefinitions(); + +if (ref($err_or_som)){ + my $result = $err_or_som->result; + foreach my $definition (@$result) { + print $definition->name, "\n"; + } +}else{ + print "$err_or_som\n"; +} + +=head1 DESCRIPTION + +Net::Soma is a module implementing a Perl interface to SOMA's iWireless +SOAP interface (ossapi). It is compatible with release 1.5 of that software +and requires the WSDLs from SOMA. + +Net::Soma enables you to simply access the SOAP interface of your SOMA +networks softair platform server. + +=head1 BASIC USAGE + +Import the Net::Soma module with + +use Net::Soma (@list_of_classes); + +Net::Soma will create any of the following classes for you + +AttributeInstance FeatureInstance ApplicationInstance ChoiceItem +AttributeDef FeatureDef ApplicationDef ApplicationDefV2 FeatureDefV2 +AttributeDefV2 CPEInfoDefV2 CPESearchStruct CPESearchResult CPEInfo +CPEInfoDef HardwarePort NoSuchCPEException DataAccessException InternalFault +BadAppParameterException BadAppParameterExceptionV2 NoSuchAppException +NoSuchFeatureException NoSuchAttributeException BadCPEParameterException +ActiveApplicationsException + +=cut + +sub import { + my $class = shift; + my @classes = @_; + my $me = __PACKAGE__; + my @classlist = qw( AttributeInstance FeatureInstance ApplicationInstance + ChoiceItem AttributeDef FeatureDef ApplicationDef + ApplicationDefV2 FeatureDefV2 AttributeDefV2 CPEInfoDefV2 + CPESearchStruct CPESearchResult CPEInfo CPEInfoDef + HardwarePort + NoSuchCPEException DataAccessException InternalFault + BadAppParameterException BadAppParameterExceptionV2 + NoSuchAppException NoSuchFeatureException + NoSuchAttributeException BadCPEParameterException + ActiveApplicationsException + ); + my (%EXPORT_OK) = map { $_ => 1 } @classlist; + + { + no strict 'refs'; #hmmm force 'use' of all to be serialized? + foreach my $class (@classlist) { + + *{"SOAP::Serializer::as_$class"} = sub { + my ($self, $value, $name, $type, $attr) = @_; + + $self->register_ns("urn:ossapi.services.core.soma.com", "netsoma"); + $self->encode_object( \SOAP::Data->value( + SOAP::Data->name($name => map { SOAP::Data->name($_ => $value->{$_}) } + keys %$value + ) + ), $name, $type, {'xsi:type' => "netsoma:$class", %$attr}); + }; + + *{"SOAP::Serializer::as_ArrayOf$class"} = sub { + my ($self, $value, $name, $type, $attr) = @_; + + $self->register_ns("urn:ossapi.services.core.soma.com", "netsoma"); + if (@$value) { + $self->encode_object( \SOAP::Data->value( + SOAP::Data->name($name => map { SOAP::Data->name(item => $_) } + @$value + ) + ), $name, $type, {'xsi:type' => "netsoma:ArrayOf$class", %$attr}); + } else { + $self->encode_object( [], $name, $type, {'xsi:type' => "netsoma:ArrayOf$class", %$attr}); + } + + }; + + } + + } + + foreach $class ( map { $_, "ArrayOf$_" } + grep { exists( $EXPORT_OK{$_} ) + or die "$_ is not exported by module $me" + } + @classes) + { + no strict 'refs'; + + *{"$class\::NEW"} = sub { + my $proto = shift; + my $class = ref($proto) || $proto; + my $self = { @_ }; + return bless($self, $class); + }; + *{"$class\::AUTOLOAD"} = sub { + my $field = $AUTOLOAD; + $field =~ s/.*://; + return if $field eq 'DESTROY'; + if ( defined($_[1]) ) { + $_[0]->{$field} = $_[1]; + } else { + $_[0]->{$field}; + } + }; + } + + # $me =~ s/::/\//g; + # $INC{"$me.pm"} =~ /^(.*)\.pm$/; + # $me = $1; + # for (@uris){ + # $schemas{$_."Service"} = SOAP::Schema + # ->schema_url("file:$me/wsdls/$_.wsdl") + # ->parse->services->{$_."Service"}; + # } + +} + +=head1 CONSTRUCTOR + +=over 4 + +=item new HASHREF + +Creates a new Soma object. HASHREF should contain the keys url and namespace +for the URL of the Soma SOAP proxy and the namespace of the methods you would +like to call. You may optionally define the key die_on_fault to cause that +behavior for methods. + +=cut + +sub new { + my $proto = shift; + my $class = ref($proto) || $proto; + my $self = { @_ }; + + for (@uris){ + $schemas{$_."Service"} = SOAP::Schema + ->schema_url($self->{url}."$_?wsdl") + ->parse->services->{$_."Service"}; + } + + return bless($self, $class); +} + +=head1 METHODS + +All Soma methods may be invoked as methods of the Net::Soma object. +The return value is either the fault string in the event of an error +or a SOAP::SOM object. + +If the option die_on_fault was set for the Net::Soma object, then +instead the method dies on error and returns the result component +of the SOAP::SOM object on success. + +=cut + +sub AUTOLOAD { + my $self = shift; #hmmm... test this? + + my $method = $AUTOLOAD; + $method =~ s/.*://; + return if $method eq 'DESTROY'; + + my $nscount = 1; + my $uri = $self->{namespace}; + $uri =~ s/Service$//; + my $soap = SOAP::Lite + -> autotype(1) + -> readable(1) + -> uri($uri) + -> proxy($self->{url}); + + $soap->serializer(Net::Soma::Serializer->rebless($soap->serializer)); + +# local *SOAP::Transport::HTTP::Client::get_basic_credentials = sub { +# return $self->{user} => $self->{password}; +# }; + + my $param = 0; + my $som = + $soap->$method( map { + my $paramdata = + $schemas{$self->{namespace}}{$method}{'parameters'}[$param++]; + my ($pre,$type) = SOAP::Utils::splitqname($paramdata->type); + SOAP::Data->name($paramdata->name => $_ ) + ->type(${[SOAP::Utils::splitqname($paramdata->type)]}[1]) } @_ + ); + + if ($som) { + if ($som->fault){ + if ($self->{die_on_fault}){ + die $som->faultstring; + } else { + return $som->faultstring; + } + }else{ + if ($self->{die_on_fault}){ + return $som->result; + } else { + return $som; + } + } + } + + die "Net::Soma failed to $method for $self->{namespace} at " . $self->{url}; +} + + +=back + +=head1 SEE ALSO + + SOAP::Lite, SOAP::SOM + + http://www.somanetworks.com/ for information about SOMA and iWireless. + + http://www.sisd.com/freeside/ for the ISP billing and provisioning system + which provoked the need for this module. + +=head1 BUGS + +Namespace promiscuous. +Lax handling of arguments and return values. +In fact, calling a bogus method with arguments causes complaints about +accessing methods on undefined values (at line 233, paramdata->name) + +Quite probably others. Use at your own risk. + +=head1 AUTHOR AND COPYRIGHT + +Copyright (c) 2008 Jeff Finucane jeff-net-soma@weasellips.com + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +This software is neither authorized, sponsored, endorsed, nor supported +by Soma Networks. + +=cut + +1; diff --git a/t/Net-Soma.t b/t/Net-Soma.t new file mode 100644 index 0000000..071eab9 --- /dev/null +++ b/t/Net-Soma.t @@ -0,0 +1,19 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl Net-Soma.t' + +# Not very exciting testing + +use Test; +BEGIN { plan tests => 3 }; +eval "use Net::Soma"; +ok($@ eq ''); + +no Net::Soma; +eval "use Net::Soma qw(ApplicationDef)"; +ok($@ eq ''); + +no Net::Soma; +eval "use Net::Soma qw(BadClass)"; +ok($@ ne ''); + + -- 2.11.0