Friday, April 16, 2010

How to use BI Publisher Web Service with JDeveloper 11G?

How can I call BI Publisher Web Service from my Java application with JDeveloper?

BI Publisher provides a set of Web Service APIs, with which you can do pretty much everything you can do from the UI such as running reports, scheduling reports, creating/editing/deleting reports, etc. With JDeveloper you can easily integrate the BI Publisher Web Service with your Java application and start developing your code.

I wrote a ‘BI Publisher Web Service development guide for Java developers with JDeveloper’ paper quite a while ago, but never talked about this topic on this blog. And there have been some changes since then. Now JDeveloper is 11G and BI Publisher has added more APIs and fixed some issues we had before.

So I’ll spend the next couple of posts talking about this topic, hope it will be useful for Java Developers out there who want to integrate with BI Publisher to run and manage BI Publisher reports within your application.

Environment

Here is my environment information:

  • BI Publisher 10.1.3.4.1 with March Patch Set (9546699)
  • JDeveloper 11.1.1.2
  • WebLogic Server 11G (10.3.2)

Get BI Publisher WSDL File

First, you need to get a WSDL file first before start anything. You can obtain your BI Publisher Server’s WSDL file by submitting the following URL from your browser.

http://hostname:port/xmlpserver/services/PublicReportService?WSDL

Note: Somehow I couldn’t get this with my BI Publisher running on a OC4J. I don’t know why but keep getting an error message. Looks many people are just fine or it worked fine after upgraded or something. Since I didn’t have enough time to keep debugging I’ve just simply moved to my another BI Publisher Server running on WebLogic 11g Server, which is working perfect, thanks god!

Once you get the WSDL file then save it to your local system.

Create a Web Service Proxy

Now, in order to integrate with Web Service within Java application you need to create a Web Service Proxy. There is a UI wizard to generate this with JDeveloper. In the New Gallery (right click on Project and ‘New’), select Web Server Proxy under Business Tier/Web Services and follow the steps with the default options until finish. When you are asked to provide a WSDL then use the WSDL you just saved at above.

image

In my example I have chosen ‘JAX-WS Style’ as Client Style.

image

Once you click the ‘Finish’ button it automatically generates all the required Java classes to provide you a set of Java APIs each of which corresponds with each Web Service API. Also it generates the Proxy class called ‘PublicReportServiceService’ like the below.

public class PublicReportServiceClient
{
  @WebServiceRef
  private static PublicReportServiceService publicReportServiceService;

  public static void main(String [] args) {
    publicReportServiceService = new PublicReportServiceService();
    PublicReportService publicReportService = publicReportServiceService.getPublicReportService();
    // Add your code to call the desired methods.
  }
}

Now you can start writing your own code with the BI Publisher Web Service corresponding Java methods after the ‘Add your code to call….’ line.

Call BI Publisher Web Service

First, I’m going to use a simple API called ‘login(String username, String password)’ to test if the web service integration works. This API accepts two parameters, one is username and another is password. It passes those two values to the BI Publisher Server and returns a session token if the combination of the username and password is valid. You can use this session token later for any following actions such as running a report, scheduling a report, etc, without needing to be authenticated at every communication with the Server.

Anyway, so this ‘login()’ API is one of the BI Publisher Web Service APIs and I can call it through the Web Server Proxy. In the example below ‘publicReportService’ is the proxy, once this is instantiated then I can call it through the proxy ‘publicReportService’.

With the below example, I’m setting ‘Administrator’ for the username and ‘Administrator’ for the password, and trying to print the returned session token in the standard out.

public class PublicReportServiceClient
{
  @WebServiceRef
  private static PublicReportServiceService publicReportServiceService;

  public static void main(String [] args) throws AccessDeniedException_Exception,
                                                  MalformedURLException {
    publicReportServiceService = new PublicReportServiceService();

    PublicReportService publicReportService = publicReportServiceService.getPublicReportService();

    String sessionid = publicReportService.login("Administrator", "Administrator");
    System.out.println(sessionid);    
  }
}

When I run this program I get a session token like ‘6691223D7D070473ABA31D91AAB89’, which means the login was successful and I can use this token later when I call other BI Publisher Web Service APIs.

How to Change Endpoint?

Now, as long as I’m developing and testing in this instance I would be fine. But what if I need to migrate my code to a QA or Production and I need to run the BI Publisher calls against a different BI Publisher Server?

