Cosmos WebServer
Cosmos como proveedor de servicios web
Cosmos como proveedor de servicios web
Cosmos WebServer (CWS) es una utilidad que permite utilizar Cosmos como proveedor de servicios web, permitiendo crear servicios REST.
Esta utilidad está disponible a partir de la versión 6.0 de Cosmos, excepto el fichero de Log: Cwslog.log, que se ha incorporado a partir de la versión 7.2.
A partir de la versión 7.4 de Cosmos, Cosmos WebServer admite también conexiones HTTPS.
A partir de la versión 7.4.2 de Cosmos se puede indicar la versión de la máquina virtual de Java con variables de entorno, sin necesidad de modificar la variable PATH del sistema.
Cosmos WebServer no funciona con licencias de tipo Cosmos SQL Desktop ni Cosmos SQL Workgroup.
Cosmos WebServer se puede arrancar en línea de comando o bien como servicio Windows.
Una vez arrancado, el servidor atiende las peticiones HTTP en el puerto definido (por defecto 8081). Una petición puede convertirse en invocación a un método de una aplicación Cosmos configurada.
El esquema básico de Cosmos WebServer (CWS) es el que se muestra en la siguiente figura:
Una instalación Cosmos WebServer estará compuesta por:
Cosmos WebServer utiliza la dll “JVM.dll” de la máquina virtual de Java. Por lo tanto, para ejecutar CWS es necesario disponer de una máquina virtual Java de 32 bits (con versión 1.8 o superior) instalada en la misma máquina que Cosmos WebServer.
A partir de la versión 7.4 de Cosmos, Cosmos WebServer admite también conexiones HTTPS.
La aplicación Cosmoswebserver.exe permite arrancar el servidor CWS desde la línea de comando o como servicio Windows.
Este fichero incluye las siguientes funcionalidades:
Estas funcionalidades no son excluyentes entre sí.
Para instalar Cosmos WebServer como un servicio Windows es necesario crear un fichero con el nombre «cosmoswebserver.ini» que debe estar ubicado en “COSMOSDIR/etc”.
Por cada servicio que se cree, se deberá definir una sección con el nombre del servicio. Cada sección contendrá una variable, llamada INIFILE, con el path absoluto del fichero de configuración para el servidor REST.
Ejemplo
[ServicioWeb] INIFILE=c:\cosmos\etc\stockserver.ini [ServicioWebCompras] INIFILE=c:\cosmos\etc\comprasserver.ini
A partir de la versión 7.4.2 de Cosmos es posible indicar a Cosmos WebServer la versión de la máquina virtual de Java que deberá utilizar. Para ello, será necesario definir en la sección [Environment] las variables de entorno CWSUSEJAVAVERSION o CWSUSELASTJAVAVERSION:
Si Cosmos WebServer no se inicia como servicio, pero se desea indicar la máquina virtual de Java que se va a utilizar, también será necesario definir estas variables en cosmoswebserver.ini.
En el fichero de configuración de Cosmos Webserver se indicará, entre otras cosas, el puerto donde escuchará el servidor, la ruta del fichero de configuración de los servicios REST Cosmos, los parámetros propios de la máquina virtual Java (ruta del fichero cosmosrestserver.jar, parámetros de memoria) y, opcionalmente, la ruta de recursos HTML del servidor.
Ejemplo
[Server] CONFIG=c:\cosmosRestApp\etc\stockConfiguration.xml PORT=8080 RESOURCEPATH=c:/cosmosRestApp/resources/webapp [JAVA] -Xms256m -Xmx1024m -Djava.class.path=c:\\cosmos\\bin\\cosmoswebserver.jar;
CONFIG
Esta variable indica la ruta del fichero de configuración de los servicios REST del servidor (la configuración de este fichero se explica en el apartado “Fichero de configuración del servidor REST”).
PORT
Indica el puerto del servidor donde CWS escuchará peticiones HTTP.
RESOURCEPATH
Esta variable de entorno indica la ruta del directorio donde CWS almacenará recursos que serán accesibles mediante la URL del servidor. Estos recursos podrán ser páginas HTML, ficheros de imágenes, etc.
NUMBEROFTHREADS
Esta variable será necesario definirla para que la ejecución de Cosmos WebServer sea multihilo, es decir, que permita procesar más de una petición REST a la vez sin tener que esperar a que finalice una para procesar la siguiente.
Se define en la sección [Server] del fichero INI del servicio.
El valor de esta variable será el número de hilos que deberá ser capaz de manejar el servidor.
Para que Cosmos WebServer sea multihilo:
Cuando Cosmos WebServer esté definido como multihilo, la conexión a la base de datos solo se podrá hacer en arquitectura cliente-servidor.
No se podrán establecer conexiones locales a la base de datos. En conexiones locales retornará el mensaje:
“Imposible conectar con el servidor de SQL. (Unable to connect to local database from Cosmos WebServer in MULTI-THREAD MODE. The connection must be client-server)”.
Para configurar una conexión HTTPS será necesario definir las siguientes variables:
SSL_PORT
SSL_KEYSTORE
SSL_KEYSTORE_PWD
SSL_KEYSTORE_ALIAS
SSL_KEYSTORE_ALIAS_PWD
Si se produce un error en el proceso de arranque de Cosmos WebServer, el servicio no se iniciará y no se podrán realizar conexiones de ningún tipo. Por ejemplo, si la contraseña del almacén de certificados es incorrecta, o si el puerto de escucha HTTP o HTTPS indicado ya está en uso o si se indica el mismo puerto para las conexiones HTTP y HTTPS, se producirá un error en el proceso de arranque y no se podrán realizar conexiones con el servidor.
En este fichero de configuración se especifica, en formato XML, el nombre de la aplicación Cosmos, el nombre de los módulos y de los métodos que serán los encargados de implementar los servicios REST, así como la ruta (URL) y verbo HTTP (GET, POST, PUT, DELETE, etc.) que se deberá emplear para acceder a cada uno de estos métodos. Cada servicio REST en Cosmos se corresponderá con un método definido en las secciones «module», a las que se accederá mediante su ruta y la del módulo «module» y proyecto «Project» al que pertenecen (propiedades path de «Project», «module» y «method»). Cada método Cosmos correspondiente con un servicio REST deberá retornar un string con el resultado de la ejecución del servicio REST.
Ejemplo
A continuación se muestra un ejemplo de fichero de configuración de un servidor REST. En él se definen el proyecto, los módulos y los métodos Cosmos que implementarán los servicios REST, así como la manera de acceder a ellos:
xml version=«1.0» encoding=«UTF-8»?>
Para información más detallada de estas secciones consulte el documento PDF.
El nombre del parámetro, ya sea de tipo “queryParameter”, “urlParameter”, “bodyParameter” o “headerParameter”, deberá coincidir con el nombre del parámetro indicado en el fuente Cosmos del método.
Ejemplo de llamada a servicio REST Cosmos
Dado el fichero XML de configuración definido anteriormente, para ejecutar el servicio resultCount del módulo states.smd, se deberá ejecutar desde la parte cliente una operación de tipo POST en la URL: http://«host»:«puerto»/stock/rest/states/resultCount
Un servicio REST en Cosmos se traduce como una función o método definido en un módulo de un proyecto en Cosmos, que recibe unos parámetros desde la URL o desde el cuerpo de una petición HTTP (request), y retorna un String con el resultado de la ejecución del mismo, así como de un código de estado donde se indica si la ejecución ha sido exitosa, fallida, etc.
Este código deberá ser un código de estado estándar HTTP (200 – ok, 201 – created, 405 – Method not allowed, etc).
Este código de estado lo establecerá el método o función Cosmos correspondiente al servicio REST mediante la ejecución del método SetExecStatus de la clase Module al finalizar el cuerpo de la función.
Ejemplo de función que implementa un servicio REST en Cosmos WebServer
Ejemplo del servicio REST findByKey implementado en la función findByKey del módulo States.smd. En ella se realiza la conexión a la base de datos y se indica que no muestre errores por pantalla. La función processQuerySingleResult realiza la búsqueda, recopila los registros en un objeto JSON, que retorna como cadena de caracteres, indica el estado de la ejecución con el método SetExecStatus, y se desconecta de la base de datos.
public function findByKey(key as char) return char
objects begin
retStr stmtStr as char default NULL
end
begin
Conecta();
ErrorLevel(0);
stmtStr = «select * from states «;
if key is not null then begin
stmtStr = stmtStr + » where state = ‘» + key + «‘»;
retStr = processQuerySingleResult(stmtStr);
end else begin
Module.SetExecStatus(BAD_REQUEST);
end
Desconecta();
return retStr;
end
private function processQuerySingleResult(stmtStr as char) return char
objects begin
retStr as char default «»
miCursor as SqlCursor
jsonArray as json
jsonRecord as json
stateStr nameStateStr as char
retStatus as integer
found as boolean default FALSE
end
begin
miCursor.Prepare(stmtStr);
if Sql.Error() == 0 then begin
miCursor.Open();
if miCursor.Fetch(stateStr, nameStateStr).Found() then begin
jsonRecord.Clear();
jsonRecord.Set(«state», stateStr);
jsonRecord.Set(«sname», nameStateStr);
found = TRUE;
end
miCursor.Close();
if not found then retStatus = getNoRecorsStatusCode();
end else begin
retStatus = BAD_REQUEST;
end
miCursor.Free();
Module.SetExecStatus(retStatus);
retStr = jsonRecord;
return retStr;
end
La utilidad Cosmos WebServer puede ser iniciada desde la línea de comando o como servicio Windows.
Antes de iniciar la instalación del aplicativo deberá estar instalada la máquina virtual de Java y asegurarse que incluye la DLL JVM.dll.
En versiones de Cosmos anteriores a la 7.4.2, para que Cosmos WebServer localice la DLL deberá añadirse a la variable PATH del sistema la ruta donde se encuentre dicha DLL.
A partir de la versión 7.4.2 de Cosmos no es necesario indicar la ruta de la JVM.dll en la variable de entorno PATH del sistema operativo. Para ello se han implementado las variables de entorno CWSUSEJAVAVERSION y CWSUSELASTJAVAVERSION. Estas dos variables de entorno deberán definirse en la sección [Environment] del fichero de configuración cosmoswebserver.ini.
Esto implica que, a partir de la versión 7.4.2 de Cosmos, el fichero cosmoswebserver.ini debe existir necesariamente en caso de utilizar las variables de entorno mencionadas, tanto si el aplicativo se arranca desde la línea de comando como desde un servicio de Windows.
El fichero cosmoswebserver.ini deberá estar situado en “COSMOSDIR\etc”.
Para iniciar Cosmos WebServer desde la línea de comando tendremos que utilizar la siguiente sintaxis:
Cosmoswebserver.exe –ini c:\cosmos\etc\stockserver.ini
El problema de iniciar Cosmos WebServer desde la línea de comando reside en que, al reiniciarse el servidor donde está instalado, es necesario reiniciar manualmente Cosmos WebServer.
Este problema se soluciona instalando Cosmos WebServer como servicio Windows.
Para instalar Cosmos WebServer como servicio será necesario ejecutar Cosmos WebServer con el parámetro “–install
Cosmoswebserver.exe –install ServicioWeb –user .\usuario –passwd passwd
El parámetro “nombre_de_servicio” indicará un nombre de servicio Windows no existente, y que será el que identificará al servicio de Cosmos WebServer. Este nombre de servicio deberá estar incluido en el fichero de configuración cosmoswebserver.ini.
Los parámetros “–user” y “–passwd” indican respectivamente el usuario que arranca el servicio y su contraseña. Estos parámetros son opcionales, si no se indican, el servicio arrancará con una cuenta de sistema local.
El servicio se instalará por defecto como “AUTOMÁTICO”, es decir, cuando se reinicie el servidor el servicio se iniciará automáticamente.
Para iniciar el servicio CosmosWebServer instalado con “-install” se deberá ejecutar CosmosWebServer con el parámetro “–start
Cosmoswebserver.exe –start ServicioWeb
Cosmos WebServer necesita el nombre de un fichero de configuración. Este nombre lo obtendrá del fichero cosmoswebserver.ini, que deberá estar situado en “COSMOSDIR\etc”. Por cada servicio que queramos instalar se deberá definir una sección con el nombre del servicio y una variable, llamada INIFILE, con el path absoluto del fichero de configuración para ese servicio.
Ejemplo de cosmoswebserver.ini con dos servicios Cosmos WebServer configurados
[ServicioWeb] INIFILE=c:\cosmos\etc\stockserver.ini [ServicioWebCompras] INIFILE=c:\cosmos\etc\comprasserver.ini
Para detener el servicio CosmosWebServer instalado con “-install” se deberá ejecutar CosmosWebServer con el parámetro “–stop «nombre_de_servicio»”.
Cosmoswebserver.exe –stop ServicioWeb
A partir de ese momento el servicio estará instalado, pero no disponible para aceptar nuevas conexiones, hasta que no se rearranque con “-start”.
Para desinstalar el servicio CosmosWebServer instalado con “-install” se deberá ejecutar CosmosWebServer con el parámetro “-remove «nombre_de_servicio»”.
Cosmoswebserver.exe –remove ServicioWeb
El servidor Cosmos WebServer permite la generación de un fichero de log en el que se almacenará información del funcionamiento de Cosmos WebServer.
Cosmos WebServer utiliza la herramienta Log4j2 para la generación del fichero de log.
Por defecto, CosmosWeb Server no genera fichero de log. Si se desea que la aplicación almacene información de log se deberá indicar en el fichero de configuración de Cosmos WebServer (ver el apartado: Fichero de configuración de la aplicación Cosmos WebServer).
El nombre del fichero de configuración de log se indicará en la sección [JAVA] mediante la definición de la siguiente variable:
-Dlog4j.configurationFile=c:/cosmos/cosmoswebserver/log4j2.xml
En este caso, el fichero de configuración de log se llama log4j2.xml. Este es un fichero de configuración en formato XML donde se podrá indicar la ruta y el nombre del fichero de log, el formato de salida y el nivel de log que se desea (ALL, DEBUG, ERROR, FATAL, INFO, OFF, TRACE y WARN).
Ejemplo de fichero de configuración log4j2.xml
filePattern=»logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz» append=»true»>
retStr stmtStr as char default NULL
En este fichero de configuración se indica la ruta completa del fichero de log (propiedad fileName de la sección RollingFile), y el nivel de log (propiedad level de sección AppenderRef).
Para más información, ver: http://logging.apache.org/log4j/2.x/manual/index.html
Este fichero se crea en el directorio c:\tmp, y en él Cosmos WebServer escribirá la información generada en la instalación, puesta en marcha, parada y eliminación del servicio Windows o en el proceso de arranque de Cosmos WebServer como aplicación.
Cosmos WebServer como servicio
2018-07-19 16:20:49 Checking JVM:JVM found
2018-07-19 16:20:49 Installing the service:cosmoswebserver
2018-07-19 16:20:49 cosmoswebserver instalado
2018-07-19 16:20:50 La configuración del servicio cosmoswebserver ha sido cambiada.
2018-07-19 16:21:07 Checking JVM:JVM found
2018-07-19 16:21:07 Starting the service:cosmoswebserver
2018-07-19 16:21:07 La configuración del servicio cosmoswebserver ha sido cambiada.
2018-07-19 16:21:08 Checking JVM:JVM found
2018-07-19 16:21:08 Running as service
2018-07-19 16:21:08 cosmoswebserver puesto en marcha.
2018-07-19 16:21:08 Starting Cosmos Web Server
2018-07-19 16:21:08 Ini file loaded: c:\cosmos\etc\cwsdemo.ini
2018-07-19 16:21:48 Checking JVM:JVM found
2018-07-19 16:21:48 Stopping the service:cosmoswebserver
2018-07-19 16:21:48 cosmoswebserver parado.
2018-07-19 16:21:52 Checking JVM:JVM found
2018-07-19 16:21:52 Removing the service:cosmoswebserver
2018-07-19 16:21:52 cosmoswebserver eliminado.
Cosmos WebServer como aplicación
2018-07-19 16:22:16 Checking JVM:JVM found
2018-07-19 16:22:16 Starting Cosmos Web Server
2018-07-19 16:22:16 Ini file loaded: c:\cosmos\etc\cwsdemo.ini
La salida de los errores generados por el runtime de Cosmos WebServer durante los procesos podrá ser a fichero si en el directorio temporal se crea un fichero con el nombre CWSLog.log.
Cosmos WebServer como servicio
Si se produce un error durante la ejecución de un servicio Cosmos y el ErrorLevel es mayor de 0, en el fichero de log se volcará información referente al error, así como el método y el módulo donde se ha producido el error, y la pila de llamadas de la aplicación.
Si se produce un error durante la ejecución y el ErrorLevel es igual a 0, no se escribirá la información del error en el fichero de log.
Si en el código fuente del servicio Cosmos se ejecuta el método Trace, en el fichero de log se escribirá el texto asociado al método Trace.
Cosmos WebServer como aplicación
Si se produce un error durante la ejecución de un servicio Cosmos y el ErrorLevel es mayor de 0, en el fichero de log se volcará información referente al error, así como el método y el módulo donde se ha producido el error, y la pila de llamadas de la aplicación. Esta misma información se mostrará en pantalla mediante un MessageBox.
Ejemplo
En el proyecto de ejemplo se han realizado las siguientes modificaciones:
Función findByKey:
public function findByKey(key as char) return char
objects begin
retStr stmtStr as char default NULL
end
begin
Conecta();
key.Trace();
// ErrorLevel(0);
stmtStr = «select * from1 states»;
stmtStr.Trace();
if key is not null then begin
stmtStr = stmtStr + » where state = ‘» + key + «‘»;
retStr = processQuerySingleResult(stmtStr);
end
Desconecta();
return retStr;
end
Cosmos WebServer como servicio
En el fichero de log se mostrará la siguiente información:
[2018-07-19 10:35:40] CWS Service Mode
[2018-07-19 10:35:40] Char::Trace
MA
[2018-07-19 10:35:40] CWS Service Mode
[2018-07-19 10:35:40] Char::Trace
select * from1 states
[2018-07-19 10:35:40] CWS Service Mode
[2018-07-19 10:35:40] Warning
Warning (M50700000)
File STATES
Method STATES::processQuerySingleResult
Falta la cláusula FROM en la sentencia.
==========
CALL STACK
==========
–>SqlCursor::Prepare
STATES::processQuerySingleResult
STATES::findByKey
Cosmos WebServer como aplicación
En el fichero de log y en la pantalla se mostrará la siguiente información:
[2018-07-19 10:44:29] CWS Application Mode
[2018-07-19 10:44:29] Warning
Warning (M50700000)
File STATES
Method STATES::processQuerySingleResult
Falta la clausula FROM en la sentencia.
==========
CALL STACK
==========
–>SqlCursor::Prepare
STATES::processQuerySingleResult
STATES::findByKey
NOTA: En este caso, al no haber utilizado al método SetExecStatus en la cabecera de la respuesta, el servidor Web retornará: 500 Server Error.