martes, 23 de febrero de 2016

Desplegar servicios Web con y sin autenticación

Es una pregunta recurrente. ¿Cómo se deben desplegar los servicios Web? ¿Cómo gestionar la autenticación?

En base a la experiencia que tenemos en otros clientes, es posible usar un usuario con permisos limitados para invocar los servicios. Esta opción inicialmente está bien, pero si estudiamos los requisitos de seguridad posiblemente se nos queda corto.

Lo ideal sería:
1 - Dejar el acceso al portal privado y evitar el acceso al puerto del portal desde el exterior
2 - Utilizar un puerto diferente para las invocaciones de servicios web y habilitar SSL si es necesario
3 - Facilitar el acceso no autenticado en la invocación del servicio si no es necesario identificar el usuario que invoca
4 - Establecer políticas de seguridad especificas para los usuarios y procesos que puedan ser invocados desde el exterior, como en este caso los servicios web.

Resumiendo la situación, cuando se despliega un servicio web en Ensemble, este servicio puede ser invocado a través del CSP Gateway (habilitando la propiedad "entable standard request" de manera que se dispone de URL) o a través del puerto directo del adaptador (no se dispone URL, solo servidor y puerto). 

Esta imagen representa la configuración expuesta en el párrafo anterior:



OPCIÓN 1:
Podéis utilizar para los servicios solo el puerto del adaptador, de manera que podéis establecer políticas de acceso y seguridad mediante cortafuegos, etc. diferentes para cada uno de estos puertos. Así podéis conservar el puerto del CSP Gateway privado dentro de una red limitada y solo con objeto de administración (es el canal que se utiliza para llegar al portal de gestión), mientras que el puerto del adaptador lo podéis hacer público para posibilitar la invocación del servicio. 

Sin embargo esta opción tiene un par de restricciones, al no pasar por el CSP Gateway el WSDL no puede ser consultado por ese canal (el WSDL solo se genera a través de CSP, aunque esto se puede resolver publicando el WSDL de manera estática en una URL) pero además no puedes establecer estrategias de seguridad basadas en CSP a la hora de invocar el servicio.

OPCIÓN 2:
Simplemente crear una nueva aplicación dentro del Namespace de la producción. De esta manera no necesitas un usuario con permisos especiales, incluso puedes no necesitar autenticación en el servicio y entonces se usará el UnknowUser como usuario que lo invoca.

Para tener 2 aplicaciones web asociadas al mismo Namespace (y así tener diferentes niveles y políticas de seguridad en una y en otra) hay que ir a security —> Web aplications y crear una nueva aplicación que use el mismo Namespace. Luego en el servicio web añadir un parámetro:

Parameter LOCATION = "http://localhost:57773/csp/test2”; // Cambiar por la URL de tu aplicación

Por supuesto hay que tener en cuenta que el usuario que invoque el servicio tenga los roles de acceso adecuados dentro del namespace.

Aquí el problema es que utilizareis el mismo puerto para los servicios como para el portal de manera que no se puede limitar el acceso desde el exterior mediante cortafuegos o similares.

OPCIÓN 3:
Esta es la opción más general, consiste en instalar un nuevo servidor web (canal CSP Gateway) para manejar las peticiones por un puerto diferente del portal de administración (en este caso 1981), esto soluciona gran parte de las cuestiones de seguridad ya que las llamadas pasan por un canal CSP diferente al del canal de administración que queda privado. 

De esta manera la configuración sería la siguiente:



Para llevarla a cabo solo es necesario instalar un nuevo servidor web conectado a un nuevo CSP Gateway y configurarlo correctamente. Requiere hacer instalación de un par de componentes en la máquina (el servidor y el CSP gateway).

El problema es tener que involucrar a recursos de sistemas. Aunque a priori esta solución te pueda parecer algo complicada, es muy flexible y escalable y no es difícil de implementar.

Espero haberme explicado adecuadamente. 

martes, 19 de mayo de 2015

Guía rápida de Apache 2.4 como Servidor Web de Ensemble

Esta es una guía rápida de configuración de Apache 2.4 para actuar como servidor web para Ensemble. Esta guía esta escrita para Windows.

PASO1:
Descargar la versión 2.4 de Apache para windows. Yo lo he hecho desde http://www.apachehaus.com/cgi-bin/download.plx

PASO2:
Después de descomprimir el ZIP podemos colocar el contenido en c:\Apache24, tendremos una estructura como esta:


