28 Using RIDC to Access Content Server

This chapter describes how to initialize and use Remote Intradoc Client (RIDC), which provides a thin communication API for communication with Oracle WebCenter Content Server.

The Remote Intradoc Client (RIDC) can be downloaded from the Oracle Technology Network (OTN) at http://www.oracle.com/technetwork/index.html.

Note:

This chapter includes the following sections:

28.1 About Remote Intradoc Client

Remote Intradoc Client (RIDC) is a thin communication API for talking to Content Server. It's main functionality is to provide the ability to remotely execute Content Server services. In addition, RIDC handles things like connection pooling, security, and protocol specifics.

Key Features

Remote Intradoc Client (RIDC) has these features:

  • Supports Intradoc socket-based communication and the HTTP and JAX-WS protocols.
  • Supports Secure Socket Layer (SSL) communication with Content Server.
  • Provides client configuration including setting the socket time outs, connection pool size, and so on.
  • RIDC objects follow the standard Java Collection paradigms.

28.1.1 Supported Protocols

Remote Intradoc Client (RIDC) 12c (12.2.1.3.0) supports the idc, idcs, http, https, and jax-ws protocols.

Intradoc: The Intradoc protocol communicates to the Content Server over the over the Intradoc socket port (typically 4444). This protocol requires a trusted connection between the client and Content Server and will not perform any password validation. Clients that use this protocol are expected to perform any required authentication themselves before making RIDC calls. The Intradoc communication can also be configured to run over SSL.

HTTP: RIDC can create an HTTP connection to Content Server using one of three supported HTTP client packages:

  • Oracle HTTPClient

  • JDK HttpURLConnection

Unlike Intradoc, this protocol requires valid user name and password authentication credentials for each request.

For details, see HttpClient Libraries.

JAX-WS: The JAX-WS protocol is supported only in Oracle WebCenter Content 12c with a properly configured Content Server instance and the RIDC client installed. JAX-WS is not supported outside this environment.

For more information about JAX-WS, see Introduction to JAX-WS Web Services in Developing JAX-WS Web Services for Oracle WebLogic Server and Using the JAX-WS Reference Implementation in Oracle Fusion Middleware Programming Advanced Features of JAX-WS Web Services for Oracle WebLogic Server. Also see the Java API for XML Web Services (JAX-WS) documentation on the Java Community Process website at http://www.jcp.org/.

28.1.2 Supported URL Formats

The following table shows the URL formats that are supported.

URL Description

idc://localhost:4444

Uses the Intradoc port; requires only the hostname and the port number.

idcs://localhost:4443

Uses SSL over the Intradoc port; requires extra configuration to load the SSL certificates.

http://localhost:16200/cs/idcplg

Specifies the URL to the Content Server CGI path.

https://localhost:16200/cs/idcplg

Uses SSL over HTTP; requires extra configuration to load the SSL certificates.

http://wlsserver:16200/idcnativews

Uses the JAX-WS protocol to connect to the Content Server.

28.1.3 Required Environments

The following table summarizes the environment RIDC needs to support each connection type.

URL Description

idc://

  • oracle.ucm.ridc.jar

idcs:/

  • oracle.ucm.ridc.jar

  • SSL certificate configuration

http:/

  • oracle.ucm.ridc.jar

  • HttpClient libraries

https:/

  • oracle.ucm.ridc.jar

  • HttpClient libraries

  • SSL certificate configuration

jax-ws

  • Oracle shiphome having WLS and JRF stacks

28.1.4 HttpClient Libraries

RIDC requires supporting HTTP client libraries to communicate with the web server attached to the Content Server instance using an HTTP connection. Currently two libraries are supported:

  • Oracle HTTPClient

  • JDK HttpURLConnection

JDK HttpURLConnection is the default.

Note:

By default, RIDC leverages JVM's internal HTTP Client Library, java.net.HttpURLConnection for HTTP/HTTPS protocol connections. JVM's HTTP client is known as httpurlconnection client library within RIDC. If you are using the RIDC httpurlconnection client implementation within your application, be aware that any auxiliary application code or libraries in classpath that modifies or overrides static java.net configuration may impact RIDC behavior. For example, if the auxiliary code sets a static custom cookie handler by using the java.net.CookieHandler setDefault() method, the custom cookie handler may incorrectly submit cookies in to RIDC HTTP/HTTPS URL connection requests, and this may be invisible to the RIDC cookie management framework. In other words, cookies from the global cookie store may inadvertently be submitted to UCM back-end.

To request the Oracle HttpClient in Java code:

IdcClient idcClient = manager.createClient("http://localhost/cs/idcplg");
idcClient.getConfig ().setProperty ("http.library", "oracle");

If you are creating a new RIDC application using the JDeveloper extension, you can add to your connection, in the Configuration Parameters section, the parameter http.library with an appropriate value, such as oracle.

If you are in a Site Studio for External Applications (SSXA) application in JDeveloper, because there is no user interface, you need to create your connection and save it without testing the connection first. Then open the connections.xml file in the Connections > Descriptors > ADF META-INF node. Add the StringRefAddr section to the connections.xml file, and save the file.

Connection Example in connections.xml
<Reference name="sample"
 className="oracle.stellent.ridc.convenience.adf.mbeans.IdcConnection" xmlns="">
  <Factory className=
  "oracle.stellent.ridc.convenience.adf.mbeans.IdcConnectionFactory"/>
  <RefAddresses>
    <StringRefAddr addrType="oracle.stellent.idc.connectionUrl">
       <Contents>idc://<IPv6 Hostname>:4444</Contents>
    </StringRefAddr>
    <StringRefAddr addrType="oracle.stellent.idc.idcServerURL">
       <Contents>http://localhost/cs/idcplg</Contents>
    </StringRefAddr>

    <StringRefAddr addrType="oracle.stellent.idc.http.library">
        <Contents>oracle</Contents>
    </StringRefAddr>

  </RefAddresses>
