Loading ...
Sorry, an error occurred while loading the content.

MIME Attachment problems

Expand Messages
  • creeping999
    Hi Guys, I m working on a proof of concept to see if SOAP::Lite can provide the implementation for web services etc. I ve been battling with things so far but
    Message 1 of 1 , Mar 12, 2006
    • 0 Attachment
      Hi Guys,

      I'm working on a proof of concept to see if SOAP::Lite can provide
      the implementation for web services etc. I've been battling with
      things so far but I have managed to get some of the way down the
      path. I have not really used Perl (especially the OO stuff) or
      SOAP:lite before so any help would be apprecated.

      The current difficulty I'm having is with MIME attachments in
      SOAP::Lite server/client. Firstly I can't get it work correctly. I
      setup a HTTP SOAP web service and TCP/IP SOAP service and have tried
      to get them to talk to each other. To a degree I've got them working
      when not attaching MIME entities. But as soon as I attach a `part' I
      get the following error:

      Application failed during request deserialization: Can't call
      method "as_string" on an undefined value at
      C:/Perl/site/lib/SOAP/Packager.pm line 185.

      My second problem is the speed of the serialization, transfer and
      deserialization of the MIME envelope. On a 2mb file I'm getting
      quite some delay before the request is processed. Is there something
      I can do to speed this up or is this a MIME::Tools efficiency matter?

      I have attached the files I've been using to test things out. The
      files are:

      A client (democlient.pl)
      Web service (demowebservice.pl and Demo.pm),
      TCP/IP SOAP service (jobserver.pl).

      The client calls the web service and the web service calls the
      TCP/IP SOAP service.

      Thanks for your time
      Jeremy

      Note: I'm using windows 2k, Activestate perl 5.8.7 build 815,
      SOAP::Lite 0.67 and MIME::Tools 5.419. However I've also been able
      to reproduce the same problems on LINUX FC4.


      democlient.pl:

      #!/usr/bin/perl

      # This is a simple SOAP client to demo remote object calls

      use SOAP::Lite;
      use MIME::Entity;

      @ARGV != 1 || die <<EOD;

      Syntax: demowebservice.pl port [ws_host ws_port ]

      Where ws_host The host in which the web service is running
      ws_port The port the web service is running on
      EOD

      my $host = shift || 'localhost';
      my $port = shift || 9000;
      my $endpoint = "http://$host:$port";

      # some test data for a job...
      my $email = 'Jeremy.Palmer@...;
      my $antenna = "DORNE MARGOLIN";
      my $height = "1.54";
      my $file = 'TRNG2270.05O';

      my $job = { email => $email,
      antenna => $antenna,
      ant_height => $height,
      rinex_file => $file };

      my $ent = build MIME::Entity
      Type => "text/rinex",
      Encoding => "base64",
      Path => $file,
      Filename => $file,
      Disposition => "attachment";

      my $soap = SOAP::Lite ->proxy($endpoint)
      ->uri("$endpoint/Demo");

      $soap->on_fault(\&ProcessException);

      $soap->parts( [$ent] );
      print "Trying to add a job through web service...\n";
      my $jobid = $soap->AddJob($job)->result;
      my $numjobs = $soap->JobsInQueue->result;
      print "Job $jobid has been added\n";

      print "Current number of jobs in queue is $numjobs\n";

      my $status = $soap->GetJobStatus($jobid)->result;
      print "Current Status of job $jobid is $status\n";

      print "Deleting job $jobid...\n";
      $soap->DeleteJob($jobid)->result;
      print "Job $jobid has been deleted\n";

      exit(0);

      sub ProcessException {
      my($soap,$res) = @_;
      die ref $res ? $res->faultstring : $soap->transport, "\n";
      }

      demowebservice.pl:

      #!/usr/bin/perl

      # This is a simple SOAP web service which interfaces with both the
      client
      # and the Job Manager

      use strict;
      use SOAP::Transport::HTTP;
      use SOAP::Lite;
      use Getopt::Std;
      use Demo;

      my $syntax = <<EOD;

      Syntax: demowebservice.pl [options] service_host

      Options are:
      -p port local port to run the web server (default 9000)
      -j host host in which the job server is running (default
      localhost)
      -P port port the job server is running on (default 1234)

      EOD

      my %opts;
      &getopts('p:j:P:',\%opts);
      my $srvport = exists $opts{p} ? $opts{p} : 9000;
      my $jshost = exists $opts{j} ? $opts{j} : 'localhost';
      my $jsport = exists $opts{P} ? $opts{P} : 1234;
      # global variable!
      our $jsendpoint = "tcp://$jshost:$jsport";

      @ARGV > 0 || die $syntax;
      my $srvhost = shift(@ARGV) || 'localhost';

      my $daemon = SOAP::Transport::HTTP::Daemon
      ->new(LocalAddr => $srvhost, LocalPort => $srvport)
      ->dispatch_to('Demo');

      print "Contact to SOAP server at ", $daemon->url, "\n";

      $daemon->handle;

      exit;

      Demo.pm:

      package Demo;
      use vars qw(@ISA);
      @ISA = qw(SOAP::Server::Parameters);
      use SOAP::Lite;

      sub JobsInQueue {
      my $class = shift;

      my $soap = SOAP::Lite->uri('urn:/JobManager')
      ->proxy($main::jsendpoint);
      return $soap->JobsInQueue->result;
      }

      sub AddJob {
      my ($self, $job) = @_;
      my $envelope = pop;

      unless ( $job->{email} and $job->{antenna}
      and $job->{ant_height} and $job->{rinex_file} ) {
      return "job object is not defined correctly";
      }
      my $attach = [ ];
      foreach my $part (@{$envelope->parts}) {
      push(@$attach, $part);
      }

      my $soap = SOAP::Lite->uri('urn:/JobManager')
      ->proxy($main::jsendpoint);

      return $soap->AddJob($job)->result;
      }

      sub DeleteJob {
      my ($self, $jobid) = @_;

      my $soap = SOAP::Lite->uri('urn:/JobManager')
      ->proxy($main::jsendpoint);

      return $soap->DeleteJob($jobid)->result;
      }

      sub GetJobStatus {
      my ($self,$jobid) = @_;

      my $soap = SOAP::Lite->uri('urn:/JobManager')
      ->proxy($main::jsendpoint);

      return $soap->GetJobStatus($jobid)->result;
      }

      1;

      demojobserver.pl:

      #!/usr/bin/perl

      # simple TCP SOAP server

      use warnings;
      use strict;

      use MIME::Entity;
      use SOAP::Transport::TCP;

      our @jobs;
      our $start_id = 1000;

      my $syntax = <<EOD;

      Syntax: jobserver.pl service_host service_port

      EOD

      @ARGV !=1 || die $syntax;

      my $port = pop(@ARGV) || 1234;
      my $host = shift(@ARGV) || 'localhost';

      SOAP::Transport::TCP::Server
      ->new(LocalAddr => $host, LocalPort => $port,
      Listen => 5, Reuse => 1)
      ->dispatch_with({ 'urn:/JobManager' =>
      'JobManager' })
      ->objects_by_reference('JobManager')
      ->handle;

      exit;

      package JobManager;

      sub JobsInQueue {
      return $#jobs + 1;
      }

      sub AddJob {
      my ($self,$job) = @_;
      #my $envelope = pop;

      #add a few new attributes
      $job->{id} = ++$start_id;
      $job->{status} = 'PEND';
      $job->{datesub} = localtime;
      &PrintJobdetails($job);

      # foreach my $attachment (@{$envelope->parts}) {
      # #quick and nasty check for the binary data
      #
      # open(BINOF,">$attachment->Body") || die "can not open
      output file\n";
      # binmode(BINOF);
      # print BINOF $attachment;
      # close(BINOF);
      # }
      push(@jobs, $job);
      return $job->{id};
      }

      sub DeleteJob {
      my ($self,$jobid) = @_;

      foreach my $index (0 .. $#jobs) {
      if ($jobs[$index]->{id} = $jobid) {
      delete $jobs[$index];
      last;
      }
      }
      return $self;
      }

      sub GetJobStatus {
      my ($self,$jobid) = @_;

      foreach my $job (@jobs) {
      if ($job->{id} = $jobid) {
      return $job->{status};
      }
      }
      return "Job $jobid does not exist\n";
      }

      sub PrintJobdetails {
      my $job = shift;
      print '='x20 ."\n";
      print "Job id = $job->{id}\n";
      print "Job status = $job->{status}\n";
      print "Date submitted = $job->{datesub}\n";
      }

      1;
    Your message has been successfully submitted and would be delivered to recipients shortly.