Quantcast
Channel: SCN : All Content - RESTful Web Services SDK
Viewing all 262 articles
Browse latest View live

How do we get "total" rows or "breaks"?

$
0
0

Hey guys,

 

Is there a way to obtain row "totals" (known as breaks in Webi) via the RESTful services?

 

I'm trying to obtain them via the dataset call, but they aren't appearing:

 

https://company.ca:6543/biprws/raylight/v1/documents/2138228/reports/1/elements/14/dataset

 

EX:

bi_webi_totals.png

 

 

Hiding the actual values, here is what I get when I call /dataset:
Notice how it leaves out the "total" rows as shown above in the Webi document

 

...

 

<row><value>01-BUSINESS LEVEL and REVENUE</value>

  <value>Revenue Tons per Load</value>

  <value>111</value>

</row>

<row><value>01-BUSINESS LEVEL and REVENUE</value>

  <value>Trailing GTMs</value>

  <value>111</value>

</row>

<row><value>03-TRIP PLAN</value>

  <value>Assessed Carload Trip Plans</value>

  <value>111</value>

</row>

<row><value>03-TRIP PLAN</value>

  <value>Assessed Intermodal Trip Plans</value>

  <value>111</value>

</row>

<row><value>03-TRIP PLAN</value>

  <value>Carload Trip Plan Performance (Pct)</value>

  <value>1111</value>

</row>

<row><value>03-TRIP PLAN</value>

  <value>Failed Intermodal Trip Plans</value>

  <value>111</value>

</row>

<row><value>03-TRIP PLAN</value>

  <value>Intermodal Trip Plan Performance (Pct)</value>

  <value>89.1</value>

</row>

<row><value>03-TRIP PLAN</value>

  <value>Trip Plan Fails (Car)</value>

  <value>1111</value>

</row>

<row><value>04-YARD</value>

  <value>Avg Industry Process Dwell</value>

  <value>1111</value>

</row>

<row><value>04-YARD</value>

  <value>Avg Through Dwell</value>

  <value>111</value>

</row>

 

...

 

Note: this is on version BI 4.1 SP3.

 

 

 

 

Thanks!

Scott


REST query for BW connection displays other OLAP connections also

$
0
0

Hi,

 

When I issued the following get request

 

<http://server:port/biprws/raylight/v1/bwconnections>

 

I am getting all the OLAP connections (HANA) along with BW.  How to identify the non BW connection from the result set.  There is no node/attribute contains this detail.

 

When I try to get the details of the non BW based connection using the following get request

 

<http://server:port/biprws/raylight/v1/bwconnections/{nonbwconnectionid}>

 

I am getting 503 Service Unavailable as status code and "The resource of type 'BW connection' with identifier '{nonbwconnectionid}' is not available." as the message.  Is there any other work around to get the type of the connection.

 

 

The above get request works fine when its a BW connection.

 

I am on build 14.1.5.1501.

 

Kindly guide me.

 

Regards,

Subramanian S.

System fault occured:SOAP:1007 SRT:Unsupported xstream encountred found("HTTP Code 200 : ok") while consuming webservice(WSDL)

$
0
0

We are consuming WSDL and within SAP we consumed it and SAP generated few proxy methods.

Following are the list of methods :-

a) CALL METHOD LO_PROXY1->CONNECT_CAB (executed successfully)

b) CALL METHOD LO_PROXY->DOWNLOAD_DOC_IN_FILE(Issue encountred : Unsupported xstram)

c) CALL METHOD LO_PROXY1->DISCONNECT_CAB (executed successfully)

Use Microsoft PowerShell to manage your BI Platform

$
0
0

With the new and upcoming release of SAP BusinessObjects Business Intelligence Platform 4.2, you are no longer bound to either Java or .NET in order to manage your BI platform though the SDK.

 

The new BI Platform has an extended set of new API’s through the Business Intelligence Platform RESTful Web Services.

 

REST stands for Representational State Transfer, and is a way to communicate with another system though standard HTTP, and HTTP commands like GET, POST, DELETE ect.

 

The beauty about using the new REST API, is than you are no longer bound to use the old API’s which required JAVA or .NET language skills. This new API can be used with any other language that can use the HTTP protocol, so now you can use other languages like PERL, PHP, Node.js, PowerShell ect.

 

