
Nuestro Alfresco Simple OCR Action se ha convertido en los últimos meses en el addon de referencia para incorporar un servicio de OCR a la versión Community de Alfresco tanto en servidores Linux como en servidores Windows.
A pesar de que en muchos casos la guía de configuración provista en GitHub es suficiente, existen otros escenarios de uso intensivo que requieren un despliegue más complejo. En este artículo os mostramos cómo configurar un servicio de OCR para Alfresco alojado en un servidor externo, lo que permite mantener la calidad de servicio de Alfresco independientemente del nivel de carga OCR que esté experimentando el sistema.
Describiremos una configuración de Alfresco comunicándose por SSH con un servidor de OCR corriendo pdfsandwich en un CentOS 7, pero podéis utilizar otro protocolo de comunicación, sistema operativo Windows o un software de OCR distinto para implementar vuestro servicio.
Configuración del servidor de OCR
Software requerido:
- CentOS Linux release 7.3.1611 (Core)
- pdfsandwich 0.1.4
Puertos requeridos:
- 22 (SSH): servicio de proceso OCR de pdfsandwich
La aplicación pdfsandwich es utilizada para la generación de PDFs buscables a partir de ficheros PDF con imágenes o imágenes TIFF. Este servicio será invocado por línea de comandos desde Alfresco a través del addon Alfresco Simple OCR instalado en el servidor de Alfresco.
Instalando pdfsandwich
Se instalan las dependencias necesarias.
$ yum -y install wget gcc gcc-c++ make autoconf automake libtool libjpeg-devel libpng-devel libtiff-devel zlib-devel ocaml ImageMagick ImageMagick-devel
Se instala el programa leptonica a partir de los fuentes.
$ wget http://www.leptonica.org/source/leptonica-1.72.tar.gz $ tar xvf leptonica-1.72.tar.gz $ cd leptonica-1.72 $ ./configure $ make $ make install
Se instala el programa tesseract OCR a partir de los fuentes.
$ wget http://github.com/tesseract-ocr/tesseract/archive/3.04.01.tar.gz $ tar xvf 3.04.01.tar.gz $ cd tesseract-3.04.01 $ ./autogen.sh $ ./configure $ make $ make install $ ldconfig
Se instalan todos los paquetes de idioma de tesseract.
$ wget https://github.com/tesseract-ocr/tessdata/archive/3.04.00.tar.gz $ tar xvf 3.04.00.tar.gz $ mv tessdata-3.04.00/* /usr/local/share/tessdata/
Se instala el programa unpaper a través de su RPM.
$ wget http://dl.fedoraproject.org/pub/epel/6/x86_64/unpaper-0.3-4.el6.x86_64.rpm $ rpm -ivh unpaper-0.3-4.el6.x86_64.rpm
Se instala el programa pdfsandwich a partir de los fuentes.
$ wget http://downloads.sourceforge.net/project/pdfsandwich/pdfsandwich%200.1.4/pdfsandwich-0.1.4.tar.bz2 $ tar xvf pdfsandwich-0.1.4.tar.bz2 $ cd pdfsandwich-0.1.4 $ ./configure $ make $ make install
Se verifica que el programa ha sido correctamente instalado.
$ pdfsandwich -version pdfsandwich version 0.1.4
Configuración del servidor de Alfresco
Una vez instalado un Alfresco en el addon Alfresco Simple OCR, creamos un script para la invocación al servidor remoto de OCR.
#!/bin/bash # pdfsandwich hostname PDFSANDWICH_SERVER="alfresco-ocr.keensoft.es" # extract filenames INPUT=$(basename "$3") OUTPUT=$(basename "$5") # SSH parameters SCP=scp SSH=ssh # copy original pdf to pdfsandwich server $SCP $3 root@$PDFSANDWICH_SERVER:/tmp/$INPUT # execute pdfsandwich program (requires administrator privileges) $SSH root@$PDFSANDWICH_SERVER "pdfsandwich $1 $2 /tmp/$INPUT $4 /tmp/$OUTPUT $6" # copy transformed pdf back to alfresco server $SCP root@$PDFSANDWICH_SERVER:/tmp/$OUTPUT $5 # remove temporal files $SSH root@$PDFSANDWICH_SERVER "rm -f /tmp/$INPUT; rm -f /tmp/$OUTPUT"
Se genera la clave RSA en el servidor de Alfresco y se envía la parte pública al servidor de OCR para permitir comandos ssh sin interacción.
$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. $ ssh-copy-id -i ~/.ssh/id_rsa.pub alfresco-ocr.keensoft.es
Se actualiza la propiedad de alfresco-global.properties para que utilice el script que hemos creado arriba.
ocr.command=/opt/alfresco/scripts/ocr.sh
Se reinicia el servicio de Alfresco.
$ systemctl restart alfresco
Conclusiones
Una vez realizada esta configuración, los trabajos de OCR serán enviados por Alfresco al servidor externo alfresco-ocr.keensoft.es, permitiendo mantener la calidad de servicio en el propio servidor de Alfresco. También es posible aumentar la capacidad de este servicio, configurando el pool de hilos asíncronos de Alfresco.
# Default Async Action Thread Pool default.async.action.threadPriority=1 default.async.action.corePoolSize=8 default.async.action.maximumPoolSize=20
En ocasiones, para mejorar la calidad de servicio de Alfresco no es necesario disponer de nuevo software, sino de instalar el disponible de la manera adecuada.
Hola Angel,
Muchas gracias por tus contribuciones. Me preguntaba si podrias ayudarme.
He intentado en más de cinco ocasiones configurar el servidor de pdfsandwich remoto (en local funciona sin problemas).
Para poder instalar simple-ocr y que alfresco inicie, no he encontrado otra manera que instalar también pdfsandwich en el servidor “local”.
servidor debian 8.7.1 (local)
alfresco 5.2
servidor ubuntu 16.1 (también intentado 13.1 con idéntico resultado) (remoto)
pdfsandwich 0.1.6
tesseract 3.03
leptonica 1.71
unpaper 0.4.2
Modificando el archivo “alfresco-global.properties”, según indica la web de simple-ocr, pero usando el script que llama al procedimiento remoto, en lugar de la primera línea:
#ocr.command=/usr/local/bin/pdfsandwich
ocr.command=/opt/alfresco-community/scripts/ocr.sh
ocr.output.verbose=true
ocr.output.file.prefix.command=-o
ocr.extra.commands=-verbose -lang spa+eng+fra
ocr.server.os=linux
En mi caso, debo cambiar las variables del script “ocr.sh” que propones, puesto que la salida es:
/opt/alfresco-community/scripts/ocr.sh -verbose -lang cat+spa /opt/alfresco-community/tomcat/temp/Alfresco/OCRTransformWorker_source_5849973338233067610.pdf -o /opt/alfresco-community/tomcat/temp/Alfresco/OCRTransformWorker_source_5849973338233067610_ocr.pdf
así que…
$1: -verbose
$2: -lang
$3: spa
$4: source_path
$5: -o
$6: destination_path
pdfsandwich INPUT -lang spa -verbose -o OUTPUT
$SSH root@$PDFSANDWICH_SERVER “pdfsandwich /tmp/$INPUT $2 $3 $1 $5 /tmp/$OUTPUT”
para cumplir:
pdfsandwich INPUT -lang spa -verbose -o OUTPUT
y el error que aparece, en “catalina.out” es:
2017-04-22 09:37:50,217 WARN [alfresco.ocr.OCRExtractAction] [http-apr-8080-exec-5] workspace://SpacesStore/32e14ff1-a103-405a-8510-5187b01d989b: Node does not exist: workspace://SpacesStore/32e1$
2017-04-22 09:37:50,254 INFO [alfresco.ocr.OCRTransformWorker] [http-apr-8080-exec-5] EXIT VALUE: 127
2017-04-22 09:37:50,254 INFO [alfresco.ocr.OCRTransformWorker] [http-apr-8080-exec-5] STDOUT:
2017-04-22 09:37:50,254 INFO [alfresco.ocr.OCRTransformWorker] [http-apr-8080-exec-5] STDERR: /usr/bin/ssh: relocation error: /usr/bin/ssh: symbol EVP_des_cbc, version OPENSSL_1.0.0 not defined $
lost connection
/usr/bin/ssh: relocation error: /usr/bin/ssh: symbol EVP_des_cbc, version OPENSSL_1.0.0 not defined in file libcrypto.so.1.0.0 with link time reference
ssh: relocation error: ssh: symbol EVP_des_cbc, version OPENSSL_1.0.0 not defined in file libcrypto.so.1.0.0 with link time reference
2017-04-22 09:37:50,267 ERROR [web.scripts.RepositoryContainer] [http-apr-8080-exec-5] Server error (03220024)
java.lang.RuntimeException: java.lang.RuntimeException: org.alfresco.service.cmr.repository.ContentIOException: 03220023 Failed to perform OCR transformation:
Execution result:
os: Linux
command: /opt/alfresco-community/scripts/ocr.sh -verbose -lang cat+spa /opt/alfresco-community/tomcat/temp/Alfresco/OCRTransformWorker_source_6184988632786898645.pdf -o /opt/alfresco-communit$
succeeded: true
exit code: 127
out:
err: /usr/bin/ssh: relocation error: /usr/bin/ssh: symbol EVP_des_cbc, version OPENSSL_1.0.0 not defined in file libcrypto.so.1.0.0 with link time reference
lost connection
/usr/bin/ssh: relocation error: /usr/bin/ssh: symbol EVP_des_cbc, version OPENSSL_
at es.keensoft.alfresco.ocr.OCRExtractAction.executeImplInternal(OCRExtractAction.java:143)
at es.keensoft.alfresco.ocr.OCRExtractAction.executeImpl(OCRExtractAction.java:88)
at org.alfresco.repo.action.executer.ActionExecuterAbstractBase.execute(ActionExecuterAbstractBase.java:274)
at org.alfresco.repo.action.ActionServiceImpl.directActionExecution(ActionServiceImpl.java:846)
at org.alfresco.repo.action.executer.CompositeActionExecuter.executeImpl(CompositeActionExecuter.java:73)
at org.alfresco.repo.action.executer.ActionExecuterAbstractBase.execute(ActionExecuterAbstractBase.java:274)
at org.alfresco.repo.action.ActionServiceImpl.directActionExecution(ActionServiceImpl.java:846)
at org.alfresco.repo.action.ActionServiceImpl.executeActionImpl(ActionServiceImpl.java:747)
at org.alfresco.repo.action.ActionServiceImpl.executeAction(ActionServiceImpl.java:581)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:41)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:53)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:166)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
Creo que si usas el ejemplo tal cual está funcionará. ¿Has probado a realizarlo así? No entiendo demasiado bien el cambio que haces…
Hola,
Me gustaría saber si ofreceis el servicio de instalación remota de simple ocr en una instalación limpia de alfresco
Así como el precio del servicio
Un saludo y gracias
Un saludo