Child pages
  • Expose BI Query as RESTful Service
Skip to end of metadata
Go to start of metadata

Many times, you may want to expose your BI queries to external tools/systems and SAP BI provides Webservice as one of the mechanisms to do that. However, due to the nature of returned data (multi dimensional) sometimes it's not very friendly to the calling systems (for example Xcelsius). To overcome that created a RESTful service, which is basically a BSP application, which can be called over HTTP and the parameter passing is similar to webquery or webtemplate (more on this) and the results will be in just row/column format. Using this tool to call a BI query from a widget engine or ajax or xcelsius you would be using a URL similar to

http://abaphost.domain.com:1080/sap/bc/bsp/sap/ybwqs/data.xml?infocube=CO_M01&query=ZC_MY_TEST_QUERY&VAR_NAME_1=0H_CCTR&VAR_VALUE_EXT_1=ABC&VAR_NAME_2=0P_FPER&VAR_VALUE_EXT_2=2008005&VAR_NAME_3=ZMYVAR&VAR_VALUE_EXT_3=DEF&VAR_NODE_IOBJNM_3=0HIER_NODE

How to pass parameter to this url

Inforprovider => infocube=cubename

Query =>     query=query technical name

view => view=view technical name 

for passing variables check the online help .

(This has been tested in BW3.5 and BI7 (with only BI3.5 queries))

The Code

1. Create a BSP application from SE80 and add a page with extension .xml (also check the page attribute to see that MIME type is set as text/xml)

(if you are new to BSP applications check this online help to get started)

2. Create the following page attributes with auto check box checked.

infocube TYPE CHAR30
query TYPE CHAR30
view TYPE CHAR30

3. Remove all the default code in the Layout section.

4. Add the following code to the onInitialization event of the BSP page.

 
* event handler for data retrieval
TYPE-POOLS: rrx1 .
DATA: r_dataset TYPE REF TO cl_rsr_data_set.
DATA: lcount TYPE i .
DATA: xcount TYPE i .

DATA: i_var TYPE rrx1_t_var.
DATA: i_var_final TYPE rrx1_t_var.
DATA: wf_variant TYPE variant .
DATA: wa_axis LIKE LINE OF r_dataset->n_sx_version_20a_1-axis_data .
DATA: wa_axis_info LIKE LINE OF r_dataset->n_sx_version_20a_1-axis_info .
DATA: wa_chars LIKE LINE OF wa_axis_info-chars .
DATA: tmp_char TYPE rrws_thx_axis_chars.
DATA: wa_tmp_char TYPE rrws_sx_axis_chars .
DATA: wa_attrinm TYPE rrws_s_attrinm.

DATA: wa_cell LIKE LINE OF r_dataset->n_sx_version_20a_1-cell_data .
DATA: wa_textsymbols LIKE LINE OF r_dataset->n_sx_version_20a_1-txt_symbols .
DATA: wa_textsymbols1 LIKE LINE OF r_dataset->n_sx_version_20a_1-txt_symbols .
DATA: wa_set LIKE LINE OF wa_axis-set.
DATA: tmp_set TYPE rrws_tx_set.
DATA: wa_tmp_set TYPE rrws_sx_tuple .
DATA: wa_dattrinm TYPE rrws_s_attributes .
DATA: i_iset_iobjnm TYPE  rsd_iobjnm ,
      e_iobjnm TYPE  rsd_iobjnm .
DATA: error_message TYPE string ,
      xml_out TYPE string .
DATA: q_variables TYPE rrxw3tquery .

DATA: error_string TYPE string.
DATA: no_of_chars TYPE  i ,
      no_of_keyf TYPE i .
DATA: var_nam(10) .
DATA: iobj_detail TYPE bapi6108 .
DATA: iobj_details TYPE bapi6108_t .
DATA: it_fieldcat TYPE lvc_t_fcat,
      is_fieldcat LIKE LINE OF it_fieldcat.

DATA: return TYPE bapiret2_tab .
FIELD-SYMBOLS: <ltable> TYPE ANY TABLE,
               <l_line>  TYPE ANY,
               <l_field> TYPE ANY.
TYPES: BEGIN OF metatype ,
       fieldname(30),
       outputlen(6) TYPE n,
       datatype(4) ,
       scrtext_l(40),
       END OF metatype .