In this blogpost, I will show how easy it is to

 

  1. Logon to the BI Platform using the RESTful Web Service, and retrieve a token
  2. Create a new user
  3. Create a new user group
  4. Assign the newly created user to the newly created user group
  5. Log off / Clean up

 

And this all done in PowerShell

 

Before you can use the RESTful Web Service, you need to make sure it is up an running.

 

You can simply try to open and url like this http://<url of your BI platform>:6405/biprws

 

Port 6405 is the standard port for the BI Platform RESTful Web Service, and I recommend that you also take a look on the Business Intelligence platform RESTful Web Service Developer Guide 4.2found on the Help SAP portal SAP BusinessObjects Business Intelligence platform 4.2 – SAP Help Portal Page

 

For this short demonstration, I have chosen to use the PowerShell comandlet Invoke-RestMethod, which is an easier to use than Invoke-WebRequest, but does not handle HTTP status codes and therefore I have “assumed” nothing fails in my code examples.

 

A good developer would most likely have added all sorts of error handling and checking

 

So let us get started

 

Logon to the BI Platform using the RESTful Web Service, and retrieve a token

 

I have done my editing and testing in the PowerShell ISE, but you could as well just type it all in the PowerShell command window.

 

First I start by defining some variables I need to use for logon

 

# Define username and password used to logon
$userName = "Administrator"
$passWord = "Password1"
$authType = "secEnterprise" # can be either secEnterprise, secLDAP, secWinAD or secSAPR3

 

Second I define some variables for the ease of use, so if I change the baseURL, I do not need to go over all the lines of code

 

# Define the base URL and URLs for logon and logoff
$baseURL   = "http://localhost:6405/biprws"
$logonURL  = "$baseURL/logon/long"
$logoffURL = "$baseURL/logoff"

Then I create a generic dictionary to hold the HTTP headers needed for communicating with RESTful Web Service.

 

# Create a generic dictionary to hold the headers needed to communicate with the BI Rest Web Service
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Accept","Application/Json")
$headers.Add("Content-Type","Application/Json")

In my example I have chosen to use JSON as the content type. I could have used Application/xml instead, as the service supports that as well, but for my purpose it was easier to work with the JSON format.

 

Next I created the object needed to create a new user as JSON

 

$logonJson = @"
{    "userName":  "$userName",    "password":  "$passWord",    "auth":  "$authType"
}
"@

Next I use the Invoke-RestMethod to logon on the BI platform and get the SAP Logon Token I need for further communication with the BI Platform

 

# Log on to the BI Platform
$response = Invoke-RestMethod -Uri $logonURL -Method Post -Headers $headers -Body $logonJson
# Retrieve the logonToken, this assumes everything went OK, since Invoke-RestMethod doesn't support .StatusCode
$SAPToken = $response.logonToken

And finally I add this token to the HTTP header collection, so I don’t have to code username and password into all the other requests

 

# Add the logonToken to the headers collection
$headers.Add("X-SAP-Logontoken",$SAPToken)

Create a new user

 

If I am not certain on how a command should look for creating a new user, and can allways call a GET request to /users/user to receive a template that can be used in the request body of a POST request to the same URL, like

 

$response = Invoke-RestMethod -Uri "${baseUrl}/users/user " -Method Get -Headers $headers
$response | ConvertTo-Json

Now when I have this template I can create the JSON used to create the new user

 

# Create json for a new user
$userJson = @"
{    "emailAddress":  "",   "isPasswordToChangeAtNextLogon":  false,    "isPasswordChangeAllowed":  false,    "description":  "This user was created by a script",    "fullName":  "Demo User 01",    "newPassword":  "Password1",    "connection":  0,    "isPasswordExpiryAllowed":  true,    "title":  "Demo01"
}
"@

In this case, I have changed some of the default values for my purpose with this demo user; however, the user is still created as a “Named User”. If I wanted to create the user as a “Concurrent User”, the “connection” property should be set to 1.

The user “Demo01” is created with the default password “Password1” and the user cannot change it, or is prompted to change it when the user logs on for the first time.

 

Next I use this REST call to create the user, and retrieve this new users ID for later user

 

# Post the userJson to the BI platform
$response = Invoke-RestMethod -Uri "${baseUrl}/users/user " -Method Post -Headers $headers -Body $userJson
# Retrive the user ID for later use
$userID = $response.entries.id

An example of the properties for the newly created user looks like this:

DemoUser01Properties.png

 

Create a new user group

 

