header_lecciones_v5

Mandamientos IBM WebSphere Portal

por Willington Bedoya Corrales, el 28 de marzo de 2019

h_mandamientos_ibm_websphere_portalEn toda construcción de portales, haciendo uso de la herramienta IBM WebSphere Portal, es importante tener presente algunas buenas prácticas que evitan problemas futuros en la implementación.

En el desarrollo de diferentes portales, tanto de tipo transaccional como de contenido, se han detectado una serie de prácticas de desarrollo de software que atentan contra el buen desempeño y rendimiento del portal. De estas experiencias, se recopilan una serie de buenas prácticas, adicionales a las propuestas por IBM, que tienen los siguientes objetivos:

  • Evitar problemas de rendimiento en ambientes productivos.
  • Minimizar la ocurrencia de errores derivados por malas prácticas de desarrollo.
  • Estar alineados con el sizing propuesto.
  • Simplificar el desarrollo de portlets.

Adicionalmente, al desarrollar un proyecto de portlets, se debe tener presente que la arquitectura de portlets es una extensión de la arquitectura Servlets de Java.

Por tal motivo, aunque existen diversos aspectos que son comunes al desarrollo de aplicaciones Web, el desarrollo de portlets tiene una serie de características únicas que hacen que el modelo de aplicación sea más complejo.

Las principales características que se observan en un proyecto de portlets son las siguientes:

Múltiples portlets en una misma página.

  • Direccionamiento basado en URL de Portlets
  • Control de flujo en las páginas de Portlets.
  • Restricciones de rendering en la interfaz de usuario
  • Comunicación entre Portlets.
  • Manejo de eventos.
  • Reglas de visualización.
  • Configuración por medio de preferencias del portlet.

Por último, en el proceso de desarrollo de Portlets se adopta el modelo de diseño MVC (Modelo, Vista, Controlador) que permite que el Portlet actúe en muchas formas como un controlador, delegando las tareas de computación complejas a otros componentes y servicios, los cuales se pueden ver como un modelo, mientras que las páginas JSP's actúan como vistas que generan y despliegan HTML en las máquinas clientes.

Y Dios le habló a Moises...

1. Ninguna JSP de los portlets debe tener las etiqueta de cabecera de las páginas, es decir: <Head>, <body>, <meta>, <link>, <style>. Estas etiquetas ya se cargan desde el Theme del portal.

2. Las JSP´s de los portlets deben tener aplicada la etiqueta <%@ page session="false" %>. El tener esta etiqueta en true, puede representar problemas de rendimiento.

3. Todos los estilos se deben manejar con clases, ninguna etiqueta de HTML debe contener estilos "quemados" en el código.
La forma correcta: <div id="headContainer" class="rowPortal">.
La especificación de estos estilos se deben manejar en una hoja de estilos a parte y debe estar ubicada en el Theme del portal.

4. Todas las imágenes deben tener alt y tittle que describan el nombre de la imagen o algún texto descriptivo de la misma.

5. Las URL's a los recursos deben ser relativas, ¡jamás deben contener el dominio del servidor!.
Ejemplo: /wps/portal/mipagina.

6. Los proyectos portlets no deben contener en la carpeta bin/lib librerías de apoyo (jar). Estos jar deben estar como librerías compartidas en el WAS de ser necesario.

7. Los proyectos portlets no deben tener imágenes, archivos javascript o CSS dentro el proyecto. Estos deben estar incluidos en el Theme y desde allí se cargan.

8. En las JSP's del portlet no deben existir javascript y estilos quemados, estos deben estar en archivos CSS y JS independientes que se encuentren en el Theme del portal.

9. Los textos de las etiquetas, campos y mensajes que se muestran en las JSP's, se deben manejar en archivos properties para permitir el soporte a varios idiomas. Por cada idioma debe existir un properties.

10. Es posible utilizar JSTL en las JSP cuando se requiera mostrar HTML de forma dinámico.

