Technology Blog Posts by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
thomas_weiss
Product and Topic Expert
Product and Topic Expert
3,316

Introduction and Overview

Are you tired of creating large numbers of data types in your client-system when you call a remote enabled function module (RFM) by RFC and the data types of its parameters do not exist on the client? Let transaction ACO_PROXY do it for you. In a fraction of the time you need to create all these data types yourself, this tool, also called ABAP connector (ACo) and available as of ABAP 7.40, generates:

  • All data types of an RFM’s parameters as well as the parameters themselves  and
  • A static global proxy class with a method that encapsulates the call of this RFM by RFC.  
Note: You can also generate one ACo proxy class for RFC calls of several RFMs, if calling each of them with a different method of the same proxy class makes sense from a design perspective. Since, in principle, it is irrelevant to the explanations in this weblog whether a proxy class covers calls to one or many RFMs and in order to keep things simple, I explain the concepts and features of transaction ACO_PROXY using the case of generating a proxy that calls one RFM.

Reading this weblog,

  • You get an idea of how much time you save with ACO_PROXY by looking at a real-world example with a BAPI that uses hundreds of elementary data types in its interface. (“BAPI” is short for Business Application Programming Interface. You find some more explanation of this concept in the next section below.)
Note: Transaction ACO_PROXY performs a recursive analysis of all complex data types used in the relevant RFM’s interface down to the elementary ones and recreates all of them in the client system. Since this tool creates global data types, you can use them not only in your caller program, but in any program in your client system.
  • Get to know the few simple steps it takes to have this transaction create these data types and a proxy class.
  • You learn about some more options this tool offers such as instantiating the proxy class via a constructor vs. using a factory class or directly calling the proxy class vs. calling it via an interface etc.  (again, all additional entities such as a factory class or an interface will be generated by this tool).
  • You get to know why you always should choose RFC’s fast serialization for new scenarios when calling RFMs via ACo proxy.
  • You see how little code is needed in the client program to call an RFM via an ACo proxy class.
  • You understand why, in most cases, you are better off with a static proxy – generated by transaction ACO_PROXY – than with a dynamic proxy – generated by an ACo API – and also why in one specific case the dynamic ACo proxy is a better choice. 

Note: Two other use cases of transaction ACO_PROXY are just mentioned in this introduction, because the first one needs little explanation, and the second one is treated in great detail in a weblog of an SAP colleague:

  1. Obviously, an ACo proxy class supports you in writing completely object-oriented code, when you need to call an RFM via RFC, because the call itself is hidden in the generated proxy class.
  2. In the weblog How to generate a wrapper for function modules (BAPIs) in tier 2 my SAP colleague Andre Fischer discusses how you profit from an ACo proxy when you want to call a local RFM which is not C1-released  in a program compliant with Clean Core guidelines: In this case, transaction ACO_PROXY generates a C1-released factory class, a C1-released interface for the ACo proxy class, and the proxy class itself. For all further details you are recommended to read my SAP colleague’s weblog.

How ACo Saves You a Lot of Time – a Real-World Example

Let us now consider a real-world example of using transaction ACO_PROXY:  

Imagine yourself writing a client program which calls the BAPI BAPI_BUPA_ADDRESS_CHANGE  by RFC to change the address of a business partner. Its interface has 8 importing and 38 table parameters, which all have complex data types, and neither the BAPI nor any of its data types exist in your client system.

Note: “BAPI” is an Acronym for “Business Application Programming Interface”. From a technical perspective a BAPI is an RFM for which SAP guarantees a stable interface. From a business perspective BAPIs are interfaces to business objects, which are implemented as function modules.

If we break all these complex data types down into their components, we get almost 800 elementary data types, which you all have to recreate in the client system – and on top of them also the 46 complex data types. Assuming that you are a fast developer, let us estimate that, on average, in ABAP Dictionary (transaction SE11), it takes you one minute to define an elementary data type and another 20 seconds per component to define a complex data type. Based on this very optimistic estimate, you need about 17 hours for this job.

When you are facing such a repetitive task, transaction ACO_PROXY is a game changer: Just enter the name of the relevant RFM and of a suitable destination as well as some other values in the tool. This is all it takes to make this transaction generate all the almost 800 elementary and 46 complex data types used in this BAPI’s parameters and a proxy class for an RFC call to the BAPI BAPI_BUPA_ADDRESS_CHANGE.

