Create a service for Cognos reports in Integration Designer

You can browse Cognos business intelligence reports, view them and select to import a report as a web service. These web services can be used to access the Cognos reports from an application.

Cognos business intelligence reports provide insight into the management and performance of your enterprise. Using data from across an organization, these reports can be useful in decision making situations. You can view, import, and create services accessing these reports with the editors in Integration Designer.

You must access a server with Cognos 8.4.1 or higher to use these functions. You can also use the Cognos BI 10.1 that is built-in to IBM Business Monitor. You can then have your processes dynamically react to values in reports against those processes; for example, it could offer a discount if the monthly sales report against your Sales process returns a value that is too low.


Set up the preferences page for Cognos reports

The preferences page for Cognos reports specifies the default Cognos Universal Resource Identifier (URI) address and manages credentials saved from connecting to a Cognos server using the External service wizard. To specify the default URI address, follow these steps:

  1. From the menu, select Window > Preferences. In the Preferences window, expand Business Integration and select Cognos Report.

  2. Enter the URI address in the Cognos gateway URI field and click Apply to save your work.
  3. When you connect to a Cognos server from the External service wizard, you can save the credentials. These credentials are saved in the table on the page.
  4. To remove saved credentials, select the address in the table and click Remove. Remove All deletes all addresses. Click Apply to save your work.
  5. When finished, click OK to exit the Preferences window.



Related concepts:

Work with Cognos reports


Related tasks:

View and importing a Cognos report as a web service


View and importing a Cognos report as a web service

You can browse a Cognos report on a server, view it and import the report as a web service. To work with the Cognos reports on a Cognos server, follow these steps:

  1. Right-click a module you have created and select New > External Service. In the New External Service window, expand Web and click From Cognos Reports. Click Next. The Select a Cognos Report page opens.
  2. The address in the Cognos gateway URI field will be the one you entered on the Preferences page. You can enter a different URI. Click Retrieve.
  3. At this point, you are accessing a Cognos server and security is required. However, how you interact with the security on the Cognos server is determined by how the security for the server was configured.

    1. Single sign-on: A single sign-on configuration is a way of letting users access one or more systems by logging on once. Single sign-on security is only available if Cognos is running on WAS. Single sign-on security is discussed for both the JAX-WS and JAX-RPC web bindings in the working with Cognos reports section.
    2. Credentials: In this case, you are prompted for these security credentials: a namespace, a user ID and a password. Selecting Save credentials stores the security credentials locally so you do not need to enter them again when you access the server the next time.
    3. No security: In this case, the server has been set up to let you log on without any security credentials. You are not prompted for any security.

  4. A list of Cognos reports from the server appear in the panel on the page. Select the report you want to work with. To see a report, click Preview Report.
  5. To import the report and create a service, click Next. The SCA Module or Library Name page opens. The Target module or library field is filled with the module name you chose earlier. You can also browse for another module or library name or create a new one. The following options are available:

    • Extract inline elements (interfaces and business objects) lets you separate interfaces and business objects from the WSDL file you are importing, which is useful in Integration Designer to reuse the business objects within your application.
    • Generate Web service for Cognos authentication lets you generate the business objects, interface and web service binding for a Cognos authentication service.

  6. Click Finish and the report is imported into the module, where it can be used as a web service in your application.



Related concepts:

Work with Cognos reports


Related tasks:

Set up the preferences page for Cognos reports


Work with Cognos reports

Developing services that use Cognos reports requires you to use SOAP headers, be aware of security requirements and keep track of the state of the report being retrieved. Cognos reports use the SOAP header to pass state between invocations, such as security between logon and report retrieval, or the state when looping on report retrieval. Cognos reports support single sign-on and logging on providing security credentials. Examples of how to work with Cognos reports are provided below.



Related tasks:

Set up the preferences page for Cognos reports

View and importing a Cognos report as a web service


JAX-WS handler for a SOAP header

When using the JAX-WS a JAX-WS handler is needed to serialize and deserialize SOAP header information.


Create a JAX-WS handler

Use the following Java code to create a JAX-WS handler for working with the SOAP header.

The final method, cleanHeader, also should be added to the end of your business process (see Retrieve a Cognos report to see how it is invoked).

public class CognosSOAPHandler implements SOAPHandler<SOAPMessageContext> {

