3 nov 2011

Usando un usuario para todas las conexiones de Site Studio for External Applications (SSXA)

En una de las aplicaciones que estoy trabajando actualmente se nos ha dado la necesidad de utilizar un único usuario para todas las consultas que se hacen en UCM.

Si estamos familiarizados con WebCenter y su integración con UCM, es tan sencillo como crear un "External App" que haga el login/password del usuario que le indicamos, y todas las operaciones que se realicen hacia el content server serán con dicho usuario.

Buceando por las librerías de SSXA, he visto que si la aplicación hace login y tenemos el usuario en sesión, éste es el usado para las consultas.


Podemos ver en la clase oracle.stellent.wcm.client.ClientApplication.java de la librería oracle.ucm.wcm.core-11.1.1.jar la siguientes líneas de código.


    Principal principal = request.getUserPrincipal();
    if (principal != null)
    {
      siteContext.setIdcContext(new IdcContext(principal.getName()));
    }


Como vemos, se recupera el usuario de sesión y con este se crea la conexión a RIDC para consultar en UCM.

Sobreescribimos la clase, creando el paquete oracle.stellent.wcm.client en mi proyecto y dentro de el la clase ClientApplication.java

Modificamos las líneas anteriores para que ponga un usuario directo, por ejemplo:

siteContext.setIdcContext(new IdcContext("mi-usuario"))


Con la clase modificada debemos seguir con la segunda parte.

Se debe alterar el classloader de la aplicación y de Weblogic para que usen nuestra nueva clase en vez de la original desplegada en la shared-library de UCM.

Copiamos el JAR oracle.ucm.wcm.core-11.1.1.jar al proyecto y vamos al menú Application - Project properties



Seleccionamos añadir nueva librería
Indicamos que se trata de una nueva

Creamos la nueva seleccionando el JAR oracle.ucm.wcm.core-11.1.1.jar y de nombre SSXA-Override con la opción de "deployed by default"


Quedando asignada en mi proyecto la nueva librería, es importante que la pongamos por encima de la librería estándar de Site Studio.



Ahora vamos a modificar el fichero weblogic.xml para que incluya la siguiente entrada:


  <container-descriptor>
    <prefer-web-inf-classes>true</prefer-web-inf-classes>
  </container-descriptor>

Modificamos también el weblogic-application.xml para que incluya la siguiente entrada:


  <prefer-application-packages>
    <package-name>oracle.stellent.wcm.client.*</package-name>
    <package-name>oracle.stellent.wcm.core.idc.*</package-name>
  </prefer-application-packages>

Con esto hemos finalizado, desplegamos la aplicación y probamos los cambios. Aunque la aplicación haga login los contenidos mostrados son aquellos a los que el usuario que pusimos arriba tiene acceso.

11 oct 2011

Speed up your JDeveloper for 64bit systems

This options will increase the performance of your JDeveloper under 64bit systems with 4 or more GB or RAM.

First locate the file jdev.conf (on my system is C:\Oracle\Middleware\jdeveloper\jdev\bin\jdev.conf)  and add this values:

#Extra tunning options
AddVMOption -XX:+AggressiveOpts
AddVMOption -XX:+UseStringCache
AddVMOption -XX:+OptimizeStringConcat
AddVMOption -XX:+ScavengeBeforeFullGC
AddVMOption -XX:+UseCompressedOops
AddVMOption -XX:+UseConcMarkSweepGC
AddVMOption -XX:+UseGCOverheadLimit

AddVMOption  -XX:MaxPermSize=800M

After that configure your JVM to use more memory

Under directory C:\Oracle\dev_home\system11.1.1.5.37.60.13\DefaultDomain\bin (or similar) the file setDomainEnv.bat (this only applies to 64 bit)
set XMS_SUN_64BIT=256
set XMS_SUN_32BIT=256
set XMX_SUN_64BIT=1024
set XMX_SUN_32BIT=512

Thats all, now your JDeveloper should be a bit faster 

:-)

