SAP / fundamental-tools

Web applications with ABAP, done simple.
Apache License 2.0
70 stars 13 forks source link

Possibility to provide abap system details in command instead of reading from config/system.yaml & sapnwrfc.ini #11

Closed h2plucifer closed 3 years ago

h2plucifer commented 3 years ago

Hi,

Currently using sapnwrfc.ini that contains the required system details that abap-api-tools utilizes to call the BAPI function. At present only able to use abap executable from '\node_modules.bin" (same path used inside node js script) & it tries to look for sapnwrfc.ini in the same directory.

But since due to permission issue not able to write sapnwrfc.ini in the '\node_modules.bin" & manually creation of same gets removed on every execution of SDK (due to fresh installation of npm packages)

So Is it possible to provide system details as parameters in command itself instead of checking the existence of config/system.yaml file & system details in it so the same command can be used in node script file directly.

(Like : abap get dest:QKX lang:EN user:abc passwd:abc sysnr:00 client:014 ashost:abc QKX STFC_STRUCTURE).

Or is there any way that abap tool doesn't look for sapnwrfc.ini file in the same directory but can read from other directory

Regards Hari

bsrdjan commented 3 years ago

Hi Hari,

abap get dest:QKX lang:EN user:abc passwd:abc sysnr:00 client:014 ashost:abc ... could be tricky because of many connection parameters' combinations (websockets, snc ...). sapnwrfc.ini is generally recommended as more secure because only the dest id passed instead of all connection parameters.

The backend.ts constructor interface could be however extended but abap get should be then called programatically, rather than CLI.

Why sapnwrfc.ini is required in node_modules folder? It is normally in current working folder of the user.

Another possibility would be new abap get option, to pass the absolute path to sapnwrfc.ini, but why is that needed in a first place?

Kind regards, Srdjan

h2plucifer commented 3 years ago

Hi @bsrdjan ,

Thanks for the update. Following is the current use case for which the requirement is to dynamically get/set system details in sapnwrfc.ini:

We have following workflow for automation : BAPI_workflow

Here we are getting BAPI parameters using the following code of line node.js script : const ls = execSync(cd "..\\node_modules\\irpa_bapi\\node_modules\\.bin" && abap call ${abapSystem} ${bapiName}).toString();

Mentioned command used since global installation is not possible for the use case & the tool looks for sapnwrfc.ini in the same directory ("..\node_modules\.bin").

And currently we are not able to write sapnwrfc.ini inside "..\node_modules\.bin" dynamically So was checking the possibility to bypass reading the configuration file .

