Fullmenu null

 

19 March 2018

En el post Docker y Groovy (básico) vimos cómo podemos hacer que la imagen oficial de Groovy para Docker ejecute nuestros scripts en host donde no se encuentre instalado Groovy. Así mismo esta imagen nos permite aprovechar todas las características de Docker como montar volúmenes, conexión entre contenedores, etc de tal forma que nuestros scripts puedan interactuar con otros contenedores y/o sistema anfitrión.

Si pensamos un poco sobre ello vemos que podemos utilizar estas características para ejecutar de forma programada nuestros scripts incluso desde un servidor remoto, de tal forma que no tenemos ni tan siquiera que tener instalado Groovy en nuestro equipo.

Para este ejemplo vamos a utilizar un script que se ejecutará de forma recurrente y que accederá a la información del Ayuntamiento de Madrid sobre incidencias que se están produciendo en ese momento en las vías de esta ciudad. Esta información viene formateada en XML y, de todas las incidencias, el script buscará aquellas que no han sido planificadas y las irá tuiteando una a una.

Para la ejecución recurrente aprovecharemos la posibilidad que ofrece Gitlab de ejecutar Pipelines de forma planificada de tal forma que nuestro código será ejecutado por un runner cuando así lo determinemos.

Así pues deberás tener:

  • cuenta en Gitlab así como crear un repositorio y añadir el script al mismo.

  • cuenta en twitter y crear unas credenciales para que tu script pueda tuitear en tu nombre.

IncidenciasMadrid.groovy
@Grab(group='org.twitter4j', module='twitter4j-core', version='4.0.6')

import twitter4j.TwitterFactory
import twitter4j.StatusUpdate
import twitter4j.conf.ConfigurationBuilder

tf = TwitterFactory.singleton
if( new File('twitter4j.properties').exists() == false ){	//(1)
	def env = System.getenv()
	ConfigurationBuilder cb = new ConfigurationBuilder()
	cb.setDebugEnabled(true)
	  .setOAuthConsumerKey(env['CONSUMER_KEY'])
	  .setOAuthConsumerSecret(env['CONSUMER_SECRET'])
	  .setOAuthAccessToken(env['ACCESS_TOKEN'])
	  .setOAuthAccessTokenSecret(env['ACCESS_SECRET']);
	tf = new TwitterFactory(cb.build())
}
twitter = tf.instance

body = new URL("http://informo.munimadrid.es/informo/tmadrid/incid_aytomadrid.xml").newReader()
NewDataSet = new XmlSlurper().parse(body)	//(2)
NewDataSet.Incidencias.each{

	if( "$it.incid_prevista" == 'N' && "$it.incid_planificada"=='N' ){

		String tweet="""
@101GroovyScript te informa
Atención, incidencia no prevista
$it.nom_tipo_incidencia:
$it.descripcion
"""

		try{
			twitter.updateStatus tweet	//(3)
		} catch(e){
			println "no se ha enviado"
		}
	}
}
  1. Si no existe fichero de credenciales de Twitter usamos variables de entorno

  2. Obtenemos las ultimas incidencias en formato XML filtrando por las no previstas

  3. tuiteamos un mensaje con el contenido de cada una.

Gitlab

Para que Gitlab pueda ejecutar nuestro código tenemos que especificarle cómo debe hacerlo y para ello usaremos un fichero .gitlab-ci.yml que deberá estar en el raiz de nuestro proyecto. Para más información consulta la documentación oficial https://about.gitlab.com/features/gitlab-ci-cd/

gitlab-ci.yml
execute incidencias:    //(1)
 image:
   name: groovy:2.4-jdk8    //(2)
 only:
  - schedules       //(3)
 stage: build
 script:
  - groovy IncidenciasMadrid.groovy //(4)
  1. identificamos nuestro job con un nombre. Podemos tener varios más

  2. usaremos la imagen oficial de Groovy para ejecutar nuestro script

  3. este job sólo se ejecuta de forma planificada por Gitlab

  4. comando a ejecutar. Como usamos la imagen Groovy el comando groovy se encuentra disponible

Planificación

Desde la consola web de Gitlab podemos configurar cuando queremos que se ejecute el Pipeline mediante una expresión chron (minutos horas dia etc) e incluso especificar qué rama de nuestro repo queremos utilizar para ello, así como variables de entorno a utilizar:

gitlab schedule

Resultado

Como resultado tendremos que cada cierto tiempo Twitter publicará las incidencias usando nuestra cuenta como en este ejemplo:

tweet schedule

Como puedes ver gracias a la imagen Docker podemos ejecutar nuestros scripts de forma desatendida y con todas las funcionalidades que ofrece el lenguaje (consumir servicios REST, SOAP, conexión a servicios externos y/o internos, etc)


Script
@Grab(group='org.twitter4j', module='twitter4j-core', version='4.0.6')

import twitter4j.TwitterFactory
import twitter4j.StatusUpdate
import twitter4j.conf.ConfigurationBuilder

tf = TwitterFactory.singleton
if( new File('twitter4j.properties').exists() == false ){	//(1)
	def env = System.getenv()
	ConfigurationBuilder cb = new ConfigurationBuilder()
	cb.setDebugEnabled(true)
	  .setOAuthConsumerKey(env['CONSUMER_KEY'])
	  .setOAuthConsumerSecret(env['CONSUMER_SECRET'])
	  .setOAuthAccessToken(env['ACCESS_TOKEN'])
	  .setOAuthAccessTokenSecret(env['ACCESS_SECRET']);
	tf = new TwitterFactory(cb.build())
}
twitter = tf.instance

body = new URL("http://informo.munimadrid.es/informo/tmadrid/incid_aytomadrid.xml").newReader()
NewDataSet = new XmlSlurper().parse(body)	//(2)
NewDataSet.Incidencias.each{

	if( "$it.incid_prevista" == 'N' && "$it.incid_planificada"=='N' ){

		String tweet="""
@101GroovyScript te informa
Atención, incidencia no prevista
$it.nom_tipo_incidencia:
$it.descripcion
"""

		try{
			twitter.updateStatus tweet	//(3)
		} catch(e){
			println "no se ha enviado"
		}
	}
}