Then, I create the JSON needed for creating a new user group, since it is rather simple

 

# Create json for adding new group
$groupJson = @"
{    "description":  "Group containing Demo Users",    "title":  "Demo Users"
}
"@

It simply consist of a title and a description

 

Then I post the JSON and retrieve the ID for the new group for later use

 

# Post the groupJson to create the new group
$response = Invoke-RestMethod -Uri "${baseUrl}/userGroups/userGroup" -Method Post -Headers $headers -Body $groupJson
# Retrieve the newly created group ID
$groupId = $response.entries.id

Simple, right?

 

Assign the newly created user to the newly created user group

 

Now this part is a bit trickier. I have the userID for the newly created user and the groupID for the newly created group, now I just need to combine those.

 

The way I did this, was to first retrieve the object needed to add or remove users from a group

 

# Retrive the group object for the newly created group
$groupInfo = Invoke-RestMethod -Uri "${baseUrl}/userGroups/${groupId}" -Method Get -Headers $headers

Then I added the userID to the addMembers part of the object

 

# Add the new user to the group
$groupInfo.addMembers = "$userID"

Note that I added the user ID in quotes. This is because the addMembers is a string array, which means that the users you would like to add is done as a string separated with comma, like "11111,22222,33333"

 

Now, the ideal part for me, would just have been to post the groupInfo JSON object back, but unfortunately it contains some other derived information, that is not suited to post back. Instead I create a new object with the information from my groupInfo object, and convert the new object to JSON

 

# Create a new object that can be used to parse the information back
$newGroupObject = @{    cuid = $groupInfo.cuid    Description = $groupInfo.Description    addMembers = $groupInfo.addMembers    removeMembers = $groupInfo.removeMembers    id = $groupInfo.id    title = $groupInfo.title    parentID = $groupInfo.parentID
}
$newGroupJson = ConvertTo-Json($newGroupObject)

At the time of writing, I did not have any other workaround, but the complete script is on github so feel free to fork it there, and do a pull request

 

Now I can put back the changes, yes – do note that this command uses PUT and not POST

 

# Submit the changes back to the server
$response = Invoke-RestMethod -Uri "${baseUrl}/userGroups/${groupId}" -Method Put -Headers $headers  -Body $newGroupJson
Write-Host $response.entries.SuccessAddingMessage

The last line writes the success response, and if everything went alright, yuu should see:

All Successfully Added

When user is created and added to the group, it should look something like this in CMC:

DemoGroup.png

Log off / Clean up

 

That is it; we have now created a user, a user group and added the user to the user group.

The last thing we could do is to delete the group and user again, if you were only testing.

 

In my script the lines is commented out but looks like this

 

<#
Invoke-RestMethod -Uri "${baseUrl}/userGroups/${groupId}" -Method Delete -Headers $headers
Invoke-RestMethod -Uri "${baseUrl}/users/$userID" -Method Delete -Headers $headers
#>

So the last thing needed is actually just so sign of, and release the token

 

# Log off the BI Platform (and release the logonToken)
Invoke-RestMethod -Uri $logoffURL -Method Post -Headers $headers

So that is how simple it is to create users and groups (and delete them) with the new RESTful Web Service in the upcoming Business Objects 4.2.

 

As mentioned, the complete script is released on GitHub, and you can find it here: https://github.com/Verakso/BO-PowerShell

 

Happy coding

Static images in HTML Export

$
0
0

I must be missing something.  For charts in Webi Reports, I can't understand why exporting a Webi Report to HTML would generate a link back to the server with a ticking time bomb logon token attached for the chart URL?  Is there some way to have the HTML export contain static normal images of charts, like jpeg or png?

Uploading Agnostic Documents with BI Platform RESTful Web Services

$
0
0

A new RESTful API introduced with the release of SAP BusinessObjects Business Intelligence Platform 4.2 allows for uploading and downloading agnostic documents to/from the BI Platform repository.


The purpose of this blog is to describe the basic requirements for uploading files and to provide some sample code to help with getting started.


When uploading a document, sending the file to the request stream requires some very specific formatting that can be frustrating if you need to construct the full request manually, or it can be very easy if you have tools or classes that take care of the formatting for you.  I will cover 3 scenarios to hopefully demonstrate this:

  1. Using a REST client – Easy
  2. Using .NET to construct the request from scratch – Tricky
  3. Using the Java class MultipartEntityBuilder to build the request – Moderately easy.
  4. Using Javascript. - Moderately easy.


 


