I have a requirement were I need to read ABAP code written by SAP developers. I want to write my own client using Java/Python which can integrate with SAP system and get me the ABAP code.
What I understand that ABAP code is stored in SAP database like HANA, mysql etc. So is there a way which SAP provides where we can read the code like we can do in Git/SVN etc.
I've used RFC calls RPY_FUNCTIONMODULE_READ and RPY_FUNCTIONMODULE_READ_NEW through the perl NWRFC wrapper/library to retreive ABAP code.
You can access tables with below techniques:
Using SAP Connectors via RFC (RFC_READ_TABLE)
Using SOAP Web Service with same function (RFC_READ_TABLE)
Using custom web services with existing functions which are reading report, functions, etc.
You can use both Java or Pyhton for RFC, there is already exits github repo for python.
If you will select reading directly in db table, you need to know structure of saved data. It has own mechanism for OOP objects. Daniel Berlin try to implement binary parser in C++ in sap-reposrc-decompressor project. Never forget this source depended with SAP version.
I think using ADT (ABAP Development Tools) plugin is good for updated systems. There is already Eclipse plugin exists for ADT. ADT not exists in old systems.
If you are planning to use your solution in old system (after 7.01), you can build your own solution with abapGit and custom web services.
NOTE: Keep in mind, report and data elements (variables, tables, types) saved in separate tables. Dynpro objects (screens etc), reports (Smartforms) hard things to decompile.
Before you re-invent a wheel, Take a look at:
ABAPgit. https://docs.abapgit.org/
or the old SAPLink https://wiki.scn.sap.com/wiki/display/ABAP/SAPlink.
If you want JUST the source code, You could expose a very simple rest service/ Endpoint in SAP.
This service would just read the raw code and return it as plain text.
Every abaper could create this for you.
BUT is the raw source only. There is much more to a complete development
and why tools like ABAPGIT exist.
In SICF, create a new endpoint / service.
EG ZCODE_MONKEY with the class below as an example.
Now activate the service.
Call the endpoint
http://server:PORT/zcode_monkey?name=ZCODE_MONKEY
Sample implementation
CLASS zcode_monkey DEFINITION
PUBLIC
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: if_http_extension.
ENDCLASS.
CLASS zcode_monkey IMPLEMENTATION.
METHOD if_http_extension~handle_request.
DATA: lo_src type ref to CL_OO_SOURCE,
l_name TYPE string,
l_repname type c length 30,
l_clskey type seoclskey ,
l_source type rswsourcet,
resultcode TYPE string.
FIELD-SYMBOLS: <line> TYPE LINE OF rswsourcet.
l_name = server->request->get_form_field( name = 'NAME' ).
l_clskey = l_name.
l_repname = l_name.
create OBJECT lo_src
EXPORTING
clskey = l_clskey
EXCEPTIONS
class_not_existing = 1
others = 2 .
IF sy-subrc <> 0.
read REPORT l_repname into l_source.
else.
lo_src->read( ).
lo_src->if_oo_clif_source~get_source( IMPORTING source = l_source ).
ENDIF.
LOOP AT l_source ASSIGNING <line>.
CONCATENATE resultCode
cl_abap_char_utilities=>cr_lf
<line>
INTO resultCode RESPECTING BLANKS. " always show respect ;)
ENDLOOP.
SErver->response->set_content_type( content_type = 'text/plain' ).
server->response->set_cdata( EXPORTING data = resultcode ).
server->response->set_status(
EXPORTING
code = 200
reason = 'this is a 3.50 piece of code. Dont ask...its a demo ' ).
ENDMETHOD.
ENDCLASS.
Related
Hi I made my first Hello World in BTP and it didn't show my user alias...
Why?
CLASS zpo_hello_world DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zpo_hello_world IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
out->write( |Hello World ! ({ cl_abap_context_info=>get_user_alias( ) })| ).
ENDMETHOD.
ENDCLASS.
Some of the methods in cl_abap_context_info can only be used in a cloud environment.
cl_abap_context_info=>
New Method
Old Environemnt
ET_SYSTEM_DATE
SYST-DATUM
GET_SYSTEM_TIME
SYST-UZEIT
GET_USER_TECHNICAL_NAME
SYST-UNAME
GET_USER_LANGUAGE_ABAP_FORMAT
SYST-LANGU
GET_USER_LANGUAGE_ISO_FORMAT
ISO format for language
GET_USER_TIME_ZONE
SYST-TZONE
GET_USER_ALIAS
Alias of user master data (Cloud)
GET_SYSTEM_URL
URL of the system (Cloud)
GET_USER_FORMATTED_NAME
BAPI_USER_GET_DETAIL
GET_USER_DESCRIPTION
BAPI_USER_GET_DETAIL
GET_USER_BUSINESS_PARTNER_ID
Business-Partner-ID of the user (Cloud)
(see here)
Thus means if you run On-Premise those methods will not return any value as far as I know.
But I just saw that you are using the BTP abap cloud example. I've also tested it here it seems that there no alias is set for the users.
You can verify your user with the get_user_business_partner_id-method which is only valid in cloud.
METHOD if_oo_adt_classrun~main.
TRY.
out->write( |Hello World { cl_abap_context_info=>get_user_business_partner_id( ) }| ).
CATCH cx_abap_context_info_error.
ENDTRY.
ENDMETHOD.
I'm not sure weather you can set a user alias with transaction SU1 due there is no SAP Gui support I guess.
The source projectId and source datasetId are supposed to be defined in the Params. But I am not sure how to set Params properly.
TransferConfig transferConfig = TransferConfig.newBuilder()
.setDisplayName(jobName)
.setDestinationDatasetId(dstDatasetId)
.setParams(Struct.newBuilder().build())
.build();
The corresponding cli looks like this.
bq mk --transfer_config
--data_source="cross_region_copy"
--display_name=copy-cli-display-name
--project_id=play
--target_dataset=copy_dataset_cli
--params='{"source_project_id": "tough-talent", "source_dataset_id": "billing"}'
Actually Google BigQuery Data Transfer service represents a plenty of client libraries with a flexible way developing data transport capabilities across BigQuery Data Transfer API.
Assuming that your aim is just to develop transfer service via compatible Bigquery transfer Java client library, you might be looking for TransferConfig.Builder class in order to create data transfer configuration. This class contains dedicated methods for declaring destination Bigquery location path, however source data transfer settings are basically enclosed in setParams() method, invoking Struct() class for propagating key-value structured data parameters, originally included in google.protobuf package.
Due to the fact that:
Struct represents a structured data value, consisting of fields
which map to dynamically typed values.
You can supposedly use either putAllFields() or putFields() methods for mapping key-value parameters within Struct.newBuilder() class as demonstrated in this example:
Struct struct1 = Struct.newBuilder().putFields(
"some-key", Value.newBuilder().setStringValue("some-value").build()
).build();
Find more related examples here.
I am trying to use cl_salv_bs_runtime_info in order to get the ALV data in memory after using SUBMIT in a standard report.
The code for the above is:
REPORT ztest1.
FIELD-SYMBOLS <lt_pay_data> TYPE ANY TABLE.
DATA lr_pay_data TYPE REF TO data.
cl_salv_bs_runtime_info=>set(
EXPORTING display = abap_false
metadata = abap_false
data = abap_true ).
SUBMIT rfts7000
AND RETURN.
TRY.
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING r_data = lr_pay_data ).
ASSIGN lr_pay_data->* TO <lt_pay_data>.
CATCH cx_salv_bs_sc_runtime_info.
MESSAGE `Unable to retrieve ALV data` TYPE 'E'.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
When it is run the program rfts7000 runs and prompts for data selection.
After submitting the selection screen i get:
ST22 extract:
Any ideas?
After some research based on comments in the relative SCN Question the case is as follows.
The system is throwing this error in order to prevent me from running outdated and obsolete (or soon to be obsolete) programs.
The specific program that i call through SUBMIT, is part of the Cash Management (CM) module which although is still active in S4/HANA , i think that is going to be replaced.
So SAP Note 2392358 says exactly that: "According to the S/4HANA Simplification List, the totals tables of classic CM are completed eliminated and therefore they shall not be accessed any more."
In order for this protection to work, SAP has a blacklist where the programs are listed in order not to be used.
But there is a possible "backdoor" to that as explained in SAP Note 2249880. The backdoor is just a way to remove a program from the Blacklist.
The note suggests to get approval from SAP first and then to follow the steps to remove the program from the blacklist.
As a side note, i worry more that we have implemented cash management in an outdated module rather than worrying about the error after all...
I would like to get information about a report. I want to know which values are available if I call the report like this:
SUBMIT (IV_REPORT_NAME)
WITH SELECTION-TABLE selection_table
AND RETURN.
Here is my attempt:
FUNCTION /FOO/GET_REPORT_INFO.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(IV_REPORT_NAME) TYPE PROGRAMM
*" EXPORTING
*" VALUE(EV_RESULT_JSON) TYPE STRING
*"----------------------------------------------------------------------
DATA:
ld_return TYPE BAPIRET2,
it_selscreen_info TYPE STANDARD TABLE OF BAPI_SELSCREEN_INFO,"TABLES PARAM
wa_selscreen_info LIKE LINE OF it_selscreen_info,
it_selscreen_texts TYPE STANDARD TABLE OF TEXTPOOL,"TABLES PARAM
wa_selscreen_texts LIKE LINE OF it_selscreen_texts,
ld_external_user_name TYPE BAPIXMLOGR-EXTUSER.
ld_external_user_name = 'foo'.
CALL FUNCTION 'BAPI_XBP_READ_SELSCREEN'
EXPORTING
program = IV_REPORT_NAME
external_user_name = ld_external_user_name
IMPORTING
return = ld_return
TABLES
selscreen_info = it_selscreen_info
.
ev_result_json = /ui2/cl_json=>serialize( data = it_selscreen_info pretty_name = /ui2/cl_json=>pretty_mode-low_case ).
IF sy-subrc <> 0.
MESSAGE |Error sy-subrc: { sy-subrc }| TYPE 'E'.
ENDIF.
ENDFUNCTION.
But the result is always empty.
What am I doing wrong? Is BAPI_XBP_READ_SELSCREEN the right method for my goal?
This is an answer about "why BAPI_XBP_READ_SELSCREEN doesn't work", not an answer about the main question which is "how to retrieve selection screen parameters".
I'm not sure, but I guess BAPI_XBP_READ_SELSCREEN doesn't work because you don't apply the usual logic of XBP.
XBP ("eXternal Background Processing") is a library of APIs used to schedule jobs from an external scheduler. It's based on XMI ("eXternal Management Interface" Framework) which is used by other APIs, and which offers common features, especially the log.
XMI and the applications based on XMI are RFC-capable, so that they can be called remotely.
To use the APIs based on XMI, the minimum is to :
call the function module BAPI_XMI_LOGON to open a session to use a library of APIs you want to use.
For XBP, use the parameters INTERFACE = 'XBP' and VERSION = '3.0' (or the version you want).
The parameters EXTCOMPANY and EXTPRODUCT can be any max-16-characters names, as agreed with the administrators of the SAP software (they can be possibly blank too), and are subject to S_XMI_PROD authorizations if defined. If they are used with different XMI API libraries during the same RFC session, the same values must be passed.
call the APIs you want (BAPI_XBP_READ_SELSCREEN in your case).
Note that there's an "external user" parameter (usually EXTERNAL_USER_NAME), which is a free field, to be an identifier of the external application. This value is stored with the logs so that you may display or retrieve the XMI logs by external application (transaction RZ15).
call BAPI_XMI_LOGOFF
There is one INTERFACE parameter, whose value must be the same as the one used in BAPI_XMI_LOGON.
In case, you have called an API which updates data, call BAPI_TRANSACTION_COMMIT to commit these updates.
I've just tested BAPI_XBP_READ_SELSCREEN successfully with the program below (please handle the exceptions), so I think it's a good idea to use it :
DATA rfcdest TYPE rfcdest.
rfcdest = ''. " XBP is well suited for RFC, but this test doesn't need remote call.
CALL FUNCTION 'BAPI_XMI_LOGON'
DESTINATION rfcdest
EXPORTING
extcompany = 'ABAPERS&CO'
extproduct = 'NICEJOBSCHEDULER'
interface = 'XBP'
version = '3.0'.
DATA: selscreen_info TYPE STANDARD TABLE OF bapi_selscreen_info,
selscreen_texts TYPE STANDARD TABLE OF textpool.
CALL FUNCTION 'BAPI_XBP_READ_SELSCREEN'
DESTINATION rfcdest
EXPORTING
program = 'BTCAUX10'
external_user_name = 'SRO'
sel_text_lang = 'E' " English
TABLES
selscreen_info = selscreen_info
selscreen_texts = selscreen_texts.
CALL FUNCTION 'BAPI_XMI_LOGOFF'
DESTINATION rfcdest.
IF rfcdest IS NOT INITIAL. " if you use RFC, close the connection!
CALL FUNCTION 'RFC_CONNECTION_CLOSE'
EXPORTING
destination = rfcdest
EXCEPTIONS
destination_not_open = 1
OTHERS = 2.
ENDIF.
Please check user name "foo". If foo is not external user then result will be empty because of wrong external user.
regards,
Umar Abdullah
I need to write to a non-VSAM dataset in the mainframe. I know that we need to use the ZFile library to do it and I found how to do it here
I am running my Java batch job in the WebSphere Liberty on zOS. How do I specify the dataset? Can I directly give the DataSet a name like this?
dsnFile = new ZFile("X.Y.Z", "wb,type=record,noseek");
I am able to write it to a text file on the server itself using Java's File Writers but I don't know how to access a mvs dataset.
I am relatively new to the world of zOS and mainframe.
It sounds like you might be asking more generally how to use the ZFile API on WebSphere Liberty on z/OS.
Have you tried something like:
String pdsName = ZFile.getSlashSlashQuotedDSN("X.Y.Z");
ZFile zfile = new ZFile(pdsName , ...options...)
As far as batch-specific use cases, you might obviously have to differentiate between writing to a new file that's created for the first time on an original execution, as opposed to appending to an already-existing one on a restart.
You also might find some useful snipopets in this doctorbatch.io repo, along with the original link you posted.
For reference, I'll copy/paste from the ZFile Javadoc:
ZFile dd = new ZFile("//DD:MYDD", "r");
Opens the DD namee MYDD for reading
ZFile dsn = new ZFile("//'SYS1.HELP(ACCOUNT)'", "rt");
Opens the member ACCOUNT from the PDS SYS1.HELP for reading text records
ZFile dsn = new ZFile("//SEQ", "wb,type=record,recfm=fb,lrecl=80,noseek");
Opens the data set {MVS_USER}.SEQ for sequential binary writing. Note that ",noseek" should be specified with "type=record" if access is sequential, since performance is greatly improved.
One final note, another couple useful ZFile helper methods are: bpxwdyn() and getFullyQualifiedDSN().