11. Evitar el uso de PortletSession. Si es necesario utilizarlo incluirlo en un try - catch y en el finally destruirlo: Ejemplo: PortletSession.remove("sesion") ó PortletSession.invalidate().
Es muy importante tener en cuenta que cuando se requiera almacenar objetos en la sesión del usuario, la forma recomendada es hacerlo a través de Objetos almacenados en un Dynamic Cache y nunca en PortletSession. Tener en mente lo siguiente:
"During the generation of markup or during the execution of an action, it is often necessary to access a slow backend or perform some type of time consuming calculation. The result of such an operation should be cached to enable subsequent requests to execute faster. The portlet session, however, is not the correct place to cache this information because it conceptually consists of non-recreatable data. The portlet container (and in the end the application server) makes sure that session state is preserved across node failure in a clustered environment and even might get replicated across the cluster. This management requires resources. Furthermore, cached data in the session cannot be discarded automatically (that is, in case of low memory conditions) before the end of the lifetime of the session."
Tomado del artículo "IBM WebSphere Developer Technical Journal: Develop high performance Web sites with both static and dynamic content using WebSphere Portal V5.1" IBM Developer

12. Evitar al máximo el uso de librerías y framework externos que no estén soportados nativamente por IBM WebSphere Portal y/o el servidor de aplicaciones (WAS). La razón fundamental, es que las librerías externas pueden cargar mucho el Portal si no se saben manejar adecuadamente y esto se traduce en problemas de rendimiento.

13. Para las conexiones a DB, utilizar JPA o JDBC (tener cuidado en el cierre de conexión). JPA es soportado de forma nativa por el servidor de aplicaciones (WAS) y no es necesario agregar librerías adicionales.

14. Cerrar siempre la conexión al WCM cuando se utilicen aplicaciones que requieran extraer contenido de las bibliotecas. Se recomienda hacerlo en un finally.

15. Los mensajes de error y las configuraciones propias de la aplicación (textos, img, tiempos de rotación, etc...), se debe leer de componentes y contenidos del WCM. Para el caso de label’s, o textos de apoyo en formularios que no sean cambiantes en el tiempo, entonces se debe manejar los textos en archivos properties y las img en el Theme.

16. Todo portlet que se construya, debe ser RWD.

17. El HTML debe pasar la validación W3C de HTML (Markup Validation).

18. El HTML de los portlets, en lo posible debe ser en porcentajes, es decir, que el portlet pueda moverse libremente en la página u otras páginas y adaptarse a cualquier dimensión. Esto evita tener problemas con el drag and drop que ya trae nativamente el portal.

19. Si se va a utilizar alguna librería JS siempre se debe utilizar la misma versión que se defina en la estructura base y estas librerías deben estar en el Theme del portal. Para el caso de Angular JS, React JS y Bootstrap JS, hacer uso del Script Portlet para embeber la aplicación.

20. Todas las clases y métodos deben tener comentarios y una breve descripción de lo que hace. El uso de swagger es una buena alternativa para comentar el código fuente.

21. Es importante declarar variables al inicio de la clase que no sean susceptible a cambios durante la ejecución del portlet.

22. El uso de preferencias del portlet no debe ser excesivo (En promedio deben existir 2 a 5 como máximo).

23. Como sugerencia todas las clases portlets deben estar contenidas en la siguiente estructura de paquetes: com.micompañía.funcionalidad.portlet

24. Procurar que la estructura de los paquetes del proyecto sea de la siguiente forma: com.micompañía.funcionalidad.servicio, com.micompañía.funcionalidad.utils. Los nombres no deben ser muy largos.

25. Todas las JSP´s de los portlets deben estar guardadas en una carpeta llamada: WebContent/jsps

26. Utilizar eventos en los portlets para comunicarse entre si. Esto es para el caso de portlets construidos en java. Si se tienen aplicaciones en Script Portlets, hacer uso de mecanismos de almacenamiento que provee el navegador para compartir información (Ej: localStorage, indexedDB)

27. Procurar que el portlet sea lo más simple posible. Solo debería tener recursos front end. En caso de querer utilizar algún framework, consultarlo con el equipo de arquitectura.

28. Se recomienda el uso de RAD o eclipse para construir portlets java.

29. Siempre realizar las pruebas en IE (la versión más antigua soportada). nunca probar solo en Chrome o Firefox.

30. Siempre utilizar una JSP de error por cada portlet. El error debe mostrarse de tal forma que el usuario no piense que el portal ha dejado de funcionar. Solo debe fallar el portlet y no toda la página.

31. Nunca se deben traer todos los resultados en una única consulta. Siempre paginar. Como sugerencia, al utilizar paginador en las consultas a base de datos, la paginación debe hacerse en un SP (stored procedure) y se realiza la consulta por página.

32. Puesto que Windows limita la longitud máxima de la vía de acceso a 260 caracteres, el nombre del archivo WAR debe ser inferior a 25 caracteres. En un servidor de Portal que se ejecute en Windows, la instalación de un archivo WAR con un nombre que tenga más de 25 caracteres dará un error.