Uploading a file over http requires that a request be sent using a Content-Type of multipart/form-data (RFC2388).  This means that the request sent to the server is made up of a series of parts separated by a boundary.  The boundary is content that is unique in the body of the data being sent. When uploading a file to the request stream, the stream should be constructed as follows:

    • Two dashes.
    • The boundary (a unique string that does not occur in the data).
    • One CRLF (\r\n).
    • A content-disposition header with the name of the form field corresponding to the file and the name of the file. That looks like: Content-Disposition: form-data; name="formfieldname"; filename="mydocument.pdf"
    • One CRLF (\r\n).
    • A content-type header describing the MIME type of the file. For example: Content-Type: application/pdf
    • Two CRLFs (\r\n\r\n). An empty line must exist between the form data and the file contents.
    • The entire contents of the file, byte for byte.
    • One CRLF (\r\n).
    • Two dashes + The boundary + Two dashes (the trailing two dashes represent the closing of the boundary)
    • One CRLF (\r\n).

 

 

Uploading a file using a REST client.

 

Rest clients provide an easy way to test RESTful calls without having to write any code.  For this example, The Postman Rest client (downloaded from the Chrome web store) is used to upload a file.  Additionally, a tool to monitor HTTP traffic is also used. This tool is Fiddler.

 

To upload an agnostic file, use the following API :

 

POST   http://<serverName>:6405/biprws/infostore/folder/<folderId>/file

 

<serverName> is the name of the machine hosting the Web Application Container Server (WACS)

 

<folderId> is the SI_ID of the folder in the CMS repository that you are uploading the file to.

 

Headers:

                X-SAP-LogonToken : “<yourLogonToken>”

 

The below Postman screenshot shows that we are using a POST to upload a file to a folder with the SI_ID of 8835

 

PostmanUpload.png

 

For the Body of the request

  • Select “form-data”
  • Provide a name corresponding to the file being uploaded (this is used in the Content-Disposition header)
  • Browse to the file you wish to upload
  • Click “Send”

 

PostmanUpload2.png

A response with the title, cuid, id and parentID is returned in the following format.

 

PostmanUpload_response.png

 

 

Note we did not have to worry about the content-type of the file, the boundary separator etc.  This is all handled for you by the REST client. You can see that the multipart/form-data format (described above) was used by looking at the request in Fiddler:

 

POST http://bipw08r2:6405/biprws/infostore/folder/8835/file HTTP/1.1

Host: bipw08r2:6405

Connection: keep-alive

Content-Length: 85463

X-SAP-LogonToken: "BIPW08R2:6400@{3&2=10032,U3&2v=BIPW08R2:6400 … KBdq7C65TRllA,UP}"

Cache-Control: no-cache

Origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAOQ9N10uh0pJmNxr

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36

Postman-Token: 8d1983b3-afbb-c895-1e5e-f7939b842ed4