DATA: meta_data TYPE STANDARD TABLE OF metatype ,
      wa_meta_data TYPE metatype .

DATA: off  TYPE i,
    moff TYPE i,
    mlen TYPE i.
DATA: iobj_return TYPE bapiret2_tab .
DATA: wf_ip TYPE rsinfoprov ,
      wf_query TYPE rszcompid ,
      wf_view TYPE rszviewid .

DATA: i_axis_info TYPE  rrws_thx_axis_info ,
      i_cell_data TYPE  rrws_t_cell ,
    i_axis_data TYPE  rrws_thx_axis_data ,
    i_txt_symbols TYPE  rrws_t_text_symbols .

DATA: n_counter(3) TYPE n .
DATA: char_count TYPE i .
DATA: wf_fldnm(40) .

DATA: struct_type TYPE REF TO cl_abap_structdescr,
tab_type TYPE REF TO cl_abap_tabledescr ,
    comp_tab TYPE cl_abap_structdescr=>component_table,
    comp LIKE LINE OF comp_tab,
    dref TYPE REF TO data ,
    dref1 TYPE REF TO data ,
    op_len TYPE i .
DATA: fields TYPE tihttpnvp .
DATA: wa_fields TYPE ihttpnvp ,
      wa_var TYPE w3query .


CLEAR :fields, q_variables ,i_axis_info,i_cell_data,i_axis_data,i_txt_symbols.
REFRESH: fields, q_variables,i_axis_info,i_cell_data,i_axis_data,i_txt_symbols .


CALL METHOD request->get_form_fields
  CHANGING
    fields = fields.
IF NOT fields[] IS INITIAL .
  CLEAR wa_fields .
  LOOP AT fields INTO wa_fields WHERE name CS 'VAR_'.
    CLEAR wa_var .
    MOVE-CORRESPONDING wa_fields TO wa_var .
    TRANSLATE wa_var-name TO UPPER CASE .
    APPEND wa_var TO q_variables .
    CLEAR wa_fields .
  ENDLOOP .

ENDIF .
CLEAR: wf_ip , wf_query , wf_view  .
MOVE: infocube TO wf_ip,
      query TO wf_query,
      view TO wf_view .

IF NOT wf_query IS INITIAL OR NOT wf_view IS INITIAL .
  CLEAR : xml_out , return .
  REFRESH return .

  CALL FUNCTION 'RRW3_GET_QUERY_VIEW_DATA'
    EXPORTING
      i_infoprovider          = wf_ip
      i_query                 = wf_query
      i_view_id               = wf_view
      i_t_parameter           = q_variables
    IMPORTING
      e_axis_info             = i_axis_info
      e_cell_data             = i_cell_data
      e_axis_data             = i_axis_data
      e_txt_symbols           = i_txt_symbols
    EXCEPTIONS
      no_applicable_data      = 1
      invalid_variable_values = 2
      no_authority            = 3
      abort                   = 4
      invalid_input           = 5
      invalid_view            = 6
      OTHERS                  = 7.

  CASE sy-subrc .

    WHEN 0 .
** find no. of key figures
      CLEAR: lcount ,wa_axis , wa_axis_info .
      READ TABLE i_axis_data  INTO wa_axis WITH KEY axis = '000'  .
      IF sy-subrc EQ 0 .
        CLEAR no_of_keyf .
        LOOP AT wa_axis-set INTO wa_set .
          AT NEW tuple_ordinal .

            no_of_keyf = no_of_keyf + 1 .
          ENDAT .
        ENDLOOP .
        CLEAR wa_set .
      ENDIF .

** find number of characteristics
      READ TABLE i_axis_info  INTO wa_axis_info WITH KEY axis = '001'  .
      IF sy-subrc EQ 0 .
        CLEAR no_of_chars .
        DESCRIBE TABLE wa_axis_info-chars LINES no_of_chars .
      ENDIF .

      CLEAR : iobj_detail , iobj_details .
      REFRESH iobj_details .
      CLEAR wa_axis_info .
