Help-Site Computer Manuals
Software
Hardware
Programming
Networking
  Algorithms & Data Structures   Programming Languages   Revision Control
  Protocols
  Cameras   Computers   Displays   Keyboards & Mice   Motherboards   Networking   Printers & Scanners   Storage
  Windows   Linux & Unix   Mac

SAP::Rfc
SAP RFC - RFC Function calls against an SAP R/3 System

SAP::Rfc - SAP RFC - RFC Function calls against an SAP R/3 System



    Copyright (c) 2002 - 2006 Piers Harding.

                    All rights reserved.


NAME

SAP::Rfc - SAP RFC - RFC Function calls against an SAP R/3 System


SYNOPSIS


  # WARNING - as of SAP::Rfc 1.40 USER and PASSWD are case sensitive ready for 

  # R3 7.x

    use SAP::Rfc;

    $rfc = new SAP::Rfc(

                      ASHOST   => 'myhost',

                      USER     => 'ME',

                      PASSWD   => 'secret',

                      LANG     => 'EN',

                      CLIENT   => '200',

                      SYSNR    => '00',

                      TRACE    => '1' );

  my $it = $rfc->discover("RFC_READ_TABLE");

  $it->QUERY_TABLE('TRDIR');

  $it->ROWCOUNT( 2000 );

  $it->OPTIONS( ["NAME LIKE 'RS%'"] );

  # or pass a list of hash refs like so:

  $it->OPTIONS( [ { TEXT => "NAME LIKE 'RS%'" } ] );

  $rfc->callrfc( $it );

  print "NO. PROGS: ".$it->tab('DATA')->rowCount()." \n";

  print join("\n",( $it->DATA ));

  $rfc->close();


DESCRIPTION

SAP::Rfc - is a Perl extension for performing RFC Function calls against an SAP R/3 System. Please refer to the README file found with this distribution. This Distribution also allows the creation of registered RFCs so that an SAP system can call arbitrary Perl code created in assigned callbacks.

The best way to describe this package is to give a brief over view, and then launch into several examples. The SAP::Rfc package works in concert with several other packages that also come with same distribution, these are SAP::Iface, SAP::Parm, SAP::Tab, and SAP::Struc. These come together to give you an object oriented programming interface to performing RFC function calls to SAP from a UNIX based platform with your favourite programming language - Perl. A SAP::Rfc object holds together one ( and only one ) connection to an SAP system at a time. The SAP::Rfc object can hold one or many SAP::Iface objects, each of which equate to the definition of an RFC Function in SAP ( trans SE37 ). Each SAP::Iface object holds one or many SAP::Parm, and/or SAP::Tab objects, corresponding to the RFC Interface definition in SAP ( SE37 ).

For all SAP::Tab objects, and for complex SAP::Parm objects, a SAP::Struc object can be defined. This equates to a structure definition in the data dictionary ( SE11 ). Because the manual definition of interfaces and structures is a boring and tiresome exercise, there are specific methods provided to automatically discover, and add the appropriate interface definitions for an RFC Function module to the SAP::Rfc object ( see methods discover, and structure of SAP::Rfc ).

Please note that USER and PASSWD are now case sensitive - this change has the potential to break backward compatibility.


METHODS:

PARAM_NAME()


  $rfc->PARM_NAME( 'a value ')

  The parameter or tables can be accessed through autoloaded method calls

  - this can be useful for setting or getting the parameter values.

discover()


  $iface = $rfc->discover('RFC_READ_REPORT');

  Discover an RFC interface definition, and automaticlly add it to an 

  SAP::Rfc object.  This will also define all associated SAP::Parm, 

  SAP::Tab, and SAP::Struc objects.

structure()


  $str = $rfc->structure('QTAB');

  Discover and return the definition of a valid data dictionary 

  structure.  This could be subsequently used with an SAP::Parm, or 

  SAP::Tab object.

is_connected()


  if ($rfc->is_connected()) {

  } else {

  };

  Test that the SAP::Rfc object is connected to the SAP system.

sapinfo()


  %info = $rfc->sapinfo();

  map { print "key: $_ = ", $info{$_}, "\n" }

        sort keys %info;

  Return a hash of the values supplied by the RFC_SYSTEM_INFO 

  function module.  This function is only properly called once, and

  the data is cached until the RFC connection is closed - then it 

  will be reset next call.

callrfc()


  $rfc->callrfc($iface);

  Do the actual RFC call - this installs all the Export, Import, and

  Table Parameters in the actual C library of the XS extension, does

  the RFC call, Retrieves the table contents, and import parameter

  contents, and then cleans the libraries storage space again.