Accept: */*

Accept-Encoding: gzip, deflate

Accept-Language: en-US,en;q=0.8

 

------WebKitFormBoundaryAOQ9N10uh0pJmNxr

Content-Disposition: form-data; name="uploadFileTest"; filename="testUpload.pdf"

Content-Type: application/pdf


<pages of binary data>

------WebKitFormBoundaryAOQ9N10uh0pJmNxr--

 

Uploading a file using .NET


.NET provides a class called MultipartFormDataStreamProvider to use for HTML file uploads, however for the purpose demonstrating how to construct a request from scratch, it will not be used in this example.  The Sample code below contains comments to describe each step.  While it is not complicated, it demonstrates the “tricky” part mentioned earlier, which is ensuring that carriage returns are inserted in key parts of the request, or it will fail.

 

        private void uploadAgnosticFile(String uploadURL, string rwsToken, string contentType, string filePath)        {            /************************************************************************************             * Parameters:             *             * uploadURL   …/biprws/infostore/folder/<folderId>/file             * rwsToken the logonToken contained inside of double quotes             * contentType The Mimetype of the file to be uploaded             * filePath the full path to the file including the filename and extension             *             ***********************************************************************************/            string fileName = filePath.Substring(filePath.LastIndexOf("\\")+1);            //Create the unique boundary            String boundary = "--" + System.Guid.NewGuid().ToString();            byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");            byte[] boundaryCloseBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");            //Create the Web request            HttpWebRequest myWebRequest = (HttpWebRequest)WebRequest.Create(uploadURL);            myWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;            myWebRequest.Method = "POST";            myWebRequest.Headers.Add("X-SAP-LogonToken", rwsToken);            myWebRequest.Accept = "*";            //Construct the form data            string myFormData = string.Empty;            myFormData = "Content-Disposition: form-data; name=\"myuploadfile\"; filename=\"" + fileName + "\"\r\n";  //fileName is the name shown in launchpad            myFormData += "Content-Type: " + contentType + "\r\n\r\n";          // must have an extra blank line between the form data and the filestream or a zero byte file is uploaded            //convert the string myFormData to an array of bytes            byte[] formDataBytes = System.Text.Encoding.ASCII.GetBytes(myFormData);            // Read the file to upload as a stream            FileStream fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);            int fileSize = (int)fStream.Length;            byte[] filebytes = new Byte[fileSize];            fStream.Read(filebytes, 0, fileSize);            fStream.Close();            // add it all together into the request stream.            Stream reqStream = myWebRequest.GetRequestStream();            reqStream.Write(boundaryBytes, 0, boundaryBytes.Length);            //boundary            reqStream.Write(formDataBytes, 0, formDataBytes.Length);            //form data with Content-Disposition            reqStream.Write(filebytes, 0, fileSize);                            //file as a stream of bytes            reqStream.Write(boundaryCloseBytes, 0, boundaryCloseBytes.Length);  //boundary with closing dashes.            reqStream.Close();            string output = string.Empty;            try            {                WebResponse myWebResponse = (WebResponse)myWebRequest.GetResponse();                StreamReader sr = new StreamReader(myWebResponse.GetResponseStream());               output = sr.ReadToEnd();                sr.Close();                Response.Write(output);             }            catch (WebException ex)            {                Response.Write("Error getting response.  Response Code: " + ex.Message.ToString());            }            catch (Exception ex)            {                Response.Write("general error: " + ex.Message.ToString());            }        }


Uploading a file with Java


For uploading a file using Java, the MultipartEntityBuilder class is used in the below code. Required jars are httpclient-4.5.1.jar and httpmime-4.5.1.jar.

 

private static String parentFolderId = "8835";
private static String rwsToken = null;
private static  File fileToUpload = new File("c:\\testfiles\\testupload.pdf");
private static String baseURL = "http://<serverName>:6405/biprws/";
private static String logonURL = baseURL + "logon/long";
private static String infostoreURL = baseURL + "infostore/";
private static String uploadURL = infostoreURL + "folder/" + parentFolderId + "/file";
rwsToken = getToken(userName,password,auth);
HttpPost httpPost = null;
CloseableHttpClient httpClient = null;
HttpResponse httpResponse = null;
MultipartEntityBuilder multipartEntityBuilder = null;
FileBody fileBody = new FileBody(fileToUpload);
multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setCharset(Charset.forName("UTF-8"));
multipartEntityBuilder.addPart("File",fileBody);
httpPost = new HttpPost(uploadURL);
httpPost.setHeader("X-SAP-LogonToken", rwsToken);
httpPost.setEntity(multipartEntityBuilder.build());
httpClient = HttpClientBuilder.create().build();
httpResponse = httpClient.execute(httpPost);


Uploading a file with Javascript


The following html page demonstrates how to log on and upload a file using Javascript.

 

<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body ><input id="File1" type="file" /><input id="Button1" type="button" value="upload file" onclick="uploadtoCMS()" /><script type="text/javascript">
function uploadtoCMS()
{         // debugger;    // Logs into the platform    var logon = new XMLHttpRequest();    var url = 'http://bipw08r2:6405/biprws/logon/long';        var body = '<?xml version="1.0"?><attrs xmlns="http://www.sap.com/rws/bip"><attr name="userName" type="string">user_name</attr><attr name="password" type="string">your_password</attr><attr name="auth" type="string" possibilities="secEnterprise,secLDAP,secWinAD">secEnterprise</attr></attrs>';    var logonToken;    logon.open('POST', url, false);    logon.setRequestHeader('Content-Type', 'application/xml');    logon.setRequestHeader('Accept', 'application/xml');    logon.send(body);    //retrieve logon token from response    logonToken = logon.getResponseHeader('X-SAP-LogonToken');    //uploads file to CMS    var fileToUpload = document.getElementById("File1").files[0];    var uploadRequest = new XMLHttpRequest();    var fd = new FormData();    var uploadURL = 'http://<servername>:6405/biprws/infostore/folder/<folderId>/file';    fd.append('uploadtest', fileToUpload);    uploadRequest.open('POST', uploadURL, false);    uploadRequest.setRequestHeader('X-SAP-LogonToken', logonToken);    uploadRequest.send(fd);    document.write("The following file was uploaded to the CMS: " + fileToUpload.name);
}</script></body></html>

