Skip to Content

Introduction

A few weeks back there was a discussion on one of the Forums about the Java WebService Navigator application that is present in Netweaver 04.  This application shows a tree of all the local Java released webservices.  The questions was if there was a way to show the ABAP released WebServices here as well (presently they can be seen in the SAPGui transaction WSADMIN). After some research it appears that this application provided by SAP only displays local Java WebServices. However research on the subject lead me to find out that there is a standard similar to WSDL called WSIL (Web Service Inspection Language) for exposing a directory of WebServices. A nice article on WSIL and the differences between WSIL and UDDI can be found here .  True to SAP’s approach to support open standards, both the ABAP and J2EE personalities expose their WebServices Directories in the WSIL format (Not to be overlooked, Publishing ABAP WebServices to an External UDDI Server).

Screen Shot of the Java WebService Navigator

!https://weblogs.sdn.sap.com/weblogs/images/1918/J2EE_WSNav.jpg|height=390|alt=image|width=385|src=https://weblogs.sdn.sap.com/weblogs/images/1918/J2EE_WSNav.jpg|border=0!

Screen Shot of the ABAP WSADMIN

!https://weblogs.sdn.sap.com/weblogs/images/1918/WSADMIN_Example.jpg|height=345|alt=image|width=567|src=https://weblogs.sdn.sap.com/weblogs/images/1918/WSADMIN_Example.jpg|border=0!

Now armed with the knowledge, I set out to create an application that combined the functionality of both the Java WebService Navigator and the ABAP transaction WSADMIN. I decided to build it upon the Open WSIL standard so theoretically it could support a WebService Directory from a Non-SAP system as well (The WSIL definition was co-authored by Microsoft and IBM so I would assume there is built in support in their tools as well). But I also decided to build this application as a BSP, Stateless Model View Controller Program.  This approach is built upon the BSP: Stateless Modelbinding – Proof Of Concept put forth by Thomas Ritter a few weeks back.  So I will be serializing my Model Class and storing it in Server Cookie to avoid excessive calls to the remote systems to re-gather the WSIL definitions.  This example application is also closely tied to the Java WebService Navigator application.  Although the display of the WebServices is done in BSP and the WSIL Parsing is done in ABAP, I still launch the Java WebService Test tool for detailed interaction with the WebServices themselves.

Hopefully I have included a enough screen shots and complete code samples so that is application can easily be recreated in anyone’s 640 WebAS system (as well as serving as a tutorial for the concepts discussed).

Screen Shot of the Finished Product

!https://weblogs.sdn.sap.com/weblogs/images/1918/BSP_WSNav.jpg|height=323|alt=image|width=515|src=https://weblogs.sdn.sap.com/weblogs/images/1918/BSP_WSNav.jpg|border=0!

Getting the WSIL

The first part to tackle will be about what the WSIL format is and how to get it. Like I said before both the Java and ABAP sides have web endpoints that will deliver a WSIL file. The endpoint for ABAP is /sap/bc/srt/wsil. The endpoint for JAVA is /inspection.wsil. So I started off by just opening my browser to these locations and downloading the WSIL samples for both personalities.

Screen Shot of the ABAP WSIL

!https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_wsil.jpg|height=332|alt=image|width=596|src=https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_wsil.jpg|border=0!

Screen Shot of the JAVA WSIL

!https://weblogs.sdn.sap.com/weblogs/images/1918/Java_wsil.jpg|height=390|alt=image|width=581|src=https://weblogs.sdn.sap.com/weblogs/images/1918/Java_wsil.jpg|border=0!

Now I know that I can use the HTTP Client Functionality in ABAP to make the same call that my browser just made and retrieve the XML file with the WSIL information. However I want maximum flexibility for maintaining the systems that I will get this information from. Being an old school ABAPer, I naturally turn to my old friend – the configuration table. I setup a customizing table and generated table maintenance for it. This table will hold my destinations and their descriptions. I also decided not to store my connection information in this table. Instead for greater flexibility I will store this information in an RFC Destination (either type G – External HTTP or type H – HTTP Connection to R/3 system) in SM59.

Screen Shot of the Customizing Table

!https://weblogs.sdn.sap.com/weblogs/images/1918/config_table.jpg|height=247|alt=image|width=530|src=https://weblogs.sdn.sap.com/weblogs/images/1918/config_table.jpg|border=0!

Screen Shot of the Customizing Table Sample Data

!https://weblogs.sdn.sap.com/weblogs/images/1918/Config_table_contents.jpg|height=80|alt=image|width=478|src=https://weblogs.sdn.sap.com/weblogs/images/1918/Config_table_contents.jpg|border=0!

Setting Up the RFC Destinations

