Archiving en Alfresco 3.2

image_archivingActualización 25/Feb/2010: ver demo-config-files para configuración más cómoda incluso desde Share, reglas y demás (doc calentito que me han enviado desde Alfresco, Gracias Paul!!).

¿Que es el archiving/archivado? Un archivo en gestión documental es una colección de documentos históricos, así como el lugar donde se encuentran. Pues bien, vamos a ver como se configura Alfresco para poder almacenar los contenidos en diferentes sistemas de ficheros, particiones o filesystem (como quieras llamarlo). Cada filesystem puede ser de diferente naturaleza, es decir, los contenidos que se trabajan actualmente deberán estar en los discos más rápidos (discos locales o en una SAN) y los contenidos históricos o de acceso poco frecuente pero debemos mantener, podemos almacenarlos en discos más lentos/baratos o por ejemplo en una NAS.

Todo esto se consigue en Alfresco gracias al Content Store Selector. El Content Store Selector ofrece un mecanismo de control que relaciona el contenido lógico con un fichero físico y su ubicación. Usando el aspecto cm:storeSelector y asignándole una propiedad cm:storeName podemos mover el contenido de un Store a otro de forma totalmente transparente tanto para el usuario como para la aplicación a la hora de mostrar los contenidos, claro que previamente tenemos que definirlos. Esto nos permitirá declarar políticas para controlar la capa de almacenamiento y el uso que de ella hace Alfresco en base a regales de negocio.

Veamos como se configura en base al siguiente escenario:

El repositorio y los ficheros de uso diario, los más usados, los tenemos en /opt/alfresco/alf_data/contentstore, supongamos que ese filesystem corresponde a los discos más rápidos. También tenemos un disco local más lento montado en /opt/alfresco/alf_data/storeA, e incluso podemos tener un filesystem de tipo NAS para los datos que ya no usamos pero necesitamos almacenar montado en /opt/alfresco/alf_data/storeB.

¿Cómo lo configuramos?

Creamos un fichero llamado “sample-content-store-selector-context.xml” en shared/classes/alfresco/extension con el siguiente contenido, lee los comentarios para entender la configuración:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http:// www.springframework.org/dtd/spring-beans.dtd'>
<!-- Define the new file stores -->
<beans>
        <bean id="firstSharedFileContentStore" class="org.alfresco.repo.content.filestore.FileContentStore">
                <constructor-arg>
                        <value>${dir.root}/storeA</value>
                </constructor-arg>
        </bean>
        <bean id="secondSharedFileContentStore" class="org.alfresco.repo.content.filestore.FileContentStore">
                <constructor-arg>
                        <value>${dir.root}/storeB</value>
                </constructor-arg>
        </bean>
<!-- Declare the mapping between store names and store instances -->
        <bean id="storeSelectorContentStore" parent="storeSelectorContentStoreBase">
                <property name="defaultStoreName">
                        <value>default</value>
                </property>
                <property name="storesByName">
                        <map>
                                <entry key="default">
                                        <ref bean="fileContentStore" />
                                </entry>
                                <entry key="storeA">
                                        <ref bean="firstSharedFileContentStore" />
                                </entry>
                                <entry key="storeB">
                                        <ref bean="secondSharedFileContentStore" />
                                </entry>
                        </map>
                </property>
        </bean>
<!-- Point the ContentService to the 'selector' store -->
        <bean id="contentService" parent="baseContentService">
                <property name="store">
                        <ref bean="storeSelectorContentStore" />
                </property>
        </bean>
<!-- Add the other stores to the list of stores for cleaning -->
        <bean id="eagerContentStoreCleaner" class="org.alfresco.repo.content.cleanup.EagerContentStoreCleaner" init-method="init">
                <property name="eagerOrphanCleanup" >
                        <value>${system.content.eagerOrphanCleanup}</value>
                </property>
                <property name="stores" >
                        <list>
                                <ref bean="fileContentStore" />
                                <ref bean="firstSharedFileContentStore" />
                                <ref bean="secondSharedFileContentStore" />
                        </list>
                </property>
                <property name="listeners" >
                        <ref bean="deletedContentBackupListeners" />
                </property>
        </bean>