* get chars. details
      READ TABLE i_axis_info  INTO wa_axis_info WITH KEY axis = '001'  .
      IF sy-subrc EQ 0 .
        CLEAR wa_chars .
        REFRESH tmp_char .

        LOOP AT wa_axis_info-chars INTO wa_chars .
          CLEAR wa_tmp_char .
          MOVE-CORRESPONDING wa_chars TO wa_tmp_char .
          INSERT wa_tmp_char INTO TABLE tmp_char.
          IF NOT wa_chars-attrinm[] IS INITIAL .
            LOOP AT wa_chars-attrinm INTO wa_attrinm .
              CLEAR :wa_tmp_char-chanm , wa_tmp_char-caption .
              MOVE: wa_attrinm-attrinm TO wa_tmp_char-chanm ,
                    wa_attrinm-caption TO wa_tmp_char-caption .
              INSERT wa_tmp_char INTO TABLE tmp_char.
            ENDLOOP .
          ENDIF .
        ENDLOOP .


        LOOP AT tmp_char INTO wa_chars .
          CLEAR off .
          CLEAR :off, moff, mlen .
          FIND '___' IN SECTION OFFSET off OF
                 wa_chars-chanm .
          IF sy-subrc EQ 0 .
            CLEAR : i_iset_iobjnm , e_iobjnm .
            MOVE: wa_chars-chanm TO i_iset_iobjnm .
            CALL FUNCTION 'RSD_IOBJNM_GET_FROM_INFOSET'
              EXPORTING
                i_iset_iobjnm = i_iset_iobjnm
              IMPORTING
                e_iobjnm      = e_iobjnm
              EXCEPTIONS
                name_error    = 1
                no_field      = 2
                OTHERS        = 3.

            CLEAR wa_chars-chanm  .
            MOVE: e_iobjnm TO wa_chars-chanm .

          ELSE.

            FIND '__' IN SECTION OFFSET off OF
                   wa_chars-chanm
                   MATCH OFFSET moff
                   MATCH LENGTH mlen.
            IF sy-subrc EQ 0 .
              off = moff + mlen .
              SHIFT wa_chars-chanm LEFT BY off PLACES .
            ENDIF .
          ENDIF . " two __ or three _
          CLEAR: iobj_return .
          REFRESH : iobj_return .

          CALL FUNCTION 'Z_BAPI_IOBJ_GETDETAIL'
            EXPORTING
              version    = rs_c_objvers-active
              infoobject = wa_chars-chanm
            IMPORTING
              details    = iobj_detail.


          IF  NOT iobj_detail IS INITIAL .
            APPEND iobj_detail TO iobj_details .
            CLEAR iobj_detail .
          ELSE .

            MOVE: wa_chars-chanm TO iobj_detail-infoobject ,
                  wa_chars-caption TO iobj_detail-textlong .

            APPEND iobj_detail TO iobj_details .
            CLEAR iobj_detail .

          ENDIF .
          CLEAR : iobj_detail .
        ENDLOOP .
      ENDIF .

* build field cat. for building the itab
      CLEAR: is_fieldcat, iobj_detail, it_fieldcat .
      REFRESH : it_fieldcat .
      LOOP AT iobj_details INTO iobj_detail .
        is_fieldcat-fieldname = iobj_detail-infoobject .
        IF is_fieldcat-fieldname+0(1) EQ '0' .
          SHIFT is_fieldcat-fieldname LEFT BY 1 PLACES .
        ENDIF .
*        IF iobj_details-datatp = 'CHAR' .
*          is_fieldcat-datatype = iobj_details-datatp.
        is_fieldcat-outputlen = '130' .
*        ELSE .
        is_fieldcat-datatype = 'CHAR' . "iobj_details-datatp.
*          is_fieldcat-outputlen = iobj_details-outputlen .
*        ENDIF .

        is_fieldcat-scrtext_l = iobj_detail-textlong.
        APPEND is_fieldcat TO it_fieldcat.
        CLEAR : is_fieldcat , iobj_detail .
      ENDLOOP .


      CLEAR :n_counter, wa_axis .
      READ TABLE i_axis_data  INTO wa_axis WITH KEY axis = '000'  .
      IF sy-subrc EQ 0 .
        LOOP AT wa_axis-set INTO wa_set .
          AT NEW tuple_ordinal .

            n_counter = n_counter + 1 .

            CONCATENATE 'VALUE' n_counter INTO is_fieldcat-fieldname .
            is_fieldcat-outputlen = '30'.
            is_fieldcat-datatype = 'CHAR'.
          ENDAT .
          CONCATENATE is_fieldcat-scrtext_l wa_set-caption INTO is_fieldcat-scrtext_l SEPARATED BY  ` ` .

