En esta serie de posts vamos a comentar diferentes aspectos de Azure Stream Analytics (ASA de ahora en adelante), que pueden resultarnos útiles en nuestros desarrollos del día a día. Si no conoces Azure Stream Analytics puedes ver una introducción en este enlace.
En este post veremos cómo aprovechar funciones JavaScript dentro de ASA, cuando pueden sernos útiles y cómo implementar un par de ejemplos sencillos.
Las funciones JavaScript permiten el uso de métodos como RegExp, Mah, Array, Date y varios más que resultan muy útiles para realizar transformaciones más complejas de forma más sencilla que usando código SQL en la Query del job, como por ejemplo, dar formato a fechas, comprobar correos electrónicos o buscar patrones en strings, operaciones matemáticas complejas, recorrer niveles y extraer campos de ficheros json, etc…
Ejemplo 1: Convertir la hora del sistema a la hora de la zona horaria local
En este primer ejemplo vamos a ver como mostrar la hora del sistema adaptada a nuestro país. En la Query de ASA se puede usar la propiedad System. Timestamp para mostrar la hora del sistema, el problema es que la hora está en UTC y según donde vivas, tu hora local no suele coincidir con la UTC, por ejemplo, en el caso de España según si estamos en horario de verano sería UTC+1 o UTC+2.
Una solución fácil para este problema es sumar 1 o 2 a ese System.Timestamp, el problema con esta solución es que al cambiar del horario de verano al de invierno o viceversa habría que cambiar esa suma de forma manual y lo más normal es que se nos olvide. Para automatizar esta suma una función de JavaSript nos puede resultar muy útil.
Creación de la función JavaScript
El primer paso es crear la función, para crearla vamos a ir a nuestro job de ASA (en nuestro caso se llama asa_pruebas_test) y en el panel de la parte izquierda, bajo “Job topology” seleccionamos “Functions” y después pulsamos sobre “+ Add” como se muestra en la imagen 1 e imagen 2:
Tenemos que darle un nombre a nuestra función y elegir el tipo de dato para la salida. Los tipos de datos aceptados como salida en una función JavaScript en ASA son los que se muestran en la imagen 3:
En nuestro caso vamos a llamar a nuestra función “AjusteUTC” y el tipo de dato para el output será “bigint”, porque lo que queremos que nos devuelva la función es el número de horas que tenemos que sumar al System TimeStamp para ajustarla a nuestra zona horaria.
Luego en la parte derecha tenemos que escribir el código de nuestra función, en este caso como parámetro de entrada a nuestra función le vamos a poner la zona horaria que queremos mostrar.
La función quedaría de la siguiente manera:
function main(zonaHoraria) { //obtenemos la hora del sistema date_sys = new Date(); //obtenemos la hora de la zona horaria deseada en formato string date_str = date_sys.toLocaleString('en-US', {timeZone: zonaHoraria}) //convertimos la hora a tipo date date = new Date(date_str); //realizamos la resta entre la hora deseada y la hora del sistema para obtener los milisegundos de diferencia date_final = date - date_sys; //convertimos esos milisegundos en horas hour_diff = Math.round(date_final/3600000) return hour_diff; }
Como podemos observar, en esta función usamos los métodos toLocaleString y Math, el primero para obtener la hora de la zona horaria deseada y el segundo para redondear los milisegundos (obtenidos de la resta de las 2 fechas) a horas.
Uso de la función JavaScript en la query de ASA
Para usar la función en la Query de ASA tenemos que poner “udf.[nombre de la función]”.
En este ejemplo tenemos una Query muy sencilla para ver el resultado:
SELECT udf.AjusteUTC('Europe/Madrid') horas, System.Timestamp as Hora_Sistema, DATEADD(hour,udf.AjusteUTC('Europe/Madrid'),System.Timestamp) as Hora_ESP INTO [Output] FROM [Input]
En la primera línea tenemos la llamada a la función para ver el número de horas de diferencia entre la hora del sistema y la hora de España, en la segunda línea tenemos la hora de sistema y en la tercera usamos la función DATEADD para sumarle a la hora del sistema las horas de diferencia entre la hora del sistema y nuestra zona horaria.
Para testearla tenemos 2 opciones, una de ellas es subir un fichero de ejemplo de entrada en nuestro input y la segunda es recoger una muestra de los datos que van llegando en el caso de que el input esté activo y le estén llegando eventos, para hacerlo, pulsamos sobre los 3 puntos al lado de nuestro input y seleccionamos la opción que queramos (Imagen 4) y pulsamos sobre el botón de “Test” (Imagen 5) que se encuentra en la parte superior:
El resultado aparecerá en la parte inferior y en nuestro caso sería el que se muestra en la imagen 6:
Como se puede observar en la imagen 6, la hora del sistema son 2 horas menos que la hora de España para el día 1970-01-01 y en la tercera columna se puede observar como aparece esa HORA_ESP con 2 horas más.
Ejemplo 2: Cambiar formato de fecha en la hora de sistema
En este segundo ejemplo vamos a ver como transformar el formato que nos trae por defecto la hora de sistema que sería este: “1970-01-01T12:01:01.0010000Z” a un formato más amigable como por ejemplo YYYY-MM-DD HH:MM, esto es solo un ejemplo pero podemos darle cualquier formato que queramos.
Creación de la función JavaScript
El proceso de creación de la función es igual que en el caso anterior, en este ejemplo le pondremos de nombre “FormatDateTime” y el tipo de dato de la salida será “nvarchar(max)”.
El código de la función quedaría así:
function main(date) { var fecha = date.substring(0,10) var hora = date.substring(11,19) return fecha.concat(" ",hora); }
Recibe como parámetro la fecha que queremos formatear, en la variable fecha guardaremos el substring correspondiente a la fecha YYYY-MM-DD y en la variable hora guardaremos el substring correspondiente a la hora HH:MM, para esto usamos la función substring que nos permite extraer partes de un string a partir de su posición. Y como resultado vamos a concatenar ambas variables con una separación de un espacio en el centro.
Uso de la función JavaScript en la query de ASA
La consulta que vamos a utilizar en el job quedaría de la siguiente manera:
SELECT System.Timestamp as hora_sys, udf.FormatDateTime(System.Timestamp) as hora_formateada INTO [OutputEventHub] FROM [InputLaLigaFantasyWebEvent]
En la primera columna vamos a mostrar la hora del sistema y en la segunda como quedaría después de darle el formato deseado, este sería el resultado:
Conclusión
Como podemos observar, las funciones de JavaScript que nos permite realizar ASA pueden resultar bastante útiles para realizar cosas que no serían posible a través de código SQL, o para realizar transformaciones complejas de una forma más sencilla que usando SQL. Para más información sobre funciones JavaScript en ASA podéis consultar el siguiente enlace.
Espero que estos ejemplos os hayan servido de ayuda y no os perdáis los siguientes capítulos en los que hablaremos sobre escalado, particionamiento y optimización de Azure Stream Analytics para soluciones de alto rendimiento.