PASO3:
Dentro de c:\Apache24, crear el directorio CSPGateway\bin. Dentro de este directorio estarán los siguientes ficheros:

CSPa24.dll
CSPa24Ssys.dll
CSP.ini

Estos ficheros se pueden copiar del directorio de CSP/bin de instalación de Ensemble.

PASO4:
Modificar el fichero httpd.conf dentro de c:\Apache24\conf, añadir las siguientes entradas (la primera es la ruta al fichero CSPa24.dll que acabamos de copiar, las siguientes son las rutas a los directorios virtuales que creemos, en este caso se presenta el directorio completo CSP de la ruta de instalación como ejemplo, en este caso se podría servir el portal de gestión desde el nuevo servidor web):

#### BEGIN-ApacheCSP-SECTION ####
LoadModule csp_module_sa C:/Apache24/CSPGateway/bin/CSPa24.dll 
<Location "/csp/bin/Systems/"> 
  SetHandler csp-handler-sa 
</Location> 
<Location "/csp/bin/RunTime/"> 
  SetHandler csp-handler-sa 
</Location>
<Location /csp>
   CSP On 
   SetHandler csp-handler-sa
</Location> 
CSPFileTypes csp cls zen cxw 
Alias /csp/ c:/InterSystems/Ensemble/CSP/ 
<Directory "c:/InterSystems/Ensemble/CSP"> 
    AllowOverride None 
    Options MultiViews FollowSymLinks ExecCGI 
    Require all granted
    <FilesMatch "\.(log|ini|pid|exe)$"> 
    Require all denied 
    </FilesMatch>
</Directory> 
#### END-ApacheCSP-SECTION-CACHE ####

PASO5:
Instalar el servidor web como servicio (desde el directorio  c:\Apache24\bin, ejecutar):

C:\Apache24\bin>httpd -k install

PASO6:
Iniciar el servidor web (desde el directorio  c:\Apache24\bin, ejecutar):

C:\Apache24\bin>httpd -k start

PASO5:
Ya es posible accede al portal de Ensemble desde la url
http://localhost/csp/sys/UtilHome.csp

Y a la gestión del CSP Gateway desde
http://localhost/csp/bin/Systems/Module.cxw

miércoles, 15 de octubre de 2014

Publicar Servicios Web en Ensemble

Cuando se despliega un servicio web en Ensemble, este servicio puede ser invocado a través del CSP Gateway (habilitando la propiedad "enable standard request" de manera que se dispone de URL) o a través del puerto directo del adaptador SOAP (no se dispone URL, solo servidor y puerto). 

Esta imagen representa la configuración expuesta en el párrafo anterior:



En la documentación se explica que el uso del adaptador EnsLib.SOAP.InboundAdapter no se recomienda para entornos productivos:
"The EnsLib.SOAP.InboundAdapter class is not meant for production use but can be helpful for debugging and demos"

Y siempre para implementar el servicio se debe seguir estas normas:

En concreto para evitar el uso del adaptador:
"The class should define the ADAPTER parameter as null (“")"

De esta forma siempre se está eligiendo la ruta “CSP”. Pero adicionalmente si se quiere utilizar el mecanismo CSP en entornos productivos, es recomendable instalar un nuevo servidor web (canal CSP Gateway) para manejar las peticiones por un puerto diferente del portal de administración (por ejemplo el 1981), esto soluciona la integración ya que las llamadas pasan por un canal CSP diferente al de administración del portal. 

Tal y como se explica aquí:

"Caché supplies a minimal web server that runs the Management Portal, sometimes called the  private web server . The private web server can also display the supplied CSP samples and run CSP pages. It cannot run robust CSP applications in a production environment. For that, you need to install a separate, full installation of a supported web server, such as Apache web server, Microsoft's IIS web server, or a Sun web server"

De esta manera la configuración sería la siguiente:


El canal que va al puerto 1980 sería el del adaptador SOAP y en producción no se utilizaría. Sin embargo si es para hacer pruebas se puede utilizar.

Por otro lado hay que tener en cuenta que si la aplicación web tiene establecido autenticación mediante password entonces las llamadas requieren utilizar la cabecera SOAP security. Si es para hacer pruebas basta con des-habilitar el mecanismo de autenticación de la aplicación CSP. Otra alternativa es crear una nueva aplicación CSP y dejar una con seguridad y otra con acceso no autenticado. Sin embargo para entornos de producción es más recomendable tener siempre un canal CSP diferente.