*        is_fieldcat-scrtext_l = wa_set-caption.
          AT END OF tuple_ordinal .
            SHIFT is_fieldcat-scrtext_l LEFT DELETING LEADING ' ' .
            APPEND is_fieldcat TO it_fieldcat.
            CLEAR : is_fieldcat .
          ENDAT .

        ENDLOOP .
      ENDIF .

      CLEAR: meta_data, wa_meta_data .
      REFRESH meta_data .
      LOOP AT it_fieldcat INTO is_fieldcat .

        MOVE-CORRESPONDING is_fieldcat TO wa_meta_data .
        APPEND wa_meta_data TO meta_data .
        CLEAR: wa_meta_data, is_fieldcat .
      ENDLOOP .

* create itab
      SORT it_fieldcat BY fieldname.
      DELETE ADJACENT DUPLICATES FROM it_fieldcat COMPARING fieldname .
      CLEAR: comp , comp_tab ,is_fieldcat .
      REFRESH comp_tab .

      LOOP AT it_fieldcat INTO is_fieldcat .
        CLEAR op_len .
        op_len = is_fieldcat-outputlen .
        comp-name = is_fieldcat-fieldname.
        comp-type = cl_abap_elemdescr=>get_c( op_len ).
        APPEND comp TO comp_tab.
        CLEAR : is_fieldcat , comp .
      ENDLOOP .

      CLEAR struct_type .

      CALL METHOD cl_abap_structdescr=>create
        EXPORTING
          p_components = comp_tab
          p_strict     = cl_abap_structdescr=>false
        RECEIVING
          p_result     = struct_type.

      CLEAR tab_type .
      CALL METHOD cl_abap_tabledescr=>create
        EXPORTING
          p_line_type  = struct_type
          p_table_kind = cl_abap_tabledescr=>tablekind_std
        RECEIVING
          p_result     = tab_type.

      CREATE DATA dref1 TYPE HANDLE tab_type.

      ASSIGN dref1->* TO <ltable>.

      CREATE DATA dref TYPE HANDLE struct_type.

      ASSIGN dref->* TO <l_line>.

      CLEAR :wa_axis , char_count , lcount, xcount.
      REFRESH tmp_set .
      LOOP AT i_axis_data INTO wa_axis WHERE axis = '001' .
        LOOP AT wa_axis-set INTO wa_set .
          CLEAR wa_tmp_set .
          MOVE-CORRESPONDING wa_set TO wa_tmp_set .
          INSERT wa_tmp_set INTO TABLE tmp_set.
          IF NOT wa_set-attributes[] IS INITIAL .
            LOOP AT wa_set-attributes INTO wa_dattrinm .
              CLEAR: wa_tmp_set-chanm , wa_tmp_set-chavl , wa_tmp_set-chavl_ext , wa_tmp_set-caption .
              MOVE: wa_dattrinm-attrinm TO wa_tmp_set-chanm ,
                    wa_dattrinm-attrivl TO wa_tmp_set-chavl ,
                    wa_dattrinm-attrivl TO wa_tmp_set-chavl_ext ,
                    wa_dattrinm-caption TO wa_tmp_set-caption .

              INSERT wa_tmp_set INTO TABLE tmp_set.
            ENDLOOP .
          ENDIF .
        ENDLOOP .
      ENDLOOP .

      LOOP AT tmp_set INTO wa_set .
        AT NEW tuple_ordinal .
          IF lcount GT 0 .
            lcount = lcount - 1 .
          ENDIF .
          CLEAR <l_line> .
        ENDAT .
        CLEAR off .

        CLEAR :off, moff, mlen .
        FIND '___' IN SECTION OFFSET off OF
               wa_set-chanm .
        IF sy-subrc EQ 0 .
          CLEAR : i_iset_iobjnm , e_iobjnm .
          MOVE: wa_set-chanm TO i_iset_iobjnm .
          CALL FUNCTION 'RSD_IOBJNM_GET_FROM_INFOSET'
            EXPORTING
              i_iset_iobjnm = i_iset_iobjnm
            IMPORTING
              e_iobjnm      = e_iobjnm
            EXCEPTIONS
              name_error    = 1
              no_field      = 2
              OTHERS        = 3.

          CLEAR wa_set-chanm  .
          MOVE: e_iobjnm TO wa_set-chanm .
        ELSE.

          FIND '__' IN SECTION OFFSET off OF
                 wa_set-chanm
                 MATCH OFFSET moff
                 MATCH LENGTH mlen.
          IF sy-subrc EQ 0 .
            off = moff + mlen .
            SHIFT wa_set-chanm LEFT BY off PLACES .
          ENDIF .
        ENDIF . " check three _ or two _

        IF wa_set-chanm+0(1) EQ '0' .
          SHIFT wa_set-chanm LEFT BY 1 PLACES .
        ENDIF .
        ASSIGN COMPONENT wa_set-chanm OF STRUCTURE <l_line> TO <l_field>.
        IF wa_set-chavl = '#' .