</beans>

Si te fijas en los dos primeros beans, los valores que se especifican están relacionados con la ubicación de los dos Stores adicionales que estamos creando, en esta caso, relativos a ${dir.root} que es un atributo declarado en alfresco-global.properties. Si nuestros nuevos filesystems no están dentro de dir.root podemos poner la ruta absoluta, por ejemplo <value>/mnt/storeA</value>.

Para poder usar los nuevos contentStores debemos configurar el web-client (Alfresco Explorer) y declararlo como aspecto. Editamos web-client-config-custom.xml y añadimos las siguientes lineas:

<!-- Configuring in the cm:storeSelector aspect -->
        <config evaluator="aspect-name" condition="cm:storeSelector">
                <property-sheet>
                        <show-property name="cm:storeName" />
                </property-sheet>
        </config>
        <config evaluator="string-compare" condition="Action Wizards">
                <aspects>
                        <aspect name="cm:storeSelector"/>
                </aspects>
        </config>

Hecho lo anterior ya podemos reiniciar el servidor de aplicaciones para que los cambios surtan efecto.

Ahora vamos a ver como empezar a usarlo. Recuerda que el aspecto, aunque pueden aplicarlo todos los usuarios, sólo el usuario administrador podrá especificar el store correspondiente y sólo es aplicable a contenidos (no a espacios). En este ejemplo veremos como hacerlo de forma manual, para sistemas en producción deberíamos hacer un script que modifique dicho metadato automáticamente en base a las necesidades que tengamos, por ejemplo los que estén dentro de un espacio concreto, los que tengan más de N años en el repositorio, etc. El procedimiento sería el siguiente:

  • Localizamos el fichero con el que queremos probar (lo moveremos al storeA).
  • Vamos a “Ver detalles” de dicho fichero y pinchamos en “Ejecutar una acción”
  • Seleccionamos “Agregar aspecto al contenido” -> “ContentStore Selector” -> Aceptar -> Finalizar
  • En las propiedades del fichero ya veremos un nuevo metadato llamado “Store Name”.
    propiedades
    Editamos las propiedades y en Store Name especificamos: storeA
    storea
    Cuando pinchemos en Aceptar, automáticamente el contenido se moverá de forma transparente al filesystem alf_data/storeA/2010/2/17/22/50/4365380f-daf1-494c-b79d-db11480cb171.bin correspondiente, en mi ejemplo, a un fichero pdf.

¿Interesante no?

ACTUALIZACIÓN: para automatizar la clasificación por “Stores” podemos hacer un script en Java Script llamado, por ejemplo, action_storeA.js o B según el sitio donde queramos colocar los ficheros, con el contenido:

document.properties["cm:storeName"]="storeA";
document.save();

Lo guardamos y subimos a Diccionario de datos -> Scripts. Hecho esto podemos ejecutar una acción sobre el fichero de turno y seleccionamos “Ejecutar un script” -> Seleccionamos nuestro script “action_storeA.js” y listo. También podemos incluirlo en una regla y hacer el proceso de forma automática, cuando entren los ficheros a un espacio concreto, o incluso clasificar si son vídeos, imágenes, pdf, cad, etc.