</Reference>

Note that the connection types for SSXA and RIDC are similar:

  • When you are using SSXA connections in JDeveloper, the addrType value in the connections.xml file is oracle.stellent.idc.http.library.

  • When you are using RIDC connections in JDeveloper the addrType value in the connections.xml file is oracle.stellent.ridc.http.library.

28.1.5 Convenience Classes

There are some patterns of actions that many applications perform using RIDC. The convenience package supplies some of these for reuse. The classes in the convenience package space are consumers of the RIDC code and as such don't add any new functionality. They can be thought of as a new layer on top of RIDC.

For information about using convenience classes, see Setting User Security.

28.2 Initializing Connections

This section provides sample code to initialize an Intradoc connection, an HTTP connection, and code that initializes a JAX-WS client.

The code initializes an Intradoc connection.

Intradoc Connection Initialization
// create the manager
IdcClientManager manager = new IdcClientManager();

// build a client that will communicate using the intradoc protocol
IdcClient idcClient = manager.createClient("idc://localhost:4444");

The code initializes an HTTP connection. The only difference from an Intradoc connection is the URL.

HTTP Connection Initialization
// create the manager
IdcClientManager manager = new IdcClientManager();

// build a client that will communicate using the HTTP protocol
IdcClient idcClient = manager.createClient("http://localhost:16200/cs/idcplg");

The code initializes a JAX-WS client. The URL includes the idcnativews web context root. This web context root (by default) is used by two web services exposed by Content Server: the login service and the request service.

JAX-WS Client Initialization
// create the manager
IdcClientManager manager = new IdcClientManager();

// build a client that will communicate using the JAXWS protocol
IdcClient idcClient = manager.createClient
      ("http://wlsserver:16200/idcnativews");

28.3 Configuring Clients

Configuration of the clients can be done after they are created. Configuration parameters include setting the socket timeouts, connection pool size, and so on. The configuration is specific to the protocol; if you cast the IdcClient object to the specific type, then you can retrieve the protocol configuration object for that type.

28.3.1 Configuring Clients for Intradoc Connections

The code sets the socket time-out and wait time for Intradoc connections.

Client Configuration for Intradoc Connections

// build a client as cast to specific type
IntradocClient idcClient =
  (IntradocClient)manager.createClient("http://localhost/cs/idcplg");

// get the config object and set properties
idcClient.getConfig().setSocketTimeout(30000);  // 30 seconds
idcClient.getConfig().setConnectionSize(20);    // 20 connections

28.3.2 Configuring SSL

Remote Intradoc Client (RIDC) allows Secure Socket Layer (SSL) communication with Content Server using the Intradoc communication protocol. The typical port used is 4444. For more information about configuring SSL and enabling ports, see Configuring Oracle WebCenter Content to Use SSL in Oracle Fusion Middleware Administering Oracle WebCenter Content.

For SSL communication, you must install and enable the SecurityProviders component in the Content Server instance that you want to access. You must configure Content Server for SSL communication with a new incoming provider, and specify the truststore or keystore information. You must have a valid keystore or trust manager with signed, trusted certificates on both the client and Content Server.

Oracle does not provide signed certificates. For most implementations, you will want a certificate signed by a universally recognized Certificate Authority.

To configure SSL communication with Content Server, perform the following tasks:

28.3.2.1 Installing and Enabling SecurityProviders Component
The SecurityProviders component is installed and enabled by default in the Content Server.
28.3.2.2 Creating Self-Signed Key Pairs and Certificates

For most implementations, you need a certificate signed by a universally recognized Certificate Authority. However, if you control both the client and server and only need to ensure that your transmissions are not intercepted, or if you are simply testing your implementation, you can create your own self-signed key pairs and certificates by using the JDK utility called keytool. Key and Certificate Management Tool (keytool) is a key and certificate management utility that enables users to administer their own public and private key pairs and associated certificates for use in self-authentication. It is provided as part of the Sun JDK. Keytool is a command-line utility. The executable is located in the bin subdirectory.

28.3.2.2.1 Creating Client and Server Keys

From a command-line prompt, navigate to the JDK-Home/bin subdirectory, and issue the -genkey command. This command generates a new key and takes several arguments. The arguments in the following table are used with this command.

Argument Description
-alias Alias of the key being created. Enables a keystore understand which element in the file you are referring to when you perform operations on it.
-keyalg Encryption algorithm to use for the key.
-keystore Name of the binary output file for the keystore.
-dname Distinguished name that identifies the key
-keypass Password for the key that is being generated.
-storepass Password used to control access to the keystore.

Generate a separate key pair for both the client and the server. To do this, run the -genkey command twice, each time placing the key pair into a separate keystore. Specify the alias, the algorithm to use, the keystore name, the distinguished name, and passwords for the keys and the keystore. .

This example uses RSA as the algorithm and idcidc as the password for the key and the keystore. Use these argument values for the client:

  • -alias SecureClient
  • -keyalg RSA
  • -keystore client_keystore
  • -dname "cn=SecureClient"
  • -keypass idcidc
  • -storepass idcidc
# keytool -genkey -alias SecureClient -keyalg RSA -keystore client_keystore -dname "cn=SecureClient" -keypass idcidc -storepass idcidc

Use these argument values for the server:

  • -alias SecureServer
  • -keyalg RSA
  • -keystore server_keystore
  • -dname "cn=SecureServer"
  • -keypass idcidc
  • -storepass idcidc
# keytool -genkey -alias SecureClient -keyalg RSA -keystore client_keystore -dname "cn=SecureClient" -keypass idcidc -storepass idcidc
# keytool -genkey -alias SecureServer -keyalg RSA -keystore server_keystore -dname "cn=SecureServer" -keypass idcidc -storepass idcidc
# keytool -importcert -file $WL_HOME/server/lib/CertGenCA.der -keystore server_truststore.jks
      -storepass idcidc –noprompt

Note:

