Quantcast
Channel: SCN : All Content - SAP Gateway
Viewing all 2823 articles
Browse latest View live

Issue while creating Odata with RFC mapping

$
0
0

Hi Experts,

 

I have created simple Odata where mapping RFC(BAPI_SALESORDER_GETSTATUS)  with  GET_ENTITY_SET method.

 

System giving me below error.Please suggest.

 

Error3.JPG


Gateway service call not triggering DPC_EXT class

$
0
0


Hi,

 

I have created a gateway project and have implemented the DPC_ EXT method of getentityset. While testing in Gateway client I am getting status 200 for the service call [/sap/opu/odata/sap/ZTEST_SRV/EmpolyeeadressSet?$filter=Pernr eq'00000012'], but there is no data in results object. I have put external debugger for my user in the DPC_EXT ->EmployeeadressSet_getentityset method, but not getting triggered even as iam testing the service with my userid. (Gateway is implemented as Hub. Trusted RFC connection has login user configured. Was able to debug gateway services of standard fiori apps previously in the same way ).

 

thanks in advance

CORS Issue While Consuming ODATA from Gateway Hub

$
0
0

Hi

 

We have developed the odata service and trying to use it in the non sap custom application but we are getting error Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource (Reason: CORS header 'Access-Control-Allow-Origin' missing)

We are on ECC 6.0 EHP7 and using the Separate Gateway Hub. We are using MSSQL as database. As mentioned in some of the post have also tried setting up the header in the server side in the service:

DATA: ls TYPE ihttpnvp.

     ls-name = 'Access-Control-Allow-Origin'.

     ls-value = '*'.

     CALL METHOD super->/iwbep/if_mgw_conv_srv_runtime~set_header

       EXPORTING

         is_header = ls.


But still getting the error. Application that is calling the ODATA is residing at the localhost.


Appreciate your responses. Let me know in case further information is required.


Regards,

Rohit

Convert RTF format to PDF format to PHP

$
0
0

Hi Team,

 

I want to convert an RTF format to PDF format in sap code.

Can anyone suggest an idea on it .

 

Regards,

Karthik S

Conversion from RTF format to PDF in odata service

$
0
0

Hi Team,

 

Module - EHS - Doc in DMS

 

I have converted the binary table content to Xstring and when i have sent it to PHP system, they were

able to see the data only in RTF format not in PDF format.

 

Can i know the steps in convvertin to PDF from RTF format .

 

Regards,

Karthik S

sample code for converting RTF to ITF in sap abap

$
0
0

Hi Team,

 

Request to provide the sample code with required parameters in converting the RTF to ITF format , so that

i can convert ITF to PDF and display it in PHP System via ODATA .

 

Can suggest an idea on it .

 

Regards,

Karthik S

Consume HANA XSODATA services on SAP NW GW

$
0
0

Hi Team,

 

We have an requirement for UI5 application to consume HANA DATA via XSODATA services.

The solution architecture is defined as following .

 

SAP NW GW system connected with HANA DB with HTTP Destination having system alias configured. The UI5 application get deployed into SAP GW, here GW is a just web container and not using any ABAP functionalities with  ui5 application.

 

In order to consume the XSODATA services on SAP GW , followed below links and tried to consume ODATA service at application side .

http://www.saplearners.com/how-to-consume-hana-xs-odata-service-in-sap-netweaver-gateway/

http://scn.sap.com/thread/3587498

http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/d0b5be6f-afb7-2f10-e68c-dad80774a223?overridelayout=true

We are able to get the metadata of XSODATA service and as well as Entityset data at GW client , but $Filter is not working  when passed on URI.  PFB the details

/sap/opu/odata/sap/ZFINALSANVIEW_SRV/getPdaPgaData?$filter=MSN eq '07102'

Getting error attached  while testing above link at GW client

But the $filter is working on XSODATA when applied as below

https://:

please let us know if we need to implement any logic with-in runtime classes as similar as we do in general for SAP ODATA services. I suspect here that the final filter should happen on HANA side and GW ODATA just to pass the request as part of service configured within its definition

please share your pointers , advance thanks for your support

Thanks ,

Ratnakar

Getting /IWBEP/CX_SBCM_FATAL from SEGW

$
0
0

Hello Experts,

 

 

I don't know why but since this morning every time I want to check/generate from SEGW I'm getting dump:

 

Category               ABAP Programming Error

Runtime Errors         UNCAUGHT_EXCEPTION

Except.                /IWBEP/CX_SBCM_FATAL

ABAP Program           /IWBEP/CL_SBUI_CONTROLLER=====CP

Application Component  OPU-BSE-SB

Date and Time          16.11.2015 10:07:39

 

An exception has occurred that was not caught.

 

What happened?

     Exception '/IWBEP/CX_SBCM_FATAL' was raised, but it was not caught anywhere

      along the

     call hierarchy.

 

     Since exceptions represent error situations, and this error was not

     adequately responded to, ABAP program '/IWBEP/CL_SBUI_CONTROLLER=====CP' had

     to be terminated.

    

Error analysis

    An exception has occurred which is explained in more detail below. The

    exception, which is assigned to class '/IWBEP/CX_SBCM_FATAL' was not caught and

    therefore caused a runtime error. The reason for the exception is:

    Fatal error in Service Builder

 

    This exception is closely related to a previous exception "CX_SY_NO_HANDLER",

     which

    was raised in program "/IWBEP/CL_SBDSP_DATA_SOURCE===CP", in line 1 of

     (include) program "/IWBEP/CL_SBDSP_DATA_SOURCE===CM00T". The

    reason for the exception occurring was:

    An exception with the type CX_SY_REF_IS_INITIAL occurred, but was neither

    handled locally, nor declared in a RAISING clause

 

    This exception is closely related to a previous exception

     "CX_SY_REF_IS_INITIAL", which

    was raised in program "/IWBEP/CL_SBDSP_DATA_SOURCE===CP", in line 11 of

     (include) program "/IWBEP/CL_SBDSP_DATA_SOURCE===CM00T". The

    reason for the exception occurring was:

    Dereferencing of the NULL reference

 