30 thoughts to “Archiving en Alfresco 3.2”

  1. Muy interesante. Como bien dices, asignándole un proceso que directamente los coloque en StoreA cuando pase un tiempo, o que avise a los usuarios correspondientes, debe quedar una cosa bastante chula.

  2. Gracias a los dos. La potencia de los scripts en Alfresco, junto con las acciones y las reglas (ejecutar un script) es considerable así como su planificador de tareas, se le puede sacar mucho jugo a todo esto.

    Hablándolo con Fernando (fegor), se puede poner ese aspecto como parte del tipo “content” por defecto y de esa forma es más fácil ir clasificando el contenido a posteriori. También se pude mejorar el “Action Wizard” para que mediante una regla más sencilla y sin necesidad de script, podamos clasificar el contenido por stores automáticamente. Por ejemplo, todo lo que entre en un espacio (directorio) concreto, que lo almacene en el storeA.

  3. Interesnate post Toni, pero mas que archiving yo estaria hablando de la posibilidad de realizar ILM en cuanto a la getión del almacenamiento que utiliza el gestor documental Alfresco. Resulta realmente interesante poder priorizar el I/O del online de datos mas utilizado a nivel de aplicación frente al menos utilizado al igual que el online de tipo historico. En cualquier caso habria que considerar igualmente la gestión del almacenamiento como backend de cada uno de este tipo de FileSystems, en este aspecto ZFS incorpora estructuras de tipo pool realmente potentes por la discriminación de la configuración de los niveles de tolerancia a fallos RAID, al igual que las caches de escritura y/o lectura en discos SAS (caros), SATA (mas baratos) e incluso SSD (mas rapidos).

  4. Hola Toni:

    Muy interesantes las posibilidades del content store selector combinados con las reglas de contenido de Alfresco. Sabes si esta disponible esta característica con la versión Community 3.2? Y con las versiones 3.1.1 (Enterprise o Community)?

    Un saludo.

    –C.

  5. Si Victor, la verdad es que sería más apropiado haberlo dicho de otra forma, es decir, como implementar HSM (http://en.wikipedia.org/wiki/Hierarchical_storage_management) basados en la estrategia ILM (http://es.wikipedia.org/wiki/Information_Lifecycle_Management) en Alfresco, no? 😉

    Cesar, por lo que he hablado con Alfresco y según la wiki, por ahora sólo está disponible para la versión Enterprise 3.2. Entiendo que este tipo de opciones sólo son útiles para instalaciones en sistemas de producción con gran volumen de datos para los que está destinado la versión Enterprise.

    Gracias a los dos por los comentarios!!

  6. Sobre la actualización, exacto, era lo que te comentaba. Es más, puedes hacer que se realice todo al mismo tiempo, es decir, la asignación del aspecto y del valor concreto en el mismo script.

    Por ejemplo, en un script llamado StoreB.js

    var props = new Array(1);
    props[“cm:storeName”] = “storeB”;
    document.addAspect(“cm:storeSelector”, props);

  7. Pingback: Cesar Capillas
  8. Muchas gracias Toni por la información.

    Soy novata en Alfresco y la verdad es que me esta resultando muy útil.
    Pero al intentar ejecutar tu ejemplo, me he encontrado con un problema.
    Mi tomcat no es capaz de encontrar el bean storeSelectorContentStoreBase.
    Y creo que me va a suceder lo mismo con fileContentStore y baseContentService.

    Te agradecería mucho si me pudieras aclarar donde esta definida esta clases.
    Y si debe estar definida dentro del propio sample-content-store-selector-context.xml, ¿Podrías facilitarme su código?.

    Muchas gracias de antemano y un saludo.

  9. Hola María José, que versión de Alfresco estás utilizando? Recuerda que esta opción es válida para la versión Enterprise solamente, por ahora.

    Gracias por comentar en el blog.

  10. Buenos días Toni.
    Pues creo que va a ser eso.
    Yo estoy usando el Alfresco Community 3.2.
    ¿Y existe alguna alternativa para hacer esto mismo con Alfresco Community?.
    Muchisimas gracias por contestar tan rápido.
    Un saludo.

  11. Hola, pues por ahora no existe una alternativa de esa misma forma. Se podría jugar con los directorios de Año/Mes/Día a nivel de file system pero no a nivel de contenidos. No se si el Transfer Service te puede servir aunque no es para eso. El TS está disponible en la 3.3 Community.

    Saludos.

  12. Hola Toni,

    Muy interesante lo que comentas de hecho nosotros queremos hacer eso precisamente para mantener un historico. El caso es que me gustaría que este historico no se idenxará y no se viera en la búsqueda de documentos. Se podría indicar que no se tenga en cuenta este repositorioen las búsquedas ni en la indexación?

  13. Gracias Aina,

    Muy buena pregunta la tuya, aunque como caso de uso no se si tiene mucho sentido, si tienes la información almacenada pero no la puedes localizar, ¿para que la necesitas? Igual se podría filtrar por metadatos para evitarlas en las búsquedas modificando el formulario de búsquedas.

    La semana que viene hacemos un webinar donde hablaremos de estos temas:

    http://www.alfresco.com/es/about/events/2011/06/%20gestion_del_almacenamiento_en_alfresco/

    Saludos.

  14. Hola Toni,

    A pesar de la antiguedad del post me ha resultado útil para la versión de Alfresco con la que estoy trabajando (4.1) me parece que el principio de la activación del contentStoreSelector es el mismo.

    En mi caso por limitaciones técnicas del espacio donde se almacenan los documentos fue necesario crear otro espacio distinto para continuar almacenando los nuevos documentos manteniendo los anteriores en donde estaban y pudiendo acceder de forma transparente tanto a los antiguos como a los nuevos.

    Al leer por primera vez el post entendí que para poder llevar a cabo lo que necesitaba hacer tenia que a parte de activar el contentStoreSelector configurar bien sea por un script o de otro modo cada nuevo documento para especificarle que se archivaría en el nuevo contentStore. Ya constaté que para lo que yo necesitaba no era necesario ésto solo activar el contentStoreSelector y especificar el store default será el nuevo, de ésta manera ya todos los nuevos documentos irán a éste nuevo espacio y podrás seguir viendo los anteriores en el espacio anterior de forma transparente para el usuario.

    Saludos

  15. Hola Leo, si mal no recuerdo, en el training que os di os pasé archivos de ejemplo para implementarlo, hay que tener en cuenta otros factores como el eagerCleaner, contáctame por email si necesitas algo adicional. Recuerda también que en el portal de soporte hay un KB sobre eso.

    Saludos.

  16. Hola TONI
    Muchas gracias por tu post, me ha ayudado a entender el problema que se me está presentando, resulta que estoy usando alfresco community versión 4.2.e y últimamente he tenido problemas con la velocidad, he mirado el servidor y la capacidad esta en 63% y lo único que hace que vuelva a trabajar correctamente es parar los servicio y subirlos nuevamente. Te cuento esto porque me gustaría saber si hay alguna solución para este problema ya que dice que solo está disponible en Enterprise, no pues teniendo en cuenta la fecha.

    Muchas gracias.

  17. Hi TONI sorry if I write in english but I don’t know espanol (i used translator to read article), i have succesfully moved data between /alfresco…/alf_data/contentstore to /alfresco…/alf_data/storeA but when i check disk space, there is a copy of data in both path. Can you help me please?

  18. Hi TONI,

    I have read this article:

    http://blyx.com/2014/08/18/understanding-alfresco-content-deletion/

    and to test I added in alfresco-global.properties file these rows:

    system.content.eagerOrphanCleanup=true #a
    system.content.orphanProtectDays=0 #b
    system.content.orphanCleanup.cronExpression=0 0/5 * * * ? #c

    a) data don’t stay in contentstore.deleted, but they will be deleted directly
    b) time to wait until data is removed from contentstore directory
    c) process that checks orphanProtectDays and move/delete data from contentstore value in DB is set every 5 minutes

    This effectively works when I delete datas from trashcan, freeing immediately space on my disk, but they remain stored in double when I use contentstore selector (contentstore and store A directories) anyway until I dont delete them from trashcan.

    I think that the link I provide is the same that you refer in your previous post.

    Sorry if I ask to you again but i’m evaluating trial version of Alfresco One before decide to buy it and it’s difficult find public information about this argument.

    Thank you so much if you can help me.

  19. Hi DB,
    Answering your questions:
    a) yes, once trashcan is empty contents are gone (deleted from filesystem, never go to contentstore.deleted).
    b) if you use eagerOrphanCleanup you don’t have to worry about this because nothing has to be protected before going to contentstore.deleted since this is not going to happens.
    c) same as before, leave it by default.

    If using Content Store Selector this doesn’t work in the same way it should be because you don’t have it properly configured. You should have something like this in your content-store-selector-context.xml file http://pastebin.com/508a3zzx (see section eagerContentStoreCleaner).

    Additionally, we have to documents covering this and other related topics here:
    http://www.slideshare.net/toniblyx/alfresco-security-best-practices-guide
    http://www.slideshare.net/toniblyx/alfresco-backup-and-disaster-recovery-white-paper?related=1

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.