Herramientas de usuario

Herramientas del sitio


plugins:copiadechangelog

Funcionalidad de copia de Changelog en instalación

Es posible “clonar” el changelog de una base de datos origen a una destino durante el proceso de instalación de un componente, facilitando así el desarrollo distribuido. Para ésto, se crea un componente temporal de desarrollo, el cual luego es instalado en la base de datos general, impactando no solo los cambios que dicho componente tenga registrado, sino también generando el changelog correspondiente en esta última. El resultado final es una base de datos general cuyo contenido y changelog fue virtualmente creado directamente sobre ésta.

IMPORTANTE: El desarrollo del componente se debe realizar sobre un componente que no exista actualmente. Esto es, NO se debe desarrollar sobre una versión del componente Libertya CORE ya que el prefijo es el mismo que uno existente. Para evitar inconvenientes, se puede crear el componente con el nombre del desarrollador, en cualquier versión, por ejemplo Componente Matías Cap, prefijo MCAP, versión 1.0. Como estos componentes son temporales, los UID origen se van a reemplazar (esto se explica luego) y no van a incidir a futuro en ningún componente existente. En el ejemplo que se explica más abajo, se utiliza el componente FOO, el cual es temporal.

Alternativas de instalación: La instalación de un componente ahora abarca tres posibilidades distintas:

  1. Instalación tradicional: En este caso simplemente se instala el componente como hasta el momento se venía trabajando.
  2. Instalación con copia de changelog: En este caso, además de instalar el componente, se registrarán las entradas en el changelog, respetando los datos del componente instalado. Esto significa que se generarán las entradas en AD_Component y AD_ComponentVersion correspondientes, y que los registros referenciarán al AD_ComponentVersion en cuestión.
  3. Instalación con copia de changelog con mapeo a componente existente: En este caso, además de instalar el componente, se generarán las entradas en el changelog utilizando un componente ya existente como referencia de desarrollo. Con esto se logra “simular” el desarrollo en la base de datos destino.

Para comprender más en detalle este tema, se verá a continuación un ejemplo. Supongamos que tenemos un componente temporal FOO 1.0, el cual queremos instalar de diferentes maneras.

Instalación tradicional

Aquí no es necesario realizar ninguna acción adicional, dado que es el caso por defecto de instalación. Se registrará FOO como un nuevo componente y se impactarán los cambios en base de datos sin realizar incorporaciones al changelog.

Instalación con copia de changelog

En este caso instalaremos FOO, registrando como un nuevo componente, se impactarán los cambios en base de datos, y se incorporarán los mismos también al changelog; utilizando las referencias al componente FOO en todos los casos. Esto es: los registros referenciarán al AD_ComponentVersion_ID de FOO 1.0, y los AD_ComponentObjectUID serán los indicados en el XML de origen (por ejemplo FOO-AD_Column-1938272).

Para lograr este tipo de instalación es necesario incorporar la siguiente linea en el archivo manifest.properties del componente:

COPYTOCHANGELOG = Y

Instalación con copia de changelog con mapeo a componente existente

En este caso no registraremos a FOO como un nuevo componente, sino que el mismo deberá ser mapeado (en todo sentido) a un componente ya existente en nuestra base de datos. En este caso entonces los registros referenciarán a un AD_ComponentVersion_ID especificado en la instalación y los AD_ComponentObjectUID serán el resultado de una unión entre origen y destino, como se detalla más adelante.

Por ejemplo, suponemos que queremos incorporar FOO al CORE de Libertya como un desarrollo de éste. En el archivo manifest.properties del componente a “instalar” debemos indicar los siguientes datos:

COPYTOCHANGELOG = Y
MAPTOCOMPONENTUID = CORE-AD_Component-1010001
MAPTOCOMPONENTVERSIONUID = CORE-AD_ComponentVersion-1010024

Además de especificar la copia al changelog, se indican dos valores adicionales: el AD_ComponentObjectUID del componente al cual mapear, y el AD_ComponentObjectUID de la versión del componente al cual mapear. En este caso CORE-AD_Component-1010001 refiere al componente CORE, y CORE-AD_ComponentVersion-1010024 refiere a la versión de componente 12.03. De esta manera toda referencia a FOO (tanto de componente, de versión, o de UID) se cambia durante la instalación a CORE, en los cambios impactados y en el changelog generado.

Mapeo de UIDs

MUY IMPORTANTE: A partir de la revisión r2819 (Soporte para microcomponents), la lógica de generación de los identificadores universales de registros (campo AD_ComponentObjectUID) se modificó a fin de garantizar un UID único e inequívoco. El nuevo formato universal es: PREFIJO-TableName-TimeStamp-Desambiguador, por ejemplo: CORE-AD_Column-20191219101230703-090793). Es por esto que al utilizar la funcionalidad de CopyToChangelog, no se requerirá mapeo de UIDs ante cualquier desarrollo llevado a cabo a partir de dicha revisión (tradicional o microcomponente). Por defecto el mapeo de UIDs queda desactivado, debiendo forzarlo mediante la propiedad MAPUIDS = Y en el manifest.properties del archivo .jar a instalar. Para más detalles ver Soporte para desarrollo de microcomponentes