When you create the Web Server Proxy with JDeveloper it generates it with a default endpoint URL setting, which is retrieved from the WSDL file. That means, every time I run the BI Publisher Web Service it goes against a BI Publisher server with the endpoint URL. So I want to dynamically change the endpoint URL address instead of hard-coding it somewhere.

With 10G JDeveloper it generated an API that I can use to set the endpoint URL address. But with 11G JDeveloper I need to do that in a slight different way, which is to set that as part of the proxy construction. With my example, I can set that when I initiate ‘publicReportServiceService’. I need to provide a URL, which is the endpoint, and a QName, which consists of namespace and localname. My example, those are something like following.

  • Endpoint URL: http://knishida-lap.us.oracle.com:7001/xmlpserver/services/PublicReportService
  • Namespace: http://xmlns.oracle.com/oxp/service/PublicReportService
  • Localname: PublicReportServiceService

You can find these information from your BI Publisher Server WSDL file, or you just need to change the hostname and port number of the example above. And you can set those values something like below.

Before:

publicReportServiceService = new PublicReportServiceService();

After:

//publicReportServiceService = new PublicReportServiceService();
publicReportServiceService = new PublicReportServiceService(new URL("http://knishida-lap.us.oracle.com:7001/xmlpserver/services/PublicReportService"), new QName("http://xmlns.oracle.com/oxp/service/PublicReportService", "PublicReportServiceService"));

Now you have a control of which BI Publisher Server instance you want to communicate with the Web Service calls. Great!

Test with Java Servlet

With the above example I was testing with a Java application. But for the next couple of posts I want to use a Java Servlet to demonstrate other APIs. In case you are not familiar with Java Servlet, don’t worry, you can create it with JDeveloper pretty easily. Just select ‘HTTP Servlet’ under ‘Web Tier/Servlet’ in the ‘New Gallery’ menu and follow the wizard steps.

image

Now I created a Java Servlet to test called ‘BipServletTest’ under the same project. I’m going to use this Servlet to go over the next couple of posts to introduce other BI Publisher Web Service APIs such as runReport, scheduleReport, etc, so stay tuned!