*            <l_field> =  wa_set-chavl_ext .
        ELSE .
          CONCATENATE wa_set-chavl_ext wa_set-caption INTO <l_field> SEPARATED BY ' ' .
        ENDIF .

        AT END OF tuple_ordinal .
          CLEAR: xcount , char_count , n_counter .

          lcount = lcount + 1 .

          LOOP AT i_cell_data INTO wa_cell FROM lcount .

            n_counter = n_counter + 1 .
            IF n_counter GT no_of_keyf .
              EXIT .
            ENDIF .

            CONCATENATE 'VALUE' n_counter INTO wf_fldnm .
            ASSIGN COMPONENT wf_fldnm OF STRUCTURE <l_line> TO <l_field>.

            <l_field> = wa_cell-value .


          ENDLOOP .

          lcount = lcount + no_of_keyf .
          INSERT <l_line> INTO TABLE <ltable>.

        ENDAT .


      ENDLOOP .
      CLEAR :xml_out .

      CALL TRANSFORMATION (`ID`)
            SOURCE meta   = meta_data[]
                   output = <ltable>[]
            RESULT XML xml_out.
      IF xml_out IS INITIAL .
        IF NOT return[] IS INITIAL .
          CALL TRANSFORMATION (`ID`)
                    SOURCE return = return[]
                    RESULT XML xml_out.

        ELSE .
          MOVE: `Unknown Error` TO error_message .
          CALL TRANSFORMATION (`ID`)
               SOURCE errormessage = error_message
               RESULT XML xml_out.
        ENDIF .
      ENDIF .
    WHEN 1 .
      MOVE: 'no_applicable_data' TO error_message .
      CALL TRANSFORMATION (`ID`)
                        SOURCE errormessage = error_message
                        RESULT XML xml_out.
    WHEN 2 .
      MOVE: 'invalid_variable_values' TO error_message .
      CALL TRANSFORMATION (`ID`)
                        SOURCE errormessage = error_message
                        RESULT XML xml_out.
    WHEN 3 .
      MOVE: 'no_authority' TO  error_message .
      CALL TRANSFORMATION (`ID`)
                        SOURCE errormessage = error_message
                        RESULT XML xml_out.
    WHEN 4 .
      MOVE: 'abort' TO   error_message .
      CALL TRANSFORMATION (`ID`)
                        SOURCE errormessage = error_message
                        RESULT XML xml_out.
    WHEN 5 .
      MOVE: 'invalid_input' TO  error_message .
      CALL TRANSFORMATION (`ID`)
                        SOURCE errormessage = error_message
                        RESULT XML xml_out.
    WHEN 6 .
      MOVE: 'invalid_view'  TO error_message .
      CALL TRANSFORMATION (`ID`)
                        SOURCE errormessage = error_message
                        RESULT XML xml_out.
    WHEN OTHERS .
      MOVE: 'unknown_error'   TO error_message .
      CALL TRANSFORMATION (`ID`)
                        SOURCE errormessage = error_message
                        RESULT XML xml_out.
  ENDCASE .
ELSE .
  MOVE: `Enter Query/view Name` TO error_message .
  CALL TRANSFORMATION (`ID`)
                     SOURCE errormessage = error_message
                     RESULT XML xml_out.