Each of these commands will generate a key pair wrapped in a self-signed certificate and stored in a single-element certificate chain.
28.3.2.2.2 Self-Signing Certificates

Keys are unusable unless they are signed. The keytool utility will self-sign them for you so that you can use the certificates for internal testing. However, these keys are not signed for general use.

From a command line prompt, issue the -selfcert command (this command self-signs your certificates and takes several arguments). Run the -selfcert command twice, once for the client and again for the server.

Use these argument values for the client:

  • -alias SecureClient
  • -keystore client_keystore
  • -keypass idcidc
  • -storepass idcidc

Use these argument values for the server:

  • -alias SecureServer
  • -keystore server_keystore
  • -keypass idcidc
  • -storepass idcid

Examples of -selfcert commands follow:

# keytool -selfcert -alias SecureClient -keystore client_keystore -keypass idcidc -storepass idcidc
# keytool -selfcert -alias SecureServer -keystore server_keystore -keypass idcidc -storepass idcidc 

The certificate is now signed by its private and public key resulting in a single-element certificate chain. This replaces the one that you generated previously.

28.3.2.2.3 Exporting Certificates

After you have created the client and server keys and self-signed the certificates, you now have two key pairs, public and private keys in two certificates locked in two keystores. Since each application needs a public key of the other to encrypt and decrypt data, you must place a copy of each public key in the other application's keystore.

From a command-line prompt, issue the -export command. This command exports your certificates and takes several arguments. Run the -export command twice, once for the client and again for the server. Use the -file argument to redirect the output to a file instead of the console.

Use these argument values for the client:
  • -alias SecureClient
  • -file client_cert
  • -keystore client_keystore
  • -storepass idcidc

Use these argument values for the server:

  • -alias SecureServer
  • -file server_cert
  • -keystore server_keystore
  • -storepass idcidc
Examples of -export commands follow:
  • Certificate stored in the file client_cert
# keytool -export -alias SecureClient -file client_cert -keystore client_keystore -storepass idcidc
  • Certificate stored in the file server_cert
# keytool -export -alias SecureServer -file server_cert -keystore server_keystore -storepass idcidc

The certificate containing the public key and signer information is now exported to a binary certificate file.

28.3.2.2.4 Importing Certificates

The last step in setting up your self-signed certificates is to import the public certificates of each program into the keystore of the other. Keytool presents you with the details of the certificates you are requesting to be imported and provides a request confirmation.

From a command line prompt, issue the -import command. This command imports your certificates and takes several arguments. Run the -import command twice, once for the client and again for the server. Notice that the -keystore values are reversed.

Use these argument values for the client:

  • -alias SecureClient
  • -file client_cert
  • -keystore server_keystore
  • -storepass idcidc

Use these argument values for the server:

  • -alias SecureServer
  • -file server_cert
  • -keystore client_keystore
  • -storepass idcidc

Examples of -import commands follow:

# keytool -import -alias SecureClient -file client_cert -keystore server_keystore -storepass idcidc

Owner: CN=SecureClient Issuer: 
CN=SecureClient 
Serial number: 3c42e605 
Valid from: Mon Jan 14 08:07:01 CST 2002 until: Sun Apr 14 09:07:01 CDT 2002 
Certificate fingerprints:
 MD5: 17:51:83:84:36:D2:23:A2:8D:91:B7:14:84:93:3C:FF 
 SHA1: 61:8F:00:E6:E7:4B:64:53:B4:6B:95:F3:B7:DF:56:D3:4A:09:A8:FF 
Trust this certificate? [no]: y 
Certificate is added to keystore
 
# keytool -import -alias SecureServer -file server_cert -keystore client_keystore -storepass idcidc

Owner: CN=SecureServer 
Issuer: CN=SecureServer
 Serial number: 3c42e61e
Valid from: Mon Jan 14 08:07:26 CST 2002 until: Sun Apr 14 09:07:26 CDT 2002 
Certificate fingerprints: 
 MD5: 43:2F:7D:B6:A7:D3:AE:A7:2E:21:7C:C4:52:49:42:B1 
 SHA1: ED:B3:BB:62:2E:4F:D3:78:B9:62:3B:52:08:15:8E:B3:5A:31:23:6C 
Trust this certificate? [no]: y 
Certificate is added to keystore

The certificates of each program are now imported into the keystore of the other.

28.3.2.3 Configuring an Incoming Provider for SSL Communication

You can set up a new keepalive incoming socket provider or a new SSL incoming socket provider. Using keepalive improves the performance of a session and is recommended for most implementations.

To set up a new incoming socket provider, perform the following steps:
  1. Log in to Oracle Content Server as an administrator.
  2. Click Administration and then Providers.
  3. Click Add corresponding to sslincoming provider.
    The Add Incoming Provider page is displayed.
  4. Enter a provider name and description.
  5. Enter an open server port.
  6. Enter the following configuration information:
    To configure SSL keepalive incoming socket provider, enter the following values:
    • Provider Class: idc.provider.ssl.SSLSocketIncomingProvider
    • Connection Class: idc.provider.KeepaliveSocketIncomingConnection
    • Server Thread Class: idc.server.KeepaliveIdcServerThread

    Note:

    Using keepalive improves the performance of a session and is recommended for most implementations.
    To configure SSL incoming socket provider, enter the following values:
    • Provider Class: idc.provider.ssl.SSLSocketIncomingProvider
    • Connection Class: intradoc.provider.SocketIncomingConnection
    • Server Thread Class: intradoc.server.IdcServerThread
  7. Select the Request Client Authentication check box.
  8. Enter the location where the keystore file is stored. For example, D:\OraclePS4\Middleware\Oracle_Home\user_projects\domains\base_domainNew\ucm\cs\data\providers\sslincomingcs\server_keystore.jks.
  9. Enter the password to access the keystore file.
  10. Enter the keystore alias name.
  11. Enter the keystore alias password.
  12. Enter the location where the truststore file is stored. For example, D:\OraclePS4\Middleware\Oracle_Home\user_projects\domains\base_domainNew\ucm\cs\data\providers\sslincomingcs\server_truststore.jks.
  13. Enter the password to access the truststore file.
  14. Click Add.
  15. Restart the server.