Un aspecto de especial interés es el de los AD_ComponentObjectUIDs. Dado que en este último caso estamos llevando a CORE un componente desarrollado en otra base de datos, el mapeo no se resuelve sencillamente cambiando FOO por CORE en el UID. Es probable que dicho UID ya exista en la base destino. Se detallan a continuación las acciones que realiza el mapeador durante la “instalación” del componente.

  • Se determina la operación a realizar (Insert, Modification, Deletion)
  • Si la operación es I, se genera un nuevo UID utilizando ambos prefijos y un timestamp desambiguador (guardamos y mapeamos la nómina de registros creados en esta instalación). Por ejemplo:
    • FOO-AD_Column-1348734 se mapea a FOO2CORE-AD_Column-1348734_20120321111740
    • Se genera una map en memoria que almacena: Clave: viejo UID, Valor: nuevo UID.
  • Si la operación es M o D se busca primeramente el UID del registro a modificar/eliminar en la map. De encontrarse (es un registro creado en este proceso de instalación), se utiliza el nuevo UID. En caso de no ser encontrado (es un registro ya existente previamente), se utiliza el UID tradicional.
  • Para las referencias a otras tablas también se busca primeramente en la map, a fin de respetar el mapeo en todos los casos.

Nota: Aunque el UID se podría mapear a CORE-AD_Column-xxxxxxx (donde xxxxxxx es el AD_Column_ID del registro que se está insertando, para esto se requiere complejidad adicional de procesamiento post-persistencia), se buscó almacenar una referencia al componente que originó el/los registro/s y el changelog correspondiente; así como la fecha de incorporación (en este caso al CORE). Además, el timestamp garantiza la unicidad de UIDs para casos en que se desarollen e instalen componentes temporales con el mismo prefijo.

Consideraciones adicionales en instalación con mapeo

Hay que tener especial cuidado si se cuenta con un proceso post-install ad-hoc, el cual realiza modificaciones basadas en UIDs. Se recomienda en estos casos utilizar otra clave de búsqueda (dado que los UIDs mapeados poseen el timestamp para desambiguación).

TODO INTERNO: Al instalar con mapeo el UID crece considerablemente. Si en algún caso se vuelve a instalar con mapeo a partir de un export del instalado, el mismo generará un UID enorme y mal formado. Para solucionar esto, habría que modificar la forma de manejar los UIDs, con los siguientes pasos:

  1. Generar un UID temporal y ponerlo en la map al insertar
  2. Luego, en el metodo handleSuccess() de PluginXMLUpdater, cambiar el UID del registro (y en el changelog) con un valor natural de UID (ej. CORE-AD_Column-xxxxxxx, donde xxxxxxx es el AD_Column_ID del registro que se acaba de insertar insertando).
  3. Actualizar la map con el nuevo UID
/**
 * En caso de ser necesario, ejecutar acciones adicionales luego del
 * exito en la ejecucion de la sentencia SQL generada e impactada en BBDD
 * Este metodo puede ser redefinido por subclases según sea necesario
 */
protected void handleSuccess(String sentence, ChangeGroup changeGroup) throws Exception
{
  // Implemented by subclass
}

Limitaciones en instalación con mapeo

MUY IMPORTANTE: Una vez que el componente temporal fue instalado, el mismo no puede seguir siendo utilizado para desarrollo. De hacerlo, podrían generarse entradas de modificación a registros ya existentes, los cuales sus UIDs fueron mapeados en la base de datos destino, haciendo imposible su posterior recuperación al momento de realizar una segunda instalación complementaria.

Ejemplo:

  1. Instalación 1
    1. Se inserta una columna. UID original: FOO-AD_Column-1348734, nuevo UID: FOO2CORE-AD_Column-1348734_20120321111740
  2. No se descarta el componente temporal y se continua con su desarrollo
    1. Se modifica la columna con UID FOO-AD_Column-1348734
  3. Instalación 2
    1. Se intenta modificar el registro con UID FOO-AD_Column-1348734, pero no se encuentra, dado que cuando se insertó, dicho registro se registró con UID: FOO2CORE-AD_Column-1348734_20120321111740.

Por lo tanto: Luego de una instalación con mapeo, la manera correcta de proceder es crear un nuevo componente temporal, tomando como punto de desarrollo inicial la base de datos donde se instaló el anterior componente temporal.

Operatoria en instalación con copia al changelog y mapeo

Los pasos para instalación de un componente y copia al changelog con mapeo son los siguientes:

  1. Tomar el .jar exportado de la bbdd origen
  2. Modificar el properties.manifest, incorporando las 3 lineas especificadas anteriormente
  3. Instalar el componente
  4. Verificar la correctitud en las tablas y el changelog
  5. Copiar el preinstall.sql del .jar original al preinstall.sql del componente destino
plugins/copiadechangelog.txt · Última modificación: 2021/04/30 19:19 (editor externo)