With transaction “ACO_PROXY”, it takes a few minutes to generate the many hundred data types in our example, compared to about 17 hours you need for this task without tool support. In fact, 17 hours is an optimistic estimate for such a job, actually creating all data types used in the parameters of BAPI BAPI_BUPA_ADDRESS_CHANGE might take far longer.

Basic Steps to Create a Static ACo Proxy

Let us now dive into the details of how to use this transaction. Below, there is a screenshot of ACO_PROXY’s UI with a few numbered labels, which refer to relevant input fields to be explained in this section. You will get to know also some more details of the transaction’s UI in the section to follow.

Picture 1: Transaction ACO_PROXY and its input fieldsPicture 1: Transaction ACO_PROXY and its input fields

  • ACo transaction needs to know where to get the called RFM’s metadata (cf. label 1):
    • You select the option “locally” if the respective RFM is available on your client system.
    • In case you choose “by RFC”, you need to input a destination pointing to your target system or to another system that contains the relevant RFM.
    • If the respective metadata are to be retrieved via file upload, first get them into the relevant file. To achieve this, you also use the ACo tool’s “Get Metadata” options and, again, you choose between the two options “locally” and “by RFC”.  Next, select “File” (cf. label 2) in the line starting with the label “Create” and then press the execute button or F8. In the popup shown next you input file name plus location and confirm.

Note: The option to get the metadata by RFC – whether you retrieve them directly from the remote system or upload them from a file that in turn has got them from the remote system - is needed if, for example, you want to generate an ACo Proxy call to an RFM that, in your landscape, is not available on any system whose release supports transaction “ACO_PROXY”.

  • Enter the name(s) of the RFM(s) for which ACo should generate a proxy with the data types of the RFM’s parameters (cf. label 3). (Surely you remember that you can create a proxy class to encapsulate the connections to one or many RFM depending on what suits your design best.)
  • Enter name and package of your proxy class (cf. label 4).
  • Define whether to create a proxy class for (a) a synchronous RFC call, (b) an asynchronous one with or without response / result method or (c) a bgRFC call. (cf. label 5) While using the synchronous RFC proxy is the self-explanatory default option, options (b) and (c) need some more explanation: As for option (b), an ACo proxy for an asynchronous RFC call with response also has a result method, and you need a sync point in your client program where it waits until the asynchronous response is available and where it can process the result once it is provided. Option (c), creating an ACo proxy that encapsulates a bgRFC call, requires prior creation of a bgRFC unit, which needs to be passed to the relevant method of the ACo proxy class.

More Options in Transaction “ACO_PROXY”

You can also choose:

  • Whether you prefer to create the proxy instance using a constructor or a factory class.
  • Whether you want to create an interface, in which case you have to enter its name. Selection of this option is enforced by the tool, if  “Create Factory Class” is chosen.
  • (a) Whether you want to create a public instance method of the proxy class to encapsulate the RFC call or (b) Whether you prefer to use a private instance method to achieve this, in which case – in addition to the private method - also a public method is generated that, in turn, calls this private method.  
  • (a) Whether you want to pass the destination name to the relevant proxy method when calling an RFM – which is the default – or (b) whether you want to pass the destination via constructor, in which case you should select the respective option. Note that, in the latter case,  usage of interface IF_RFC_DEST is mandatory in SAP BTP ABAP Environment and SAP S/4HANA Cloud Public Edition.
  • Whether you want the called RFM(s) to throw class-based, classic or BAPI exceptions.
  • Whether you want to generate the relevant objects so that they can be used system -internally, in which case you select “C1 Release”. In this case, you should also define if you want to create only C1-released data types that do not already exist in the system. This is what the option “Do not Create Shadows of C1-released Types” is for.

Normally, you are almost done now. Just press “Execute” or F8 to generate:

  • A persistent proxy class.
  • An  instance method that encapsulates the call of the respective RFM for each RFM covered by this proxy class a method and a constructor.
  • All complex and elementary data types of the relevant RFMs’ parameters.
  • (If you have made the respective choice) an interface and a factory class.

Always Choose the Correct Serialization in Destinations Used in an RFC Call via ACo Proxy

In an SM59 destination that is used in an RFC call via an ACo proxy you should always select these options in the tab “Special Options”:

  • “Protocol -> Serializer -> Fast serializer” plus  
  • “Interface Check for Fast Serialization -> Destination for new scenario

