miércoles, 4 de abril de 2012

Content Store Selector

Una de las consultas más habituales cuando se está haciendo una instalación de Alfresco es si existe la posibilidad de guardar los documentos en diferentes discos dependiendo de alguna característica como, por ejemplo, su tamaño. La respuesta es sí.

El mecanismo más simple para conseguir repartir los contenidos en diferentes discos es utilizar el aspecto storeSelector. Este aspecto va incluído por defecto en Alfresco pero no es accesible para los usuarios a través de los clientes web. La definición de este aspecto es muy simple ya que incluye una única propiedad llamada storeName y que indica el nombre del store donde se almacenará físicamente el contenido. 

En la configuración por defecto de Alfresco, sólo existe un store definido por el bean fileContentStore. Para definir nuevos stores hay que crear nuevos beans que apunten a la ubicación donde queremos que se guarden los contenidos. Por jemplo:

<bean id="imagesFileContentStore" class="org.alfresco.repo.content.filestore.FileContentStore">
      <constructor-arg>
         <value>${dir.root}/images</value>
      </constructor-arg>
   </bean>

En la definición del bean el elemento importante es la ruta a la ubicación física donde se guardarán los contenidos.

El siguiente elemento a definir es el contentStoreSelector, que hace referencia a todos los stores válidos definidos en Alfresco. Para el store anterior, este elemento sería así:

<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="images">
                   <ref bean="imagesFileContentStore" />
               </entry>
          </map>
       </property>
   </bean>

Con este bean identificamos cual es el store por defecto de todos los contenidos (default) y la lista completa de los stores disponibles (default, images).

Una vez definidos los stores sólo falta decidir como aplicar el aspecto storeSelector a los contenidos. El mecanismo más seguro es mediante un behaviour, aunque para este ejemplo lo haremos con una regla. Esta regla realizará dos acciones: primero, asignar el aspecto al contenido, y segundo, ejecutar un script que dé valor a la propiedad storeName.

El contenido del script puede ser tan sencillo como:

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

Como se puede comprobar, el valor que hay que darle a la propiedad storeName coincide con el que se haya usado en el bean storeSelectorContentStore.

La definición de la regla podría ser esta:



De esta forma, cualquier documento de tipo TIFF que se cree en el repositorio se guardará en el nuevo store, y el resto de contenidos se almacenará en el store por defecto.

Hay que recordar que el aspecto storeSelector no aparece por defecto en los clientes web de Alfresco por lo que para crear la regla desde Share habrá que añadir el aspecto en el elemento DocumentLibrary del fichero share-config-custom.xml.

<aspects>
         <visible>
            <aspect name="cm:generalclassifiable" />
            <aspect name="cm:complianceable" />
            <aspect name="cm:dublincore" />
            <aspect name="cm:effectivity" />
            <aspect name="cm:summarizable" />
            <aspect name="cm:versionable" />
            <aspect name="cm:templatable" />
            <aspect name="cm:emailed" />
            <aspect name="emailserver:aliasable" />
            <aspect name="cm:taggable" />
            <aspect name="app:inlineeditable" />
            <aspect name="gd:googleEditable" />
            <aspect name="cm:geographic" />
            <aspect name="exif:exif" />
            <aspect name="cm:storeSelector"/>
         </visible>
         ... 

      </aspects>

Un hecho destacable es que tal como está implementado este mecanismo, el efecto sobre el espacio de disco ocupado por los contenidos puede no ser el esperado a priori. Cuando se sube un contenido, siempre se guarda en el store por defecto, y cuando se ejecuta la regla, el contenido se copia a la ubicación indicada por el nuevo store. El hecho de que el contenido se copie implica que ocupa espacio tanto en el store por defecto como en el nuevo store. Esta duplicidad se resuelve cuando se ejecuta el proceso de eliminación de huerfanos del store por defecto.

Si se quiere evitar la duplicidad de contenidos por esta causa, se ha de añadir esta propiedad en la configuración del Alfresco:

system.content.eagerOrphanCleanup=true

Esto hará que la copia que se quedaba en el store por defecto sea eliminada al momento.