How to correct the error

    If the error occurs in a non-modfied SAP program, you might be able to

    find a solution in the SAP Notes system. If you have access to the SAP

    Notes system, check there first using the following keywords:

 

    "UNCAUGHT_EXCEPTION" /IWBEP/CX_SBCM_FATAL

    "/IWBEP/CL_SBUI_CONTROLLER=====CP" bzw. /IWBEP/CL_SBUI_CONTROLLER=====CM00C

    "/IWBEP/IF_SBUI_CONTROLLER~ON_COMMAND_REQUESTED"

 

Chain of Exception Objects

 

Attrib. Name                   Value

 

Level    1     Class    /IWBEP/CX_SBCM_FATAL

Program  /IWBEP/CL_SBUI_CONTROLLER=====CP Include  /IWBEP/CL_SBUI_CONTROLLER=====CM00C Row   152

Short Te

Long Tex

 

T100_MSGID                     /IWBEP/SBCM

T100_MSGNO                     000

IS_RESUMABLE

KERNEL_ERRID

 

Level    2     Class    CX_SY_NO_HANDLER

Program  /IWBEP/CL_SBDSP_DATA_SOURCE===CP Include  /IWBEP/CL_SBDSP_DATA_SOURCE===CM00T Row   1

Short Te An exception with the type CX_SY_REF_IS_INITIAL occurred, but was neither handled locally

, nor declared in a RAISING clause

Long Tex

An exception of type 'CX_SY_REF_IS_INITIAL' occurred, that was not caught anywhere in

the call hierarchy. It was not handled locally or declared using a RAISING clause.

 

CLASSNAME                      CX_SY_REF_IS_INITIAL

IS_RESUMABLE

KERNEL_ERRID                   UNCAUGHT_EXCEPTION

 

Level    3     Class    CX_SY_REF_IS_INITIAL

Program  /IWBEP/CL_SBDSP_DATA_SOURCE===CP Include  /IWBEP/CL_SBDSP_DATA_SOURCE===CM00T Row   11

Short Te Dereferencing of the NULL reference

Long Tex

An attempt was made to execute a dynamic method callon an initial(NULL-) object

reference. The reference must refer to an object.

 

IS_RESUMABLE

KERNEL_ERRID

 

Information on where terminated

    The termination occurred in ABAP program "/IWBEP/CL_SBUI_CONTROLLER=====CP",

     in "/IWBEP/IF_SBUI_CONTROLLER~ON_COMMAND_REQUESTED". The main program

    was "/IWBEP/R_SBUI_SERVICE_BUILDER".

 

    In the source code, the termination point is in line 152 of (Include)

    program "/IWBEP/CL_SBUI_CONTROLLER=====CM00C".

   

Source Code Extract

 