getTicket()


        This is for using SAP Logon Tickets, generated by your R/3 system.

  retrieve the requested ticket:

  $rfc = new SAP::Rfc(

                      ASHOST   => 'myhost',

                      USER     => 'ME',

                      PASSWD   => 'secret',

                      GETSSO2   => 1,

                      LANG     => 'EN',

                      CLIENT   => '200',

                      SYSNR    => '00',

                      TRACE    => '1' );

  my $ticket = $rfc->getTicket();

  The ticket can then be used to do logins like so:

  $rfc = new SAP::Rfc(

                      ASHOST   => 'myhost',

                      MYSAPSSO2   => $ticket,

                      LANG     => 'EN',

                      CLIENT   => '200',

                      SYSNR    => '00',

                      TRACE    => '1' );

close()


  $rfc->close();

  Close the current open RFC connection to an SAP system, and then 

  reset cached sapinfo data.

error()


  $rfc->error();

  Returns error string if previous call returned undef (currently 

  supported for discover, structure, is_connected and sapinfo).

errorKeys()


  $rfc->errorKeys();

  Returns a hash of all the RFC error components as found in the standard

  RFC trace file:

  $VAR1 = {

          'KEY' => 'RFC_ERROR_SYSTEM_FAILURE',

          'GROUP' => '104',

          'EXCEPT' => 'SYSTEM_FAILURE',

          'MESSAGE' => 'Name or password is incorrect. Please re-enter'

      };

  Is an example of a login faliure.

accept()

This is the main function to initiate a registered RFC. Consider this example that implements the same functionality as the standard rfcexec executable that comes with all SAP R/3 server implementations:


  use SAP::Rfc;

  use SAP::Iface;

  use Data::Dumper;

  # this enables the user to call die "MY_CUSTOM_ERROR"

  # and only the string MY_CUSTOMER_ERROR is returned to SAP instead of

  # the whole die text + line number etc.

  $SAP::Rfc::EXCEPTION_ONLY = 1;

  # construct the Registered RFC conection

  my $rfc = new SAP::Rfc(

                TPNAME   => 'wibble.rfcexec',

                GWHOST   => '172.22.50.1',

                GWSERV   => '3300',

                TRACE    => '1' );

  # Build up the interface definition that the ABAP code is going to

  # call including the subroutine reference that will be invoked

  # on handling incoming requests

  my $iface = new SAP::Iface(NAME => "RFC_REMOTE_PIPE", HANDLER => \&do_remote_pipe);

  $iface->addParm( TYPE => $iface->RFCIMPORT,

                   INTYPE => $iface->RFCTYPE_CHAR,

                   NAME => "COMMAND",

                   LEN => 256);

  $iface->addParm( TYPE => $iface->RFCIMPORT,

                   INTYPE => $iface->RFCTYPE_CHAR,

                   NAME => "READ",

                   LEN => 1);

  $iface->addTab( NAME => "PIPEDATA",

                  LEN => 80);

  # add the interface definition to the available list of RFCs

  $rfc->iface($iface);

  # kick off the main event loop - register the RFC connection

  # and wait for incoming calls

  $rfc->accept();

  ...

  # the callback subroutine

  # the subroutine receives one argument of an SAP::Iface

  # object that has been populated with the inbound data

  # the callback must return "TRUE" or this is considered

  # an EXCEPTION

  sub do_remote_pipe {

    my $iface = shift;

    warn "Running do_remote_pipe...\n";

    my $ls = $iface->COMMAND;

    $iface->PIPEDATA( [ map { pack("A80",$_) } split(/\n/, `$ls`) ]);

    warn "   Data: ".Dumper($iface->PIPEDATA);

    # force an error

    die "MY_CUSTOM_ERROR" unless $iface->PIPEDATA;

    return 1;

  }

  If accept() returns a defined value then the $rfc->error() can be 

  checked for an associated error message.

  accept() takes a two parameters \&callback(), and $wait.  \&callback()

  is a subroutine reference that will be called each time an event has happened

  within the accept loop.  If an RFC is called then the callback is made

  after the RFC callback has been executed, otherwise the callback is made

  after the accept timeout has been reached.  $wait specifies the time 

  to wait in the accept loop before breaking to execute the callback

  function.  If no wait interval is specified, then a default of

  10 seconds is specified.

  callback() must return true (Perl true) all RFC_SYS_EXCEPTION is set, and the

  accept() loop exits.