viernes, 22 de agosto de 2014

Como hacer un GSIZE

La verdad es que la documentación sobre el GSIZE no es muy clara, pero sin embargo es un comando muy útil porque nos permite ver la distribución del tamaño de la base de datos dentro de los globals, así podemos saber si los datos corresponden a objetos de una clase determinada, si los purgados se realizan correctamente, etc.

Para lanzar el GSIZE se hace desde el terminal:

USER> zn "%SYS"
Cambiar al Namespace %SYS

%SYS>do ^%GSIZE
Lanzar el comando

Directory name: c:\intersystems\e2014\mgr\ =>
Aquí el script está preguntando el directorio donde está el CACHE.DAT del que quieres obtener las medidas. Por defecto sale el directorio de la base de datos de %SYS que normalmente no es la que queremos (Si pulsas RETURN cogerá esa). Hay que mirar la ruta donde está la base de datos de la que queremos las medidas y ponerla ahí.

All Globals? No => yes
Si elegimos "no" entonces tendremos que ir enumerando los globals que queremos analizar, por lo que normalmente elegiremos "yes"

^%nlsmisc    contains no data
Include it anyway? No => no
Aquí pregunta si se incluyen los globals que no tienen datos. Lo habitual es elegir "no".

Exclude any other similar globals without asking again? Yes => yes

A partir de aquí aparece un listado con los globals descartados y finalmente aparece un mensaje similar a este: 

46 items selected from
64 available globals
Show details?? No => yes
Debemos elegir "yes" para tener información detallada

Device: c:\intersystems\e2014\gsize_output.txt
Aquí el script nos pregunta el nombre del fichero para guardar los resultados, si lo dejamos vacío y pulsamos RETURN únicamente aparece en pantalla 

Parameters? "WNS" => 
Pulsamos RETURN para escoger la opción por defecto

Directory name: c:\intersystems\e2014\mgr\ => CTRL+C 
El script nos pregunta iterativamente para ir eligiendo una base de datos cada vez, cuando hayamos analizado todas las elegidas debemos hacer un CTRL+C para terminar


%SYS>

Al finalizar el proceso dispondremos de un fichero con contenido similar a este:

directory: c:\intersystems\e2014\mgr\
Page: 1                           GLOBAL SIZE                                                                            31 Jul 2014
                                                                                                                            10:36 AM
      Global        Blocks       Bytes Used  Packing   Contig.
      --------    --------  ---------------  -------   -------
      %                  2           13,020     80 %         0
      %iKnow           115          835,164     89 %       114
      %IS                1            1,940     24 %         0
      %ISC.SASchema
                         1              612      7 %         0
      %ISC.SASchema.Timestamp
                         1              148      2 %         0
      %ISCLOG            5           36,860     90 %         3
      %ISCStudioTemplate
                         1            6,492     80 %         0
      %MV.DICTDICT       1            1,076     13 %         0
      %MV.DICTMVPIDTAB
                         1              800     10 %         0
      %MV.DICTSYSTEM
                         1              148      2 %         0
      %MV.DICTTERMCMP
                         1               52      1 %         0
      %MV.DICTTERMDEFS
                         1               52      1 %         0
      %MV.DICTVOC        1              328      4 %         0
      %MV.ERRMSG         7           40,269     70 %         5
      %MV.NEWACC         1            7,996     98 %         0
      %MV.TERMDEFS       6           35,900     73 %         5
      %RS                1              836     10 %         0
      %Studio.DocumentHistory
                         1            7,692     94 %         0
      %SYS               4           24,248     74 %         0
      CONFIG             7           38,824     68 %         2
      ISC.Monitor.ComponentD
                         1              244      3 %         0
      ISC.Monitor.Debug
                         1               28      0 %         0
      ISC.Monitor.Health.AlertAge
                         1               36      0 %         0
      ISC.Monitor.Health.Callback
                         1               32      0 %         0
      ISC.Monitor.Health.Startwait
                         1               40      0 %         0
      ISC.Monitor.Interval
                         1               32      0 %         0
      ISC.Monitor.SensorObjectD
                         1            1,632     20 %         0
      ISCMonitor         1               84      1 %         0
      Monitor.ApplicationD
                         1              108      1 %         0
      Monitor.ItemD
                         4           24,700     76 %         2
      Monitor.ItemGroupD
                         1            3,108     38 %         0
      NET                1              592      7 %         0
      oddCOM         1,414       10,353,288     90 %     1,413
      oddDEF           349        2,496,096     88 %       343
      oddDEP             1            1,568     19 %         0
      oddEXTR          122          882,192     89 %       121
      oddMAP           202        1,473,292     89 %       201
      oddPROC          313        2,254,060     88 %       312
      oddSQL            81          585,328     89 %        79
      rINC              97          709,092     90 %        95