33. Siempre trabajar con la especificación JSR286 (o la más reciente soportada) para la construcción de portlets.

34. La versión de java con la que se compila el proyecto, debe ser la soportada por IBM WebSphere Application Server. Esta versión de java varía dependiente de la versión del WAS.

35. La autenticación y autorización se hace desde el Portal no desde el portlet. Esta responsabilidad se debe delegar a Portal.

36. En lo posible para el envío de correos electrónicos utilizar la funcionalidad proporcionada por el WAS.

37. Toda aplicación / portlet debe tener su propio log. Este archivo de logs debe tener la siguiente estructura: /wp_profile/logs/WebSphere_Portal/[nombre_aplicacion]/[nombre_aplicacion.log]

38. Seguir estándares de desarrollo aprobados para Java.

39. Seguir estándares de desarrollo aprobados para Front EndEstas etiquetas ya se cargan desde el Theme del portal.

mandamientos ibm

Otras buenas prácticas que ayudan a mejorar el desempeño del portal

Uso de librerías adicionales

Actualmente se vienen usando librerías de desarrollo para la implementación de portlets en diversos proyectos. Las más comunes son Hibernate y Spring.

Ambas librerías son usadas para el manejo de la capa de acceso a datos. Esta combinación era recomendada en versiones anteriores de WebSphere Portal en las cuales aún no se contaba con el soporte a JPA. Hoy no es necesario incluir estas librerías dado que WebSphere Application Server cuenta con soporte a OpenJPA y para su uso, desde la versión 7, no es necesario realizar ningún tipo de instalación adicional en el contenedor de aplicaciones.

Aunque ambas librerías son soportadas por el WebSphere Application Server, se recomienda no hacer uso de este tipo librerías por las siguientes razones:

  • Soporte por parte de IBM. Si se configuran librerías adicionales y se requiere soporte de IBM, el soporte no cubre lo desarrollado con las librerías adicionales. En este caso, el problema debe ser aislado a si es un problema del contenedor de aplicaciones o al uso de librerías adicionales. Si el problema es del contenedor, IBM brinda el soporte hasta llegar a la posible causa del problema. Si el problema es de las librerías, el desarrollador tendrá que seguir buscando una solución por su propia cuenta.
  • El costo del soporte. Cualquier problema que se encuentre relacionado con el contenedor de aplicaciones no tiene un costo adicional y está cubierto dentro del licenciamiento.
  • Actualización. La actualización de las librerías adicionales es un proceso que debe ser coordinado por el cliente y no viene incluído dentro de los fixpacks liberados por IBM para el contenedor de aplicaciones.
  • El uso de librerías adicionales puede afectar las mediciones que se realizan para obtener el sizing inicial del portal. En el sizing se catalogan los portlets por página en simples, moderados y pesados.
  • Los simples son portlets ligeros con funcionalidades básicas.
  • Los moderados incluyen funcionalidades más complejas, por ejemplo el consumo de un servicio REST.
  • Los pesados son aquellos que incluyen librerías adicionales, tienen procesamientos complejos, accesos a backends, entre otros.
  • Según esto, se puede observar que al incluir librerías o frameworks adicionales, todos los portlets que hagan uso de estos quedarían como pesados independiente del estimado que se haya realizado en el sizing inicial.

Con esto en mente, la recomendación es que se debe simplificar el desarrollo en la capa de portal, es decir, el desarrollo de portlets. Es prioritario validar si el acceso a base de datos se puede realizar por medio de JDBC o hacer uso de la versión de JPA incluida en el contenedor de aplicaciones.

En los casos que se requiera contar con una funcionalidad más robusta y que haga uso de frameworks adicionales, se debe considerar en la arquitectura de la solución, ubicar en librerías compartidas, ser instaladas en un perfil de WebSphere Application Server adicional o tener un ambiente dedicado. Siendo este último el más recomendado y los accesos a estos componentes se deberían realizar por medio de interfaces REST ó WSDL.

Manejo de librerías dentro de los portlets

Cuando se tengan librerías que son comunes a varios portlets, éstas no se deben incluir dentro del WAR del módulo que contiene el portlet, sino que se deben ubicar en una librería compartida a nivel de classloader evitando que:

  • La librería sea cargada varias veces cuando se inicializan los portlets
  • El tamaño de los módulos se incremente

Timeout en Web Services

