Net::Soma initial-import
authorjeff <jeff>
Fri, 21 Nov 2008 04:37:14 +0000 (04:37 +0000)
committerjeff <jeff>
Fri, 21 Nov 2008 04:37:14 +0000 (04:37 +0000)
Changes [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
META.yml [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
README [new file with mode: 0644]
Soma.pm [new file with mode: 0644]
t/Net-Soma.t [new file with mode: 0644]

diff --git a/Changes b/Changes
new file mode 100644 (file)
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 (file)
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 (file)
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 (file)
index 0000000..5305cbc
--- /dev/null
@@ -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 <jeff-net-soma@weasellips.com>',
+    'VERSION_FROM'  => 'Soma.pm', # finds $VERSION
+    'PREREQ_PM'     => { SOAP::Lite => 0.71 },
+);
diff --git a/README b/README
new file mode 100644 (file)
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 (file)
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 (file)
index 0000000..071eab9
--- /dev/null
@@ -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 '');
+
+