In this blog I will talking about my findings of using Oracle HCM Cloud as storage. You can actually checkin/checkout your files here. There are various reasons you may want to store your files there. Few could be
1. FBL
2. HDL
3. You Paas Application needs to store some file (Although I will prefer storage cloud but then you might need a separate license. Why not to use UCM of Oracle HCM Cloud itself).
Before coming to actual implementation, I would like to clear few things.
2. As we are going to use RIDC apis we need to understand supported protocols:
Intradoc (with SSL also): This is a
direct connection between client and server. Server must be configured to
accept request from selected clients. You must be setting IntradocServerPort
and SocketHostAddressSecurityFilter in WCC_domain/ucm/cs/config/config.cfg file or (Web UI
hos:port/cs/idplg >> Administration >> Admin Server >>
General Configuration
As
this connection is done over trusted network, it does not need any password
authentication. Only provide username and do transaction.
IdcContext userContext = new
IdcContext("HCM_ADMIN"); //No need of password.
Intradoc communication can also be done over SSL. You should do below
line of coding for that.
// create the manager
IdcClientManager manager = new
IdcClientManager();
// build a client that will communicate
using the intradoc protocol
IdcClient idcClient =
manager.createClient("idc://localhost:4444");
// set the SSL socket options
IntradocClientConfig config = (IntradocClientConfig)
idcClient.getConfig();
config.setKeystoreFile("ketstore/client_keystore"); //location of keystore file
config.setKeystorePassword
("password"); // keystore
password
config.setKeystoreAlias("SecureClient"); //keystore alias
config.setKeystoreAliasPassword("password"); //password for keystore alias
In
case of SaaS, intradoc may not be useful as we can’t configure SocketHostAddressSecurityFilter
property of UCM server.
http/https: RIDC communicates with the web server for Oracle Content Server using the Apache HttpClient package. Unlike Intradoc, this protocol requires authentication credentials for each request. It does not require any configuration on server side.
If you want to use http/https, you need to use url as
// create the manager
IdcClientManager manager = new IdcClientManager();
IdcClient idcClient = manager.createClient("https://host.oracleoutsourcing.com/_dav/cs/idcplg");
//NOTE: we have used _dav in url. Otherwise you will receive //oracle.stellent.ridc.protocol.http.HttpProtocolException: Http status: //HTTP/1.1 302 Moved Temporarily //ERROR
//If you are using https, you need to set truststores as
System.setProperty("javax.net.ssl.trustStore", "D:/jks/Cert_DER.jks");
System.setProperty("javax.net.ssl.trustStorePassword","mypassword");
//For usercontext you should set AuthScheme as Basic
IdcContext userContext = new IdcContext("username", "password");
userContext.setAuthScheme(IdcContext.HttpAuthScheme.BasicAuth);
JAX-WS: The JAX-WS protocol is supported only in Oracle WebCenter Content 11g with Oracle Content Server running in Oracle WebLogic Server. To provide JAX-WS support, several additional JAR files are required.
NOW COMING TO THE MAIN PART: Steps to import a file on Oracle HCM Cloud (UCM) server
1. No special configuration is needed on server side
2. Get url to make connection. It should be https://host.oracleoutsourcing.com/_dav/cs/idcplg
Replace host with your environment and don’t forget _dav
3. Get username/password who has access to UCM. You can use your SaaS username/password to login to https://host.oracleoutsourcing.com/cs
If you are able to login successfully then check if you can upload/download documents etc. If you can do it through UI, you should be able to do it programmatically.
4. Create keystore and install certificate. (THIS STEP IS IMPORTANT and ERROR PRON)
NOTE: In case of weblogic web program you may want to get existing keystore and then add new certificate instead of creating new keystore.
keytool -import -file D:\jks\Cert_DER.cer -alias orakey -keypass mypassword -keystore D:\jks\Cert_DER.jks -storepass mypassword
This command will cerate a keystore (jks file) with a key (named orakey). Password for key and keystore is same as ‘mypassword’. Certificate is imported in this keystore.
If you already have keystore and you want to import certificate in it
keytool -importcert -file D:\jks\Cert_DER.cer –keystore D:\oldjks\Cert_DER.jks -alias orakey -storepass <whatever-is-keystore-password>
If you want to list keystore data you can
keytool -list -v -keystore D:\jks\Cert_DER.jks -storepass mypassword
Following above keystore steps your keystore should be ready with appropriate certificate.
Now we need to write a java code with RIDC apis and configure it to use jks file we just created.
NOTE: If you are using weblogic server then you should configure weblogic keystore instead of referring jks from code.
5. Java Code: Let say you have placed your jks as D:/jks/Cert_DER.jks and file that you want to import at D:/file/test.txt
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import oracle.stellent.ridc.IdcClient;
import oracle.stellent.ridc.IdcClientException;
import oracle.stellent.ridc.IdcClientManager;
import oracle.stellent.ridc.IdcContext;
import oracle.stellent.ridc.model.DataBinder;
import oracle.stellent.ridc.model.TransferFile;
import oracle.stellent.ridc.protocol.ServiceResponse;
public class RIDCUtil {
public static void main(String[] arg) throws Exception {
try {
IdcClientManager m_clientManager = new IdcClientManager();
IdcClient idcClient = m_clientManager.createClient("https://host.oracleoutsourcing.com/_dav/cs/idcplg");
IdcContext userContext = new IdcContext("username", "pwd");
userContext.setAuthScheme(IdcContext.HttpAuthScheme.BasicAuth);
System.setProperty("javax.net.ssl.trustStore", "D:/jks/Cert_DER.jks");
System.setProperty("javax.net.ssl.trustStorePassword","mypassword");
checkin(idcClient, userContext, "D:/file/test.txt", // Replace with fully qualified path to source file
"Document", // content type
"Test Document to check RIDC", // doc title
userContext.getUser(), // author
"FAFusionImportExport", // security group
"hcm$/dataloader$/import$", // account
"TEST_DOC_FOR_RIDC") // dDocName - this is the ContentId
;
} catch (IdcClientException e) {
e.printStackTrace();
}
}
/** * Method description * *
* @param idcClient *
* @param userContext *
* @param sourceFileFQP fully qualified path to source content *
* @param contentType content type *
* @param dDocTitle doc title *
* @param dDocAuthor author *
* @param dSecurityGroup security group *
* @param dDocAccount account *
* @param dDocName dDocName * *
* @throws IdcClientException */
public static void checkin(IdcClient idcClient, IdcContext userContext,
String sourceFileFQP, String contentType,
String dDocTitle, String dDocAuthor,
String dSecurityGroup, String dDocAccount,
String dDocName) throws IdcClientException {
InputStream is = null;
try {
String fileName = sourceFileFQP.substring(sourceFileFQP.lastIndexOf('/') + 1);
is = new FileInputStream(sourceFileFQP);
long fileLength = new File(sourceFileFQP).length();
TransferFile primaryFile = new TransferFile();
primaryFile.setInputStream(is);
primaryFile.setContentType(contentType);
primaryFile.setFileName(fileName);
primaryFile.setContentLength(fileLength); // note!!! when using HTTP protocol (not intradoc/jaxws) - one must explicitly // set the Content Length when supplying an InputStream to the transfer file // e.g.
primaryFile.setContentLength(fileLength); // otherwise, a 0-byte file results on the server
DataBinder request = idcClient.createBinder();
request.putLocal("IdcService", "CHECKIN_UNIVERSAL");
request.addFile("primaryFile", primaryFile);
request.putLocal("dDocTitle", dDocTitle);
request.putLocal("dDocAuthor", dDocAuthor);
request.putLocal("dDocType", contentType);
request.putLocal("dSecurityGroup", dSecurityGroup);
// if server is setup to use accounts - an account MUST be specified
// // even if it is the empty string; supplying null results in Content server
// // attempting to apply an account named "null" to the content!
request.putLocal("dDocAccount", dDocAccount == null ? "" : dDocAccount);
if (dDocName != null && dDocName.trim().length() > 0) {
request.putLocal("dDocName", dDocName);
}
// execute the request
ServiceResponse response = idcClient.sendRequest(userContext, request); // throws IdcClientException
// get the binder - get a binder closes the response automatically
DataBinder responseBinder = response.getResponseAsBinder(); // throws IdcClientException
} catch (IOException e) {
e.printStackTrace(System.out);
} finally {
if (is != null) {
try { is.close();
} catch (IOException ignore) {
}
}
}
}
}
If you are making your RIDC call using a web program deployed on weblogic server, you should not set javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword property in java code but you should configure jks file in weblogic.
6. Above code can be improved in many way. You may
want to checkin file in a particular folder, you may want to see if file
already present, You may want to handle exception gracefully, you may want to
take all hardcoded strings (ucm-url, ucm-username/password,
keystore-location/password, content-type, security-group, account etc.) to a
property file. Here it is just a POC.
7. To run java program from command prompt, generate
a jar file containing RIDCUtil (say MyIntegrationJar.jar). Place all required
jars in one directory and run below command from that directory.
C:\jdk1.6.0_31_64\bin\java
-classpath
.\MyIntegrationJar.jar;.\oracle.ucm.ridc-11.1.1.jar;.\commons-httpclient-3.1.jar;.\commons-logging-1.0.4.jar;.\commons-codec-1.2.jar
RIDCUtil
8. You can verify document in UCM by login into UCM https://host.oracleoutsourcing.com/cs and searching the document
Below are the various issue that you may face while implementing it. Most of them are actually certificate related