En los casos que se deban consumir Web Services, se debe verificar que el nivel de acoplamiento sea bajo. Si un Web Service no funciona o no responde se debe realizar un buen manejo de las excepciones e informar al usuario que no se puede realizar la petición, pero nunca debe generar indisponibilidad en el servidor. Se deben implementar timeouts o que las invocaciones se puedan generar de manera asíncrona, vía JMS y colas.

 Desarrollo Simple

El desarrollo de los portlets debe ser lo más simple posible y evitar hacer uso de patrones que implementen diversas capas agregando complejidad y carga de procesamiento. Si los portlets son desarrollados con patrones que le agreguen distintas capas de procesamiento, se pueden tener problemas con tiempos de respuesta alto y un throughtput bajo ya que el servidor tiene que destinar más tiempo y recursos para procesar las invocaciones entre capas y el procesamiento de la conversión de objetos entre las diferentes capas.

Manejo de formularios

A continuación se describe un ejemplo de como deberían estar implementados los formularios para IBM WebSphere Portal dentro de un portlet desarrollado en Java.

Codificación de la jsp

<%@taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@taglib uri="http://www.ibm.com/xmlns/prod/websphere/portal/v6.1/portlet-client-model" prefix="portlet-client-model"%>
<%@taglib uri="http://java.sun.com/portlet" prefix="portletx"%>
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt"%>
<%@taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt_rt"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" session="false"%>
<portlet-client-model:init>
   <portlet-client-model:require module="ibm.portal.xml.*" />
   <portlet-client-model:require module="ibm.portal.portlet.*" />
</portlet-client-model:init>
<fmt_rt:setBundle
   basename="com.ibm.training.destinationinfoportlets.nl.FlightPriceTrackerPortletResource"/>
<table border="1" cellpadding="2" cellspacing="0">
   <tbody>
   <tr>
   <th><fmt_rt:message key="flightPriceTracker.originationCity" /></th>
   <th><fmt_rt:message key="flightPriceTracker.destinationCity" /></th>
   <th><fmt_rt:message key="flightPriceTracker.airline" /></th>
   <th><fmt_rt:message key="flightPriceTracker.flightNumber" /></th>
   <th><fmt_rt:message key="flightPriceTracker.flightDate" /></th>
   <th><fmt_rt:message key="flightPriceTracker.cost" /></th>
   </tr>
  
   <c_rt:forEach items="${requestScope.flightPrices}" var="flightPrice">
   <tr>
   <td>
   ${flightPrice.originationCity}
   </td>
   <td>
   ${flightPrice.destinationCity}
   </td>
   <td>
   ${flightPrice.airline}
   </td>
   <td>
   ${flightPrice.flightNumber}
   </td>
   <td>
   <fmt_rt:formatDate value="${flightPrice.flightDate}"/>
   </td>
   <td align="right">
   <fmt_rt:formatNumber type="currency"
   value="${flightPrice.cost}" />
   </td>
   </tr>
   </c_rt:forEach>
   </tbody>
</table>
Y el archivo propierties
# Default Resource Bundle
#
# filename: FlightPriceTrackerPortletResource.properties
# Portlet Info resource bundle example
javax.portlet.title=FlightPriceTracker
javax.portlet.short-title=FlightPriceTracker
javax.portlet.keywords=FlightPriceTracker
flightPriceTracker.originationCity=Departure City
flightPriceTracker.destinationCity=Arrival City
flightPriceTracker.airline=Airline
flightPriceTracker.flightNumber=Flight
flightPriceTracker.flightDate=Date
flightPriceTracker.cost=Cost

 

Referencias

WebSphere Portal Best Practices de IBM

WebSphere Portal Application Development Best Practices using Rational Application Develope

Portlet Development Best Practices and Coding Guidelines WebSphere Portal V5.1

En estos enlaces se puede acceder a información adicional sobre las mejores prácticas de desarrollo de Portlets desplegados sobre IBM WebSphere Portal.

Descarga la guia para trabajar con ambientes IBM Websphere portal
Temas:Tecnologia e Innovación

Lecciones Pragma

Lecciones en Academia Pragma

Aquí encontrarás tutoriales técnicos para que apliques en temas de desarrollo de software, cloud, calidad en software y aplicaciones móviles. 

También puedes visitar nuestro Blog con contenido actual sobre Transformación Digital, Marketing, Conocimiento de Usuario y más. 

Blog

Suscríbete a la academia

Descarga la Guía para trabajar con ambientes IBM Websphere Portal