directory: c:\intersystems\e2014\mgr\
Page: 2                           GLOBAL SIZE                                                                            31 Jul 2014
                                                                                                                            10:36 AM
      Global        Blocks       Bytes Used  Packing   Contig.
      --------    --------  ---------------  -------   -------
      rINDEX            10           60,532     74 %         6
      rINDEXCLASS        9           61,480     84 %         4
      rINDEXSQL          8           52,316     80 %         6
      rOBJ           2,014       14,248,363     87 %     1,285
      ROUTINE          580        3,962,020     84 %       573
      SYS              952        5,811,096     75 %       795


      TOTAL         Blocks       Bytes Used  Packing   Contig.
      --------    --------  ---------------  -------   -------

                     6,326       44,033,816     85 %     5,364

Como se puede comprobar GSIZE lista cada uno de los globals existentes en la base de datos y para cada uno indica el número de bloques y los bytes usados dentro de los bloques. 

Recordad que un bloque normalmente son 8KB de manera que 10 bloques pueden contener 10 x 8 x 1024 bytes = 81.920 bytes, si ese global por ejemplo indica que dentro de los 10 bloques solo tiene 60.532 bytes entonces la columna packing indicará 74%, eso quiere decir que el 74% está ocupado y el 100-74=26% está disponible y podrá ser usado.





miércoles, 9 de abril de 2014

Banco de Mensajería de Ensemble


El banco de mensajería es una producción especial de Ensemble que está preparada para recoger mensajes de otras producciones remotas.

  
La utilidad del banco de mensajería es poder centralizar y unificar la mensajería de diferentes fuentes en un único repositorio de mensajes global.

Los mensajes son copiados (enviados) desde las producciones “cliente” hacia la producción de banco de mensajería. Los mensajes de las producciones origen o cliente no son eliminados después de ser enviados de manera que sigue siendo necesario el purgado de los mismos.

El banco de mensajería puede recibir cualquier mensaje de cualquier origen, sin embargo no dispone en su Namespace de las clases de definición de estos mensajes (excepto las del sistema como EnsLib.HL7.Message o cualquier otra disponible en los paquetes Ens o EnsLib). Para poder incorporar los mensajes personalizados (es decir los que no son del sistema) al banco de mensajería estos son “serializados” en XML. De esta manera la visualización de los mensajes a través del visor de mensajes cambia:


Menú “Ver” estándar

Menú “Ver” banco de mensajería

En el caso del banco de mensajería, al ser una producción tiene sus propios mensajes (como cualquier otra), aunque esto no es muy habitual, si se envían mensajes que no son los manejados por el servicio del banco de mensajería estos se ven desde el visor de mensajes estándar. 

Sin embargo, todos los mensajes que se reciben desde las producciones cliente con objeto de replicación se ven desde la opción Banked Messages, el log de eventos también se replica y se ve desde la opción Banked Events.

Los mensajes que se ven desde la opción de mensajes almacenados (Banked Messages) tiene una visualización algo diferente a la habitual ya que, como se comentó anteriormente, no se dispone de la definición de las clases.



Como se ve en la imagen anterior los mensajes personalizados se presentan serializados. Además existe una columna Client que identifica el Servidor, la Instancia y el Namespace desde el que se envía el mensaje.

Los mensajes incorporados en el banco de mensajería se registran mediante la clase Ens.Enterprise.MsgBank.MessageHeader. Esta clase tiene las siguientes propiedades:
  •  MessageBodyClassName: Nombre de la clase que contiene el mensaje
  • MessageBodyId: Identificador del objeto que contiene el mensaje
  • ClientBodyClassName: Nombre de la clase cuerpo del mensaje en la producción original.
  • ClientBodyId: Identificador del objeto que contiene el cuerpo del mensaje en la producción original.
Siempre que el mensaje original sea personalizado, es decir, no se implemente con una clase del sistema (Ens o EnsLib) entonces MessageBodyClassName se establece a %Stream.GlobalCharacter y el mensaje se serializa en XML. 