28.3.2.3.1 Sample Code for Verifying SSL Incoming Provider

Since RIDC code is the client, you can specify the client keystore and truststore details:

Use the following sample code to test the SSL incoming provider:

Note:

Use the same port number that you specified while creating the SSL incoming provider.
public static void main(String[] args)
    throws IdcClientException, FileNotFoundException, IOException
  {
	   
	  //ssl provider test
	  
	  IdcClientManager manager = new IdcClientManager();
	  IdcClient idcClient = manager.createClient("idcs://localhost:6666");
IdcContext userContext = new IdcContext("weblogic");
	  IntradocClientConfig config = (IntradocClientConfig)idcClient.getConfig();
	  config.setKeystoreFile("D:/OraclePS4/Middleware/Oracle_Home/user_projects/domains/base_domainNew/ucm/cs/data/providers/sslincomingcs/client_keystore.jks");
	  config.setKeystorePassword("welcome1");
	  config.setKeystoreAliasPassword("SecureClient");
	  config.setKeystoreAliasPassword("welcome1");
	  idcClient.initialize();
	  DataBinder dataBinder = idcClient.createBinder();
	  dataBinder.putLocal("IdcService", "PING_SERVER");
	  ServiceResponse response = idcClient.sendRequest(userContext, dataBinder);
	  DataBinder responseData = response.getResponseAsBinder();
	  System.out.println(responseData.getLocal("StatusMessage"));
	  
  }
}
28.3.2.4 Configuring an Outgoing Provider for SSL Communication
To set up a new outgoing socket provider, perform the following steps:
  1. Log in to Oracle Content Server as an administrator.
  2. Click Administration and then Providers.
  3. Click Add corresponding to ssloutgoing provider.
    The Edit Outgoing Socket Provider page is displayed.
  4. Enter a provider name and description.
  5. Enter an open server port.
  6. Enter the following configuration information:
    To configure SSL outgoing socket provider, enter the following values:
    • Provider Class: idc.provider.KeepaliveSocketOutgoingProvider
    • Connection Class: idc.provider.ssl.SSLSocketOutgoingConnection
    • Request Class: idc.provider.KeepaliveServerRequest
    • Number of Connections: 3
  7. Enter the following server and port information:
    • Server Host Name: localhost

      Note:

      This is the hostbox name used to set the SSL incoming provider.
    • Server Port: 6666

      Note:

      This is the same port number that is specified when creating the SSL incoming provider.
    • Instance Name: localhost6666

      Note:

      This is the instance where the SSL incoming provider is set up.
    • Relative Web Root: /ibr

      Note:

      This is the root of the server where the SSL incoming provider is set up.
  8. Enter the location where the keystore file is stored. For example, D:\OraclePS4\Middleware\Oracle_Home\user_projects\domains\base_domainNew\ucm\cs\data\providers\ssloutgoingcs\client_keystore.jks..
  9. Enter the password to access the keystore file.
  10. Enter the keystore alias name.
  11. Enter the keystore alias password.
  12. Enter the location where the truststore file is stored. For example,D:\OraclePS4\Middleware\Oracle_Home\user_projects\domains\base_domainNew\ucm\cs\data\providers\ssloutgoingcs\client_truststore.jks..
  13. Enter the password to access the truststore file.
  14. Select the Handles Inbound Refinery Conversion Jobs check box.
  15. Click Add.
28.3.2.4.1 Verifying SSL Outgoing Provider
Perform the following steps to test your SSL outgoing provider configuration:
  1. Log in to Oracle WebCenter Content: Inbound Refinery as an administrator and create SSL incoming provider on IBR.
  2. Ensure that IBR components are enabled on the Content Server as well as IBR.
  3. Log in to Oracle Content Server as an administrator.
  4. Click Administration, Admin Server, and then General Configuration
  5. Enter the IP address in Server IP Filter and click Save.
  6. Click Administration, Refinery Administration, and then File Formats Wizard.
  7. Select all the file types and click Update.
  8. Restart the Content Server and IBR.
    After you perform the preceding steps, the conversion of documents checked in to the Content Server will happen as expected.

28.3.3 Configuring JAX-WS

To make a JAX-WS connection, the RIDC client and Content Server must be configured with compatible client and service web service policies, respectively.

For the RIDC client, you can either set an explicit client policy (LPA mode) using jaxwsConfig.setClientSecurityPolicy(...) or inherit a GPA client policy, provided the application consuming RIDC is deployed to an Oracle WebLogic Server domain with a GPA policy for ws-client correctly configured and targeted.

A service policy can be directly attached to the Oracle WebCenter Content web services (IdcWebLoginPort) end-point (LPA mode), or a GPA ws-service policy can be configured for the domain and inherited by the service.

28.3.3.1 Setting LPA Mode for a Service

You can set LPA mode for a service with Oracle Enterprise Manager Fusion Middleware Control.

To set LPA mode for a service with Fusion Middleware Control:

  1. Log in to Oracle Enterprise Manager 12c Fusion Middleware Control.
  2. In the navigation tree on the left, expand Application Deployments, and click Oracle UCM Native Web Services.
  3. From the Application Deployment drop-down menu on the Oracle UCM Native Web Service page, choose Web Services.
  4. Under Web Service Details on the Web Services (Oracle Infrastructure Web Services) page, click the Web Service Endpoints tab.
  5. Click IdcWebLoginPort in the Endpoint Name column.
  6. On the IdcWebLoginPort (Web Service Endpoint) page, click the OWSM Policies tab.
  7. Under Directly Attached Policies , click Attach/Detach, and choose an appropriate available policy; for example, oracle/wss_saml_or_username_token_service_policy.
