Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
ted_ueda
Employee
Employee

Synopsis: In this series of Blogs, I'll explore how the Web Intelligence RESTful Raylight Web Services allow users to automate and simplify the management, modification, creation and updates to a batch of Web Intelligence documents.  This series will be of interest to Web Intelligence administrators, designers, consultants and power users, to save time and effort and get the most out of your investment in Web Intelligence.

Previous Entry: http://scn.sap.com/community/restful-sdk/blog/2013/09/08/scripting-web-intelligence-the-restful-rayl...

Localization

We all want to be understood. 

Or to be more precise, we just don't want to be misunderstood.  But with internationalization of businesses, processes and yes, information, it's very easy to write something that means obviously one thing to someone, but means obviously something else to someone else.

Take 02/01/2011, for example.

Had an issue a while back where a client enters that value in a date prompt, and the Web Intelligence document returns no data.  The client is none too happy, since the backend data server shows several hundred transactions dated February 1st, 2011. 

Quick inspiration - we check and find that January 2nd, 2011 falls on a Sunday.

The client locale was set inadvertantly to en-GB instead of the expected en-US, and the British place day before month rather than month before day.  Correct that error and all is well.

But then again, what if the user happened to be British?  Then the above would have been the expected behavior.  We don't always want 02/01/2011 to be interpreted as a day in February. 

And let's talk numbers, 1,234,567.   Or 1.234.567 in some Locales.  Or 1 234 567 in others.

Add different languages into the mix, and the possible formats become much more numerous.  Fortunately, WebI knows how to format dates and numbers depending on the user's locale.  Here's a screenshot of PDF exports of the same WebI document, but with Users located in different countries:

It's pretty clear that the 'correct' format to use for data such as dates and numbers depend on the Locale where the user reading the document resides.  In SAP BusinessObjects Platform, a user defines his or her Preferred Viewing Locale (PVL) to specify preference.  So if a user selects "English (Great Britain)", then 02/01/2011 means January 2nd, 2011 and if a user selects "English (United States)", then 02/01/2011 means February 1st, 2011.

By default, when a user loads a Web Intelligence document in Raylight, the user's Preferred Viewing Locale specifies the WebI =GetContentLocale() vallue with which data is formatted.

Let's say you need to export a specified Web Intelligence document multiple times, each with a different locale.  For example, a sales report that you need to generate and send to each regional sales head in different countries.   Publications with personalization is made for jobs like that, but if that's not appropriate for your task, then the manual workflow would be quite tedious:  (1) set your PVL to the desired Locale, (2) open the WebI doc, (3) export, (4) close document (5) repeat.  That's where Raylight can come in - you can automate this workflow.

Preferred Viewing Locale and Document Lifecycle

With Raylight, you can specify the Content Locale for a WebI document via the Preferred Viewing Locale via the HTTP header X-SAP-PVL.  Set this header value to the desired locale identifier. The identifier string is the ISO-6390-1 language code and the ISO-3166 country code separated by a hyphen-minus. For example, the English(US) Locale is represented by en-US, English(Great Britain) by en-GB, French France by (fr-FR), and Japanese Japan by (ja-JP).

A few things to watch out for:  languages and countries strongly associated to the language don't necessarily have the same code, e.g., Korean Korea is ko-KR and not kr-KR or ko-KO, and the separating character is the hyphen-minus (Unicode U+002D or the 'minus' sign on your keyboard) and not underscore (like all you Java programmers want to use) or dash or en dash or em dash or long dash or how-many-different-dash-types-do-people-really-need.

The most important thing to watch out for:  Raylight will load one instance of a Web Intelligence document for each PVL requested by the User in a User session.  This is probably a good time to review the previous blog entry in this series, Scripting Web Intelligence: the RESTful Raylight Web Services - Logon/Logoff, Load/Unload, where I describe the lifecycle of documents in Raylight - how a WebI doc is loaded and unloaded in the Raylight container.

The rule to remember here:  if you send in the X-SAP-PVL header for a Raylight WebI document requests, always send in the same X-SAP-PVL header for every subsequent Raylight request until and including the Raylight request to unload the document.

Corollary to this rule is, if you don't send in a X-SAP-PVL header, then the default PVL setting for the User is going to be used, so don't send in a X-SAP-PVL header for all subsequent requests until and including the request to unload the document.

Why the rule?  If you change the X-SAP-PVL value, then Raylight will check to see if an instance of the WebI document with that Content Locale is already loaded, and if not, load a new instance with that Locale.

So let's walk through a Raylight code where breaking the above rule would lead to a problem.  Below's a snippet of Microsoft Powershell script that calls Raylight:

% Get parameters
$headers = @{ "X-SAP-LogonToken" = $logonToken ;
                            "X-SAP-PVL"        = "fr-FR"
              }
$parametersResult = Invoke-RestMethod -Method Get -Uri ($documentUrl + "/parameters") -Headers $headers
% Modify parameters
<..deleted...>
% Set parameters
$headers = @{ "X-SAP-LogonToken" = $logonToken ;
                             "X-SAP-PVL" = "en-US"
              }
$result = Invoke-RestMethod -Method Put -Uri ($documentUrl + "/parameters")  -Headers $headers -Body $parametersResult
% Export to PDF
$headers = @{ "X-SAP-LogonToken" = $logonToken ;
               "Accept"          = "application/pdf";
               "X-SAP-PVL"       = "fr-FR"
             }          
Invoke-RestMethod -Method Get -Uri ($documentUrl + "/pages") -Headers $headers -OutFile $filePath