ENDIF .
CALL METHOD response->if_http_entity~set_cdata
  EXPORTING
    data = xml_out.

5. Just save the page now (do not activate).

6. If you see the code above i have used a Z Fm called 'Z_BAPI_IOBJ_GETDETAIL'. This is basically copy of BAPI_IOBJ_GETDETAIL with just the following code removed to override the authority check

call method cl_rsd_iobj=>authority_check
    exporting
      i_iobjnm            = infoobject
      i_activity          = rssb_c_auth_actvt-display
    exceptions
      user_not_authorized = 1.
  if sy-subrc <> 0.
    bapi_syserror.
    exit.
  endif.

So go ahead and create the'Z_BAPI_IOBJ_GETDETAIL' and then activate your BSP.
7. Now you are ready to use this service to expose your BI query as a RESTful service.

20 Comments

  1. Unknown User (99pzdaj1)

    Hi Raja,

     I have a BI 7.0 system here and also installed XCelsius v5.0. The creation of the BSP service and XML page is clear, but I was wondering if you new how then to integrate this into XCelsius.

     In the "Data Manager", you can choose connection type "Web Service Connection". There are three input options:

     WSDL URL, Method, and Web Service URL.

     Am I to use the Web Service URL, and point it to the appserver with the xml page and variables on the end of it (As per your example URL)? Can I then use the Input Values and Output Values boxes?

    I'm really just trying to get a BW query into XCelsius. I hope in the future, it will be less complex.

    Many Thanks for the wiki.

     Cheers

    rob

  2. Unknown User (1055yw6uj)

    Rob,

          did you solve your problem?  Can you use the link from BSP in the XCelsius?  We are trying to do the same thing...

    Thanks.

  3. Unknown User (uj1xe4t)

    How can this service be consumed in Excelsius?  can you please provide some insight into this....

  4. Unknown User (a7ts7u0)

    Hello guys! The BSP page construction is very clear at all, but I have the same problem on configuring the datamanager in Xcelsius to consume the data from this BSP page.

     Any help will be very helpful.

     Thanxs. Sergio.

  5. Former Member

    Hi all,

    I tried to use it with Xcelsius 2008. But I had no chance to consume the WebService. Xcelsius gives an error message about a memory read method.

     If you have some news, please let me know.

    Kindly,

    Sebastian

  6. Unknown User (elvv5ny)

    Hi,

    I tried this out because I'm trying to feed a query results into YUI.

    I have 2 questions.

    #1:  When I tried to activate the Z_BAPI_IOBJ_GETDETAIL, I get this compile error message:

    Field "RS_C_OBJVERS-ACTIVE" is unknown. It is neither in one of the specified tables nor defined by a "DATA" statement.

     #2: How do I figure out what the front part of the URL is?   http://abaphost.domain.com:1080/sap/bc/bsp/sap/ybwqs/

    Where do I find out what our abaphost domain is and our port number?

    What is ybwqs?

     Thanks!

  7. Unknown User (iuigq5t)

    hi ,

    i guess xcelsius expects a specific xml format which looks like this:

    - <data>
    - <variable name="Bereich_0">
    - <row>
      <column />
      <column />
      </row>
    - <row>
      <column />
      <column />
      </row>
      </variable>
      </data>

    THe provided code i to complex for this format. So i've reworked an example xml, deleted all meta data and renamed <item> tags into <row> tags & infoobject/value tags into <column> tags. i've generated a new bsp using this fixed xml file without coding and i could import it into xcelsius without problems. however i'm not able to rework the code to the expected format. Maybe someone of you has the respective capabilities!?

    Best

    Stefan

  8. Former Member

    Hi Raja,

     Thanks for this very valuable Blog for the SAP community.

     I just wanted some help from you in using the BSP Application you described that can be used in Xcelsius. I followed your steps as described to define my BWP and the Page ( nothing on the layout tab ).

     But when I go to test the BSP service from SICF it is not able to launch the page and gives the error in german which basically says "BSP page is not a valid Object".

     My goal here is to try and use this BSP in Xcelsius to build dashboards directly off BEx queries without having to go through BO's Universe / QAAS layers. I tried using the URL in Xcelsius and it is not able to load the URL even there.

     Can you please advice if I am missing any steps such as - configuring the BSP service OR missing content on the layout tab for the page ?

    Thanks

     Shailendra

  9. Former Member

    In an effort to help Shailendra with her issues. I would make sure you can run the copied function module in SE37 before testing the service. I had issues with some objects not being activated even though the FM showed up in SE37. Be sure to do a test execution. Also, I wasnt able to get this working until I set the Page Attributes to Auto. That is a tickbox on the screen. After that, the service was working properly.

     -John

  10. Unknown User (hom2doy)

    When testing this via internet explorere i always get the error:

    Invalid at the top level of the document. Error processing resource 'http://sapt21p.poing.de.oce.net:8021/sap/bc/bsp/sap/...

    * event handler for data retrieval

    Any idea what is going wrong?

    thanks

    Tom

  11. The RESTFul service can be included into an Excel sheet using XML Maps and then the Xcelsius dashboard can be built on top of this

  12. Former Member

    The only idea I would like to add onto this already well thoughout example/model is a caching mechanism.

    The one value the LiveOffice connection via the BOE gives you is a cached data set(i.e. latest instance of data), so there is no server roundtrip to BI.  Actually your BI system would be down and the Xcelsius dashboard would still load, how cool is that.

     I would recommend that afer running the query_view_data function module you could dynamically populate an already created shared memory area in ABAP(SHMM Tcode).  Then if 10 different people load your dashboard, in the beginning of your RESTFUL service you could simply read from ABAP Shared memory if the variables passed were identical.  This would prevent you from running the query again in BI.

    This is really powerful if you are only loading data once a day and therefore most users would hit ABAP shared memory instead of the OLAP processor.

    -Alex 

  13. Unknown User (alo4oiq)

    Hi Raja,

    I have tried to implement a RESTful web service as per your instructions but receive the following error when attempting to test it with Internet Explorer:


    Switch from current encoding to specified encoding not supported.

    <?xml version="1.0" encoding="utf-16"?>

    Any suggestions about rectifying this error would be much appreciated.  We are running Netweaver 7.01 SP6.

    Thanks,

    Mustafa.

  14. Unknown User (102gc1ij5)

    Hi Mustafa Bensam,

    Did you solve your problem with the XML unicode? Currently i've the same problem. Could you please post your solution in this forum?

    Regards,

    Pieter

  15. Unknown User (alo4oiq)

    Hi Pieter,

    Raja (the original author) provided the following code revision to resolve the XML unicode problem:

    Replace code

    
    CALL TRANSFORMATION (`ID`)
                SOURCE meta   = meta_data[]
                       output = <ltable>[]
                RESULT XML xml_out.
    
    

    with code

    
    CALL TRANSFORMATION (`ID`)            
                options            
                xml_header    = no
                SOURCE meta   = meta_data[]
                       output = <ltable>[]
                RESULT XML xml_out.
    
    

    Regards,

    Mustafa.

  16. Unknown User (102gc1ij5)

    Mustafa,

    Thanks for your reply. Sorry for my delayed answer. When I replaced your code I get an error --> Field NO is unknown. I created the following code:

    CALL TRANSFORMATION (`ID`)
    	OPTIONS
    	xml_header = 'no'
    	SOURCE meta = meta_data[]
    	       output = []
    	RESULT XML xml_out.
    

     But when I excecuted the BSP application, the same error (XML unicode) occurred.

     System specifications are: BI 7.01 level 0007.

  17. Unknown User (alo4oiq)

    Hi Pieter,

    The only difference I notice in your code is that the reference to '<ltable>' is missing in the 'output' parameter.  Beyond that, I would suggest contacting the original author of this article directly by email.  His contact details are on his business card:  Durairaj Athavan Raja 

    Good luck,

    Mustafa.

  18. Unknown User (wxxfwub)

    Hi Alexander,

    I found the idea quite interesting from a performance point of view. Could you elaborate your shared memory idea with some example code?

    Thanks

    Aditya

  19. Former Member

    Hi,

    I was facing an authorization issue with this BAPI and found your post.

    Is Z_BAPI_IOBJ_GETDETAIL a good solution ?

    Why not to grant S_RS_IOMAD  ?

    Regards,

    Laurent

  20. Has anyone tried to consume this using jquery ajax?  Every time I run it I come up with a error.