With any other serialization or interface check, you might run the risk of data corruption due to incorrect data offset, which might happen to a parameter with a structured data type if this data type differs between client and server system. Though the probability that this might occur is small, once it happens, it might corrupt a large part of the data in the relevant table or structure and thereby cause big harm. Therefore, it is important to always choose fast serialization for new scenarios in destinations used by an ACo proxy.

The Code to Call an RFM with an ACo Proxy

Now, let us call an ACo proxy in a program. Suppose you have created a proxy class zcl_rfc_system_info, which calls RFM RFC_SYSTEM_INFO via RFC, which needs the destination name in the constructor, and which you want to call in the same system.

This is how you instantiate this class and pass destination SELF to the constructor:

ACO_Code_1_60.png

 And this is the code to call this RFM using the proxy class instance:ACO_Code_2_60.png

 Obviously, this code is self-explaining and does not offer any surprise for you ABAP developers.

Note: The name of the public instance method to call an RFM always is the name of the respective RFM. But there is no need to choose a proxy class name that contains the respective RFM’s name – as we do it in the example above.

Static vs. Dynamic ACo Proxy

There is also the option to create a dynamic ACo proxy class, and certainly you want to know, if there are use cases, in which a dynamic proxy might be advantageous over the static proxy generated by transaction “ACO_PROXY”. So, let’s start with a short description how dynamic ACo proxy works:

Note: For a code example of how to create and use a dynamic ACo proxy, look at the program SAP_ACO_EXAMPLE_DYNAMIC_PROXY – also delivered with ABAP 7.40. Developers familiar with using SAP JAVA and SAP .NET Connector will see that, in many respects, creating and using a dynamic ACo proxy class is similar to how you things work with these other two connectors.

Each time a program runs that uses a dynamic ACo proxy to call an RFM, this proxy is created via API based on the respective RFMs metadata. The dynamic proxy class is not persisted. For this reason, the parameters of the proxy class are always up-to-date, even after an upgrade of the server side involving changes to the respective RFM’s interface, which would require recreation of a static proxy. This, at first sight, appears to be a big advantage of the dynamic proxy over the static one. But in this case, appearances are deceiving:

If, for example, after an upgrade, the relevant RFM has additional input or output parameters, a developer has to adapt the client program’s code – be it to process additional output values or to pass values to the additional input parameters. But if developer action is required in any case – to extend the client program accordingly -, then it makes little difference whether or not the ACo proxy class also needs to be re-created as in the case of a static proxy: Compared to the effort required to adapt the client program, the additional effort needed to recreate the proxy class is negligible. Therefore, as to the case of changes to the RFM’s interface, what, at first sight, may appear to be a big advantage of the dynamic over the static proxy, in fact, carries no weight.

In contrast, the advantages of the static proxy are weighty:

  • Working with a static proxy is faster at runtime because it is created at design time and it can be re-used.
  • All global data types generated by the ACo transaction are statically available and therefore easy to use in a program while, in contrast, all program code using elements of the dynamic proxy must be completely dynamic, which is why using the dynamic proxy requires significant experience in dynamic programming.

Therefore, we arrive at the conclusion that, in most cases, you are better off using the static proxy. But – and this is the relevant exception -, you should choose the dynamic ACo proxy, if it is used in a completely dynamic framework. In all other cases, you should prefer the static proxy over the dynamic one.

Note: As with all RFC calls and no matter which kind of ACo proxy you use, after an upgrade of the respective the server system, you should have a look into possible changes of the respective RFM’s interface and also test the relevant connections. If needed, just recreate your static ACo proxy and – as required or useful for your client-program - adapt or extend the program’s code no matter which flavor of ACo you use.

Summary

After all, transaction ACO_PROXY

  • First and foremost, saves you a lot of time,
  • If you call an RFM on a remote system and if neither this RFM nor its parameters’ data types exist in the client system,
  • By generating a static proxy class as well as all relevant data types and parameters.

Normally, you are better off with a static than with a dynamic proxy class to be created by an ACo API. Only if the ACo proxy should be part of a fully dynamic framework, you should use dynamic ACo. In all other cases the static proxy is not only fully sufficient but even the better choice.

Just try it out and you will see: Transaction ACO_PROXY really is a big time saver.

 

1 Comment