accept() with tRFC ... continued


  tRFC must be activated by passing parameters to the $rfc = new SAP::Rfc( ... );

  tRFC cannot be performed at the same time as standard registered RFC, do to the 

  behaviour inside the main event loop.

  Build the tRFC server connection like this:

  my $rfc = new SAP::Rfc(

             TRFC           => 1,

             TRFC_CHECK     => \&do_my_tid_check,

             TRFC_CONFIRM   => \&do_my_tid_confirm,

             TRFC_ROLLBACK  => \&do_my_tid_rollback,

             TRFC_COMMIT    => \&do_my_tid_commit,

             TPNAME         => 'wibble.rfcexec',

             GWHOST         => 'seahorse.local.net',

             GWSERV         => '3300',

             TRACE          => '1' );

  TRFC => 1 - activates the installation of the tRFC transaction control.

  TRFC_CHECK, TRFC_CONFIRM, TRFC_ROLLBACK, TRFC_COMMIT are parameters that

  override the default callback functions for tRFC transaction control.

  consult the saprfc.h header file of the rfcsdk for the full details.

  TRFC_CHECK is the only one that can return a value - it returns true

  if this is a new transaction to be processed, or false to reject the 

  transaction.  All other TRFC_* callbacks return void().

  In the actual callback() for each registered RFC in tRFC mode, there is

  an additional parameter passed for the tRFC transaction id (tid):

  sub do_remote_pipe {

    my $iface = shift;

    my $tid = shift;

    ...

  This can be used to track the status of the callback success, and relay

  this information to the other transaction control callback (TID_*).

allow_start_program(``; separated list of programs'')


  With that the Method it is possible to launch a program. This feature is

  hevealy used by SAP DMS (Document Management System) which sends and

  receives Files from and to the client.

register()

This is the equivalent to accept() but allows you to process the main event loop one step at a time. This must be used with process() and close() to mange the loop processing manually. example that implements the same functionality as the standard rfcexec executable that comes with all SAP R/3 server implementations:


  use SAP::Rfc;

  use SAP::Iface;

  use Data::Dumper;

  # this enables the user to call die "MY_CUSTOM_ERROR"

  # and only the string MY_CUSTOMER_ERROR is returned to SAP instead of

  # the whole die text + line number etc.

  $SAP::Rfc::EXCEPTION_ONLY = 1;

  # construct the Registered RFC conection

  my $rfc = new SAP::Rfc(

                TPNAME   => 'wibble.rfcexec',

                GWHOST   => '172.22.50.1',

                GWSERV   => '3300',

                TRACE    => '1' );

  # Build up the interface definition that the ABAP code is going to

  # call including the subroutine reference that will be invoked

  # on handling incoming requests

  my $iface = new SAP::Iface(NAME => "RFC_REMOTE_PIPE", HANDLER => \&do_remote_pipe);

  $iface->addParm( TYPE => $iface->RFCIMPORT,

                   INTYPE => $iface->RFCTYPE_CHAR,

                   NAME => "COMMAND",

                   LEN => 256);

  $iface->addParm( TYPE => $iface->RFCIMPORT,

                   INTYPE => $iface->RFCTYPE_CHAR,

                   NAME => "READ",

                   LEN => 1);

  $iface->addTab( NAME => "PIPEDATA",

                  LEN => 80);

  # add the interface definition to the available list of RFCs

  $rfc->iface($iface);

  # kick off the main event loop - register the RFC connection

  # and wait for incoming calls

  my $handle = $rfc->register();

  while ($rc = $rfc->process($handle, $wait)){

          if ($rc != 0){

                  warn "Eeek! it went wrong!\n";

                        exit(1);

                }

    ...

        }

  # the callback subroutine

  # the subroutine receives one argument of an SAP::Iface

  # object that has been populated with the inbound data

  # the callback must return "TRUE" or this is considered

  # an EXCEPTION

  sub do_remote_pipe {

    my $iface = shift;

    warn "Running do_remote_pipe...\n";

    my $ls = $iface->COMMAND;

    $iface->PIPEDATA( [ map { pack("A80",$_) } split(/\n/, `$ls`) ]);

    warn "   Data: ".Dumper($iface->PIPEDATA);

    # force an error

    die "MY_CUSTOM_ERROR" unless $iface->PIPEDATA;

    return 1;

  }

  If register() returns a value less than 0 then it failed.

        If process() returns a value other than 0 then it failed.

  register() takes no parameters, but returns the created RFC handle.

  process() takes two parameters - $handle typically returned from register(), 

        and $wait.

CACHING




  Activate the caching of Interface and Structure definitions (generated via

  SAP::Rfc->discover() and SAP::Rfc->structure()).  The definitions are 

  serialized/deserialised using Data::Dumper, which has the effect of 

  speeding up the startup times of scripts (you nolonger have to the SAP

  system everytime you need get a reference to the cached definitions).  If 

  you enable caching then you need to be careful about differences in byte

  order between systems you communicate with (same definitions are retrieved 

  regardless of system connected to), and the potential differences in 

  interface/structure definitions between your systems (perhaps because of

  release etc.).



    $SAP::Rfc::USECACHE = 1;



  The default cache is set to ".rfc_cache/".  If you don't like the default 

  then you need to change this by setting $SAP::Rfc::CACHE to a directory of

  your choice.


AUTHOR

Piers Harding, piers@ompa.net.

But Credit must go to all those that have helped.


SEE ALSO

perl(1), SAP::Iface(3).

Programminig
Wy
Wy
yW
Wy
Programming
Wy
Wy
Wy
Wy