Now we come to the point where we must setup the RFC destinations. For both the Java and ABAP connections, I decided to use Type H RFC destinations (HTTP with special features for SAP products). By using type H instead of type G, I am able to set this up as a trusted connection. Therefore the user credentials of the person logged into my BSP application will pass through the HTTP Client call to the destination. Keep inmind that the setup of the RFC (especially the service number) could vary from installation to installation. The service number is effected by the setup of the ICM and the type of system (ABAP+J2EE vs. Standalone J2EE). I have my ABAP personality running on port 80 and the J2EE add-in running on Port 52000 (5XX000 where XX is your system number). However ICM is setup for Java to be the default root handler so I don’t need to specify the port number in the RFC connection.

ABAP RFC – Technical Settings

!https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Tech.jpg|height=281|alt=image|width=533|src=https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Tech.jpg|border=0!

ABAP RFC – Logon/Security

!https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Logon.jpg|height=397|alt=image|width=533|src=https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Logon.jpg|border=0!

ABAP RFC – Special Options

!https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Special.jpg|height=390|alt=image|width=465|src=https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Special.jpg|border=0!

JAVA RFC – Technical Settings

!https://weblogs.sdn.sap.com/weblogs/images/1918/Java_RFC_Tech.jpg|height=298|alt=image|width=536|src=https://weblogs.sdn.sap.com/weblogs/images/1918/Java_RFC_Tech.jpg|border=0!

JAVA RFC – Logon/Security

!https://weblogs.sdn.sap.com/weblogs/images/1918/Java_RFC_Logon.jpg|height=393|alt=image|width=429|src=https://weblogs.sdn.sap.com/weblogs/images/1918/Java_RFC_Logon.jpg|border=0!

JAVA RFC – Special Options

!https://weblogs.sdn.sap.com/weblogs/images/1918/Java_RFC_Special.jpg|height=394|alt=image|width=473|src=https://weblogs.sdn.sap.com/weblogs/images/1918/Java_RFC_Special.jpg|border=0!

Now that we have the RFCs setup, we can use the RFC test connection to make sure they are working fine. You should see a response somewhat like the following:

!https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Test.jpg|height=326|alt=image|width=516|src=https://weblogs.sdn.sap.com/weblogs/images/1918/ABAP_RFC_Test.jpg|border=0!

The Model Class

This is just personal preference, but I usually start my application by building my model class. I try to finish the model class and test it using the workbench test tool (or a custom test ABAP program) before I even create my BSP application. Therefore that is where I am going to start in this tutorial. We will start by creating a class that inherits from the CL_BSP_MODEL class.

Model Class Properties

image

.

      CLEAR link.

  • escape ‘&’ to distinguish between WSDL address

  • and URL of the test page

      REPLACE ALL OCCURRENCES OF ‘&’ IN -name.

      l_descrp = ‘description’.

  • build url of the testpage

      CONCATENATE j2ee_server co_url_wsnavigator ‘?’

                  co_param_wsdl ‘=’ receive

    exceptions

      http_communication_failure = 1

      http_invalid_state         = 2

      http_processing_failed     = 3

      others                     = 4.

****Get the response content in Binary format

  • c_content = client->response->get_cdata( ).

  r_content = client->response->get_data( ).

ENDMETHOD.

image

BSP Controller Methods – do_request

For the most part this is fairly normal high level controller do_request method. The only difference here is the coding for the serialization/deserialization of the model class. Now I took a little different approach than Thomas Ritter had done in his example. I attempt to deserialize my model before I call dispatch input. Therefore my model class is restored before the input binding and event handling. This allows for the integration of the stateless model without further modifications to the normal controller programming. You can also notice that I store away the model class right before calling to my view.

initialize_data( ).

    endif.

  endif.

****Get a pointer to the Model Object.

  model2 ?= get_model( ‘MN’ ).

  • if input is available, dispatch this input to subcomponent.

  • this call is only necessary for toplevel controllers.

  • ( if this is not a toplevel controller or no input is present,

  •   this call returns without any action)

  dispatch_input( ).

  • if any of the controllers has requested a navigation,

  • do not try to display, but leave current processing

  if is_navigation_requested( ) is not initial.

    return.

  endif.

****Serialize the Model

  me->save_model(  model2 ).

****Call our View

  view = create_view( view_name = ‘default.bsp’ ).

  view->set_attribute( name = ‘model’      value = model2 ).

  call_view( view ).

endmethod.

BSP Controller Methods – save_mode

This method has our logic to serialize our Model class and write it to a server cookie.

METHOD save_model.

*@78QImporting@     I_MODEL     TYPE REF TO CL_BSP_MODEL     BSP: Model Basis Class

  DATA: ostream TYPE string,

         xslt_err TYPE REF TO cx_xslt_exception.

          • serialize model class

  TRY.

      CALL TRANSFORMATION id

      SOURCE model = i_model

      RESULT XML ostream.

