Quantcast
Channel: ABAP Connectivity
Viewing all articles
Browse latest Browse all 73

Wave Islands in Webdynpro ABAP

$
0
0

We are one step closer to our goal: the seamless integration of Google Wave into SAP Applications

Short Timeline

  1. Display a wave in portal or WDA Application: Dagfinn Parnas Blog SAP and Google Wave - Embedding waves in SAP NetWeaver Portal
  2. Set/Get Data from SAP ERP using wave robot: my Blog VCD #16 - The REST Bot: Behind the scenes
  3. Active creation and manipulation of an embedded wave: available since Active Robot API V2 -> this Blog
  4. Inform the WDA Application about wave changes: coming soon -> Push-(Notification-) Services announced for NW 7.02 (7.03?)

 

What is the difference between a robot and an "active robot"?

A robot is an automated participant on a wave. A robot can read the contents of a wave in which it participates, modify the wave's contents, add or remove participants, and create new blips and new waves. In short, a robot can perform many of the actions that any other participant can perform

More Infos Google Wave Robots API

But what is now an "active robot"? Until last week it was not possible to manipulate or create waves from outside Google Wave. This has changed with the new Robot API v2:

Robots may not only act as passive entities, responding to events as they occur, but may initiate their own operations as well. The Active Robot API allows robots to send operations to Wave outside of the event-driven model. In particular, this API allows for the following:

  1. Performing scheduled tasks (e.g. cron jobs) at specified intervals
  2. Creating new waves within Google Wave in response to actions within Google Wave itself
  3. (Most importantly) Responding to outside events or services by updating waves or creating new ones

 

More Infos The Active Robot API

Demo

 

 

How it works

First we have to create a regular robot that does ... exactly nothing. We don't want to react on wave changes in this demo. Possible but not necessary.

The robot just creates an instance of itself:

from waveapi import robotfrom waveapi import appengine_robot_runnerif __name__ == '__main__':              bot = robot.Robot('se38xxx', image_url='http://se38xxx.appspot.com/assets/service.png', profile_url='http://se38xxx.appspot.com/')              appengine_robot_runner.run(bot)

The more interesting part is the Post-Handler-Class, where we implement the whole logic:

import cgiimport loggingfrom waveapi 
import robotfrom google.appengine.ext 
import webappfrom google.appengine.ext.webapp.util 
import run_wsgi_appclass 