Esto es una restricción ya que aunque la visualización es similar a la acostumbrada, la búsqueda de mensajes en función de su contenido se hace muy complicada y no puede hacerse directamente desde el visor de mensajes (a no ser que sean clases HL7).

Producción de Banco de Mensajería

La producción de banco de mensajería ya está construida, puede obtenerse desde la documentación y es una clase que hereda de Ens.Enterprise.MsgBank.Production.. 

A continuación se muestra una producción de ejemplo msgbank.prod.MsgBankProduction:



Como se puede comprobar la producción solo dispone de dos servicios. El servicio MsgBankService se encarga de recibir los mensajes enviados desde las producciones cliente. Escucha en el puerto 9192 por defecto. En este caso adicionalmente se ha establecido la clase msgbank.util.Helper como Bank Helper Class. Esta clase de ayuda es invocada cada vez que se recibe un mensaje y trata el mensaje en el método OnBankMsg.

ClassMethod OnBankMsg(pHeader As Ens.Enterprise.MsgBank.MessageHeader,
                      …) As %Status
{
 if (pHeader.ClientBodyClassName="test.msg.TestMessage") {
   set bodyId = pHeader.MessageBodyId
   set pStream = ##class(%Stream.GlobalCharacter).%OpenId(bodyId)
   do ##class(msgbank.util.TestSearchTable).IndexDoc(pStream)
 }
 quit $$$OK
}

En este método recibimos el objeto de tipo MsgBank.MessageHeader que ha sido almacenado y podemos realizar acciones adicionales sobre el mismo. Por ejemplo podemos realizar la indexación del mismo mediante una clase tabla de búsqueda.

La tabla de búsqueda realiza la indexación sobre un tipo especifico de objetos. En este caso es necesario implementar una clase tabla de búsqueda sobre objetos de tipo %Stream.GlobalCharacter, sin embargo el stream contendrá un XML diferente en función del ClientBodyClassName que se esté almacenando. De esta forma será necesario implementar una tabla de búsqueda diferente para cada tipo de mensaje que queramos.

Producción Cliente

La producción cliente tan solo debe añadir una operación de negocio de tipo Ens.Enterprise.MsgBankOperation y establecer la IP y puerto del servicio de banco de mensajería. Adicionalmente hay que establecer la propiedad Enable Archiving para que los mensajes puedan ser reenviados a la producción del banco de mensajería.


Para facilitar la compresión de las explicaciones he construido dos producciones como ejemplo del banco de mensajería.
  • Una producción cliente sencilla de ejemplo que simplemente coge un fichero en un formato determinado, genera un mensaje, este mensaje pasa del servicio al proceso y del proceso a la operación (Descargar). También añado un sencillo fichero de entrada de ejemplo (Descargar).
  • La otra producción es la del banco de mensajería que almacena los mensajes reenviados desde la producción original. En esta producción se utiliza una clase de ayuda y una clase de tabla de búsqueda personalizada para el caso del mensaje especifico de la producción ejemplo (Descargar).
La producción cliente se despliegue en un servidor/namespace.
La producción de banco de mensajería se despliega en otro namespace o en otro servidor/namespace

En el namespace de banco de mensajería podrás ver todos los mensajes de la producción cliente y además podrás utilizar la tabla de búsqueda desde el visor de mensajes almacenados.

Espero que sea de utilidad

miércoles, 22 de mayo de 2013

Estrategias de Alta Disponibilidad


En general existen 3 estrategias de alta disponibilidad con Caché/Ensemble:

  • Cluster en Fail-Over de Sistema Operativo
  • HA Basada en Virtualización
  • Caché Database Mirroring

Cada una de ellas tiene una serie de diferencias, pros y contra dependiendo de la infraestructura y sistemas

Cluster Fail-Over
Consiste en utilizar soluciones de Fail-Over proporcionadas a nivel de sistema operativo.
Dos servidores idénticos compartiendo:

  • un dispositivo de almacenamiento (SAN)
  • una dirección IP.

Un servidor (activo) ejecuta el trabajo y el otro permanece en Standby (pasivo) preparado para la transición. Cuando se produce un corte de servicio en el servidor activo el controlador del cluster transfiere el control de la IP y del disco al nodo pasivo y posteriormente inicia los servicios incluyendo Caché.