28.3.3.2 Setting a GPA Service Policy for a Domain

You can configure inheritance of a GPA policy with WebLogic Scripting Tool (WLST) commands.

To set a GPA ws-service policy for a domain with WLST:

  1. Initialize the WebLogic Scripting Tool (WLST), using the WebLogic Server Administration Scripting Shell:

    (/u01/app/oracle/product/Middleware/oracle_common/common/bin)% ./wlst.sh
     
    ...
     
    Initializing WebLogic Scripting Tool (WLST) ...
     
    Welcome to WebLogic Server Administration Scripting Shell
     
    Type help() for help on available commands
     
  2. Invoke a sequence of commands similar to the following ones, which are for a domain named base_domain:

    $MW_HOME/Oracle_ECM1/common/bin/wlst.sh
    connect(username='weblogic',password='password',url='t3://localhost:7001')
    beginRepositorySession()
    createPolicySet('base_domain-ws-service','ws-service','Domain("base_domain")')
    attachPolicySetPolicy('oracle/wss_saml_or_username_token_service_policy')
    validatePolicySet()
    commitRepositorySession()
    listPolicySets()
    exit()
    
  3. Verify that the GPA service policy has been set:

    1. Wait a few minutes for the GPA service policy to be picked up by IdcWebLoginPort.

    2. Inspect the WSDL and look for wsp:PolicyReference to see if changes have been applied:

      http://server:16200/idcnativews/IdcWebLoginPort?WSDL
      

For more information about setting a GPA web service client policy, see Setting a GPA Service Policy for a Domain and Add GPA for the Web Service Client.

28.3.3.3 Setting a GPA Client Policy for a Domain

To determine GPA policy for a ws-client that will be leveraged by RIDC over JAX-WS should no explicit LPA be set, initialize the WebLogic Scripting Tool (WLST) and use the WebLogic Server Administration Scripting Shell.

The following code provides an example.

Example 28-1 Determining GPA Policy with the WebLogic Scripting Tool

(/u01/app/oracle/product/Middleware/oracle_common/common/bin)% ./wlst.sh
 
...
 
Initializing WebLogic Scripting Tool (WLST) ...
 
Welcome to WebLogic Server Administration Scripting Shell
 
Type help() for help on available commands
 
wls:/offline> connect('weblogic','password','t3://localhost:7001')
Connecting to t3://localhost:7001 with userid weblogic ...
Successfully connected to Admin Server 'AdminServer' that belongs to domain 'base_domain'.
 
wls:/base_domain/serverConfig> help('wsmManage')
 
Operations that provide support to manage the global policy attachments and
Oracle MDS repository.
 
  help('abortRepositorySession')
    Abort the current repository session, 
    discarding the changes made to repository.
  help('attachPolicySet') 
    Attach a policy set to the specified resource scope.
  help('attachPolicySetPolicy')
    Attach a policy to a policy set using the policy's URI.
  help('beginRepositorySession')
    Begin a session to modify the repository.
  help('clonePolicySet')
    Clone a new policy set from an existing policy set.
  help('commitRepositorySession')
    Write the contents of the current session to the repository.
  help('createPolicySet')
    Create a new, empty policy set.
  help('deletePolicySet')
    Delete a specified policy set.
  help('describeRepositorySession')
    Describe the contents of the current repository session.
  help('detachPolicySetPolicy')
    Detach a policy from a policy set using the policy's URI.
  help('displayPolicySet')
    Display the configuration of a specified policy set.
  help('enablePolicySet')
    Enable or disable a policy set.
  help('enablePolicySetPolicy')
    Enable or disable a policy attachment 
    for a policy set using the policy's URI.
  help('exportRepository')
    Export a set of documents from the repository into a supported ZIP archive.
  help('importRepository')
    Import a set of documents from a supported ZIP archive into the repository.
  help('listPolicySets')
    Lists the policy sets in the repository.
  help('migrateAttachments')
    Migrates direct policy attachments to global policy attachments 
    if they are identical.
  help('modifyPolicySet')
    Specify an existing policy set for modification in the current session.
  help('resetWSMPolicyRepository')
    Clean the Oracle MDS repository and re-seed with the current set
    of WSM policies.
  help('setPolicySetDescription')
    Specify a description for the policy set selected within a session.
  help('upgradeWSMPolicyRepository')
    Add newly introduced WSM policies to the Oracle MDS repository.
  help('validatePolicySet')
    Validate an existing policy set in the repository or in a session.
 
wls:/base_domain/serverConfig> listPolicySets()
Location changed to domainRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help(domainRuntime)
 
Global Policy Sets in Repository:
  base-domain-ws-client 
 
wls:/base_domain/serverConfig> displayPolicySet('base-domain-ws-client')
 
Policy Set Details:
-------------------
Name: base-domain-ws-client
Type of Resources: Web Service Client
Scope of Resources: Domain("base_domain")
Description: Global policy attachments for Web Service Client resources.
Enabled: true
Policy Reference: security : oracle/wss10_saml_token_client_policy, enabled=true

28.3.4 Add GPA for the Web Service Client

The following code sets the ws-client GPA policy:

Example 28-2 Add GPA for the Web Service Client

# add GPA for the web service client assuming domain name is base_domain
beginRepositorySession()
createPolicySet('base_domain-ws-client','ws-client','Domain("base_domain")')

# assuming service policy is hardcoded to
# oracle/wss11_saml_token_with_message_protection_service_policy
# and that we want the RIDC client to leverage client policy:
# oracle/wss11_saml_token_with_message_protection_client_policy
attachPolicySetPolicy
  ('oracle/wss11_saml_token_with_message_protection_client_policy')
validatePolicySet()
commitRepositorySession()

# confirm policy set created
listPolicySets()
# add GPA for the web service client assuming domain name is base_domain
beginRepositorySession()
createPolicySet('base_domain-ws-client','ws-client','Domain("base_domain")')