MainPage(webapp.RequestHandler):
          __bot = None                  def __create_robot(self):                            self.__bot = robot.Robot('se38xxx', image_url='http://se38xxx.appspot.com/assets/service.png', profile_url='http://se38xxx.appspot.com/')                            CONSUMER_KEY = '493DEMO8625'                            CONSUMER_SECRET = 'xmW/6cHk6DEMOwIu1M0poUVd'                            self.__bot.setup_oauth(CONSUMER_KEY,                                                                           CONSUMER_SECRET,                                s                                                                         erver_rpc_base='http://gmodules.com/api/rpc')              def __add_blip(self):                            logging.debug("Add Blip")                            waveId = cgi.escape(self.request.get('waveid',                                                                                      default_value=''))                                    if waveId == '':                                          return                                    waveId = 'googlewave.com!w+' + waveId                            waveletId = 'googlewave.com!conv+root'                                    logging.debug("Fetching wavelet: " + waveId+", " + waveletId)                                    wavelet = self.__bot.fetch_wavelet(waveId, waveletId)                            text = cgi.escape(self.request.get('text',                                                                                  default_value='No text given'))                                              wavelet.reply(text)                            self.__bot.submit(wavelet)                            self.response.out.write('OK Blip created')                      def __create_wave(self):                                    wave_user = cgi.escape(self.request.get('wave_user', default_value='xxx@googlewave.com'))                                            wavelet = self.__bot.new_wave(domain='googlewave.com',                                                                                         participants=[wave_user],                                                                                                                                  message='New message',                                                                                                                                  submit=True)                            title = cgi.escape(self.request.get('title', default_value='No title given'))                                    wavelet.title = title                            wavelet.root_blip.append('This is an Integration Test')                            wavelet.root_blip.append_markup('between SAP WDA and Google Wave')                    wavelet.reply('And another Blip in Wave ' + wavelet.wave_id)                             self.__bot.submit(wavelet)                                             self.response.out.write('OK ' + wavelet.wave_id)                   def post(self):        action = cgi.escape(self.request.get('action', default_value=''))                                     if action == '':                                           return               self.__create_robot()        if action == 'new_wave':                                           self.__create_wave()                                         if action == 'add_blip':                                           self.__add_blip()          def main():                         application = webapp.WSGIApplication(http://scn.sap.com/people/uwe.fetzer/blog/2010/03/11/wave-islands-in-webdynpro-abap/('/app.*', MainPage), debug=True)                         run_wsgi_app(application)



if __name__ == "__main__":               main()       

 

Short explanation

application = webapp.WSGIApplication(http://scn.sap.com/people/uwe.fetzer/blog/2010/03/11/wave-islands-in-webdynpro-abap/('/app.*', MainPage), debug=True)

-> we react on all requests on the path "/app"

CONSUMER_KEY = '493DEMO8625'
CONSUMER_SECRET = 'xmW/6cHk6DEMOwIu1M0poUVd'

-> the OAuth keys we received from the registration of our robot

action = cgi.escape(self.request.get('action', default_value=''))

-> depending on the "action" parameter, we can process "new_wave" or "add_blip" steps. Not an REST interface yet, I know, please no comments on that

Now we can call the Post-Handler from within the WDA application:

METHOD create_wave .            DATA: lr_client  TYPE REF TO if_http_client                    , lv_content TYPE string                          , lo_nd_main TYPE REF TO if_wd_context_node                          , lo_el_main TYPE REF TO if_wd_context_element                          , ls_main TYPE wd_this->element_main                          , lv_title TYPE wd_this->element_main-title                          , lv_own_user TYPE wd_this->element_main-own_user                           .          "*--- prepare message ---*             cl_http_client=>create(                         EXPORTING                                     host = 'se38xxx.appspot.com'                         IMPORTING                                     client = lr_client                                     ).          lr_client->request->set_header_field(                         name = '~request_uri'                         value = '/app/'                         ).          "navigate from <CONTEXT> to <MAIN> via lead selection    lo_nd_main = wd_context->get_child_node( name = wd_this->wdctx_main ).          "get element via lead selection    lo_el_main = lo_nd_main->get_element( ).          "get single attribute    lo_el_main->get_attribute(                           EXPORTING                                       name =  `TITLE`                           IMPORTING                                       value = lv_title ).          "get single attribute    lo_el_main->get_attribute(                           EXPORTING                                       name =  `OWN_USER`                           IMPORTING                                       value = lv_own_user ).          lr_client->request->set_form_field(                         name  = 'title'                         value = lv_title                         ).          lr_client->request->set_form_field(                         name  = 'wave_user'                         value = lv_own_user                         ).          lr_client->request->set_form_field(                         name  = 'action'                         value = 'new_wave'                         ).          lr_client->request->set_header_field(                         name  = '~request_method'                         value = 'POST'                         ).          "*--- send ---*          lr_client->send( ).             lr_client->receive( ).             lv_content = lr_client->response->get_cdata( ).             lr_client->close( ).          "*--- store created wave id ---*          DATA: lv_waveid TYPE wd_this->element_main-waveid                     , lv_dummy TYPE string                           .          "@TODO fill attribute          IF lv_content(2) = 'OK'.                         SPLIT lv_content AT '+' INTO lv_dummy lv_waveid.             ENDIF.          "set single attribute          lo_el_main->set_attribute(                         name =  `WAVEID`                         value = lv_waveid ).


ENDMETHOD.

 

To embedd the wave I have an Iframe on the page which call an BSP (with the received WaveID as parameter):

<%@page language="abap"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">  <head>    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>    <title>Google Wave Embed API Example: Simple Wave</title>    <script src="http://wave-api.appspot.com/public/embed.js" type="text/javascript"></script>    <script type="text/javascript">    function initialize() {    var wavePanel = new WavePanel('https://wave.google.com/wave/');    var uiConfig = new WavePanel.UIConfig();    uiConfig.setFooterEnabled(true);    uiConfig.setHeaderEnabled(true);    uiConfig.setToolbarEnabled(true);    uiConfig.setBgcolor('#FFF');    uiConfig.setColor('#000');    uiConfig.setFont('verdana');    uiConfig.setFontSize('12px');    wavePanel.setUIConfigObject(uiConfig);    wavePanel.loadWave('googlewave.com!w+<%= waveid %>');    wavePanel.init(document.getElementById('waveframe'));    }    </script>  </head>  <body onload="initialize()">    <div id="waveframe" style="width: 100%; height: 400px"></div>  </body></html>

 

Outlook

As I have described in the timline, the only missing part is the hook back from wave to the WDA application. But Thomas J. promissed it will be part of NW 7.02 (or 7.03?)

Now it's your turn. What can we do with this solution?

 

G+


Viewing all articles
Browse latest Browse all 73

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>