Copiar y pegar en los Applet's de UCM

Para habilitar la capacidad de copiar y pegar en los applets de UCM necesitamos modificar el fichero de politicas de Java.

Esto afecta a las versiones de Java 6 (build 21, 22 y 23) si actualizais a la 24 se supone que está arreglado.

En concreto accedemos al directorio C:\Program Files (x86)\Java\jre6\lib\security y modificamos el fichero java.policy

Añadiendo al final la siguiente línea permission java.awt.AWTPermission "accessClipboard";

Reiniciamos los navegadores y listo.

5 sept 2011

Get metadata values from external service in a Custom Element Form

At my actual UCM project we are using some tables to store values of a metadata field.


We have already a custom service that performs a Query to the table to obtain that values, with this service we can show values of the DB table in our JSPX. (For more info on how to build this kind of components check Brian Bex Huff Book)


This is how our service returns the data:





Our customer ask us about the possibility of adding inside a Site Studio Contribution Form a custom element that shows in a combo the values of the table. After searching a bit I found Kyle's post really good and very similar to what I triying to do.


After modifying a bit the code, finally I have success, and my custom element performs this steps:
1- Executes a custom service
2- Obtain the data from XML Request via AJAX
3- Prints a combo with the data obtained.


There is the source code. (link)


For your purposes you will have to modify the next lines 36-41

var httpCgiPath = "http://" + document.location.hostname + "/cs/idcplg"; 
var myRset = "QueryResult";
var myIDField = "CT2_ID";
var myDescField = "CT2_DESC_EN";
var myFieldName = "custom-content-type-level-2";

Also should be modified the line 295 where is the URL of the service execution:



var requestUrl = httpCgiPath + "?IdcService=CUSTOM_CTN2&idN1=15&IsSoap=1";
loadXMLDoc(requestUrl, loadComboValues);



This is how it looks like:






22 ago 2011

Autenticación de PROXY NTLM en Weblogic

Recientemente estuve viendo como un simple proxy de salida de internet me estuvo dando problemas durante más de una semana para configurarlo en una aplicación web desplegada en Weblogic.


Recopilando un poco de información por internet por fin dimos con la clave para conseguir que la aplicación se conectara al exterior.


En primer lugar debemos de arrancar Weblogic con la variable de entorno PROXY_SETTINGS configurada. Esto hará que los script's de arranque del servidor de aplicaciones añaden dicha línea como parámetros de ejecución.


Ejemplo:

PROXY_SETTINGS="
-Dhttp.proxySet=true
-Dhttp.proxyHost=<proxy hostname o ip>
-Dhttp.proxyPort=<puerto proxy>
-Dhttp.proxyUser=<mi usuario>
-Dhttp.proxyPassword=<mi password>
-Dweblogic.webservice.transport.http.proxy.host=<proxy hostname o ip>
-Dweblogic.webservice.transport.https.proxy.host=<proxy hostname o ip>
-Dweblogic.webservice.transport.http.proxy.port=<puerto proxy>
-Dweblogic.webservice.transport.https.proxy.port=<puerto proxy>
-Dhttp.nonProxyHosts=\"localhost|127.0.0.1"
-DUseSunHttpHandler=true"



export PROXY_SETTINGS


De esta forma las variables de entorno están ya configuradas. Reiniciamos nuestro Weblogic o las ponemos en el propio script de arranque y reiniciamos.


Aparte de la configuración de Weblogic nos vimos obligados a incluir un código en nuestra aplicación que reescribia el authenticator del proceso Java que estaba corriendo en la JVM. Este paso sólo es necesario si tu aplicación utiliza tecnología ADF.


Antes de realizar una llamada HTTP invocaba el siguiente método:

//Proxy Weblogic
Proxy.getInstance().setup();


El código de la clase Proxy es:

public class Proxy
{
  private static final Logger logger = Logger.getLogger(Proxy.class);
  private static Proxy instance = null;
  private boolean enabled = false;