If you look at the exported PDF file, you'll see that the new parameter values I set in the <..deleted..> code aren't being used at all, but that the old values saved with the WebI doc previously are used instead.  Why?  When I retrieve the parameter values in lines 2-5,  I'm specifying the X-SAP-PVL header.  Raylight loads an instance of the WebI document with the French (France) Content Locale, retrieves the prompts, and sends them back.  Then in lines 11-14, I send the modified prompt values to Raylight, but with X-SAP-PVL for the English (US) locale.  Raylight sees that the request is for a different Content Locale, so loads a new  instance of the doc, and sets the prompts for that instance.  Then finally in lines 17-21, I'm requesting the PDF but for X-SAP-PVL set to French (France).  Raylight sees that I'm requesting operation for the instance specified for that Locale, so exports to PDF not the English (US) instance for which I've set the prompts, but the previously loaded French (France) instance for which I've not set prompts.

Oops.   What I have to do is correct line 12 and change "en-US" to "fr-FR".  Then I'll get expected output.

What if I delete line 12 altogether?  My user account default PVL is set to English (Canada), so what Raylight will do is load a new instance of the WebI doc with Content Locale set to English (Canada), and sets the prompt for that instance.  Same problem!

You have to be extra careful when unloading document from Raylight, to ensure you've specified the correct X-SAP-PVL.  Otherwise, if you're working with multiple locales, every instance of the WebI doc in each of the different locales may remain loaded within Raylight memory till timeout, significantly impacting performance.

Bursting to Multiple Content Locales

Here's a script that uses Microsoft Powershell to call Raylight, where, given a list of Locales, loads a WebI document with that Locale, exports to PDF saving to file, then unloads:

#
# Export a Web Intelligence document to PDF with specified Content Locale language.
#
# The content locale specifies how data within the document is formatted (=GetContentLocale() WebI formula returns the
# specified locale).
#
############################################################################################################################
# Input: $logonInfo, $hostUrl, $locale, $documentId and $folderPath to suite your preferences
$logonInfo = @{}
$logonInfo.userName = "Administrator"
$logonInfo.password = "Password1"
$logonInfo.auth     = "secEnterprise"
$hostUrl = "http://hostname:6405/biprws"
$contentLocales = ("en-US", "fr-FR", "de-DE", "ja-JP", "ko-KR")  # List of languages to use.
$documentId = 6581  # SI_ID for the document
$folderPath = "C:\Users\tedueda\Desktop\RESTful"  # Folder where PDF files will be saved.
############################################################################################################################
$raylightUrl = $hostUrl + "/raylight/v1"
# Logon and retrieve Logon Token and add to the HTTP Header we send out on subsequent calls.
$headers = @{"Accept"       = "application/json" ;
             "Content-Type" = "application/json" }
$result = Invoke-RestMethod -Method Post -Uri ($hostUrl + "/logon/long") -Headers $headers -Body (ConvertTo-Json($logonInfo))
$logonToken =  "`"" + $result.logonToken + "`""  # The logon token must be delimited by double-quotes.
# Get document information and use the document name as file name.
$headers = @{ "X-SAP-LogonToken" = $logonToken ;
              "Accept"           = "application/json" ;
              "Content-Type"     = "application/json"
              }
$documentUrl = $raylightUrl + "/documents/" + $documentId
$result = Invoke-RestMethod -Method Get -Uri $documentUrl -Headers $headers
$document = $result.document
foreach($contentLocale in $contentLocales) {
    # Trigger data refresh of the document by sending PUT to parameters with no parameter list.
    $headers = @{ "X-SAP-LogonToken" = $logonToken ;
                  "Accept"           = "application/json" ;
                  "Content-Type"     = "application/json"
                  "X-SAP-PVL"        = $contentLocale
                }
    $parametersUrl = $documentUrl + "/parameters"
    $result = Invoke-RestMethod -Method Put -Uri $parametersUrl -Headers $headers
    $filePath = $folderPath + "/" + $document.name + "_" + $contentLocale +  ".pdf"
    # Retrieve and save PDF only if the file path is valid
    if(Test-Path $filePath -isValid) {
        # Get PDF and save to file
        $headers = @{ "X-SAP-LogonToken" = $logonToken ;
                      "Accept"           = "application/pdf" ;
                      "X-SAP-PVL" = $contentLocale
                   }
        Invoke-WebRequest -Method Get -Uri ($documentUrl + "/pages") -Headers $headers -OutFile $filePath
    } else {
        Write-Error "Invalid file path " + $filePath
    }
    # Unload document from Raylight
    $headers = @{ "X-SAP-LogonToken" = $logonToken ;
                  "Accept"           = "application/json" ;
                  "Content-Type"     = "application/json" ;
                  "X-SAP-PVL"        = $contentLocale
                }
    $result = Invoke-RestMethod -Method Put -Uri $documentUrl -Headers $headers -Body (ConvertTo-Json(@{"document"=@{"state"="Unused"}}))
}
# Log off the Session identified by the X-SAP-LogonToken HTTP Header
$headers = @{ "X-SAP-LogonToken" = $logonToken ;
              "Accept"           = "application/json" ;
              "Content-Type"     = "application/json" }
$logoffUrl = $hostUrl + "/logoff"
Invoke-RestMethod -Method Post -Uri $logoffUrl -Headers $headers

Note how the same X-SAP-PVL header is being used to load, export and unload the WebI document for each different value of the PVL.

Summary


Raylight allows you to specify the Content Locale of a Web Intelligence document to ensure data is formatted using the Preferred Viewing Locale you want.  You have to be careful, however, to always send in the same Preferred Viewing Locale via X-SAP-PVL header, since a different PVL value will cause Raylight to load a different instance of the WebI doc in memory.

In subsequent blog entries in this series, I'll discuss other things you can do with Raylight.  If you have any requests, please send them!  I'll see what I can do.