Hopefully the above samples show how easy it can be to upload a file to the BI Platform as well as what is happening behind the scenes so you know what to look for when troubleshooting a request using a multipart request over HTTP.

Scheduling a webi report with prompts

$
0
0

Hi Friends,

 

I'm in need of help again.

 

I need to schedule Webi reports that contain prompts using RESTful web services. I am sure someone must have developed a code for scheduling by now hence don't want to reinvent the wheel. Though I have worked on developing java programs using RESTful web services for a couple of months now I am still not a well-versed coder and would greatly appreciate any help.

 

Regards,

-CF

interactive parameters using with restful api

$
0
0

Created a report configured interactive parameters. One of those parameters are Boolean and date. these are not required parameters I want them to be optional. From interactive parameters I selected those as Prompt value Optional .

 

  • When I am exporting the report using restful it is returning error no values for "parameter Name"
  • Show records which as date interactive parameter is not null

Restful features not supported in BO SP5

$
0
0

Hi,

 

We are currently using Business Objects SP5 version,

 

please suggest list of features not supported

How to create a new Document with Data Provider through RESTful API

$
0
0

Hello,

I have a simple Document created through BI Web Intelligence that looks like this:

{"document":
  "id":2128049,"cuid":"ARjk4uobpgBAjSU6RQPkx.k","name":"Test1","folderId":2128036,
  "path":"Public Folders\/WISDK","updated":"2015-11-30T10:58:59.048+02:00",
  "scheduled":false,"state":"Unused","createdBy":"Administrator",
  "lastAuthor":"Administrator","size":25886,"refreshOnOpen":false}
}

 

It has one simple Data Provider:

 

{"dataprovider":
  {"id":"DP0","name":"Query 1","dataSourceId":5085,"dataSourcePrefix":"DS0",
  "dataSourceType":"unv","updated":"2015-11-30T10:58:20.000+02:00","duration":1,
  "isPartial":false,"rowCount":13,"flowCount":1,
  "dictionary":{"expression":[
    {"@qualification":"Dimension","@dataType":"String","id":"DP0.DOa6","name":"City",
      "description":"City located.","dataSourceObjectId":"DS0.DOa6","formulaLanguageId":"[City]"},
    {"@qualification":"Dimension","@dataType":"String","id":"DP0.DOda","name":"State",
      "description":"State located.","dataSourceObjectId":"DS0.DOda","formulaLanguageId":"[State]"}
  ]},
  "query":"SELECT Outlet_Lookup.State, Outlet_Lookup.City FROM Outlet_Lookup"}
}

 

I am trying to recreate a very similar document through RESTful API and can't seem to figure out how to add Expressions to Data Provider.

 

What I am doing now (note: newlines in request JSON are added for readability, they are not present in original requests):

 

1) Sending logon request, getting token.

 

2) Creating Document.

 

Request:
  POST /biprws/raylight/v1/documents HTTP/1.1
  {"document":{"name":"eFashion document","folderId":2128036}}
Response:
  HTTP/1.1 200 OK
  {"success":
    {"message":"The resource of type \"Document\" with identifier \"2151274\" has been successfully created.",
    "id":2151274}
  }

3) Adding Data Provider.

 

Request:
  POST /biprws/raylight/v1/documents/2151274/dataproviders HTTP/1.1
  {"dataprovider":{"name":"Query 1","dataSourceId":5085}}
Response:
  HTTP/1.1 200 OK
  {"success":
    {"message":"The resource of type \"Data provider\" with identifier \"DP0\" has been successfully created.",
    "id":"DP0"}
  }

4) Interesting part, adding Expressions to Data Provider.

 

Request:
  PUT /biprws/raylight/v1/documents/2151274/dataproviders/DP0 HTTP/1.1
  {"dataprovider":
    {"dictionary":
      {"expression":[
        {"name":"State","dataSourceObjectId":"DS0.DOda"},
        {"name":"City","dataSourceObjectId":"DS0.DOa6"}
      ]}
    }
  }