 private static ThreadLocal<SOAPHeader> soapHeader = new ThreadLocal<SOAPHeader>();

 @Override
 public Set<QName> getHeaders() {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void close(MessageContext context) {
  // TODO Auto-generated method stub

 }

 @Override
 public boolean handleFault(SOAPMessageContext context) {
  // TODO Auto-generated method stub
  return true;
 }

 @Override
 public boolean handleMessage(SOAPMessageContext context) {
  Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
 
 if (outboundProperty.booleanValue()) {
   try {
    SOAPMessage message = context.getMessage();
    SOAPPart soapPart = message.getSOAPPart();
    SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
   if (soapEnvelope.getHeader() == null) {
     soapEnvelope.addHeader();
    }
   
    // set the soap header     SOAPHeader latestSOAPHeader = soapHeader.get();
   if (latestSOAPHeader != null) {
     Iterator iterator = latestSOAPHeader.getChildElements();   
     while(iterator.hasNext()) {
      SOAPHeaderElement soapHeaderElement = (SOAPHeaderElement)iterator.next();
      soapEnvelope.getHeader().addChildElement(soapHeaderElement);
     }
    }
   } catch (Exception e) {
    e.printStackTrace();
   }
  } else {
   try {
   SOAPMessage message = context.getMessage();
   SOAPPart soapPart = message.getSOAPPart();
   SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
   soapHeader.set(soapEnvelope.getHeader());
  
   // clear the default soap header.
   soapEnvelope.getHeader().detachNode();  
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 
  return true;
 }

 public static void cleanHeader() {
  soapHeader.set(null);
 }}


Set a JAX-WS handler

To set the JAX-WS handler for a service, use the Assembly editor.

  1. Select your import, and then in the properties view, select the Binding > JAX-WS Handlers tab.

  2. Add and select your handler from the list and save.



JAX-RPC handler for a SOAP header

When using the JAX-RPC a JAX-RPC handler is needed to serialize and deserialize SOAP header information.


Create a JAX-RPC handler

Use the following Java code to create a JAX-RPC handler for working with the SOAP header.

The final method, cleanHeader, also should be added to the end of your business process (see Retrieve a Cognos report to see how it is invoked).

package com.ibm.wbit.cognos;

import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.rpc.handler.Handler;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;

import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

public class CognosRPCHandler implements Handler {
 private static ThreadLocal<SOAPHeader> soapHeader = new ThreadLocal<SOAPHeader>();

 @Override
 public void destroy() {
  // TODO Auto-generated method stub
  System.out.println("@@@@@ CognosRPCHandler: In destroy. Current thread: " + Thread.currentThread().getId() + " Handler instance: " + this.hashCode());
 }

 @Override
 public QName[] getHeaders() {
  // TODO Auto-generated method stub
  System.out.println("@@@@@ CognosRPCHandler: In getHeaders");
  return null;
 }

 @Override
 public boolean handleFault(MessageContext arg0) {
  // TODO Auto-generated method stub
  System.out.println("@@@@@ CognosRPCHandler: In handleFault");
  return true;
 }

 @Override
 public boolean handleRequest(MessageContext arg0) {
  // TODO Auto-generated method stub
  System.out.println("@@@@@ CognosRPCHandler: In handleRequest. Current thread: " + Thread.currentThread().getId() + " Handler instance: " + this.hashCode());
  SOAPMessageContext context = (SOAPMessageContext)arg0;
 
  try {
   SOAPMessage message = context.getMessage();
   SOAPPart soapPart = message.getSOAPPart();
   SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
  if (soapEnvelope.getHeader() == null) {
    soapEnvelope.addHeader();
   }

   // set the soap header    SOAPHeader latestSOAPHeader = soapHeader.get();
  if (latestSOAPHeader != null) {
    Iterator iterator = latestSOAPHeader.getChildElements();   
    while(iterator.hasNext()) {
     SOAPHeaderElement soapHeaderElement = (SOAPHeaderElement)iterator.next();
     soapEnvelope.getHeader().addChildElement(soapHeaderElement);
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 
  return true;
 }

 @Override
 public boolean handleResponse(MessageContext arg0) {
  // TODO Auto-generated method stub
  System.out.println("@@@@@ CognosRPCHandler: In handleResponse. Current thread: " + Thread.currentThread().getId() + " Handler instance: " + this.hashCode());
  SOAPMessageContext context = (SOAPMessageContext)arg0;
  try {  
   SOAPMessage message = context.getMessage();
   SOAPPart soapPart = message.getSOAPPart();
   SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
   soapHeader.set(soapEnvelope.getHeader());
  
   // clear the default soap header.
   soapEnvelope.getHeader().detachNode();
  } catch (Exception e) {
   e.printStackTrace();
  }
 
  return true;
 }

 @Override
 public void init(HandlerInfo arg0) {
  // TODO Auto-generated method stub
  System.out.println("@@@@@ CognosRPCHandler: In init. Current thread: " + Thread.currentThread().getId() + " Handler instance: " + this.hashCode());
 }

 public static void cleanHeader() {
  soapHeader.set(null);
 }
}


Set a JAX-RPC handler

To set the JAX-RPC handler for a service, use the deployment editor.

  1. Right-click the module in the Business Integration view and select Open deployment editor.
  2. When the deployment editor opens, check the handler is included in the configuration.



JAX-WS single sign-on security handler

A JAX-WS security handler is required when using the Java API for XML Web Services (JAX-WS) with single sign-on security. Single sign-on security is only available if Cognos is running on WebSphere Application Server.


Create a JAX-WS single sign-on handler

Use the following Java code to create a JAX-WS handler for single sign-on security, which includes handling the Lightweight Third-Party Authentication (LTPA) token.

The final method, cleanHeader, also should be added to the end of your business process (see Retrieve a Cognos report to see how it is invoked).

To specify this handler in your application, see Set a JAX-WS handler.

package com.ibm.wbit.cognos;

import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import java.util.Iterator;

import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import com.ibm.ws.security.util.AccessController;
import com.ibm.ws.wssecurity.xss4j.dsig.util.Base64;
import com.ibm.wsspi.security.token.SingleSignonToken;

import javax.security.auth.Subject;
import com.ibm.websphere.security.auth.WSSubject;

public class CognosSOAPHandler implements SOAPHandler<SOAPMessageContext> {

 private static ThreadLocal<SOAPHeader> soapHeader = new ThreadLocal<SOAPHeader>();

 @Override
 public Set<QName> getHeaders() {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void close(MessageContext context) {
  // TODO Auto-generated method stub

 }

 @Override
 public boolean handleFault(SOAPMessageContext context) {
  // TODO Auto-generated method stub
  return true;
 }

 @Override
 public boolean handleMessage(SOAPMessageContext context) {
  Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
 
 if (outboundProperty.booleanValue()) {  
   try {
    // Get the LTPA token     String tokenData = "";
   
    final Subject subject = WSSubject.getRunAsSubject();
    Iterator ssoTokensFromSubject = null;
    ArrayList ssoArrayList = new ArrayList();
             // Get the default sso token             if (subject != null) {
                 Set privateCredentials = null;
                 Set publicCredentials = null;
                 Set newSet = new HashSet();

                    privateCredentials = (Set) AccessController.doPrivileged(new PrivilegedAction() {
                        public Object run() {
                            return subject.getPrivateCredentials(SingleSignonToken.class);
                        }
                    });
                   if (privateCredentials != null && privateCredentials.size() > 0) {
                        newSet.addAll(privateCredentials);
                    }

                    publicCredentials = subject.getPublicCredentials(SingleSignonToken.class);
                   if (publicCredentials != null && publicCredentials.size() > 0) {
                        newSet.addAll(publicCredentials);
                    }

                    ssoTokensFromSubject = newSet.iterator();
             }

            if (ssoTokensFromSubject != null) {
                 while (ssoTokensFromSubject.hasNext()) {
                     SingleSignonToken ssoToken = (SingleSignonToken) ssoTokensFromSubject.next();
                    if (ssoToken != null) {
                         byte[] ssoTokenBytes = ssoToken.getBytes();
                         tokenData = Base64.encode(ssoTokenBytes);
                         break;
                     }
                 }
             }

    // Set the Cookie
    Map<String, List<String>> headers = (Map<String, List<String>>)context.get(MessageContext.HTTP_REQUEST_HEADERS);    
   if(headers == null){
     headers = new HashMap<String, List<String>>();
     context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
    }   
    List<String> cookie = headers.get("Cookie");
   if(cookie == null){
     cookie = new ArrayList<String>();
     headers.put("Cookie", cookie);
    }
    cookie.add("LtpaToken2=" + tokenData);
   
    // Set the soap header     SOAPMessage message = context.getMessage();
    SOAPPart soapPart = message.getSOAPPart();
    SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
   if (soapEnvelope.getHeader() == null) {
     soapEnvelope.addHeader();
    }   
       
    // Set the soap header got from the response     SOAPHeader latestSOAPHeader = soapHeader.get();
   if (latestSOAPHeader != null) {
     Iterator iterator = latestSOAPHeader.getChildElements();   
     while(iterator.hasNext()) {
      SOAPHeaderElement soapHeaderElement = (SOAPHeaderElement)iterator.next();
      soapEnvelope.getHeader().addChildElement(soapHeaderElement);
     }
    }
   } catch (Exception e) {
    e.printStackTrace();
   }
  } else {
   try {
    SOAPMessage message = context.getMessage();
    SOAPPart soapPart = message.getSOAPPart();
    SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
    soapHeader.set(soapEnvelope.getHeader());
   
    // clear the default soap header.
    soapEnvelope.getHeader().detachNode();   
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 
  return true;
 }

 public static void cleanHeader() {
  soapHeader.set(null);
 }}


Configure single sign-on security with Lightweight Third-Party Authentication (LTPA)

A single sign-on configuration is a way of letting users access one or more systems by logging on once. This configuration involves passing a Lightweight Third-Party Authentication (LTPA) token. Single sign-on security is only available if Cognos is running on WebSphere Application Server. This article on enabling single sign-on discusses the configuration setup required.



JAX-RPC single sign-on security handler

A JAX-RPC security handler is required when using the Java API for XML-Based RPC (JAX-RPC) with single sign-on security. Single sign-on security is only available if Cognos is running on WebSphere Application Server.


Create a JAX-RPC single sign-on handler

Use the following Java code to create a JAX-RPC handler for single sign-on security, which includes handling the Lightweight Third-Party Authentication (LTPA) token.

The final method, cleanHeader, also should be added to the end of your business process (see Retrieve a Cognos report to see how it is invoked).

To specify this handler in your application, see Set a JAX-RPC handler.

package com.ibm.wbit.cognos;

import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.rpc.handler.Handler;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;

import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import javax.security.auth.Subject;

import com.ibm.websphere.security.auth.WSSubject;
import com.ibm.ws.security.util.AccessController;
import com.ibm.ws.wssecurity.xss4j.dsig.util.Base64;
import com.ibm.wsspi.security.token.SingleSignonToken;

public class CognosRPCHandler implements Handler {
 private static ThreadLocal<SOAPHeader> soapHeader = new ThreadLocal<SOAPHeader>();

 @Override
 public void destroy() {
  // TODO Auto-generated method stub
 }

 @Override
 public QName[] getHeaders() {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public boolean handleFault(MessageContext arg0) {
  // TODO Auto-generated method stub
  return true;
 }

 @Override
 public boolean handleRequest(MessageContext arg0) {
  // TODO Auto-generated method stub
 
  SOAPMessageContext context = (SOAPMessageContext)arg0;
 
  try {
   // Get the token from the runAs subject
   String tokenData = "";
  
   final Subject subject = WSSubject.getRunAsSubject();
   Iterator ssoTokensFromSubject = null;
   ArrayList ssoArrayList = new ArrayList();
            // Get the default sso token            if (subject != null) {
                Set privateCredentials = null;
                Set publicCredentials = null;
                Set newSet = new HashSet();

                privateCredentials = (Set) AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        return subject.getPrivateCredentials(SingleSignonToken.class);
                    }
                });
               if (privateCredentials != null && privateCredentials.size() > 0) {
                    newSet.addAll(privateCredentials);
                }

                publicCredentials = subject.getPublicCredentials(SingleSignonToken.class);
               if (publicCredentials != null && publicCredentials.size() > 0) {
                    newSet.addAll(publicCredentials);
                }

                ssoTokensFromSubject = newSet.iterator();
            }

           if (ssoTokensFromSubject != null) {
                while (ssoTokensFromSubject.hasNext()) {
                    SingleSignonToken ssoToken = (SingleSignonToken) ssoTokensFromSubject.next();
                   if (ssoToken != null) {
                        byte[] ssoTokenBytes = ssoToken.getBytes();
                        tokenData = Base64.encode(ssoTokenBytes);
                        break;
                    }
                }
            }
  
   // Set the Cookie
   HashMap sendTransportHeaders = new HashMap();
   sendTransportHeaders.put("Cookie","LtpaToken2=" + tokenData);  
   context.setProperty(com.ibm.websphere.webservices.Constants.REQUEST_TRANSPORT_PROPERTIES, sendTransportHeaders);
  
   // Set the soap header    SOAPMessage message = context.getMessage();
   SOAPPart soapPart = message.getSOAPPart();
   SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
  if (soapEnvelope.getHeader() == null) {
    soapEnvelope.addHeader();
   }

   // Set the soap header got from the response    SOAPHeader latestSOAPHeader = soapHeader.get();
  if (latestSOAPHeader != null) {
    Iterator iterator = latestSOAPHeader.getChildElements();   
    while(iterator.hasNext()) {
     SOAPHeaderElement soapHeaderElement = (SOAPHeaderElement)iterator.next();
     soapEnvelope.getHeader().addChildElement(soapHeaderElement);
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 
  return true;
 }

 @Override
 public boolean handleResponse(MessageContext arg0) {
  // TODO Auto-generated method stub 
  SOAPMessageContext context = (SOAPMessageContext)arg0;
 
  try {  
   SOAPMessage message = context.getMessage();
   SOAPPart soapPart = message.getSOAPPart();
   SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
   soapHeader.set(soapEnvelope.getHeader());
  
   // clear the default soap header.
   soapEnvelope.getHeader().detachNode();
  } catch (Exception e) {
   e.printStackTrace();
  }
 
  return true;
 }

 @Override
 public void init(HandlerInfo arg0) {
  // TODO Auto-generated method stub 
 }

 public static void cleanHeader() {
  soapHeader.set(null);
 }
}


Configure single sign-on security with Lightweight Third-Party Authentication (LTPA)

A single sign-on configuration is a way of letting users access one or more systems by logging on once. This configuration involves passing a Lightweight Third-Party Authentication (LTPA) token. Single sign-on security is only available if Cognos is running on WebSphere Application Server. This article on enabling single sign-on discusses the configuration setup required.



Log on properties for a secure server

When authentication is required and single sign-on security cannot be used then use the authentication web service to logon to Cognos providing the appropriate security credentials.

This service is created for you when you select the Generate Web service for Cognos authentication option as shown in View and importing a Cognos report as a web service. The service is shown in the following screen capture as LogonCognos.

Logging on to a secure Cognos server requires using a hash map of values. You would need to set these credentials in our example: namespace, username and password. Your configuration could require other credentials.

You can see the logon properties in a business process by selecting the assign activity containing them and clicking the Details tab in the Properties view.



Log on properties for a server without security

Logging on to a Cognos server without security requires the Uniform Resource Locator (URL) for the Cognos server. No security credentials are needed.

You can see the logon properties in a business process by selecting the assign activity containing them and clicking the Details tab in the Properties view.



Retrieve a Cognos report

Retrieve a Cognos report may require a while loop construct invoking report retrieval, as a connection to the server may time out before the report is sent. An example using a short running business process is provided.

Invoke a get function to retrieve a Cognos report could fail due to a time out condition at run time. Therefore look at the session value, which is enumerated so you can evaluate the valid values, to determine if you should try invoking again in a while loop construct. The session needs to be mapped from the response to the request of the next invocation.

The Java code snippet in the while loop is as follows:

if (GetCognosReportResponse != null) {
 if (GetCognosReportResponse.getDataObject("session") != null) {
  return !GetCognosReportResponse.getDataObject("session").getString("status").equals("complete");
 }}

return true;

Mapping the response to the request is shown in the ResetSession assign activity as follows:

Add the cleanHeader method at the end of your process, as discussed earlier in the sections on the handlers, as it frees up thread storage and allows a thread to be reused. Select a Java snippet activity from the palette and add it to the end of the business process. Select the Properties view for the Java snippet and then the Details tab. Add the code to the pane provided.



+

Search Tips   |   Advanced Search