Análisis de pros y contras:
Transición tras caída de la máquina física por perdida de corriente o similar: 
Se maneja de forma fluida 
Transición por Fallo o Corrupción en almacenamiento: 
Al utilizar un almacenamiento compartido no es posible la transición 
Transición por caída de Caché: 
Puede configurarse pero depende del sistema operativo 
Tiempo de recuperación en transición: 
Pueden ser minutos 
Sincronización de ficheros externos: 
Todos los ficheros están disponibles por ambos nodos 

Alta disponibilidad basada en virtualización
Tecnologías de virtualización como VMWare ESX, proporcionan capacidades de HA. Monitorizan la salud y viabilidad del HW así como de los OS en ejecución. En caso de fallo, el SW de HA automáticamente reinicia la VM que falló en un HW alternativo


Análisis de pros y contras:
Transición tras caída de la máquina física por perdida de corriente o similar: 
Maneja de forma fluida tanto la caída de la física como de la virtual 
Transición por Fallo o Corrupción en almacenamiento: 
Al utilizar un almacenamiento compartido no es posible la transición 
Transición por caída de Caché: 
Puede configurarse pero depende del sistema de VM 
Tiempo de recuperación en transición: 
Pueden ser minutos 
Sincronización de ficheros externos: 
Todos los ficheros están disponibles por ambos nodos 

Mirroring
Un mirror consiste en dos sistemas físicos Caché independientes, llamado failover members. Uno de los miembros tiene el rol de primario, el otro tiene el rol de backup. Los datos se replican desde el primario hacia el backup Es necesario utilizar una dirección IP virtual que es compartida por ambos nodos


Análisis de pros y contras:
Transición tras caída de la máquina física por perdida de corriente o similar: 
Por defecto no hay fail-over si el nodo primario no es alcanzable, en otro caso requiere planificación y configuración 

Transición por Fallo o Corrupción en almacenamiento: 
Utiliza almacenamiento independiente y replicación a nivel lógico de manera que resuelve muchos casos de corrupción 

Transición por caída de Caché: 
Detección rápida y muy configurable 

Tiempo de recuperación en transición: 
Pueden ser segundos 

Sincronización de ficheros externos: 
Solo las bases de datos son replicadas automáticamente no los ficheros externos 

Conclusiones
Si podemos manejar la carga de todo el sistema en uno o dos servidores es razonable configurar nodos en fail-over. Pero si se necesitan ocho servidores, entonces duplicarlos puede resultar demasiado caro comparado con N+X

La decisión sobre la configuración depende del tipo de las transacciones que serán manejadas (integridad transaccional, secuencialidad, etc.). Con todo lo anterior se pone de manifiesto la necesidad de realizar análisis y pruebas de capacidad previos al posible despliegue

jueves, 31 de enero de 2013

JobPerConnection y PoolSize

En una entrada anterior hablamos del tamaño de grupo o PoolSize (http://blogdeensemble.blogspot.com.es/2011/06/aclarando-el-concepto-tamano-de-grupo.html) ahora hablamos de otro setting que está relacionado.

En el caso especial de los adaptadores basados ​​en TCP (TCP, HTTP, SOAP, etc) el valor del setting PoolSize tiene un comportamiento ligeramente diferente al habitual y depende de la configuración de JobPerConnection.

Si el setting JobPerConnection se establece en "false" hay uno y sólo un listener (BusinessService Job) para cualquier valor de PoolSize mayor que "0" (PoolSize igual a "0" impediría que este adaptador funcionase).

Si el setting JobPerConnection se establece en "true" y el setting PoolSize es mayor que "1", este sirve como un límite en el número de jobs de conexión simultáneos que pueden crearse. En el caso de que se alcance el límite de jobs, el listener no aceptará ninguna conexión más hasta que uno de los jobs de conexión existentes termine o muera. Adicionalmente, en el caso de JobPerConnection = "true" el valor "1" en PoolSize se usa para posibilitar la creación ilimitada de nuevos jobs (excepto el límite puesto por el sistema operativo).

El setting QSize es importante en este caso porque si Qsize es igual a "0" Ensemble no permitirá que el sistema operativo acepte (encole) una conexión si el listener ha aceptado ya una conexión.

En general la configuración por defecto JobPerConnection="true", PoolSize="1" y Qsize=100 siempre nos vendrá bien.

Lo gracioso es que todo esto no viene en la ayuda. Al menos hasta la versión actual 2012.2. Así que si habeis llegado aqui buscando más información sobre esto. Enhorabuena !!