cancel
Showing results for 
Search instead for 
Did you mean: 

Creación de carpeta y comprobación si está creada(Action rule)

kaecius
Champ on-the-rise
Champ on-the-rise

Buenos días , estoy realizando una acción en java que mediante una regla todo el contenido que sea insertado se mueva a otra carpeta indicada como parámetro y sean organizados en dicha carpeta según un plantilla de fecha (yyyy/MM/dd) dada como parámetro y la fecha de creación.

Un ejemplo sería mover un archivo llamado 'test.txt' a la carpeta de inserción (con la regla añadida). La acción que se ejecutaría en el momento que ese archivo estuviera dentro de la carpeta de inserción comprobaría si las carpetas con la plantilla dada están creadas (suponiendo que la fecha de creación fuese hoy , las carpeta a comprobar serían 2017/ , 2017/04/, 2017/04/21/), si alguna de ellas no está creada la crearía y si no simplemente se movería a dicha carpeta.

El problema que estoy teniendo es a la hora de comprobar las carpetas de forma concurrente, concretamente el problema sucede cuando la carpeta no está creada y mi código la tiene que crear, uno de los hilos la crea y los demás saltan a la excepción que tengo capturada (FileExistsException), donde  hago una segunda comprobación de la carpeta con el mismo método utilizado antes para comprobar si ya está creada (fileFolderService.simpleSearch()).

Se supone que los hilos que entren a ese catch tendrían que buscar la carpeta ya creada por el primer hilo y cogerla pero no es así , ese método que utilizo para comprobar si está la carpeta me devuelve null y por lo tanto de todos los hilos ejecutados únicamente el que ha creado la carpeta es el que termina la ejecución los demás devuelven null en la búsqueda de las carpetas.

He probado a que todos los hilos que entren en el try catch de (FileExistsException) entraran en bucle hasta que el método devolviera el NodeRef de la carpeta, pero ningún hilo llega a pasar el NodeRef y se quedan en bucle hasta que manualmente paro alfresco.

private NodeRef check(NodeRef parent, String folderPathName) {
            NodeRef resultNodeRef = null;
            NodeRef temp = null;
            synchronized (this) {
               temp = fileFolderService.searchSimple(parent, folderPathName);
            }
            if (temp != null) {
                  resultNodeRef = temp
;

            } else {
                  
try {
                        resultNodeRef =
fileFolderService.create(parent, folderPathName,

                                                         ContentModel.TYPE_FOLDER).getNodeRef();

                  } catch (FileExistsException ex) {

                         resultNodeRef = fileFolderService.searchSimple(parent, folderPathName);

                  }
            }

   return resultNodeRef;

}

8 REPLIES 8

cristinamr
World-Class Innovator
World-Class Innovator

Te cuento lo que veo:

private NodeRef check(NodeRef parent, String folderPathName) {
            NodeRef resultNodeRef = null;
            NodeRef temp = null;
            synchronized (this) {
               temp = fileFolderService.searchSimple(parent, folderPathName);
            }

Hasta aquí lo que veo:

  • Le pasas el la referencia del nodo  y el nombre del padre
  • Seteas el result y temp a nulo
  • temp toma el valor que te devuelva la búsqueda del nodo por el padre.


            if (temp != null) {
                  resultNodeRef = temp
;

  • Si temp no es nulo, significa que está creada y lo guardas en result.
                

            } else {
                  
try {
                        resultNodeRef =
fileFolderService.create(parent, folderPathName,

                                                         ContentModel.TYPE_FOLDER).getNodeRef();

  • Si no está creada (es decir, temp es nulo),  creas un nodo donde el padre es folderPathName.

                  } catch (FileExistsException ex) {

                         resultNodeRef = fileFolderService.searchSimple(parent, folderPathName);

  • En caso de error lo capturas (bien hecho!)

                  }
            }

}

Si te das cuenta, no tienes un return y en la función le dices que vas a devolver un NodeRef. ¿Puedes arreglarlo y nos cuentas?

--
VenziaIT: helping companies since 2005! Our ECM products: AQuA & Seidoc

Sí , el return está solo que al copiar me lo he comido , en principio tal y como lo cuentas es la lógica que tiene que seguir pero a partir de que se crea la carpeta los demás hilos  entran al catch(cosa que debe pasar) pero la búsqueda me devuelve null cosa que no tendría que pasar ya que ya se ha creado la carpeta en algún hillo anterior a ese

cristinamr
World-Class Innovator
World-Class Innovator

Buenas Daniel.

He mirado la api y el metodo search con el FileFolderService está deprecated (en futuras versiones lo quitarán). Aquí la api del alfresco 5.1. ¿Por qué no pruebas con el SearchService? Lo coges e inicializas del ServiceRegistry (como el FileFolderService) y aquí te dejo un ejemplo de cómo puedes hacerlo (ve a la sección que pone Obtaining a NodeRef).

Un saludo,

Cris.

--
VenziaIT: helping companies since 2005! Our ECM products: AQuA & Seidoc

Ok, probaré dicho servicio y comentaré si me ha funcionado , principalmente utilizo fileFolderService con simpleQuery ya que hace las consultas directamente a la BD y no por SOLR ya que la indexación sería asincrona y no recibiría el noderef durante la ejecución de los hilos concurrentes

He mirado la API java y elll que está deprecated es la búsqueda por el metodo search y no el metodo searchSimpe que es el que uso, en cualquier caso, he estado realizando pruebas y mi metodo funciona perfectamente , el problema lo he podido encontrar al utilizar diferentes conectores a distintas bases de datos, es decir, si utilizo un alfresco con la BD que crea en su postgreSQL funciona perfectamente, pero si utilizo MySQL ya no funciona.

cristinamr
World-Class Innovator
World-Class Innovator

Ostras, pues tienes razón en cuanto al deprecated (nota mental: Necesito más café por las mañanas jajaja).

Pues Daniel, desarrollo en Alfresco y no me ha ocurrido nunca lo que comentas. A ver si alguien puede darnos la luz sobre por qué funciona con postgresql y no con Mysql. Es que además, si te paras a pensar, en realidad tu utilizas servicios y esos servicios manupilarán los datos y realizaran lo que tenga que hacer.. Vamos que para el desarrollador debería ser transparente la base de datos (siempre que esté sorportada por el producto, claro).

Un saludo,

Cris.

--
VenziaIT: helping companies since 2005! Our ECM products: AQuA & Seidoc

Sí, es tal y como dices, para mi desarrollo lo que importa es el servicio que estoy utilizando ya que él es el que se encarga de la manipulación de los datos sobre la base de datos que sea en ese momento. A ver si alguien puede ayudarnos a resolver este problema ;D. Gracias !!

togomez
Champ on-the-rise
Champ on-the-rise

Recientemente en la Beecon 2017 ha habido una charla relacionada. El vídeo aún no está disponible (supongo que lo estará en breve), pero puedes consultar las transparencias: Alfresco repo under concurrent write load.

El error podría estar relacionado con el modo en que Alfresco gestiona las transacciones y estas podrían tambien estar influídas por la base de datos concreta que se use; en cualquier caso, parece buena idea cambiar el synchronized y buscar una solución con el RetryingTransactionHelper.