# assuming service policy is hardcoded to
# oracle/wss11_saml_token_with_message_protection_service_policy
# and that we want the RIDC client to leverage client policy:
# oracle/wss11_saml_token_with_message_protection_client_policy
attachPolicySetPolicy
  ('oracle/wss11_saml_token_with_message_protection_client_policy')
validatePolicySet()
commitRepositorySession()

# confirm policy set created
listPolicySets()

28.3.5 Changing Default Settings

There are several JAX-WS specific configurations that can be done after you have created the client. However, in most cases, you should use the default settings.

This code builds a client as a cast for a JAX-WS type:

JaxWSClient jaxwsClient = (JaxWSClient) manager.createClient
      ("http://wlsserver:7044/idcnativews");
JaxWSClientConfig jaxwsConfig = jaxwsClient.getConfig();

You can set the instance name of the Content Server that you would like to connect to. This is set by default to /cs/, which is the default web context for the Content Server installation. If the server web context is different than the default, then you can set it as follows:

// set the property
jaxwsConfig.setServerInstanceName("/mywebcontext/");

Setting the JPS configuration file location. A JPS configuration file is required for most policies such as SAML and/or Message Token.

jaxwsConfig.setJpsConfigFile("/my/path/to/the/jps-config.xml");

Setting the security policy:

jaxwsConfig.setClientSecurityPolicy("policy:oracle/wss11_username_token_with_message_protection_client_policy");

Changing the Login Port WSDL URL

RIDC uses the default values for the installed web services. If, for some reason, the web services have been modified and do not conform to the default URI or URLs, you may need to modify the default values.

Changing the login port WSDL URL:

jaxwsConfig.setLoginServiceWSDLUrl
  (new URL("http://server:7044/webservices/loginPort?WSDL"));

Change the request service URL:

jaxwsConfig.setRequestServiceWSDLUrl
  (new URL("http://server:7044/anotherservice/myrequestport?WSDL"));

The default streaming chunk size is 8192. This example changes the chunk size:

jaxwsConfig.setStreamingChunkSize(8190);

28.4 Authenticating Users

All calls to Remote Intradoc Client (RIDC) require some user identity for authentication. Optionally, this identity credential can be accompanied by other parameters such as a password as required by the protocol. The user identity is held in the IdcContext object; once created, it can be reused for all subsequent calls. To create a context, you pass in the user name and, optionally, some credentials.