19 comments:

  1. Hi Kanichiro Nishida,
    The blog is very useful who are working with OBI web services.
    Here i had a doubt that if there are 4 or 5 reports in OBI, i want to give permissions to that particular report to different user. ex: report r1 is accessible to user x1 and user x2 can access r3 and r4 but not r1 and r2. like this how can i set the permissions through web services?? which wsdl i have to use for this purpose. Please suggest me,
    waiting for reply
    Regards,
    Pradeep Kumar

    ReplyDelete
  2. Pradeep,

    First, you can do the access control only at the folder level, not report level.

    And that needs to be done by Administrator from Admin UI, and all the Admin configuration tasks are not provided through Web Service.

    ReplyDelete
  3. Hi Kanichiro Nishida,
    First of all thanks for your reply, I set those permissions successfully by using the wsdl generated form http://X.X.X.X:9704/analytics/saw.dll?wsdl it provides some services among them one is WebCatlogService.
    This service provides a method called updateCatalogItemACL(); By this i can set the permissions to the reports also. Here one issue arises, from admin UI i can assign permissions like read/traverse/change/delete/full control/No access. But from web service i can only assign "read" permission to te users.
    Here the code --
    Account account1 = new Account("shekar",0); // 0 for user and 1 for Group
    AccessControlToken act22[] = new AccessControlToken[]{new AccessControlToken(account1,1)};
    ACL acl1 = new ACL(act22,account1);
    UpdateACLMode uamForWebCatloge = new UpdateACLMode("ReplaceForSpecifiedAccounts");
    UpdateCatalogItemACLParams uciaclp = new UpdateCatalogItemACLParams(true,uamForWebCatloge,false);
    WebCatalogServiceSoapProxy wcssp = new WebCatalogServiceSoapProxy();
    wcssp.updateCatalogItemACL("/shared/SH Sales Reports/Sales by promotion", acl1, uciaclp, sessionID);
    The web service guide suggest that
    AccessControlToken Structure:-
    Account account ----- Specifies a reference to the Account structure.
    int permissionMask ------Specifies a combination of the following flags:
    1 = Permission to read item content
    2 = Permission to traverse directory
    4 = Permission to change item content
    8 = Permission to delete an item
    16 = Permission to assign permissions to other accounts
    32 = Permission to take ownership of the item.
    But here only 1,2&8 are working,remaining assigns to "No Access" permissions.

    ReplyDelete
  4. Didn't realize you were talking about OBIEE Web Service, not BI Publisher Web Service. My blog post is about BI Publisher Web Service. While I have used OBIEE Web Service before but I'm not familiar with the particular API you mentioned.

    ReplyDelete
  5. Hi Kanichiro Nishida,
    In previous post i mentioned about OBIEE web service that is sample how i set permissions to reports through OBIEE webservices, but what i want is how to set permissions to the reports. you said that we can do the access control only at the folder level, not report level.Please tell me how can i set permissions to that folders, which methods i have to use. iam using URL for this is:-
    http://X.X.X.X:9704/xmlpserver/services/PublicReportService?wsdl
    (Is it correct wsdl for accessing BI publisher web services??).If there is any sample code please provide me. waiting for reply..
    Thanks in advance,
    Regards,
    pradeep

    ReplyDelete
  6. I think I have already answered to the question above .

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Thank you very much for sharing your beautiful post here I wish you to success.

    Thanks~

    Prasen Dutta

    Business Development LLC, at ecommerce web design company India

    ReplyDelete
  9. Ya it helped a lot, Iam thankful to you

    ReplyDelete
  10. Can u post sample code for using hasReportAccess() method in BI publisher web service. It helps a lot for me. Thanks in advance.

    ReplyDelete
  11. Suggestion:
    Login and retain session for all subsequent method call, will not work if you have clustered environment because BIP does not manage session properly. You will get invalid session token error.
    so better always use methods(accepting userid/password).

    ReplyDelete
  12. the session ID is shared across clusters so it can be used. But note that the session ID can be expired after certain time.

    ReplyDelete
  13. Hello,

    Thank you a lot for your post.

    But I have a problem when I launch my servlet from my form application. I have the following error message :

    Unable to locate the implementation class of service for service: bip_webservice.proxy.PublicReportServiceService_Impl

    And i am unable to find where is the problem. Any idea ??

    ReplyDelete
  14. hi kanichiro,
    have you try to implement an other publisher webservice "SecurityService" ?
    i meet some issues to implement.

    the first is the creation of the Web Service Proxy in jdeveloper.
    i have the error at the end of the wizard

    java.lang.IllegalArgumentException: Not a valid simple name: 'v2/SecurityServiceClient'

    best regards
    jean marc

    ReplyDelete
  15. hi kanichiro,
    have you try to implement an other publisher webservice "SecurityService" ?
    i meet some issues to implement.

    the first is the creation of the Web Service Proxy in jdeveloper.
    i have the error at the end of the wizard

    java.lang.IllegalArgumentException: Not a valid simple name: 'v2/SecurityServiceClient'

    best regards
    jean marc

    ReplyDelete
  16. Hi kanichiro ..thanks for the great post and information. I am BiPublisher to get reports. I have generated webservice class from the WSDL ,using Apache CXF. In my project i am using geronimo jar as a library.When i try to access BiPublisher i am getting such as WSDL parsing error..invalid address...DOCTYPE[34] etc. This works fine when i use jaxb as library.Can you please tell me whether OracleBiPublisher works well with geronimo or not .For various other reasons i cannot remove geronimo.JBOSS is my server. Thanks in advance

    ReplyDelete
  17. Hi I am using security service and trying to create user through BI Publisher web service. I am getting following exception.:

    java.lang.SecurityException: Security violation: /~TestUser; Administrator does not have permission to create this folder.

    What I have understood. Through Security service , User folder is not getting created with administrator user. Any configuration missing or something.


    Any Help....

    ReplyDelete
  18. Hi,

    I am trying to get list of templates that are uploaded into a report folder.
    I am using Oracle Business Intelligence Publisher Release 11g (11.1.1).

    I am using PublicReportService API, getFolderContents by passing folder name, and credentials to login to BIP server.
    My folder structure is like
    SharedFolder
    --Letters
    ----Sample.xdo
    ------letter1.rtf
    ------letter2.rtf
    ----Sample1.xdo
    ------letter3.rtf
    ------letter4.rtf
    --Letters1
    ----Sample2.xdo
    ------letter5.rtf
    ------letter6.rtf
    ----Sample3.xdo
    ------letter7.rtf
    ------letter8.rtf

    If I pass, "/" as folder name, I am getting all the shared folders (Letters, Letters1) available in BIP server.
    If I pass a specific folder name, say Letters; we are getting values as Sample.xdo, Sample1.xdo.
    My requirement is to see the letters/templates attached with in a report folder say Sample.xdo.

    Please let me know if any one has overcome this scenario.

    Thanks,
    Satya

    ReplyDelete