Why sapnwrfc.ini is required in node_modules folder? It is normally in current working folder of the user : Since require('abap-api-tools") not working inside nodejs script we directly executing using \node_modules\.bin\abap & it checks the sapnwrfc.ini inside same directory . And since modification of node_modules directly currently is not possible I am not able to add configuration dynamically during automation.

Please correct me if my implementation is utilizing the tool correctly .

Regards Hari

h2plucifer commented 3 years ago

Currently sapnwrfc.ini is added manually in the node_modules\.bin directory :

sapnwrfc_path

vijayg78 commented 3 years ago

Hello @bsrdjan, In the workflow above, we provide the system details where the BAPI call needs to be executed. But in many practical cases the system details and password will come from environment variable - a dynamic secure configuration we provide as part of IRPA. This way the automation will not have any sensitive information as part of it and this is required for the security compliance.

Now as part of the runtime, we need a way to pass the system details and credentials dynamically. So creating a file is bit tricky because of permission issues. Can we get an option using which we can initialize the connection dynamically without the .ini file? as an example we can pass a json structure with all the required information for connection.

Best Regards, Vijay

bsrdjan commented 3 years ago

Hi @vijayg78,

could you please let me know which CLI commands are used in scenario? Just to check if my understanding is correct and how the result is received:

Is it invoked from the command line, like this:

abap call MME bapi_user_get_detail

and the proposal is:

abap call {ashost:xyz,client:100,user:demo,pass:welcome,sysnr:00,lang:en} bapi_user_get_detail

How the result is received and processed further, in either way?

If easier, the tool could be also invoked programatically from your Node app, something like:

import {Backend} from 'abap-cli-tools';

const b  = new Backend( {system: {ashost:xyz,client:100,user:demo,pass:welcome,sysnr:00,lang:en} })

const js_template = b.call('bapi_user_get_detail')

Kind regards, Srdjan

h2plucifer commented 3 years ago

Hi @bsrdjan ,

Thanks for the update.

Currently we are using call api in the following format inside our nodejs script to get the required parameters of particular BAPI :

const abapPath="..\\node_modules\\irpa_bapi\\node_modules\\.bin"; 
........
.........
const ls = execSync( `cd ${abapPath} &&  abap call ${abapSystem} ${bapiName}`).toString();    // abap call QKX STFC_STRUCTURE

And the received output in 'ls' is used in further operations .

Sample output for the above call api execution:

STFC_STRUCTURE
//
// STFC_STRUCTURE var: 1  struct: 2  table: 1  exception: 0
//
// abap.js 1.6.4 at: 2021-02-16 19:47:50
//
// prettier-ignore
const parameters = {

// IMPORT PARAMETERS

IMPORTSTRUCT    :           {}, // RFCTEST Importing structure

// TABLE PARAMETERS

RFCTABLE        :           [], // RFCTEST Importing/exporting table

// EXPORT PARAMETERS
.....

From the obtained output parameters (ex. IMPORTSTRUCT , RECTABLE )have been utilized in automation operations .

Note : As you can see currently in the node code abap executable have been used directly from the \node_modules\.bin directory & without sapnwrfc.ini file in the same directory it is not working.

The issue we are having is writing/creating sapnwrfc.ini file dynamically inside the \node_modules\.bin directory with automation execution due to permission issue from the SDK implementation side.

So were looking for any dynamic way to provide system options

Regards Hari Pradhan

h2plucifer commented 3 years ago

Hi @bsrdjan ,

I also checked sample script you shared :

const {Backend} =require("abap-api-tools");

const b  = new Backend({system: {
    ashost: "",
    client: "014",
    user: "",
    passwd: "",   
    sysnr: "00",
    lang: "EN",
 }})

const js_template = b.call('STFC_STRUCTURE')
console.log(js_template);

But this script also getting following generic output :

C:\Users\C5310829\Documents\RFC\test2>node app.js
app.js <command>

Commands:
  app.js call <dest> <rfm...>  ABAP function module call template
  app.js get <dest> [rfm...]   ABAP API annotations
  app.js make <ui> [rfm...]    Create ui elements
  app.js languages             Supported languages
  app.js cp <ui> [to]          Copy ui configuration to local folder config
  app.js rm <ui>               Remove local ui configuration

Options:
  --help     Show help                                                 [boolean]
  --version  Show version number                                       [boolean]

Not enough non-option arguments: got 0, need at least 1

Please correct me if the approach is wrong .

Regards Hari

bsrdjan commented 3 years ago

Hi Hari,

the script is just example and the functionality must be implemented to make it work.

Before that, can you confirm the usage pattern is fine for your scenario?

No need to care about node_modules, bin etc, just consume the abap call as above, from your Node app.

Would that be ok ?

Thanks and regards, Srdjan

vijayg78 commented 3 years ago

Hello @bsrdjan , This kind of usage will be ok from our side .

import {Backend} from 'abap-cli-tools'; const b = new Backend( {system: {ashost:xyz,client:100,user:demo,pass:welcome,sysnr:00,lang:en} }); const js_template = b.call('bapi_user_get_detail');

We have a step/activity to initialize the connection, we create "new Backend" dynamically at runtime with the values we get from secure store.

With that connection to backend (object b above), we make BAPI calls. This is what we need exactly...

Thanks and Best regards, Vijay

h2plucifer commented 3 years ago

Yes @bsrdjan ,

Suggested pattern will work for our use-case .

Regards Hari

bsrdjan commented 3 years ago

With that connection to backend (object b above), we make BAPI calls.

The object b is the instance of the Backend class and b.call() returns the BAPI call template (NodeJS source code how to invoke that BAPI from NodeJS). To call (execute) BAPI, the node-rfc connection instance shall be created. Let us discuss the requirement in Teams call and clarify the requirement? You can just send me the meeting invitation.

Is it enough to consume one BAPI at the time (pass one BAPI name and receive its call template back), or multiple BAPIs (pass array of names and get array of call templates back)?

bsrdjan commented 3 years ago

Hi Hari,

please fell free to try new release with: CLI API, added for your scenario (and integration in general) and with option to pass connection parameters as JSON object:

abap-api-tools#integration

Kind regards, Srdjan

h2plucifer commented 3 years ago

Thanks @bsrdjan for the update.

I will check the same & let you know the behavior.

Regards Hari

bsrdjan commented 3 years ago

the documentation link has been changed, here the new one:

abap-api-tools#integration

(updated also in my previous comment)

bsrdjan commented 3 years ago

Hello Hari,

CliApi is renamed to AbapCliApi in 1.8.0 and make method is exposed:

README.md#integration

Kind regards, Srdjan

h2plucifer commented 3 years ago

Hi @bsrdjan ,

Thanks for the updated implementations.

I checked the get api call with following code snippet & able to make the successful ABAP connection & BAPI calls without sapnwrfc.ini file:

const {AbapCliApi}=require("abap-api-tools");
.......
let abapSystem ={
    ashost: "",
        client: "014",
        user: "",
        passwd: "",   
        sysnr: "00",
        lang: "EN",
 }})
const api = new AbapCliApi();
  try{
  let res=await api.get(abapSystem, [bapiName]);
  res=res.frontend[bapiName].js;       // at present only using 'js '  object from the response
.....

Will also check the possibility of utilizing other parameters returned from the call too & will let you know if some input needed.

Regards Hari

bsrdjan commented 3 years ago

H Hari,

thanks for the update. Hardcoded unit tests reference data are now replaced with yaml files, offering more convenient insight into api data structures: https://github.com/SAP/fundamental-tools/tree/main/abap-api-tools/tests/data

Kind regards, srdjan

h2plucifer commented 3 years ago

Thanks @bsrdjan for the update .

Regards Hari

bsrdjan commented 3 years ago

Search Help API names are now also added and the signature for passing connection parameters is changed. Calls need to be updated accordingly:

https://github.com/SAP/fundamental-tools/blob/main/abap-api-tools/tests/cliapi.spec.js#L33

bsrdjan commented 3 years ago

Please reopen if further support needed

h2plucifer commented 3 years ago

Ok sure , thanks @bsrdjan