Result:
  HTTP/1.1 200 OK
  {"success":
    {"message":"The resource of type \"Data provider\" with identifier \"DP0\" has not been modified.",
    "id":"DP0"}
  }

And no matter what I try, I can't get it to add expressions. I have tried including other properties in expressions (different combinations with id, qualification, datatype), sending dataSourceId and id with and without DS0/DP0 prefixes and even including dictionary from step 4 into request in step 3. No matter what I try, the result is the same (in case of combining steps 3 and 4 - provider is created, but without expressions).

The Document and Data Provider I get in the end look like this:

 

{"document":
  {"id":2151274,"cuid":"ASrC12AtuRxNpCx50WOmX7A","name":"eFashion document","folderId":2128036,
  "path":"Public Folders\/WISDK","updated":"2016-01-28T10:01:46.759+02:00",
  "scheduled":false,"state":"Modified","createdBy":"username","lastAuthor":"username",
  "size":14423,"refreshOnOpen":false}
}

 

{"dataprovider":
  {"id":"DP0","name":"Query 1","dataSourceId":5085,"dataSourcePrefix":"DS0",
  "dataSourceType":"unv","duration":0,"isPartial":false,"rowCount":0}
}

 

And, what is interesting, after re-logging and getting documents provider list, my new Data Provider disappears:

 

{"dataproviders":""}

 

What am I doing wrong and what are the steps necessary to recreate my target document?

Unable to access personal docs via Raylight

$
0
0

While connected to REST as Administrator, I can get a successful result from:

 

/biprws/infostore/78602,

 

but attempting to open the report with the following call produces a 404:

 

/biprws/raylight/v1/documents/78602

 

I can open reports in Public Folders, as well as personal reports belonging to Administrator, but I can not open other users' reports.

 

This is the detail of the error:

 

<error>  <error_code>WSR 00400</error_code>  <message>The resource of type "Document" with identifier "78602" does not exist.</message>  <stack_trace>com.sap.webi.raylight.RaylightException: The resource of type "Document" with identifier "78602" does not exist.&#13;
at com.sap.webi.raylight.context.Messenger.resourceNotFound(Messenger.java:122)&#13;
at com.sap.webi.raylight.actions.document.AbstractGetDocumentAction.getDocument(AbstractGetDocumentAction.java:36)&#13;
at com.sap.webi.raylight.actions.document.GetDocumentByIdAction.execute(GetDocumentByIdAction.java:60)&#13;
at sun.reflect.GeneratedMethodAccessor300.invoke(Unknown Source)&#13;
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&#13;
at java.lang.reflect.Method.invoke(Method.java:597)&#13;
at com.sap.webi.raylight.actions.ActionInvoker.invokeWith(ActionInvoker.java:123)&#13;
at com.sap.webi.raylight.actions.ActionDispatcher.invoke(ActionDispatcher.java:105)&#13;
at com.sap.webi.raylight.RaylightServiceDocument.getDocument(RaylightServiceDocument.java:49)&#13;
at sun.reflect.GeneratedMethodAccessor299.invoke(Unknown Source)&#13;
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&#13;
at java.lang.reflect.Method.invoke(Method.java:597)&#13;
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:173)&#13;
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89)&#13;
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:164)&#13;
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:242)&#13;
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:242)&#13;
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:91)&#13;
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)&#13;
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)&#13;
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)&#13;
at java.util.concurrent.FutureTask.run(FutureTask.java:138)&#13;
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)&#13;
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)&#13;
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:255)&#13;
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:113)&#13;
at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:102)&#13;
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:464)&#13;
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)&#13;
at com.sap.bip.rs.server.servlet.BIPServletController.invoke(BIPServletController.java:93)&#13;
at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:148)&#13;
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179)&#13;
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:108)&#13;
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)&#13;
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159)&#13;
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)&#13;
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)&#13;
at com.businessobjects.sdk.actionfilter.WorkflowFilter.doFilter(WorkflowFilter.java:45)&#13;
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)&#13;
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)&#13;
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)&#13;
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)&#13;
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)&#13;
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)&#13;
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)&#13;
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)&#13;
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)&#13;
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)&#13;
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)&#13;
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)&#13;
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)&#13;
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)&#13;
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)&#13;
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)&#13;
at java.lang.Thread.run(Thread.java:763)&#13;</stack_trace></error>