  public Proxy()
  {
    super();
  }


  public static Proxy getInstance()
  {
    if (instance == null)
      instance = new Proxy();


    return instance;
  }


  public void setup()
  {
    String proxySet = System.getProperty("http.proxySet");


    if (proxySet != null && proxySet.equals("true") && enabled == false)
    {
      String user = System.getProperty("http.proxyUser");
      String password = System.getProperty("http.proxyPassword");


      Authenticator.setDefault(new MyAuthenticator(user, password));
      logger.info("Proxy activado:" + proxySet);
      logger.info("Proxy usuario:" + user);
      logger.info("Proxy password:" + password);
      enabled = true;
    }
  }


  class MyAuthenticator extends Authenticator
  {
    private String username;
    private String password;


    public MyAuthenticator(String username, String password)
    {
      this.username = username;
      this.password = password;
    }


    public PasswordAuthentication getPasswordAuthentication()
    {
      return new PasswordAuthentication(username, password.toCharArray());
    }
  }
}








SSXA + RIDC en un Servlet

Durante un desarrollo de un sitio web en tecnología SiteStudio for external applications (SSXA en adelante) me vi con la necesidad de utilizar el pool de conexiones RIDC que automáticamente cada aplicación Web SSXA tiene definida. 
En concreto no fuimos capaces de descargar un fichero en su formato "original" ya que la tecnología SSXA sólo parece contemplar la descarga de ficheros en su formato web desde UCM (web rendition). Por ello desarrollamos este servlet que es capaz de conectarse a UCM a través de RIDC y realizar una descarga de un fichero dado su identificador (dDocName).


Os dejo un ejemplo de como se realiza una llamada RIDC desde un servlet aprovechando su configuración de conexiones con UCM.




Ejemplo de RIDC usando un Servlet y SSXA:

private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{
if(request.getParameter("file")!=null && request.getParameter("file")!= ""){
try
{
 ClientApplication client = getWcmApplication(this.getServletContext());
 IdcClientFactory idcClientFact = new IdcClientFactory(client.getConfigLoader().getConfiguration().getSystemConfig().getIdcConfig());
 IdcClient m_client = idcClientFact.getClientManager().createClient(idcClientFact.getIdcConfig().getConnectionUrl());
 IdcContext m_userContext = idcClientFact.getGuestContext();

//Ejecución del servicio
DataBinder dataBinder = m_client.createBinder();

dataBinder.putLocal("IdcService", "GET_FILE");
dataBinder.putLocal("dDocName", request.getParameter("file"));
dataBinder.putLocal("RevisionSelectionMethod","LatestReleased");
dataBinder.putLocal("Rendition", "Primary");

 // Ejecuto la petición
 ServiceResponse sRes = m_client.sendRequest(m_userContext, dataBinder);
 String startSplit = "filename=";
 String content = sRes.getHeader(HEADER_CONTENT);
 String fileName = content.substring(content.indexOf(startSplit) + startSplit.length() + 1, content.length() - 1);

 response.setContentType( (sRes.getHeader(HEADER_MIME) != null) ? sRes.getHeader(HEADER_MIME) : "application/octet-stream" );
 response.setContentLength(Integer.parseInt(sRes.getHeader(HEADER_LENGTH)));
 response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"" );


 //
 //  Stream to the requester.
 //
 byte[] bbuf = new byte[512];
 DataInputStream in = new DataInputStream(sRes.getResponseStream());
 int length   = 0;
 while ((in != null) && ((length = in.read(bbuf)) != -1))
 {
 response.getOutputStream().write(bbuf,0,length);
 }


 in.close();
 response.getOutputStream().flush();
 response.getOutputStream().close(); 
}
catch (ApplicationException e) {
logger.error("Error en descarga de contenido",e);
}
catch (Exception e) {
 logger.error("Error en descarga de contenido",e);
}
}
}


public ClientApplication getWcmApplication(ServletContext sc) throws Exception

  return ServletApplicationFactory.createInstance(sc);
}