Create a simple context with no password (for idc:// URLs):

IdcContext userContext = new IdcContext("weblogic");

Create a context with a password:

IdcContext userPasswordContext = new IdcContext("weblogic", "password");

For Intradoc URLs, no password is required in the credentials because the request is trusted between Content Server and the client.

For JAX-WS URLs, the requirement for credentials will be dependent on the service policy that the web service is configured to use by the server.

28.5 Using Services

To invoke a service use the IdcClient class method:

public ServiceResponse sendRequest (IdcContext userContext, DataBinder dataBinder) throws IdcClientException

The following code executes a service request and gets back a data binder of the results.

Executing a Service Request
// get the binder
DataBinder binder = idcClient.createBinder();

// populate the binder with the parameters
binder.putLocal ("IdcService", "GET_SEARCH_RESULTS");
binder.putLocal ("QueryText", "");
binder.putLocal ("ResultCount", "20");

// execute the request
ServiceResponse response = idcClient.sendRequest (userContext, binder);

The ServiceResponse object contains the response from Content Server. From the response, you can access the stream from Content Server directly, or you can parse it into a DataBinder and query the results.

The following code takes the ServiceResponse object and gets the search results, printing out the title and author value.

Get the Binder and Loop Over the Results
// get the binder
DataBinder binder = response.getResponseAsBinder ();
DataResultSet resultSet = binder.getResultSet ("SearchResults");

// loop over the results
for (DataObject dataObject : resultSet.getRows ()) {
    System.out.println ("Title is: " + dataObject.get ("dDocTitle"));
    System.out.println ("Author is: " + dataObject.get ("dDocAuthor"));
}

If you consume a stream, your code is responsible for closing the stream. The following code closes a stream.

Closing a Stream
IdcContext user = new IdcContext ("weblogic", "password");
IdcClientManager manager = new IdcClientManager ();
IdcClient idcClient = manager.getClient ("some url");
DataBinder binder = idcClient.createBinder ();
binder.putLocal ("IdcService", "GET_FILE");
binder.putLocal ("dID", "12345");
ServiceResponse response = idcClient.sendRequest (user, binder);

InputStream stream = null;
try {
  stream = response.getResponseStream ();
  int read = 0;
  int total = 0;
  byte[] buf = new byte[256];
  while ((read = stream.read (buf)) != -1) {
  total += read;
  }
} finally {
  if (stream != null) {
  stream.close ();
  }
}

For information about connection pooling and closing through the stream, see Handling Connection Pooling

28.6 Handling Connection Pooling

The IdcClientConfig#getConnectionPool property determines how RIDC will handle pooling of connections. There are two options, simple and pool.

  • The simple option is the default. The simple option does not enforce a connection maximum and rather lets every connection proceed without blocking and does not enforce a connection maximum. In most cases this option should be used.

  • The pool option specifies the use of an internal pool that allows a configurable number of active connections at a time (configurable through the IdcClientConfig#getConnectionSize property), with the default active size set to 20.

Usually, when the RIDC library is used to communicate from an application that itself is in an application container (such as a web application), the inbound requests have already been throttled. Thus, the simple option is the correct choice to use. The only scenario to use the pool option is if you are creating a standalone server and you are manufacturing a large number of concurrent calls to Content Server, which may cause Content Server to become overwhelmed.

A different pool implementation can be registered through the IdcClientManager#getConnectionPoolManager()#registerPool() method, which maps a name to an implementation of the ConnectionPool interface. The name can then be used in the IdcClientConfig object to select that pool for a particular client.

28.7 Sending and Receiving Streams

Streams are sent to the Content Server through the TransferFile class. This class wraps the actual stream with metadata about the stream (length, name, and so on). For information about methods that allow check-ins of files and streams, see the Oracle Fusion Middleware Java API Reference for Oracle WebCenter Content Remote Intradoc Client (RIDC).

The following code performs a check-in to the Content Server:

Content Server Check-In
// create request
DataBinder binder = idcClient.createBinder();
binder.putLocal ("IdcService", "CHECKIN_UNIVERSAL");

// get the binder
binder.putLocal ("dDocTitle", "Test File");
binder.putLocal ("dDocName", "test-checkin-6");
binder.putLocal ("dDocType", "ADACCT");
binder.putLocal ("dSecurityGroup", "Public");

// add a file
binder.addFile ("primaryFile", new TransferFile ("test.doc"));

// check in the file
idcClient.sendRequest (userContext, binder);

Response from Content Server

Streams are received from the Content Server through the ServiceResponse object. For a summary of available methods, see Oracle Fusion Middleware Java API Reference for Oracle WebCenter Content Remote Intradoc Client (RIDC).

The response is not converted into a DataBinder unless specifically requested. If you just want the raw HDA data, you can get that directly, along with converting the response to a String or DataBinder.

The code executes a service, gets the response as a string, and parses it into a data binder.

Parsing a String into a DataBinder
// create request
DataBinder binder = idcClient.createBinder ();

// execute the service
ServiceResponse response = idcClient.sendRequest (userContext, binder);

// get the response stream
InputStream stream = response.getResponseStream ();

// get the response as a string
String responseString = response.getResponseAsString ();

// parse into data binder
DataBinder dataBinder = response.getResponseAsBinder ();

Most Content Server service requests return a structured HDA payload that is modeled on the client using a DataBinder. The HDA payload is essentially a map-like structure optionally containing some ResultSets, which resemble tables.

Download-style service requests (such as GET_FILE) generally are expected to return the requested document's contents as a raw stream of bytes. However, if the parameters supplied to a GET_FILE request are invalid, or if the end user does not have sufficient privileges, and so on, Content Server can respond with an HDA payload containing the error information. Therefore, when performing a request such as GET_FILE, you should interrogate the ServiceResponse object to determine the response type returned, illustrated as follows.

Response Type Returned
DataBinder binder = idcClient.createBinder ();
binder.putLocal ("IdcService", "GET_FILE");
binder.putLocal ("dID", "12345");
ServiceResponse response = idcClient.sendRequest (user, binder);
if (response.getResponseType().equals(ServiceResponse.ResponseType.BINDER))
{
DataBinder responseBinder = response.getResponseAsBinder(false); // do not check for errors
int statusCode = m_binder.getLocalData ("StatusCode").getInteger("StatusCode");
String statusMessage = m_binder.getLocal ("StatusMessage");
throw new IllegalStateException("Download response was not a stream - Error: " + statusCode + " - " + statusMessage);
}

28.8 Reusing Binders for Multiple Requests

Binders can be reused among multiple requests. A binder from one request can be sent in to another request. Note that if you reuse a binder from one call to the next you need to be very careful there is nothing leftover in the binder that could impact your next call. RIDC does not clean the binder after each call.

The following code provides an example that pages the search results by reusing the same binder for multiple calls to Content Server.

Reusing Binders
// create the user context
IdcContext idcContext = new IdcContext ("sysadmin", "idc");

// build the search request binder
DataBinder binder = idcClient.createBinder();
binder.putLocal("IdcService", "GET_SEARCH_RESULTS");
binder.putLocal("QueryText", "");
binder.putLocal("ResultCount", "20");

// send the initial request
ServiceResponse response = idcClient.sendRequest (idcContext, binder);
DataBinder responseBinder = response.getResponseAsBinder();

// get the next page
binder.putLocal("StartRow", "21");
response = idcClient.sendRequest (idcContext, binder);
responseBinder = response.getResponseAsBinder();

// get the next page
binder.putLocal("StartRow", "41");
response = idcClient.sendRequest (idcContext, binder);
responseBinder = response.getResponseAsBinder();

28.9 Setting User Security

The Content Server has several security models that are controlled by settings on the Content Server. To resolve if a particular user has access to a document, three things are needed: The user's permission controls, the document's permission controls, and Content Server security environment settings.

It is assumed that the application program calling the UserSecurity module will fetch documents and the DOC_INFO metadata (in the document's binder, typically the result of a Search) as some superuser and cache this information. When the application program needs to know if a particular user has access to the document, a call is made to the Content Server as that user to fetch that user's permissions. Once the user's permission controls are known, then they can matched to the information in the document's metadata to resolve the access level for that user. (Access level is READ or READ/WRITE or READ/WRITE/DELETE). The need therefore is to reduce the number of calls to the Content Server (with a cache) and to provide a default implementation for matching the user's permissions information with the document's permission information. One further complication is that the Content Server controls which types of security are used in some server environment properties: UseAccounts=true and UseCollaboration=true or UseEntitySecurity=1. Additionally, a method allows testing to see if admin rights are assigned to a security type for that document.

The user security convenience is accessed through the IUserSecurityCache interface. There classes implement the optional Content Server security:

  • The UserSGAcctAclCache class should always be called. This class will check the Content Server for security configuration and internally adjust itself to match.

  • The UserSecurityGroupsCache class keeps a cache of user permissions and will match documents considering only Security Group information. Do not call this class directly. The UserSGAcctAclCache class will check the Content Server for security configuration and internally adjust itself to match.

  • The UserSGAccountsCache class adds a resolver to also consider Account information if the Content Server has the UseAccounts=true setting. Do not call this class directly. The UserSGAcctAclCache class will check the Content Server for security configuration and internally adjust itself to match.

The following code provides an example of setting user security.

Setting User Security
IdcClientManager m_clientManager = new IdcClientManager ();
IdcClient m_client = m_clientManager.createClient
        ("http://localhost/scs/idcplg");

//RIDC superuser context
IdcContext m_superuser = new IdcContext("sysadmin", "idc");

//This class will self-adjust (downwards) to match the security model
// on Content Server.
IUserSecurityCache m_userSecurityCache = new UserSGAcctAclCache 
   (m_client, 20, 1000, 20000, m_superuser);
ITrace trace = null;

//Example test
testDocPermission () {
  //If you don't want to do any logging, you can leave trace as null
  if (m_log.isLogEnabled(ILog.Level.TRACE)) {
  trace = new Trace ();
  }
  DataBinder m_doc1 = getDataBinder ("TEST");
  //Get the document information (typically in the first row of DOC_INFO)
  DataObject docInfo = m_doc1.getResultSet ("DOC_INFO").getRows ().get (0);
  //Get the cache id for this user
    //This makes a live call to content server to get the user ID for "Acme1"
    //CacheId acme1 = m_userSecurityCache.getCacheIdForUser 
    //  (new IdcContext("Acme1", "idc"), trace);
  IdcContext context = new IdcContext("Acme1", "idc");
  CacheId acme1 = new CacheId (context.getUser (), context);
  //Get the access level for this document by this user
  int access = m_userSecurityCache.getAccessLevelForDocument 
        (acme1, docInfo, trace);
  //Check if user has ACL admin permissions
  boolean aclAdmin = m_userSecurityCache.isAdmin 
         (acme1, docInfo, IUserSecurityCache.AdminType.ACL, trace);
    if (m_log.isLogEnabled(ILog.Level.TRACE)) {
        m_log.log (trace.formatTrace (), ILog.Level.TRACE);
        }
}
//Example code to get a Document's DOC_INFO databinder
DataBinder getDataBinder (String dDocName) throws IdcClientException {
  DataBinder dataBinder = m_client.createBinder ();
  dataBinder.putLocal ("IdcService", "DOC_INFO_BY_NAME");
  dataBinder.putLocal ("dDocName", dDocName); 
  ServiceResponse response = m_client.sendRequest (m_superuser, dataBinder);
  return response.getResponseAsBinder ();
}
//Example code to create a DataObject
DataObject dataObject = m_client.getDataFactory ().createDataObject ();
dataObject.put ("dSecurityGroup", "public");
dataObject.put ("dDocAccount", "Eng/Acme");

Internally, these fields from the document are examined during getAccessLevelForDocument():

  • For the AccessResolverSecurityGroups class: dSecurityGroup.

  • For the AccessResolverAccounts class: dDocAccount.

  • For the AccessResolverSecurityGroups class: xClbraUserList, xClbraAliasList, and xClbraRoleList.

The IAccessResolver classes determine if they should participate based on cached information from the Content Server, if they do participate, the access levels are ANDed together. You can use the hasAdmin() method to determine if there is admin access.

28.10 Using RIDC Filters

Remote Intradoc Client (RIDC) 12c, enables your application code to add a filter before the DataBinder is processed and sent to Content Server. You can create a filter by extending one of the IdcFilterAdapter classes, and then register that filter to execute with the IdcFilterManager class. Filters are executed in the order specified when registered. You can also get and remove previously registered filters.

The following code extends an adapter and overrides a method to perform an action:

Calling RIDC Filter Before Service Request
public class IdcFilterAddComment extends BeforeServiceRequestFilter {
  @Override
  public void beforeServiceRequest
       (IdcClient client, IdcContext context, DataBinder binder) 
        throws IdcClientException {
    String existingComments = binder.getLocal("xComments");
    if (existingComments != null) {
        binder.putLocal("xComments", String.format
        ("%s %s", existingComments, "--DGT WAS HERE--"));
     } else {
         binder.putLocal("xComments", "--DGT WAS HERE--");
     }
  }
}

Remote Intradoc Client (RIDC) 12c provides two more filter locations in the JAX-WS processing area. To use these filters, extend the BeforeJaxwsServiceFilter class.

The following code extends the BeforeJaxwsServiceFilter class:

Calling RIDC Filter Before JAX-WS Call
/**
 * RIDC filter called just before jaxws call is made to
 * loginPort.contentServerLogin () in authenticateUser ()
 **/
public void beforeJaxwsAuthenticateUser (IdcContext context, DataBinder binder,
        Map<String, Object> requestContext) throws IdcClientException {
    requestContext.put(oracle.wsm.security.util.SecurityConstants.
        ClientConstants.WSM_SUBJECT_PRECEDENCE, “false");
}

/**
 * RIDC filter called just before jaxws call is made to
 * loginPort.contentServerRequest () in performServiceRequest ()
 **/
public void beforeJaxwsServiceRequest (IdcContext context, DataBinder binder,
        Map<String, Object> requestContext) throws IdcClientException {
        //Override this class and implement your filter here
}

The following code registers your filter class(es):

Register Filer Classes
// If you are at the start of a pure RIDC application, you typically 
// will create a ClientManager, for example:
IdcClientManager m_clientManager = new IdcClientManager();

// New method added to IdcClient to get the ClientManager
// if you do not have the ClientManager instance:
IdcClient client = myClient; 
client.getClientManager();

// From the ClientManager, you can get the FilterManager:
IdcFilterManager fmanager = m_clientManager.getFilterManager();

// Then register your filter:
IIdcFilter addCommentFilter = new IdcFilterAddComment();
int slot = fmanager.registerFilter(100, addCommentFilter);

// Optionally, you can deregister. However, it might not be in the slot you
// assigned because there might have already been a filter in that slot.
// When registering, the next available higher slot will be used. You also need
// to pass in the instance currently in the slot you want to remove:
fmanager.deRegisterFilter(slot, addCommentFilter);

// Here is an example to remove all the filters,
// including the ones you did not register
for (Integer slot:fmanager.getUsedSlots()) {
  fmanager.deRegisterFilter(slot, fmanager.getFilter (slot));
}