****Write cookie it into the Server Cookie

      cl_bsp_server_side_cookie=>set_server_cookie( name = ‘model’

        application_name = runtime->application_name

        application_namespace = runtime->application_namespace

        username = sy-uname

        session_id = runtime->session_id

        data_name = ‘model’

        data_value = ostream

        expiry_time_rel = ‘1200’ ).

    CATCH cx_xslt_exception INTO xslt_err.

  ENDTRY.

ENDMETHOD.

BSP Controller Methods – read_mode

Now for just the opposite: we have our method to read our Model from the Server Cookie and deserialize it.

method READ_MODEL.

*@7BQReturning@     VALUE( R_MODEL )     TYPE REF TO CL_BSP_MODEL     BSP: Model Basis Class

data: iStream type string,

        xslt_err type ref to cx_xslt_exception.

        • Read Server cookie

  call method cl_bsp_server_side_cookie=>get_server_cookie

    EXPORTING

      name                  = ‘model’

      application_name      = runtime->application_name

      application_namespace = runtime->application_namespace

      username              = sy-uname

      session_id            = runtime->session_id

      data_name             = ‘model’

    CHANGING

      data_value            = iStream.

        • deserialize the Class

  if iStream is not initial.

    try.

        call transformation id

        source xml iStream

        result model = r_model.

      catch cx_xslt_exception into xslt_err.

    endtry.

  endif.

endmethod.

On 4/27/2005 I created a WebService Navigator Page for ABAP and Java: Part 2 – ABAP Unit that enhances the objects built here by including an ABAP Unit class.

Closing

It almost feels like I set out to see how many different technologies I could combine together into one solution.  But that wasn’t the intention at all.  I really just wanted to create simple tool for displaying webservices from multiple sources.  It is just nice to see how all the different technologies that we have at our disposal today can come together to make such a thing possible. 

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Craig Cmehil
    Here I am waiting for the upgrade of our 620 to 640 and now I have what looks to be an excellent test for all the new goodies packed away in 640.

    Thanks Thomas!!!!

    (0) 
  2. Community User
    Hi Thomas,

    I think you showed us how every BSP application should be built (Build modelclass -> test it -> build UI -> test it -> done). I would call it a “best practise” application 😉
    Some thoughts:
    -Jep, restoring the model before invoking the dispatch_input() method is the way to go. Didn’t think about that.
    -Why do you test your modelclass with the workbench tool? Build some unit tests instead which can repeat everytime you want =)
    -How do you clean up the old cookies?
    -I would place the read and save model methods into a untility class. I am pretty sure you will need this code again.
    -Thanks for the xml parser code. I thought about how parsing can be done with ABAP at sdn meets labs (I normally use java for this kind of stuff) because Craig told me some nice ideas for building rss feeds.

    regards

    Thomas

    (0) 
    1. Brian McKellar
      We have had a number of big scale projects using this (unofficial:) stateless MVC approach with one controller and many views very successfully. Once one becomes skilled in the art, creative solutions are just a step away. This is definitely an ellegant bit of code with a nice photobook to backup the weblog. Enjoyed it!
      –brian
      (0) 
    2. Thomas Jung
      Very good questions.

      Q. Why do you test your model class with the workbench tool? Build some unit tests instead which can repeat everytime you want

      A. Old habits die hard.  Now that I am on 640 I need to spend sometime and explore ABAP Unit.  Actually for some more complex model classes I have in the past built reusable custom ABAP programs for testing.  I can then repeat the tests.  However this was a relativly simple class so I just tested using the workbench tool. 

      Q. How do you clean up the old cookies?

      A. If you are going to work with Server Cookies in BSP, there are two very important programs you should know about.  The first is BSP_SHOW_SERVER_COOKIES.  This is nice report on all Server Cookies.  The other program is BSP_CLEAN_UP_SERVER_COOKIES.  This will delete up all your expired Server Cookies.  I have this scheduled to run once a day (since it only works off the expire date and doesn’t take time into account).  This is sort of a lazy way out.  If I had thousands of simultanous users, I would probably want to come up with a better routine.  But right now, my cookie table just doesn’t get big enough to justify the effort.

      Q. I would place the read and save model methods into a untility class. I am pretty sure you will need this code again.

      A.  Actually I have that. I have a little controller class framework of my own that inherits from CL_BSP_CONTROLLER2.  My actual controllers usually inherit from these classes instead of the SAP ones.  I have several reusable methods built into my classes.  I recently added the model read and save to this framework.  However this weblog was already getting fairly complicated and I didn’t want to throw in two many more elements that had to be created from my system.  That is why you rarely see my controller classes (and I actually have the same for application classes and models) mentioned in my weblogs.  I try to avoid too much “bagage” so that people can hopefully recreate the examples in their systems.

      (0) 

Leave a Reply