Line  SourceCde

 

  122           WHEN gc_cc_sb_cancel.

  123             mr_active_call->exit_command_active = abap_true.

  124             cancel_input_validation( ).

  125           WHEN gc_lc_wz_back.

  126             mr_active_call->exit_command_active = abap_true.

  127             cancel_input_validation( ).

  128           WHEN OTHERS.

  129             fetch_pending_user_input( ).                          " fetch pending input befo

  130         ENDCASE.

  131 *       --- move current selection ---

  132         IF mr_active_call->command_in_process-select EQ abap_true.

  133           mr_active_call->nav_state_current-marked = mr_active_call->command_in_process-requ

  134           mr_active_call->nav_state_current-marked_nodes = mr_active_call->command_in_proces

  135           mr_active_call->navigation_mandatory = abap_true.

  136         ENDIF.

  137 *       --- do process the command ---

  138         mr_active_call->command_in_process-rcode = handle_command( io_sender = mr_active_cal

  139         CASE mr_active_call->command_in_process-rcode.

  140           WHEN gc_rc_cancelled.

  141             MESSAGE ID '/IWBEP/SBUI' TYPE 'S' NUMBER '024' DISPLAY LIKE 'S'.

  142             LOG-POINT ID /iwbep/sbui FIELDS mr_active_call->command_in_process-request-fcode

  143           WHEN gc_rc_error.

  144             MESSAGE ID '/IWBEP/SBUI' TYPE 'S' NUMBER '026' DISPLAY LIKE 'S'.

  145             LOG-POINT ID /iwbep/sbui FIELDS mr_active_call->command_in_process-request-fcode

  146           WHEN gc_rc_rejected.

  147             LOG-POINT ID /iwbep/sbui FIELDS mr_active_call->command_in_process-request-fcode

  148           WHEN gc_rc_undefined.

  149             LOG-POINT ID /iwbep/sbui FIELDS mr_active_call->command_in_process-request-fcode

  150         ENDCASE.

  151       CATCH /iwbep/cx_sbcm_exception cx_sy_no_handler INTO lx_error.

>>>>>         RAISE EXCEPTION TYPE /iwbep/cx_sbcm_fatal EXPORTING previous = lx_error.

  153     ENDTRY.

  154   ENDLOOP.

  155 * --- unlock queue processing ---

  156   CLEAR mr_active_call->command_in_process.

  157

  158 ENDMETHOD.

 

 

How can I solve this error?

 

 

Regards,

Omri


Fiori Like app from AMDP

$
0
0


Hi,

Can anyone guide me on creation of fiori like app from AMDP.

Just we have to create list view in UI5.

 

 

-Amit

properties for Entity types and Entity sets

$
0
0

Dear Experts,

For my entityset I've checked Requires filter Indicator and I've checked Filterable flag for entity type.

but when I can call my webservice "Read Entityset" without $filter suffix.

 

Do I missed any thing because as what I understand that Requires filter Indicator will enforce $Filter suffix.

missing : Release Notes for SAP Gateway SP15

$
0
0

Dear Gateway Team,

 

We recently upgraded our Hub deployment gateway system running on netweaver 7.4 to SP15 (SAP_GWFND=SP15). Is there any official link to see the new features in SP15 of gateway.

 

I can only find release notes from SAP updated in help documents for SP12  here and official announcements in SCN  for SP09 here. Is there any other link  that i am  missing to stay updated with the product features shipping as the new releases..

 

Regards

Virinchy

Reusable READ functionality. Part 3

$
0
0

Welcome Back

 

Welcome back again to our third installment of the series. Today we will cover off navigation and the odata $expand operator. If you haven’t followed along already check out the previous 2 blogs to find out how we ended up here, at part 3.

 

Part 1 - Developing data driven reusable READ functionality.

Part 2 - Reusable READ functionality. $select, $orderby, $top, $skip, $inlinecount, $count

 

 

SEGW

 

Let’s start with defining some new entities to use in our examples. Referring back to part 1 of this series we’ll import from DDIC structures to create our new entities. We’ll create 3 new entities, Flight (using table SFLIGHT), FlightSchedule (using table SPFLI) and Plane (using table SAPLANE). Define them as below with their Name, Key and ABAP fieldname.

 

entities.png

 

Association / Navigation / Referential Constraints

Now let’s create some associations and navigations using the wizard, as below. As part of the creation we will also setup some referential constraints. This is the information we will be using in our navigation routine to determine associations between entities.

 

02_createAssoc_sm.png

 

 

AirlineToSchedule

The first association and navigation we will create is from the Airline entity to the FlightSchedule entity. As in the image below, in the first step specify the association details and navigation property followed by the referential constraints. Use the search help to look the values up to make it a little easier. Although you will need to type the Association Name and Navigation Property (if you wish to change it as below ).

 

airline_schedule.png

 

 

ScheduleToFlight

Next we will create the association and navigation from the FlightSchedule entity to the Flight entity. Follow the same steps as above with the below image as reference.

 

schedule_flight.png

 

FlightToPlane

Finally we will create an association and navigation from the Flight entity to the Plane entity. Again follow the same steps using the image below as reference.

Though note in this last example we are setting the dependent navigation property.

 

flight_plane.png

 

Complete Model

After all the changes made the complete model should look as below in the overview section.

 

09_final_model.png

 

Now save the model and generate our runtime objects as we did in part 1. Make sure you can see your new entities and associations by running the service with the $metadata uri option:

 

     /sap/opu/odata/sap/ZFLIGHT_SRV/$metadata

 

All good? Let’s continue.

 

 

Data Provider Extension Class - ZCL_ZFLIGHT_DPC_EXT

 

Now we will redefine our data provider methods for the newly created entities.  Simply redefine the below methods of class

ZCL_ZFLIGHT_DPC_EXT and add our standard code for get_entity() and get_entityset(), as we did in part 1 of the series for the Airline entity.

 

Redefine the methods:

10_redefine_methods.png

 

 

Code for ...get_entity():

 

get_gw_helper( )->get_entity(  exporting io_tech_request_context = io_tech_request_context  changing  cs_entity = er_entity   cs_response_context = es_response_context ).

 

Code for ...get_entityset():

 

get_gw_helper( )->get_entityset(  exporting io_tech_request_context = io_tech_request_context  changing  ct_entityset = et_entityset   cs_response_context = es_response_context ).

 

 

This stems back to our original goal of adding as little as possible to our data provider extension class in the way of reading entities and allowing the helper class to do most of the work dynamically for us.

 

Finished, that’s it for the data provider class. Save the changes and activate.

 

 

Helper Class - ZCL_GATEWAY_HELPER

Now let’s add the expand and navigation logic to our helper class.

 

First we will create two new class attributes as below.

 

class attrib.PNG

 

Mv_conv_keys, will be used to determine if we should convert our source keys, mv_entity_name will be used to check if we need to run though our init() method due to a new entity, as explained below in the init() change.

 

 

Init(), change

Now we will be running though the gateway frame work executing expands. So we’ll place a check in this method to ensure that we are not loading all the model details again for the same entity. We will check the entity name passed in does not match the entity last processed.

 

Place these new lines of code after the declaration for the field symbols.

 

  field-symbols:  <ls_property> like line of lt_table_properties.
* first check if we already loaded this entity, eg we might be processing
* through a $expand.  if mv_entity_name <> iv_entity_name.

and the following new lines at the end of the method:

 

* save this for comparison on the next round though.
* if we have already computed this then lets not do it again, eg in an $expand!    mv_entity_name = iv_entity_name.  endif.
endmethod.

 

get_entity_nav(), new method, protected

The first new method we will create is a helper method to be used with our next method process_nav_path(). The purpose of this method is select our current navigation entity in readiness for our next navigation. The method will take 3 parameters the entity name, the where condition and the returned entity selected. This entity can then be used as the data for next navigations required keys. Don’t forget to add the exceptions also.

 

Method Signature

11_get_entity_sig.png

 

At the start we just free any data which may be left over from a previous call, as you’ll see in the next method the call is embedded in the navigation loop. Next we get the DDIC structure name from the entity as we have seen in previous examples. We create some data based on this DDIC structure and assign to a field symbol ready for selection. The select is then processed using the where condition passed in. An exception will be raised if no data can be selected as we’ll be unable to continue our navigation.

 

 

method get_entity_nav.  data: lr_entity type ref to /iwbep/if_mgw_med_odata_types=>ty_s_med_entity_type.  field-symbols: <ls_entity> type any.  lr_entity = mr_model->get_entity( iv_entity_name ).  free: er_entity.
*   create our data to select into  create data er_entity type (lr_entity->attribute_struct).  assign er_entity->* to <ls_entity>.
*   select entity, for navigation  select single *         into <ls_entity>         from (lr_entity->attribute_struct)         where (iv_db_where).  if sy-subrc <> 0.    raise exception type /iwbep/cx_mgw_busi_exception      exporting        textid            = /iwbep/cx_mgw_busi_exception=>business_error_unlimited        message_unlimited = 'Navigation select failed on entity, ' && iv_entity_name && '.'.  endif.
endmethod.

process_nav_path(), new method, protected

This is a big one! I’ll try to explain most of what is going on here and justifications, in a way which makes sense!

 

To start the method takes 4 parameters, these being the navigation path, the source keys, a returned parameter to determine if we are navigating and finally the OSQL where condition to be executed in the calling get_entity() or get_entityset() method. Again remember to add the exceptions.

 

 

Method Signature

11_process_nav_sig.png

Initially we check to see if there is any navigation, if not simply exit. Otherwise we continue to loop over the navigation table.

 

First iteration

In the first iteration only (defined by AT FIRST.) we build our OSQL where condition based on the source keys. The source keys will only be converted if this is the first time though a get…() method, for example not an subsequent call via an expand or navigation, as in this case the keys should already be converted.

 

To convert the keys we use the key converter contained in the navigation structure attribute KEY_CONVERTER. We do this by defining some dynamic data based on the DDIC structure and call the EXECUTE() method of the key converter, the results are returned back into our field symbol to be used in our source key loop, again only if this is the first time in a get…() method. Otherwise we simply use the keys passed into parameter it_source_keys.

 

Once the OSQL where condition has been built we call our new method above get_entity_nav() to retrieve our entity details.

 

All iterations

Continuing on from the above first / initial processing, we can either process navigation keys or process our referential constraints.

 

Navigations with keys

Following on from the first lot of processing, we check to see if we have any key fields from navigations. For example:

 

src_nav_keys.png

If we do then we convert the navigation keys using the class: /iwbep/cl_mgw_req_key_convert. We first create the key converter using the target entity type. Next create some dynamic data based on the DDIC structure of the target entity, and finally call execute() method of the key converter to convert our key values. We loop over the key tab first attempting to get the same key value from the entity details we have at hand. This is in an attempt to stop invalid navigations where keys do not match, for example:

 

keys_no_match.png

 

If the key value can be found in the entity and it does not match the value in the navigation key an exception is raised, otherwise the value is added to the OSQL where condition. If the key value cannot be found in the entity then the value is taken directly from our converted navigation keys.

 

Lastly we check if this is the last navigation, if so we want to return this OSQL where condition back to the caller to process. Otherwise we select our next entity, set the source entity to the previous target entity and continue our next loop iteration.

 

 

Referential Constraints

If we had no navigation keys then we will drop into processing the referential constraints. We set these up at the start of this blog during the association and navigation section. We first retrieve the navigation property, from this we can then pick up the association and from the association we then pick up the referential constraints.  We loop over the referential constraints retrieving the target property and matching this up with the source key property value from our entity. Using this information we can build our OSQL where condition, to be passed back to the caller.

 

Finally after the navigation loop we combine the where condition with the one passed in, being the condition from the odata $filter operator.

 

  method process_nav_path.    data: lv_tech_name type /iwbep/if_mgw_med_odata_types=>ty_e_med_technical_name,          lr_entity_type type ref to /iwbep/if_mgw_med_odata_types=>ty_s_med_entity_type,          lr_nav_prop type ref to /iwbep/if_mgw_med_odata_types=>ty_s_med_reference,          lr_assoc type ref to /iwbep/if_mgw_odata_re_assoc,          lr_assoc_ref type ref to /iwbep/if_mgw_med_odata_types=>ty_s_med_reference,          lt_ref_constraints type  /iwbep/if_mgw_odata_re_assoc=>ty_t_mgw_odata_ref_constraints,          lv_value type string,          lv_db_and type string value '',          lv_db_where type string,          lr_entity type ref to data,          lv_max_nav type i,          lv_src_entity type /iwbep/mgw_tech_name,          lr_key_values type ref to data,          lv_ddic type string,          lr_key_conv type ref to /iwbep/if_mgw_req_key_convert,          lr_etype type ref to /iwbep/if_mgw_odata_fw_etype.    field-symbols: <ls_nav_path> like line of it_nav_path,                   <ls_key_values> type any,                   <ls_keytab> type /iwbep/s_mgw_tech_pair,                   <ls_ref_constraints> like line of lt_ref_constraints,                   <ls_key> like line of it_source_keys,                   <lv_any> type any.    ev_navigating = abap_false.
* check if we are navigating    if it_nav_path is not initial.      ev_navigating = abap_true.
* get maximum number of navigations, as we what to process the
* last select from the callers method.      lv_max_nav = lines( it_nav_path ).      loop at it_nav_path assigning <ls_nav_path>.        at first.
* in our initial iteration, read our entity using our source keys
* as this is our starting point if first time through a get...()
* method then convert keys, otherwise keys should already be converted          if mv_conv_keys = abap_true.            lr_key_conv ?= <ls_nav_path>-key_converter.            lv_ddic = lr_key_conv->get_entity_type( )->get_structure( ).            create data lr_key_values type (lv_ddic).            assign lr_key_values->* to <ls_key_values>.            lr_key_conv->execute(              exporting it_tech_pair = it_source_keys              importing es_key_values = <ls_key_values>            ).          endif.          loop at it_source_keys assigning <ls_key>.
* grab key from converted source keys?            if mv_conv_keys = abap_true.              assign component <ls_key>-name of structure <ls_key_values> to <lv_any>.              lv_value = <lv_any>.            else.
* otherwise directly from source keys              lv_value = <ls_key>-value.            endif.            lv_db_where = lv_db_where && lv_db_and && `( ` && <ls_key>-name && ` = '` && lv_value && `' )`.            lv_db_and = ` and `.          endloop.
* select our entity to complete navigation          get_entity_nav(            exporting              iv_entity_name = <ls_nav_path>-source_entity_type              iv_db_where = lv_db_where            importing              er_entity = lr_entity ).          lv_src_entity = <ls_nav_path>-source_entity_type.        endat.        free: lv_db_where,lv_db_and.
* if we have navigation key then lets process them        if <ls_nav_path>-key_tab[] is not initial.
* Create a key converter here based on the target entity type and convert our keys          lr_etype = mr_model->get_entity_type( <ls_nav_path>-target_entity_type ).          free: lr_key_values, lr_key_conv.          create object lr_key_conv            type            /iwbep/cl_mgw_req_key_convert            exporting              io_entity_type = lr_etype.          lv_ddic = lr_etype->get_structure( ).          create data lr_key_values type (lv_ddic).          assign lr_key_values->* to <ls_key_values>.          lr_key_conv->execute(             exporting it_tech_pair = <ls_nav_path>-key_tab[]             importing es_key_values = <ls_key_values>          ).          loop at <ls_nav_path>-key_tab[] assigning <ls_keytab>.
*
* first attempt is to retrieve key from source entity, if it can be found use it,
* otherwise use key from keytab, this is to stop this sort of thing returning
* valid results:
*
* ZFLIGHT_SRV/AirlineSet(AirlineId='AA')/FlightScheduleSet(AirlineId='AZ',ConnectionId='555')
*                                    \------> KEYS NOT EQUAL <------- /
*            assign lr_entity->(<ls_keytab>-name) to <lv_any>.            if sy-subrc = 0.              if <lv_any> = <ls_keytab>-value.                lv_value = <lv_any>.              else.                raise exception type /iwbep/cx_mgw_busi_exception                  exporting                    textid            = /iwbep/cx_mgw_busi_exception=>business_error_unlimited                    message_unlimited = 'Key fields differ during navigation.'.              endif.            else.
* read value from our converted keys              assign component <ls_keytab>-name of structure <ls_key_values> to <lv_any>.              lv_value = <lv_any>.            endif.            lv_db_where = lv_db_where && lv_db_and && `( ` && <ls_keytab>-name && ` = '` && lv_value && `' )`.            lv_db_and = ` and `.          endloop.
* if we are on the last navigation don't process. Pass where condition back
* to our caller, get_entity() or get_entityset() to complete          if sy-tabix <> lv_max_nav.
* select our entity to continue next navigation loop            get_entity_nav(              exporting                iv_entity_name = <ls_nav_path>-target_entity_type                iv_db_where = lv_db_where              importing                er_entity = lr_entity ).            lv_src_entity = <ls_nav_path>-target_entity_type.          endif.        else.
* if no navigation keys, then try and build our navigation from
* our referential constraints          if lv_src_entity is not initial.            lr_entity_type = mr_model->get_entity( lv_src_entity ).
* get navigation property            lv_tech_name = <ls_nav_path>-nav_prop.            lr_nav_prop = mr_model->/iwbep/if_mgw_odata_fw_model~get_nav_property_by_tech(                                        iv_name = lv_tech_name                                        ir_entity_type = lr_entity_type  ).
* get association, and ref. contraints            lr_assoc_ref = mr_model->get_association_by_id( lr_nav_prop->target_entity_id ).            lr_assoc = mr_model->/iwbep/if_mgw_odata_re_model~get_association( lr_assoc_ref->name ).            lt_ref_constraints = lr_assoc->get_ref_constraints( ).
* loop over ref contraints and marry up targets to sources            loop at lt_ref_constraints assigning <ls_ref_constraints>.              assign lr_entity->(<ls_ref_constraints>-target_property-name) to <lv_any>.              if sy-subrc = 0.                lv_db_where = lv_db_where && lv_db_and && `( ` && <ls_ref_constraints>-target_property-name && ` = '` && <lv_any> && `' )`.                lv_db_and = ` and `.              endif.            endloop.          endif.        endif.      endloop.
* return our where condition, either as is, or appended to our $filter      if cv_db_where is not initial.        cv_db_where = cv_db_where && ` and ` && lv_db_where.      else.        cv_db_where = lv_db_where.      endif.    endif.  endmethod.                    "process_nav_path

 

get_entity(), change

Now time to insert our navigation processing into our get_entity() method. First we create a new variable to determine if we are navigating. Next we add the code to call our new method process_nav_path() passing the required parameters. Then we check to see if we are navigating, if so execute the returned OSQL where condition. Otherwise continue as we previously have. Finally we update our class attribute mv_conv_keys to false, check for source key conversion in our process_nav_path() method.

 

New modified method

method get_entity.  data: lt_keys type /iwbep/t_mgw_tech_pairs,        lv_db_where type string,        lv_db_and type string value '',        lv_db_select type string,        lr_data type ref to data,        lv_navigating type abap_bool.  field-symbols: <ls_key> like line of lt_keys,                 <ls_data> type any,                 <lv_value> type any.
* initialise  init( io_tech_request_context->get_entity_type_name( ) ).  if mv_db_tabname is not initial.
* $select, grab fields to select if any    lv_db_select = process_select( io_tech_request_context->get_select_entity_properties( ) ).    lt_keys = io_tech_request_context->get_keys( ).
* read association and keys    process_nav_path(      exporting it_nav_path = io_tech_request_context->get_navigation_path( )                it_source_keys = io_tech_request_context->get_source_keys( )      importing ev_navigating = lv_navigating      changing  cv_db_where = lv_db_where ).    if lv_navigating = abap_false.
* create data struct to grab converted keys      create data lr_data like cs_entity.      assign lr_data->* to <ls_data>.      io_tech_request_context->get_converted_keys(        importing          es_key_values = <ls_data> ).
* loop over keys to build where condition      loop at lt_keys assigning <ls_key>.        assign component <ls_key>-name of structure <ls_data> to <lv_value>.        if sy-subrc = 0.          lv_db_where = lv_db_where && lv_db_and && `( ` && <ls_key>-name && ` = '` && <lv_value> && `' )`.          lv_db_and = ` and `.        endif.      endloop.    endif.    if lv_db_where is not initial.      select single (lv_db_select)        from (mv_db_tabname)        into corresponding fields of cs_entity        where (lv_db_where).    endif.  endif.  mv_conv_keys = abap_false.
endmethod.

 

 

get_entityset(), change

Now let’s put the logic in our get_entityset() method. Again we will create a new variable to determine if we are navigating. Next we call our new method process_nav_path() passing the required parameters. First we leave the check for our has_count(), if we have a count we will execute with our navigated OSQL where condition. Otherwise we check to see if we are navigating, if so execute the returned OSQL where condition, else continue as we have previously. Finally again we update our class attribute mv_conv_keys to false, check for source key conversion in our process_nav_path() method.

 

New modified method

method get_entityset.  data: lv_db_where type string,        lv_db_select type string,        lv_db_orderby type string,        lv_top type i,        lv_skip type i,        lv_navigating type abap_bool.
* initialise  init(    exporting iv_entity_name = io_tech_request_context->get_entity_type_name( )              iv_max_top = iv_max_top ).  if mv_db_tabname is not initial.
* $top, $skip, process our paging    process_paging(      exporting io_tech_request_context = io_tech_request_context      importing ev_top = lv_top                ev_skip = lv_skip ).
* $filter, grab our converted filter    lv_db_where = io_tech_request_context->get_osql_where_clause_convert( ).
* read association and keys    process_nav_path(      exporting it_nav_path = io_tech_request_context->get_navigation_path( )                it_source_keys = io_tech_request_context->get_source_keys( )      importing ev_navigating = lv_navigating      changing  cv_db_where = lv_db_where ).
* check for $count if present just count the records
* no need to order results, or select fields!    if io_tech_request_context->has_count( ) = abap_true.
* execute our select      select count(*) up to lv_top rows        into cs_response_context-count        from (mv_db_tabname)        where (lv_db_where).    else.
* $select, grab fields to select if any      lv_db_select = process_select( io_tech_request_context->get_select_entity_properties( ) ).
* $orderby grab our order      lv_db_orderby = process_orderby( io_tech_request_context ).      if lv_navigating = abap_true.
* we are navigating, execute select with determined lv_db_where
* from navigation!        select (lv_db_select)            from (mv_db_tabname)            into corresponding fields of table ct_entityset            where (lv_db_where)            order by (lv_db_orderby).      else.
* execute our select        select (lv_db_select) up to lv_top rows          from (mv_db_tabname)          into corresponding fields of table ct_entityset          where (lv_db_where)          order by (lv_db_orderby).        if lv_skip > 0.          delete ct_entityset from 1 to lv_skip.        endif.      endif.
* $inlinecount, check for inline count and update      if io_tech_request_context->has_inlinecount( ) = abap_true.        cs_response_context-inlinecount = lines( ct_entityset ).      endif.    endif.  endif.  mv_conv_keys = abap_false.
endmethod.

 

 

Time to test

Activate all changes and try some of the following examples. Note some key fields may be different depending on demo data created:

 

/sap/opu/odata/sap/ZFLIGHT_SRV/AirlineSet('UA')/ToFlightSchedules?$format=json

/sap/opu/odata/sap/ZFLIGHT_SRV/AirlineSet('UA')/ToFlightSchedules?$filter=AirportFrom eq 'FRA'&$format=json

/sap/opu/odata/sap/ZFLIGHT_SRV/AirlineSet('AZ')/ToFlightSchedules(AirlineId='AZ',ConnectionId='555')?$format=json

/sap/opu/odata/sap/ZFLIGHT_SRV/AirlineSet('AZ')/ToFlightSchedules/$count?$filter=CountryFrom eq 'IT'

/sap/opu/odata/sap/ZFLIGHT_SRV/AirlineSet('AZ')?$expand=ToFlightSchedules,ToFlightSchedules/ToFlights,ToFlightSchedules/ToFlights/ToPlane&$format=json

/sap/opu/odata/sap/ZFLIGHT_SRV/FlightSet(AirlineId='AA',ConnectionId='17',FlightDate=datetime'2016-01-13T00:00:00')/ToPlane?$format=json

 

 

Final Words

Here we are at the end of another blog in the series. Hopefully you have been able to follow along and have all the examples working. Either with this set of data or your own set that you have experimented with.

 

Remember to try and use some views as well as transparent tables, this way we can make use of some inner joins with in the view, to include data from related tables.

 

Stay tuned for another blog…

getEntitySetMethod -> passing 2 filter values

$
0
0

Hi experts,

 

i want to pass to the getEntitySet method of my service 2 filter values

 

?$filter=PAR1 eq '01'&$filter=PAR2 eq '02'

 

But how can I access both filters in my service implementation. In the input filter string only the last value is inserted (PAR2 eq '02').

thanks for support.

 

br,

christoph

Capturing Item level changes in the PR

$
0
0

Hi,

I have a requirement of Purchase Requisition. My requirement is PRs keep getting modified with new line items being added, or existing line item being changed (Eg. amount change). These PRs are then routed for approval. Now the approver would want to view the sequence of these line item changes/additions intertwined with all the approvals and rejections that have taken place till date in the header level.


currently, I am getting all the item level changes for a particular PR in cdpos table.But for a particular item number, I am not able to find changes specific to it.


Eg: 6/1/2016 line item 10 added by username

     6/2/2016 PR approved by Username2

 

please advice.



Best Regards

Step-By-Step Procedure for creating Purchase Requisition using BOR interface.

$
0
0


This blog shows how to display and create PR using gateway services(BOR interface) in detail.


Business Object Repository(BOR) in Gateway Service:

It generally used to reduce the time required to create entity types in your data model, SAP Gateway Service Builder provideImport RFC/BOR Interface function with which you can import an existing data source and reuse this data to create new entity types with ease.

 

Step 1:Open Tcode SEGW and create project as shown below.1.png

Provide project details.

2.png

 

Step 2:Create entity by importing BOR interface. For this right click on Data Model and choose Import -> RFC/BOR Interface.3.png

Provide the details.

4.png

 

Step 3:Expand and select the following fields for creating the Purchase requisition and choose next.

             Fields selected RequisitionItems(PREQ_ITEM, DOC_TYPE, MATERIAL, PLANT, QUANTITY, UNIT,

             DELIV_DATE),Number,Return(TYPE,MESSAGE,LOGMSGNO).               

5.png

Specify the key field NUMBER and choose finish.

6.png

 

For displaying (QUERY) Purchase Requisition using BOR interface.

Step 4: Now basic definition of data model is done successfully. As a next step we need to map the fields.

                 Navigate to service implementation and create the QUERY to display the Purchase requisition.

7.png

Step 5: In BOR select the GetDetail for displaying the Purchase requisition details.

8.png

Select the type as Business object Repository and choose tick box.

9.png

Step 6: Now map the fields accordingly by selecting the propose mapping button as shown in below screen.

10.png

Step 7:Fields are mapped accordingly. Check the project, save and generate the project.

11.png

For Creating Purchase Requisition using BOR interface.

Step 8:For creating purchase requisition similarly map the fields by importing the BOR interface.

12.png

Step 9: Select the BOR method (CreateFromData) as shown in below screen.

13.png

Select and proceed.

14.png

Step 10:Now similarly click on propose mapping button as shown below.

15.png

Mapping will be done according. Save and generate the project.

16.png

Testing the Service:

Step 11: Display Purchase requisition

Case1:

Goto Tcode /N/IWFND/MANIT_SERVICE register service.

17.png

Provide System Alias and Click on Get Service. Select Our Created Service and click on Add Selected Service.

Case 2:

Click on SAP Gateway Client.

18.png

Case 3:

Provide the following URL, Select GET and click on EXECUTE to get the sample XML of PR.

19.png

Step 12 :Create Purchase requisition

Case:1

Click on Use as Request and then select POST and EXECUTE it.

20.png

Purchase requisition got created.

21.png

 

Case 2:

Goto SE11 table and provide the Created PR number. So below screen shows that Purchase requisition is created successfully.

22.png

 



HCP oData Provisioning and X-CSRF-Token

$
0
0

Hi support,

I'm not able to call a "CREATE" or "UPDATE" oData service registered in "oData Provisioning service"...

I always receive a 403 HTTP error (the same as if I do not pass any CSRF Token...);

I'll try to explain my tests, could you please help me in some way?

 

I develop an oData Service (SEGW transaction) and, at first, I publish it using /IWFND/MAINT_SERVICE transaction;

 

SAP Gateway Client - Local service

- If I test both GET and POST call via SAP Gateway Client all works; I could not manually set "X-CSRF-Token : Fetch" header parameter in GET call, since the Gateway Client show a message saying: "CSRF Token is handled by SAP Gateway Client"; in fact, when I test POST call, X-CSRF-Token header parameter is set automatically by the Test Client;

Image 573.png

ARC - Local service

If I test both GET and POST call via ARC (Advanced Rest Client, a Chrome plugin used to do REST calls), all works well; in this case I have to manually ask X-CSRF-Token to the system (doing a GET call with "X-CSRF-Token : Fetch" header parameter); the response would contain a valid X-XSRF-Token I can use in the next POST call;

Image 574.png

ARC - oData provisioning

My next step was to register this service in oData Provisioning HCP service:

- GET calls works well; if I set the "X-CSRF-Token : Fetch" parameter, oData response has a CSRF token in the header parameters;

- If I do a POST call, I always obtain a 403 HTTP error (both if I pass the CSRF token or NOT); in the response header I see a "X-Csrf-token : required" header parameter...;

Image 575.png

 

 

Considerations:

- My user has both GW_ADMIN and GW_USER role in oData Provisioning service;

- CSRF token returned by the GET call is, in some way, different from the one returned by the oData published locally (only numbers in it and longer);

- Trying to pass a CSRF token obtained doing a GET call in "local" service to the "Cloud" service obviously do not work :-)