Access report with report name

$
0
0

Hi,

 

I am accessing the report using the report ID, is there a way to access it using the name. So even if the ID changes, the report can be still accessed using its name. If more than one copy of the same report is available in different folders how will it pick and chose the report to run?

 

 

Thanks,

Arun

Purge report

$
0
0

Hi,

 

I tried purging report with Java SDK, seems like the DataProvider class is deprecated in 4.1.

How it can be done with Restful?

 

Something like below will work?

 

Get = ...raylight/v1/documents/reportid/dataproviders/purge = true?

 

Thanks,
Arun

List of documents by folder name

$
0
0

Hello Friends,

 

I use the following method call to get the list of all the documents 50 at a time.

 

request.send(BIP_RWS + "/raylight/v1/documents?offset="+offsetindex+"&limit=50", "GET", null);

 

Is it possible to extract the list of documents from a specific public folder by using the folder name?

 

Regards,

-Chris

REST query for BW connection displays other OLAP connections also

$
0
0

Hi,

 

When I issued the following get request

 

<http://server:port/biprws/raylight/v1/bwconnections>

 

I am getting all the OLAP connections (HANA) along with BW.  How to identify the non BW connection from the result set.  There is no node/attribute contains this detail.

 

When I try to get the details of the non BW based connection using the following get request

 

<http://server:port/biprws/raylight/v1/bwconnections/{nonbwconnectionid}>

 

I am getting 503 Service Unavailable as status code and "The resource of type 'BW connection' with identifier '{nonbwconnectionid}' is not available." as the message.  Is there any other work around to get the type of the connection.

 

 

The above get request works fine when its a BW connection.

 

I am on build 14.1.5.1501.

 

Kindly guide me.

 

Regards,

Subramanian S.


Connecting Tableau to UNV universes - Part I

$
0
0

Hi All,

 

I would like to share another way of connecting an UNV universe to Tableau .

There is one blog post , by Ron Keller, that shows a way of doing it using OData and Web Services.

My approach will use OData and the Rest API.

But it has its drawbacks, the critical one is that the connection is not easily refreshed, making it hard to "schedule" the Tableau Dashboard.

I will cover another way of making a "persistent" connection on Part II of this blog post.

 

In order to generate a OData Url this is the workflow to be followed :

 

1 - Lolgin into the platform;

2 - Get the list of UNV Universes;

3 - Get the details of a the choosen Universe;

4 - Create a Query;

5 - Create the OData Url.

6 - append the logon token to the URL;

7 - Connect Tableau to the Odata Service;

8 - Loggof the -platform.

 

As the Query exists only in memory (it´s not saved to the CMS), you must connect to Tableau prior to logging off. And the reason way the connection cannot be reused is the fact that one must provide the logonToken  plus the Query ID which only exists in the current REST session.

 

 

In the next post I´m explaining a  way of doing the connection persistant so you can refresh the Tableau Worksheet.

Feel free to contact me in case of any doubts or comments

 

I´m attaching a simple HTML file that demonstrates the role process. My example query contains just one field. In order to run the script, one can just drag the file and drop it on a Browser

 

Regards,

Rogerio

Restful webservice sdk handbook

$
0
0

Hi,

Can anyone share the step by step usage of restful webservice sdk?

A beginners handbook

Business Objects RESTful API "Run as"

$
0
0

Hi all,

 

the "old" Java Web SDK also had the feature "Run as" for Crystal reports and WEBIs.

I cannot find any documentation on "Run as" in the RESTful API.

Was that feature implemented at all ?

 

Thank you.

 

Cheers,

Alexander

Running a Query Builder query in RESTful

$
0
0

Hi,

 

In some of the reverts Antony mentioned about a new feature of running Query Builder queries using RESTful web services BIP 4.2.  Can you please guide me to the document for the same.

 

Regards,

Subramanian S.

Schedule report to Cloud Destinations like Box or Google Drive

$
0
0

Hello Experts,

 

Is there are anyway we can schedule reports to Cloud Destinations like Box or Google Drive using RESTful Webservices?

 

Right now we have five options:

 

1. Default Destination

2. FTP

3. BI Inbox

4. Email

5. File System

 

Which of the above option can be possibly used?

 

Thanks in advance...

Viewing all 262 articles
Browse latest View live


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