insist on 0.71
[Net-Prizm.git] / lib / Net / Prizm.pm
1 package Net::Prizm;
2
3 use strict;
4 use vars qw($DEBUG $VERSION @uris %services $AUTOLOAD %schemas);
5 use SOAP::Lite 0.71;
6
7 $VERSION = '0.04';
8
9 $DEBUG = 0;
10
11 @uris = qw(CustomerIfService NetworkIfService LogEventIfService);
12
13 =head1 NAME
14
15 Net::Prizm - Perl client interface to Motorola Canopy Prizm
16
17 =head1 SYNOPSIS
18
19 use Net::Prizm;
20 use Net::Prizm qw(CustomerInfo LogEventInfo
21                   ClientDevice ConfigurationTemplate ElementLinkInfo
22                   Network PerformanceData);
23
24 $prizm = new Net::Prizm { url => 'https://prizm.example.net:8443/prizm/nbi',
25                           namespace => 'CustomerIfService',
26                           username => 'prizmuser',
27                           password => 'associatedpassword',
28                         }
29   
30 $err_or_som = $prizm->getCustomers(['import_id'], ['50'], ['<']);
31
32 if (ref($err_or_som)){
33   my $result = $err_or_som->result;
34   foreach my $customer (@$result) {
35     print $customer->contact, "\n";
36   }
37 }else{
38   print "$err_or_som\n";
39 }
40  
41 =head1 DESCRIPTION
42
43 Net::Prizm is a module implementing a Perl interface to Motorola's Canopy
44 Prizm SOAP interface.  It is compatible with version 3.0r1 of that software
45 and requires the WSDL from Motorola.
46
47 Net::Prizm enables you to simply access the SOAP interface of your Prizm
48 server.  
49
50 =head1 BASIC USAGE
51
52 Import the Net::Prizm module with
53
54 use Net::Prizm (@list_of_classes);
55
56 Net::Prizm will create any of the following classes for you
57
58 CustomerInfo LogEventInfo PrizmElement ClientDevice ConfigurationTemplate
59 ElementLinkInfo Network PerformanceData 
60     
61 =cut
62
63 sub import {
64   my $class = shift;
65   my @classes = @_;
66   my $me = __PACKAGE__;
67   my (%EXPORT_OK) = map { $_ => 1 } qw( CustomerInfo LogEventInfo PrizmElement
68                                         ClientDevice ConfigurationTemplate
69                                         ElementLinkInfo Network 
70                                         PerformanceData );
71
72   foreach $class (grep { exists( $EXPORT_OK{$_} )
73                          or die "$_ is not exported by module $me"
74                        } @classes) {
75     no strict 'refs';
76
77     *{"$class\::NEW"} = sub {
78                          my $proto = shift;
79                          my $class = ref($proto) || $proto;
80                          my $self = { @_ };
81                          return bless($self, $class);
82                        };
83     *{"$class\::AUTOLOAD"} = sub {
84                               my $field = $AUTOLOAD;
85                               $field =~ s/.*://;
86                               return if $field eq 'DESTROY';
87                               if ( defined($_[1]) ) {
88                                 $_[0]->{$field} = $_[1];
89                               } else {
90                                 $_[0]->{$field};
91                               }
92                             };
93   }
94
95   $me =~ s/::/\//g;
96   $INC{"$me.pm"} =~ /^(.*)\.pm$/;
97   $me = $1;
98   for (@uris){
99     $schemas{$_} = SOAP::Schema
100       ->schema_url("file:$me/wsdls/$_.wsdl")
101       ->parse->services->{$_};
102   }
103
104 }
105
106 =head1 CONSTRUCTOR
107
108 =over 4
109
110 =item new HASHREF
111
112 Creates a new Prizm object.  HASHREF should contain the keys url, namespace,
113 username, and password for the URL of the Prizm SOAP proxy, the namespace
114 of the methods you would like to call, and the username and password for
115 basic authentication.
116
117 =cut 
118
119 sub new {
120   my $proto = shift;
121   my $class = ref($proto) || $proto;
122   my $self = { @_ };
123   return bless($self, $class);
124 }
125
126 =head1 METHODS
127
128 All Prizm methods may be invoked as methods of the Net::Prizm object.
129 The return value is either the fault string in the event of an error
130 or a SOAP::SOM object.
131
132 =cut 
133
134 sub AUTOLOAD {
135   my $self = shift;   #hmmm... test this?
136
137   my $method = $AUTOLOAD;
138   $method =~ s/.*://;
139   return if $method eq 'DESTROY';
140
141   my $soap = SOAP::Lite
142     -> autotype(0)
143     -> readable(1)
144     -> uri($self->{namespace})
145     -> proxy($self->{url});
146   
147   local *SOAP::Transport::HTTP::Client::get_basic_credentials = sub {
148     return $self->{user} => $self->{password};
149   };
150
151   local *SOAP::Serializer::as_ArrayOf_xsd_string = sub {
152     my ($self, $value, $name, $type, $attr) = @_;
153
154     $name ||= $self->gen_name;
155     $self->encode_object(\SOAP::Data->value(
156       SOAP::Data->name('string' => @{$value})->type('string')
157       ), $name, $type);
158
159   };
160
161   local *SOAP::Serializer::as_ArrayOf_xsd_int = sub {
162     my ($self, $value, $name, $type, $attr) = @_;
163
164     $name ||= $self->gen_name;
165     $self->encode_object(\SOAP::Data->value(
166       SOAP::Data->name('int' => @{$value})->type('int')
167     ), $name, $type);
168   };
169
170   local *SOAP::Serializer::as_CustomerInfo = sub {
171     my ($self, $value, $name, $type, $attr) = @_;
172
173     my $schema = {
174            'importId'         => 'string',
175            'customerId'       => 'int',
176            'customerName'     => 'string',
177            'customerType'     => 'string',
178            'address1'         => 'string',
179            'address2'         => 'string',
180            'city'             => 'string',
181            'state'            => 'string',
182            'zipCode'          => 'string',
183            'workPhone'        => 'string',
184            'homePhone'        => 'string',
185            'mobilePhone'      => 'string',
186            'pager'            => 'string',
187            'email'            => 'string',
188            'extraFieldNames'  => 'impl:ArrayOf_xsd_string',
189            'extraFieldValues' => 'impl:ArrayOf_xsd_string',
190            'elementIds'       => 'impl:ArrayOf_xsd_int',
191     };
192
193     my (@result) = ();
194     foreach my $key (keys %$value){
195       my $to_encode = $value->{$key};
196       push @result, SOAP::Data->name($key => $to_encode)->type($schema->{$key});
197     }
198
199     return $self->encode_object(\SOAP::Data->value(
200       SOAP::Data->name($name => @result)), $name, 
201                                  $type,
202                                  {'xsi:type' => 'impl:CustomerInfo', %$attr});
203   };
204
205   my $param = 0;
206   my $som =
207     $soap->$method( map {
208       my $paramdata =
209         $schemas{$self->{namespace}}{$method}{'parameters'}[$param++];
210       SOAP::Data->name($paramdata->name => $_ )
211         ->type(${[SOAP::Utils::splitqname($paramdata->type)]}[1]) } @_
212     );
213
214   if ($som) {
215     if ($som->fault){
216       return $som->faultstring;
217     }else{
218       return $som;
219     }
220   }
221
222   "Net::Prizm failed to $method for $self->{namespace} at " . $self->{url};
223 }
224
225
226 =back
227
228 =head1 SEE ALSO
229
230   SOAP::Lite, SOAP::SOM
231
232   http://motorola.canopywireless.com/ for information about Canopy and
233 Prizm.
234
235   http://www.sisd.com/freeside/ for the ISP billing and provisioning system
236   which provoked the need for this module.
237
238 =head1 BUGS
239
240 No explicit handling of types other than CustomerInfo.
241 Namespace promiscuous.
242 Lax handling of arguments and return values.
243
244 Quite probably others.  Use at your own risk.
245
246 =head1 AUTHOR AND COPYRIGHT
247
248 Copyright (c) 2006 Jeff Finucane jeff-net-prizm@weasellips.com
249
250 This library is free software; you can redistribute it and/or modify
251 it under the same terms as Perl itself.
252
253 WDSL files copyright Motorola Inc. which reserves all rights.  
254
255 This software is neither authorized, sponsored, endorsed, nor supported
256 by Motorola Inc.
257
258 =cut
259
260 1;