- No log / error shown in oData Provisioning "Troubleshooting" section (obviously, no error also in the BACK-END system, since I'm not authorized to do a call and the system is not called at all);

- I'm using an HCP account (not a trial one);

 

Thanks to all,

BR

 

Manuel

Consume External OData in SAP Gateway

$
0
0

I have metadata service that looks like this...

 

<edmx:Edmxxmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"Version="1.0">

 

<edmx:DataServicesxmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"m:DataServiceVersion="3.0"m:MaxDataServiceVersion="3.0">

 

 

<Schemaxmlns="http://schemas.microsoft.com/ado/2009/11/edm"Namespace="HaworthEnterpriseInterfaceService.Models">

 

 

<EntityTypeName="PROE_SPEED">

 

 

<PropertyName="PROE_SPEED_ID"Type="Edm.Int64"Nullable="false"/>

 

<PropertyName="PART_NUMBER"Type="Edm.String"/>

<PropertyName="PARAMETER_NAME"Type="Edm.String"/>

<PropertyName="PARAMETER_VALUE"Type="Edm.String"/>

<PropertyName="REVISION"Type="Edm.String"/>

<PropertyName="VERSION"Type="Edm.String"/>

<PropertyName="RELEASE_LEVEL"Type="Edm.String"/>

<PropertyName="CREATED_BY"Type="Edm.String"/>

<PropertyName="CREATION_DATE"Type="Edm.DateTime"/>

<PropertyName="LAST_UPDATED_BY"Type="Edm.String"/>

<PropertyName="LAST_UPDATE_DATE"Type="Edm.DateTime"/>

<PropertyName="AMAPS_PART_NUMBER"Type="Edm.String"/>

</EntityType>

</Schema>

 

<Schemaxmlns="http://schemas.microsoft.com/ado/2009/11/edm"Namespace="Default">

 

 

<EntityContainerName="Container"m:IsDefaultEntityContainer="true">

 

 

<EntitySetName="SPEED_SPDD_PROE_SPEED"EntityType="HaworthEnterpriseInterfaceService.Models.PROE_SPEED"/>

 

<EntitySetName="SPEED_SPDP_PROE_SPEED"EntityType="HaworthEnterpriseInterfaceService.Models.PROE_SPEED"/>

</EntityContainer>

</Schema>

</edmx:DataServices>

</edmx:Edmx>


This does not make it pass the parsing. I debugged and found in class /IWFND/CL_OCI_PARSER they are replacing certain schemas in the compose_unrecognized method.

  DATA: ls_unrec TYPE ty_s_unrec   .

*  ls_unrec-actual   = 'MaxLength="Max"'.
*  ls_unrec-expected = 'MaxLength=""'.
*  APPEND ls_unrec TO mt_unrecognized .
*
*  ls_unrec-actual   = 'MaxLength="MAX"'.
*  ls_unrec-expected = 'MaxLength=""'.
*  APPEND ls_unrec TO mt_unrecognized .

   ls_unrec
-actual   = 'xmlns="http://schemas.microsoft.com/ado/2007/05/edm">'.
   ls_unrec
-expected = 'xmlns="http://schemas.microsoft.com/ado/2008/09/edm">'.
  
APPEND ls_unrec TO mt_unrecognized .

* Example: http://www.nerddinner.com/SERVICES/ODATA.SVC/$metadata
   ls_unrec
-actual   = 'xmlns="http://schemas.microsoft.com/ado/2006/04/edm">'.
   ls_unrec
-expected = 'xmlns="http://schemas.microsoft.com/ado/2008/09/edm">'.
  
APPEND ls_unrec TO mt_unrecognized .

* Example: Azure market place services
   ls_unrec
-actual   = 'http://schemas.microsoft.com/ado/2009/08/edm'.
   ls_unrec
-expected = 'http://schemas.microsoft.com/ado/2008/09/edm'.
  
APPEND ls_unrec TO mt_unrecognized
.


Does anyone know if this could be updated, perhaps even made into a customizing table?


Thanks,

Alex

problem with URI in ODATA

$
0
0

Dear experts ,

      i developed a ODATA service  successfully. For  that service i need to give plant , condition type and are single values simultaneously  i need to pass a range table for Material number.

 

i am giving URI

 

/sap/opu/odata/SAP/YHKLL_SRV/PLANTSet?$filter=ConditionType eq 'PR00' and Werks eq '3000' and Material eq 'M16283' or Material eq 'M81018'

 

 

i am getting error 500 INTERNAL SERVER ERROR .

 

please correct my URI.

 

Thank you .

Catch a POST Payload.

$
0
0

Good afternoon fellow SAPers.

 

I am wondering if there's a posibility to keep a trace of the payloads sent to GW services. I know there's the transaction /IWBEP/TRACES, however this is an On - Demand trace and it has a period for when it can keep the Trace up.

 

Question is if there's a standar way to do the following.

My client requieres us to keep a log of the info sent from our Device to the backend, I need to figure out if there's a way to catch the payload and keep it on a file like XML for reference. Otherwise I could catch the POST Payload that we get from the method read_entry_data and convert it into a XML.

 

I know it's a weird requierement, but we want to keep a trace of the failed payloads to figure out some issues with the app.

 

With no further ado, I'm grateful for any ideas that you guys could have.

 

Cheers.

HCI - Odata Services (Beta) - oData endpoint

$
0
0

Hi all,

I need to create an OData service based on an existing OData service.

It should be possible according to this blog:Introduction to Creating OData Service in HANA Cloud Integration (beta)

 

I activate Odata Beta Service and I create my oData service (doing what described in this blog adapting it from SOAP to oData: Creating OData Service from SOAP using HCI (beta))

 

At the end of the procedure, when I try to access the created and deployed service constructing my endpoint (SAP HANA Cloud Integration (Internal, SAP HCI OEM)), I receive this error as a response:

HTTP Status 500 - while trying to invoke the method com.sap.gateway.core.ip.service.SecurityConfiguration.getSubjectsAndIssuers() of a null object loaded from local variable 'secConfig'

 

This is the URL called: https://*****-iflmap.hcisbt.eu1.hana.ondemand.com/gw/odata/SAP/Customer;v=1/

Namespace and service name should be correct (see screen) and also IFLMAP URL (same URL retrieved both from Eclipse and HCP cockpit);

Image 583.png

 

Some considerations:

- From HCI monitor I could see my Integration Content deployed correctly; no logs at all;

Image 582.png

- If I try to edit the Metadata of the oData service created, I see that NAMESPACE has a space at the beginning (see preceding screen)... If I try to remove it, system automatically put a space again; I try also tu add an encoded space in the endpoint URL, but same error...

- In the integration flow, staring point is an oData sender (system and connection to start) not editable and with no reference to an endpoint... All has been created automatically by the system.

Image 584.png

 

Any suggestion? I do not know how to proceed...

Thank you so much,

Manuel

Viewing all 2823 articles
Browse latest View live