Weblogs Código

Blog Bitix

Servidores Cloud VPS de Clouding.io para hospedar blogs y páginas web

February 28, 2017 09:00 PM

Al escribir este artículo patrocinado sobre Clouding.io he podido probar de primera mano el crear un servidor virtual basado en la computación en la nube. Después de probarlo me parece una opción sencilla y sin complicaciones, adecuada y más que suficiente para proyectos de presencia en internet, blogs, pequeños y medianos proyectos de páginas web. Además, con soporte en español en caso de necesitar algún tipo de asistencia o ayuda.

Clouding.io

Toda página web, blog y servicio que está accesible en internet ha de ser hospedado en algún servidor. Por motivos de fiabilidad, también coste y flexibilidad se suele contratar un servicio de hospedaje de los muchos que hay en internet. Desde no hace tanto tiempo ha surgido una modalidad de hospedaje que permite mayor flexibilidad, la llamada cloud computing o computación en la nube, cuya características diferenciadoras son permitir variar de forma elástica, aumentando o reduciendo, los recursos de computación utilizados ya sea de procesador, memoria, almacenamiento o transferencia de datos. Otra característica de la computación en la nube es que es inmediata (en cuestión de minutos) sin necesidad de trámites administrativos o tiempos de espera, los servicios de computación en la nube incluyen paneles de administración para los servidores accesibles a través de un navegador con aplicaciones sencillas o incluso interfaces basadas en linea de comandos de modo que es posible automatizar las tareas de sistemas con DevOps.

Hay múltiples opciones de computación en la nube algunas con más servicios y funcionalidades pero también más complejas y no necesarias para proyectos sencillos y no muy grandes. Una de las opciones de computación en la nube sencilla pero suficiente en muchos casos es Clouding.io que en la opción más básica ofrece un servidor con 1 núcleo de CPU, 1 GiB de memoria, 25 GiB de almacenamiento persistente de estado sólido o SSD y 2 TiB de datos de transferencia a un precio de 10€ + IVA al mes (unos 12€), precio similar a otras opciones de servidores en la nube. Para un página web con archivos estáticos de presencia en internet o un blog como Blog Bitix que solo utiliza recursos estáticos (HTML, CSS, JavaScript e imágenes) lo más básico ya sería suficiente y para un blog con Wordpress utilizando 2 GiB y un precio de 12 € + IVA al mes también debería ser más que suficiente para un tráfico respetable en cantidad. Una de las ventajas del cloud computing es la elasticidad que permite cambiar en cualquier momento los recursos reservados según las necesidades como la cantidad de memoria, núcleos de procesador o espacio en disco, tanto para reservar más recursos o para disminuir los recursos utilizados y también el coste. En la página de Clouding.io está la simple política de precios según los recursos reservados. Desde 1 GiB hasta 32 GiB de memoria, desde 1 hasta 16 cores de CPU y desde 25 GiB hasta 1900 GiB de almacenamiento SSD por servidor cubriendo las necesidades hasta de las aplicaciones más exigentes.

Página web de Clouding.io

Algunas de las características de Clouding.io algo más detalladas en su página web es que ofrecen soporte en español y discos SSD rápidos para el almacenamiento además de las siguientes:

  • Potente: Cores Intel Xeon, Red Cisco 20Gbps, Ceph Storage, OpenStack KVM, Cache Inteligente y Discos SSD.
  • Estable: Triple Réplica, Auto Reparación, Datacenter Tier 4, Calidad Empresarial, Protección de Red, Hosting DNS.
  • Flexible: Cloud Hosting por Horas, Windows Cloud, Linux Cloud, Configuración a medida, Ampliaciones temporales, Activación inmediata.
  • Fácil: Soporte de Calidad, Cloud Pros, Teclado y Monitor Remoto, Como y cuando quieras, DIY: Hazlo tú mismo, Comunidad.

En el blog de Clouding.io hay artículos interesantes y tiene una comunidad con una base de conocimiento y una sección de preguntas y respuestas para resolver cualquier duda que nos surja, todo en español. Las imágenes de sistemas operativos que ofrecen son las siguientes en las que se incluyen la opción de Windows aunque siendo este un blog más afín al software libre recomiendo una de las versiones de GNU/Linux, una ventaja es que el precio es más barato. De Ubuntu hay múltiples versiones aunque siendo el propósito prestar un servicio durante periodos de tiempo largos lo recomendable es utilizar una versión LTS o de soporte prolongado:

  • CentOS 7, 6, 5
  • Debian 8, 7
  • Ubuntu 16.04, 14.04 y versiones no LTS
  • Docker (Ubuntu 14.04)
  • Magento 2.0 (Ubuntu 16.04)
  • Prestashop 1.6.x (Ubuntu 16.04)
  • Plesk 12 (Ubuntu 14.04)
  • Plesk 12 (Windows 2012 R2)
  • Plesk 12.5 (Ubuntu 14.04)
  • Plesk Onyx (17.0 Ubuntu 16.04)
  • VestaCP 0.9.8 (Ubuntu 14.04)
  • Windows 10 Professional (Español)
  • Windows 2003 R2 Datacenter (English)
  • Windows 2008 R2 Datacenter (English)
  • Windows 2012 R2 Datacenter (English)
  • Windows 2016 Datacenter (English)
  • Windows 8.1 Professional (Español)

Para probar su servicio ofrecen un cupón de 5€, que con la opción más básica son unos 15 días de uso continuado para evaluar su servicio sin compromiso. El registro requiere validar una cuenta de correo electrónico, móvil y tarjeta de crédito. Requerir el móvil y la tarjeta de crédito para probar el servicio es algo excesivo pero quizá necesario para evitar spam y usos no deseados. Realizado el registro ya está disponible el acceso al panel de administración desde el que crear nuevos servidores, arrancarlos, modificarlos, pararlos o eliminarlos.

Registro

Completado el registro accediendo al panel de administración en la sección servidores podremos crear las instancias y con que cantidad de recursos reservados, para ajustar el precio y dada la elasticidad de los servidores se puede empezar por las opciones mínimas e ir subiendo hasta que los recursos sean suficientes para el correcto funcionamiento de servidor según los recursos necesarios.

Panel de administración

Como utilidad Clouding.io ofrece un panel donde gestionar los registros DNS del dominio que contratemos y conocer los nombre de host y direcciones IP de los servidores de DNS de Clouding.io. Casi seguro que la entidad registradora del dominio que le asignemos al servicio para su acceso también tenga la opción de administrar los registros DNS, usar el de Clouding.io es más por unificar en un solo sitio toda la administración del servidor. En las opciones avanzadas se pueden administrar multitud de tipos de registro DNS.

Administración DNS

La sección principal es la de Servidores donde hay tres pestañas: una para los servidores, otra para las reglas de firewall para controlar el tráfico entrante y saliente de cada servidor y otra para las llaves SSH que usaremos para conectarnos desde nuestro equipo de forma segura. Seleccionado las características del servidor (memoria, procesadores y espacio en disco) al cabo de unos momentos el servidor se iniciará y estará disponible para que nos conectemos mediante SSH o desde la terminal con interfaz web ofrecida. Desde el listado de servidores podremos pararlo, reiniciarlo, redimensionarlo o eliminarlo. En la pestaña Acceso obtendremos el nombre de host asignado y la dirección IP privada y pública asignada, así como la contraseña del usuario root. En la pestaña Estadísticas monitorizaremos el estado del servidor y conoceremos si es necesario redimiensionarlo en algún parámetro.

Un servidor y sus parámetros de acceso
Nuevo servidor

Las reglas del firewall por defecto son demasiado permisivas, si solo necesitamos que el puerto 80, el del servidor web, esté abierto el resto de reglas para otros puertos se pueden eliminar para evitar posibles agujeros de seguridad. Una cosa buena es que se pueden crear múltiples reglas de seguridad y aplicar a cada servidor la más conveniente.

Reglas de firewall

Las llaves SSH son necesarias para conectarnos al servidor y lanzar comandos desde la terminal. Generada una llave SSH desde el apartado Llaves SSH descargaremos la clave privada, la añadiremos al directorio ~/.ssh y configuraremos el archivo ~/.ssh/config para acceder al servidor.

Claves SSH
En los ajustes veremos el saldo disponible que se irá descontando según los recursos consumidos durante el periodo de tiempo utilizados. Una cosa importante es que aunque el servidor esté apagado seguirá contabilizándose en la facturación. Podemos elegir recibir notificaciones cuando el saldo de la cuenta sea bajo para realizar una recarga.
Ajustes, facturación e informes

Una de las primeras cosas aconsejables realizar es tener acceso mediante SSH descargando la clave privada desde le apartado Llaves SSH, con GNU/Linux no se necesita mucho más para conectarse al servidor, en Windows se puede utilizar un programa como PuTTY. En cualquier caso siempre está disponible el acceso vía web. Otra de las cosas que a realizar es acceder al servidor SSH mediante un dominio propio que también con anterioridad hay que registrar. Y también es recomendable actualizar todos los paquetes o actualizaciones de seguridad del sistema.

Acceso mediante SSH y consola VNC

Con acceso vía SSH al servidor ya es posible administrarlo con una herramienta como Ansible instalando paquetes, actualizar el servidor y configurar servicios como los servidores web nginx o Apache, Docker y otra multitud de tareas que permite esta herramienta.

Servidor NGINX

Algunos artículos interesantes que he encontrado en su blog y base de conocimiento son los siguientes. Otros artículos de interés son los que escribí en la serie web en la que comentaba aspectos como HTTP/2, HTTPS, redirecciones o GZIP.

En definitiva Clouding.io es una opción de computación en la nube sencilla, con una política de precios simple y adecuada para proyectos desde pequeños de páginas web y presencia en internet hasta medianos que requieren una base de datos y tenga un tráfico ya notable, con soporte en español y que se puede probar sin compromiso. Al ser computación en la nube ofrece gran flexibilidad y ajustar el precio a los recursos consumidos, al usar discos SSD el buen rendimiento ya lo he notado al probar su servicio cuando he actualizado los paquetes del servidor e instalado el de nginx. Según las características anunciadas de redundancia la fiabilidad es destacable para que no haya caídas de servicio.

» Leer más, comentarios, etc...

Picando Código

OpenExpo 2017 – Feria y Congreso anual sobre Open Source & Software Libre y Open World Economy de España

February 28, 2017 06:45 PM

A continuación información sobre OpenExpo 2017, una feria y congreso anual sobre Software Libre, Open Source y economía abierta en Madrid:

Openexpo 2017

OpenExpo 2017, IV Feria y Congreso anual sobre FLOSS y Open World Economy (Open Data y Open Innovation) reunirá el 1 de junio 2017 en Madrid a más de 3.000 personalidades del sector, profesionales y empresas en búsqueda de generación de negocio. El objetivo de OpenExpo es difundir, presentar, descubrir y evaluar las soluciones y las tendencias de la industria que ofrece el Open Source & Software Libre y Open World Economy (Open Data y Open Innovation).

Esta edición está orientada a los nuevos retos del Open Source & la Transformación Digital. Descubre el innovador enfoque del evento y no te pierdas la jornada donde encontrarás:

  • Más de 120 ponencias sobre el sector
  • Más de 200 empresas dando a conocer sus productos y servicios
  • Más de 3.000 visitantes profesionales con los que hacer Networking
  • Nuevas actividades como Open Talks, Open Game, Open Talent…
  • La celebración de la Gala de entrega de premios Open Awards 2017
  • Y muchísimas cosas más…

Entradas gratis hasta el 28 de febrero – Aprovecha la oportunidad y consigue tu entrada de forma gratuita para asistir a OpenExpo 2017. Tienes de plazo hasta el 28 de febrero. ¡No olvides avisar a todo aquel que creas que le pueda interesar!

Open Awards 2017 – La II edición de los Open Awards tiene como objetivo reconocer públicamente a empresas, administraciones, personalidades y comunidades que crean, apoyan y fomentan grandes soluciones con tecnologías Open Source y Software Libre.

Abierto Call for Papers hasta 2 de marzo – ¿Eres un profesional del sector y quieres exponer tu visión sobre el Open Source y/o Software Libre? En OpenExpo te damos la oportunidad de participar en el mayor evento de tecnologías abiertas de España. Presenta tu propuesta antes del 2 de marzo.

eBook: Tendencias FLOSS 2017 – Hemos publicado con la colaboración de más de 40 profesionales del sector, el eBook “Tendencias Open Source y Software Libre 2017”, en el que podrás descubrir las tendencias más punteras en el mundo de las tecnologías abiertas.

Ver más:
Sitio oficial
Twitter

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 271

February 27, 2017 07:55 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET

ASP.NET

.NET Core / ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Data

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Cross-platform

Otros

Componentes/bibliotecas

Publicado en Variable not found

» Leer más, comentarios, etc...

Koalite

Entendiendo cómo funciona JSX

February 27, 2017 05:06 AM

El JSX usado por ReactJS para generar su Virtual DOM es una de las características de ReactJS que más chocan al principio y que más rechazo suelen generar. Eso de incluir “pseudo html” dentro de ficheros javascript no suele gustar. Por cierto, resulta curioso que a la inversa, es decir, incluir “pseudo javascript” en ficheros html, como se hace en casi todos los demás sistemas de templates, esté más aceptado.

Independientemente de que te guste mucho o poco, lo cierto es que la idea de utilizar JSX para generar un Virtual DOM que luego se sincronice con el DOM real se ha extendido a otras librerías y frameworks, como Cycle.js o Inferno. Incluso hay lenguajes, como TypeScript, que ofrecen soporte de forma nativa para esta sintaxis (lo que me parece un error, pero eso es otro tema).

Si estás trabajando con este tipo de librerías y eres de los que se preocupan por comprender en qué se basan las abstracciones que están utilizando, este post te puede ayudar a conocer mejor cómo funciona JSX y cómo afecta eso a tu aplicación.

De JSX a generar HTML

A poco que hayas leído algo sobre ReactJS, seguro que te suena la conversión que se hace para pasar de JSX a código Javascript puro. Convierte código JSX con este aspecto:

<Panel title='Opciones' color='green'>
		Texto del panel
</Panel>

En algo como esto:

React.createElement(
  Panel,
  {title: 'Opciones', color: 'green'},
  'Texto del panel')

Cada elemento JSX se convierte en una invocación a la función React.createElement, la cual recibe los siguientes parámetros:

  • El tipo del “componente”. Puede ser una función constructora si se trata de un componente implementado como una clase; una función que devuelve JSX, si se trata de un stateless functional component, o incluso un string si es un elemento html.
  • Un objeto en el que se agrupan las propiedades (props) que queremos pasarle al componente.
  • El resto de parámetros serán los hijos (children) del componente, que serán accesibles a través de props.children.

Como se puede ver, es todo bastante fácil y la traducción de JSX a invocaciones de funciones Javascript no tiene mucho misterio. Pero esto es sólo la traducción, ¿qué hace la llamada a React.createElement?

Lo más importante para entender cómo funciona React.createElement es ser consciente de que todavía no se está instanciando ningún componente.

En este punto, React.createElement crea una estructura, un Element que contiene la información necesaria para crear el componente. Cuándo y cómo será creado el componente, es algo que se decidirá más adelante.

Esta información incluye los parámetros que hemos indicado desde el JSX junto a alguna información adicional, y además se reempaqueta un poco para darle el aspecto que luego tendremos desde el componente. Por ejemplo, se copian los children, que React.createElement ha recibido por separado, dentro de lo que serán los props del componente una vez creado.

A continuación esta información llegará al subsistema encargado de montar el componente y sincronizar el DOM real con el virtual (ReactMount y ReactReconciler). Estos se encargarán de renderizar el componente, ya sea instanciándolo e invocándo su método render si es un componente de tipo clase, o ejecutándolo si es un componente funcional. Cuando todo haya quedado convertido a etiquetas HTML, se procederá a actualizar el DOM real.

Las implicaciones de este proceso

Todo esto que hemos visto está muy bien como culturilla general y por saber mejor qué terreno pisamos al utilizar ReactJS, pero es que además tiene algunas implicaciones a la hora de desarrollar que te pueden dar alguna sorpresa la primera vez que te las encuentras.

Puede resultar especialmente confuso cuando empiezas a utilizar distintos patrones de reutilización de código entre componentes y tienes que andar pasando componentes, instancias o fragmentos de JSX de un sitio a otro, dependiendo de lo que quieras hacer. Si además no cuentas con la ayuda de algún sistema de tipos (como flow o typescript), es fácil perder la pista de lo que estás haciendo.

Para hacernos una idea de los distintos escenarios que puede haber, vamos a ver de qué formas puedes acabar viendo un componente de tipo clase. Partamos de un componente Panel definido como una clase:

class Panel extends React.Component {
  render() {
    // ... lo que seas
  }
}

Como cualquier otra clase de Javascript, Panel no es más que una función constructora que podemos pasar de un sitio a otro, como veíamos al hablar de componentes de orden superior. Habrá veces que lo que queramos sea tener directamente esa función.

Por ejemplo, podríamos tener una función para encapsular componentes en indistintos tipos de contenedos, y usarla para meter elementos dentro de Panel:

function wrap(Component, children) {
  return <Component>{children}<Component>
}

// Panel (la función constructura) nos serviría en ese caso
wrap(Panel, <p>Hola</p>);
wrap(OtherContainer, <p>Hola</p>);

Otras veces necesitaremos crear “fragmentos de JSX” (en realidad son elementos como los que hemos visto apartado anterior) que incluyan nuestro Panel:

// Aquí content es una definición de cómo crear un
// panel específico, pero NO ES UNA INSTANCIA DE PANEL
let content = <Panel title='Amapola'/>

// Podríamos utilizar ese content ahora como children
// de nuestra función wrap del ejemplo anterior
let tab = wrap(Tab, content);

Es importante ser conscientes de que este caso content no es una instancia de panel. Es un Element que define cómo crear un Panel.

Al ser una clase normal, también podríamos instaciar Panel y obtener un objeto Panel real, aunque no es algo muy útil en este contexto:

// Eso es bastante inútil, pero podrías hacerlo para
// tener una instancia de Panel
let panel = new Panel();

Lo habitual cuando necesitas una instancia de Panel es que sea porque está montado en otro componente, y para eso podrías capturarlo a través de ref:

// Esta es una forma más habitual de tener una instancia
// de panel resultante de montarlo en el DOM dentro del
// método render de otro componente, 
let panel;

<Panel ref={p => panel = p} title='Amapola'/>

// Tras capturar la referencia, panel es una instancia
// de Panel y podríamos acceder a cualquier método que
// estuviera definido en la clase
panel.collapse();

Es importante distinguir los tres escenarios y utilizarlos según necesitemos. A veces necesitaremos tratar con la clase del componente, otras veces estaremos generando la información necesaria para renderizarlo desde JSX, y en ocasiones necesitaremos una referencia al componente ya instanciado y montado en el DOM.

Esto también afecta a la forma en que es tratan los children de un componente.

Si tenemos un componente que actúa como contenedor de otro(s) componente(s), y necesitamos interactuar con sus children, habrá que tener en cuenta que lo que vemos dentro de children no son instancias reales de componentes, son sólo Elements, por lo que no podremos invocar métodos definidos en esos componentes, a menos que obtengamos una referencia a ellos después de ser montados, como veíamos en el ejemplo anterior.

Otro factor a tener en cuenta a la hora de tratar con children es que, dependiendo de lo que nos interese, podemos retrasar más o menos su creación a costa de perder o ganar visibilidad.

Si tuviéramos este componente:

const FunctionalComponent = ({text}) => <p>text</p>;

Podríamos utilizarlo para incluirlo dentro de un Panel:

<Panel><FunctionalComponent text="Rosa"/></Panel>;

Haciéndolo de esta forma, en props.children del Panel habrá un Element para crear nuestro FunctionalComponent, pero el código de FunctionalComponent no se ejecutará hasta que llegue el momento de montarlo en el DOM. Si ese código es lento, con esto estaríamos posponiendo su ejecución hasta que fuera necesario (e incluso evitándola si por algún motivo al final no se renderizase).

Podemos darle la vuelta y hacerlo al revés: ejecutar primero FunctionalComponent e insertar el resultado como props.children de Panel:

 
<Panel>{FunctionalComponent({text: "Rosa"})}</Panel>

Ahora siempre estaremos pagando el precio de ejecutar la función, pero a cambio al renderizar Panel no queda rastro de FunctionalComponent. Esto puede ser útil si Panel necesita retocar sus hijos antes de renderizarlos, por ejemplo para añadirles una clase css o un manejador de eventos a través de sus respectivas props. Si estuviéramos utilizando FunctionalComponent como componente en lugar de invocándolo como una función normal, sería opaco para Panel y no podría modificar los elementos generados por FunctionalComponent al renderizarse.

Utilizar una u otra técnica depende mucho de lo que quieras resolver en cada momento, pero al final en una aplicación no es extraño acabar usando ambas.

Conclusión

Manejar este tipo de situaciones puede ser muy útil y darte un extra de flexibilidad a la hora de diseñar tus aplicaciones con ReactJS. De hecho es una de las cosas que más gusta de ReactJS, la cantidad de opciones que tienes para resolver un problema y los distintos enfoques que le puedes dar a la hora de diseñar la aplicación.

Como suele pasar, con el JSX atraviesas varias fases. Al principio todo te parece fácil porque te limitas a copiar ejemplos, no necesitas hacer cosas raras, y todo fluye. Cuando empiezas a necesitar hacer cosas más complejas e introducir algunas abstracciónes, es inevitable liarse unas cuantas veces entre clases, instancias y descriptores para construir instancias. Una vez que tienes eso interiorizado, le puedes sacar mucho partido y aplicar un patrón u otro dependiendo de lo que necesites en cada momento.

Posts relacionados:

  1. Cómo utilizar ReactJS con Browserify

» Leer más, comentarios, etc...

Blog Bitix

Desempaquetado del kit de iniciación a la electrónica para la Raspberry Pi

February 25, 2017 10:30 PM

Raspberry Pi

En el año 2012 compré una de las primeras Raspberry Pi que estuvieron disponibles a la venta, una placa modelo B de 256 MiB. La Raspberry Pi es un pequeño computador en una placa del tamaño de una tarjeta de crédito a un precio que aún se sigue manteniendo en las nuevas versiones de unos 40€ a los que hay que sumar algunos complementos necesarios como una tarjeta SD o microSD y un cargador con conector miniUSB. Las versiones iniciales que es la que tengo se componían de:

  • CPU 700 Mhz, un núcleo ARM11 de 32 bits
  • Memoria de 256 MiB
  • Ethernet 100 MB
  • Lector tarjeta SD
  • 2 x USB 2.0
  • HDMI
  • 26 pines, 17 de propósito general o GPIO
  • Salida de audio
  • Salida de vídeo

Después de unos años se han lanzado versiones notablemente mejoradas, hasta la fecha la última es la Raspberry Pi 3 de esta placa que multiplica por 4 la cantidad de memoria RAM hasta 1 GiB y con una CPU de 4 núcleos a una frecuencia de 1.2 Ghz basados en los procesadores ARM Cortex-A53 de 64 bits, incluyendo WIFI N y Bluetooth 4.1, 4 conectores USB, lector microSD y 26 pines GPIO. Aunque la finalidad original de este computador es el aprendizaje de programación y electrónica el uso principal que le he dado hasta ahora ha sido para hacer descargas P2P via torrent. Esta placa es muy popular debido a su bajo coste aunque hay que sumarle posteriormente el precio de una tarjeta microSD y el cargador para proporcionarle energía, su éxito no solo es debido a su coste ya que hay opciones aún más potentes en algunos aspectos a precio similar que no son tan populares, el valor diferenciador de la Raspberry Pi es el apoyo y soporte de la comunidad.

Placas modelos Raspberry Pi 1 B y 3 B

Hace unas semanas compré un kit de electrónica básico para la Raspberry Pi pero que incluye una buena cantidad de sensores y elementos de electrónica y sirve para cualquier placa con pines GPIO. Como el kit es para la Raspberry Pi 3 y viene con un cable de extensión de 40 pines (cantidad de pines que tiene la Raspberry Pi 3) y yo tengo la 1 debí comprar también un cable de extensión de 26 pines (los que tiene la Raspberry Pi 1) para la matriz de puntos con la que hacer pruebas sin soldar los elementos. El precio del kit no es muy caro, de unos 30€ y el barómetro no venía soldado con sus pines por lo que si queremos usarlo deberemos hacer la soldadura primero con un soldador de electrónica y estaño.

El contenido del kit es el siguiente que viene en una estupenda caja de plástico para guardar todos los componentes de forma ordenada:

  • 1 x GPIO to breadboard 40-pin breakout interface
  • 1 x solderless prototype breadboard
  • 40 x pin jumper wires (male to male 15cm)
  • 2 x 8 pin Jumper Wires (female to female 20cm)
  • 24 x LED (6 x Bright White, 6 x Red, 6 x Yellow, 6 x Green)
  • 65 x resistors (200ohm x 20pcs, 1Kohm x 20pcs, 10Kohm x 20pcs, 1Mohm x 5pcs)
  • 3 x photoresistor (light sensor)
  • 5 x push buttons
  • 3 x potentiometer (10kilohm adjustable resistor)
  • 1 x A/D converter
  • 1 x DHT11 Temperature/Humidity sensor
  • 1 x motion sensor
  • 1 x mercury tilt switch sensor
  • 1 x I2C 1602 alphanumeric LCD
  • 1 x servo motor
  • 1 x piezo Buzzer
  • 1 x BMP180 Pressure/Temperature Sensor
  • 1 x relay
  • 1 x Infrared Remote Controller and Receiver(VS1838B)
  • 1 x Raspberry Pi/Arduino 8-Channel TTL Logic Level Converter
Caja, componentes y sensores
Display 16x02 y adaptador I2C
Breadboard y adaptador
Adaptador breadboard, diodos, botones, resistencias y fotoresistores

La matriz de conexiones o breadboard es una forma cómoda de hacer pruebas sin tener que hacer soldaduras, los puntos en vertical de la mitad superior e inferior están conectados entre si de modo que con los cables macho-macho podamos poner y quitar conexiones. La matriz está numerada horizontalmente con números y verticalmente con letras de forma que cada punto sea identificable individualmente. Las dos filas de puntos superiores suelen usarse para proporcionar un voltaje de 5V y la conexión de tierra, las dos filas de puntos inferiores para proporcionar un voltaje de 3.3V y tierra. La placa está dividida en dos mitades verticalmente de las letras A-D y E-F formando columnas verticales de puntos conectadas en grupos de 5.

Mi intención para este kit es hacer unos pequeños ejemplos usando en cada uno de ellos uno o varios elementos y con el lenguaje de programación Java y la librería Diozero. Entre los ejemplos estará encender y apagar un LED, usar el display de 16x2 caracteres, el sensor de temperatura y humedad, el sensor de infrarrojos, el motor, los pulsadores, el sensor de movimiento, los detectores de luz, el detector de golpes, etc…

En la página del fabricante o distribuidor mayorista Osoyoo hay colgados varios ejemplos usando varios de estos elementos. También deberemos hacernos con las referencias de los pines para saber las conexiones que debemos hacer con los cables junto con la tabla de referencia de colores de las resistencias. Para usar las tablas de referencia debemos saber que hay varias formas de numerar los pines. Está la del header del 1 al 26 o del 1 al 40 secuencialmente según la disposición en el header, la que utiliza la librería wiringPi y Pi4J para numerar los pines GPIO y la de Broadcom que utiliza la librería Diozero. Estas tablas de referencia de nomenclatura son importantes porque cada una numera los pines de forma diferente, por ejemplo, según la numeración de wiringPi el pin número 3 corresponde al GPIO 8 cuando según la nomenclatura de Broadcom el mismo pin corresponde al GPIO 0 en el modelo RPi 1 modelo B rev1 y al GPIO 2 en la RPi 3.

Header de pines Raspberry Pi 1 B y Raspberry Pi 3 B, nomenclatura wiringPi
Headers de pines Raspberry Pi 1 B y Raspberry Pi 3 B, nomenclatura Broadcom
Código de colores de las resistencias

Un ejemplo básico sin necesidad de programar nada es encender un diodo LED. Los elementos a usar son el diodo LED, una resistencia, los cables macho-macho, el cable de extensión y la matriz de puntos. Para ello conectamos el cable de extensión a la matriz de puntos donde con los cables macho-macho haremos las conexiones en los agujeros de la matriz de puntos. Usaremos la conexión de voltaje de 3.3V y una resistencia de 200 ohmios para que el LED no reciba demasiada intensidad. Los diodos LED tienen dos patitas, una más corta que la otra que indican la polaridad, la corta es el polo negativo y se conecta a tierra, la larga es el polo positivo que se conecta a uno de los extremos de la resistencia y el otro extremo de esta la voltaje de 3.3V.

Ejemplo conexión LEDs y Raspberry Pi

Con el programa Fritzing podremos prototipar y documentar el esquema de conexiones que realicemos de los proyectos. Posee numerosos modelos, elementos electrónicos y dispositivos de entrada y salida aunque no he encontrado el correspondiente la placa de extensión de wiringPi.

Fritzing

En el siguiente artículo explicaré como crear un programa Java para encender y apagar varias veces un diodo LED con la librería Doizero. Además explicaré como con Gradle, SSH y Ansible hacerlo de forma cómoda desde nuestra máquina de desarrollo y no directamente desde la más lenta Raspberry Pi.

Software. Hardware. Complete.

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Recuperando programas antiguos: Conclusiones

February 24, 2017 08:33 AM

Después de Recuperando programas antiguos: Los programas y Recuperando programas antiguos: El proceso, dejadme que de paso a algunas conclusiones, o lecciones aprendidas. Lo primero que he percibido, es que lo que cuentan son las buenas ideas, al punto que nos motiven en su desarrollo. Pero sirve también copiar a los grandes, mejorando aquellos aspectos […]

La entrada Recuperando programas antiguos: Conclusiones aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Recuperando programas antiguos: Los programas

February 22, 2017 06:07 PM

Continuando con Recuperando programas antiguos: El proceso, vamos a proceder a analizar los programas que he encontrado, y que son parte de mi historia. Veréis que es muy fragmentario, en unos casos, no todo son las últimas versiones de lo que programé. En otros, son tan últimas, que ni siquiera funcionaban. Cuando ha sido posible, […]

La entrada Recuperando programas antiguos: Los programas aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Variable not found

Acceder a IIS Express desde otro equipo de la red local, edición 2017

February 22, 2017 08:48 AM

Aunque IIS Express está diseñado principalmente para ser utilizado por desarrolladores en el interior su equipo de trabajo, seguro que la mayoría sabéis que haciendo un par de cambios en la configuración también es posible utilizarlo desde equipos externos, por ejemplo para poder hacer pruebas de una web o servicio desde otros dispositivos conectados a la misma red.

Es sencillo encontrar cómo hacerlo porque hay mucho escrito al respecto en la red, y sin embargo de vez en cuando me encuentro con desarrolladores que no saben que esto es posible hacerlo, así que este post va por vosotros ;D

Partiremos de un proyecto ASP.NET 4.x creado en Visual Studio 2015 o 2017, da igual si se trata de una aplicación MVC, Web Forms, Web API o lo que sea. Para desarrollar el ejemplo, imaginemos que al ejecutarlo en local estamos usando la URL http://localhost:3803/.

Veamos paso a paso cómo acceder a esta aplicación desde otro equipo conectado a la red local, y cómo solucionar algunos de los problemas que podemos encontrar por el camino.


1. Averiguamos con qué dirección está visible nuestro equipo desde el exterior
Esto podemos hacerlo con cierta facilidad ejecutando el comando "ipconfig" en la consola de la siguiente forma:
C:\>ipconfig | find "IPv4"
Dirección IPv4. . . . . . . . . . . . . . : 192.168.1.33
Dirección IPv4. . . . . . . . . . . . . . : 192.168.56.1
Dirección IPv4. . . . . . . . . . . . . . : 10.71.34.1

C:\>
El número de resultados que veremos ahí dependerá de los adaptadores de red (físicos o virtuales) que tengamos configurados en nuestro equipo. De ellos tendremos que seleccionar la dirección que se encuentre en el rango de red usado por los equipos externos desde los cuales queremos acceder a nuestra web.

En mi caso, sé que todos los equipos de la red local usan direcciones del tipo 192.168.1.*, por lo que el nombre de host que deberían usar para acceder a mi equipo de trabajo sería la 192.168.1.33.

2. Localizamos el archivo de configuración de IIS Express del proyecto

Este archivo se llama "applicationhost.config" y en proyectos de Visual Studio se encuentra en una carpeta llamada ".vs" que encontramos en el directorio raíz de la solución, y dentro de ella, en la subcarpeta "config".

En otros casos, el archivo de configuración podréis encontrarlo en la carpeta de configuración de IIS Express de vuestro usuario en el equipo: %userprofile%\documents\iisexpress\config.

3. Localizamos las líneas donde se especifica la URL por defecto del proyecto

En el archivo "applicationhost.config", debemos localizar la parte de la configuración donde se indica la URL de acceso al proyecto en la máquina local. Por ejemplo, podría ser algo como esto:
<bindings>
<binding protocol="http" bindingInformation="*:3803:localhost" />
</bindings>
Observad que este binding está limitando el acceso a vuestro sitio web, permitiendo únicamente el uso del host "localhost" para acceder al mismo. Para habilitar el acceso desde equipos externos, lo primero que tenemos que hacer es añadir otros bindings con el nombre de host que se utilizará desde fuera.

4. Añadimos a la configuración de IIS Express el nuevo binding con la dirección de nuestro equipo

En la sección de configuración <bindings>, añadimos una nueva línea en la que indicaremos que la aplicación también será accesible utilizando como host nuestra IP, de forma que quedaría más o menos como aparece a continuación. Ojo, ¡tened en cuenta que debemos elegir un puerto distinto al que usamos en localhost para que no haya conflictos!
<bindings>
<binding protocol="http" bindingInformation="*:3803:localhost" />
<binding protocol="http" bindingInformation="*:3804:192.168.1.33" />
</bindings>
Bien, pues si ahora intentamos ejecutar sin depuración nuestra aplicación es posible que pensemos que algo hemos roto ;)

Unable to launch the IIS Express Web server.
Failed to register URL "http://192.168.1.33:3804/" for site "DemoMvc5" application "/". Error description: Acceso denegado. (0x80070005)
Unable to launch the IIS Express Web server.

Este error aparece siempre que no hayamos lanzado Visual Studio como administrador, pues el nivel de permisos del proceso bajo el que se lanza IIS Express no es suficiente como para "apropiarse" de una dirección y puerto TCP/IP del equipo y utilizarla para escuchar peticiones.

En cambio, si iniciamos Visual Studio como administrador veremos que arranca correctamente y que, de hecho, podemos acceder a la aplicación utilizando tanto localhost:3803 como 192.168.1.33:3803, lo que quiere decir que, si no existen problemas de permisos, el binding está bien hecho.

5. Reservar la URL y conceder permisos de uso (sólo no administradores)

Como hemos comentado antes, este paso no será necesario si estamos ejecutando Visual Studio (y por tanto IIS Express) como administrador. Pero si no es así, debemos abrir una la línea de comandos con permisos elevados y utilizar la siguiente instrucción para reservar la URL y darle derechos de uso a determinados usuarios del equipo, por ejemplo como sigue:
C:\>netsh http add urlacl url=http://192.168.1.33:3808/ user=todos

La reserva de dirección URL se agregó correctamente

C:\>
Pero antes de hacerlo tened en cuenta unos detalles:
  • Primero, la URL debe estar completa, incluida la barra del final.
  • El usuario puede ser cualquier grupo del sistema o nombre de usuario con dominio. En mi caso, en lugar de "todos" podría haber indicado "pc-jma\josem", que es mi usuario en la máquina local.
  • Los nombres de grupo son sensibles al idioma de instalación de Windows. Es decir, si vuestro Windows está instalado en inglés, debéis usar el nombre "everyone" en lugar de "todos".
Tras ejecutar el comando, ya debería ser posible acceder a la aplicación desde el equipo utilizando tanto la URL interna (localhost) como la externa (192…), cada una con su puerto correspondiente.
IIS Express mostrando que la aplicación está disponible a través de dos URL distintas

Pero el acceso externo aún no está garantizado: el firewall impedirá el acceso a no ser que le indiquemos lo contrario.

6. Abrir el firewall

Por defecto, el firewall de Windows rechazará cualquier intento de acceso a la máquina desde el exterior, por lo que debemos configurar una regla de entrada que asegure que las peticiones hacia nuestra web podrán entrar sin problema.

Esto podemos hacerlo a base de ratón, utilizando las herramientas de administración de Windows o, ya que teníamos abierta una consola de comandos con permisos de administrador, ejecutando la siguiente orden:
C:\>netsh advfirewall firewall add rule name="External Access to MyApp" dir=in action=allow protocol=TCP localport=3804

C:\>
Por supuesto, recordad que:
  • El parámetro localport debe ser el puerto que habéis elegido para el acceso externo, el mismo que usamos en el archivo de configuración de IIS Express, y más adelante al reservar la URL.
  • Es conveniente poner un nombre reconocible a la regla, de forma que más adelante podamos identificarla con facilidad.
¡Y eso es todo! Si habéis llegado hasta aquí, ya podréis ejecutar o depurar vuestra aplicación en Visual Studio, y acceder a ella desde cualquier equipo de la red local usando la dirección que hayáis elegido en los pasos anteriores.

Espero que os resulte de utilidad ;)

Publicado en Variable not found.

» Leer más, comentarios, etc...

Poesía Binaria

¿Qué son y cómo utilizar direcciones IP flotantes en DigitalOcean? [Vídeo]

February 21, 2017 09:36 PM

Un problema que teníamos los que utilizamos los servicios de Digital Ocean es que cuando paras una máquina para realizar una actualización, la dirección IP de la misma es inaccesible y dejas a todos tus visitantes en la estacada y mi humilde blog sin visitas ni nada que le diga a mis visitantes que sigo vivo.

Al menos sucedía así hasta hace un tiempo, cuando lanzaron las IP flotantes o Floating IPs.

Te lo cuento

Si prefieres leerlo todo, puedes saltarte el vídeo. Aunque son 3 minutos.

Para más información, sigue leyendo…

El problema

En DigitalOcean la asignación de direcciones IP públicas va por cada uno de los servidores que reservas. Eso por un lado quiere decir que todos VPS que pides están conectados a Internet (¿Quién puede querer que un VPS no esté conectado? Lo veremos pronto). Y por otra parte, podemos comprobar cómo las direcciones pueden cambiar. Es decir, nadie nos garantiza que cuando sacamos una máquina de nuestro sistema, cuando metamos otra, ésta vuelva a tener la misma dirección IP. Es verdad que en muchos casos es así, pero es que Digital Ocean no es capaz de saber si vamos a crear una máquina tras destruir una antigua.
Por otro lado es muy común que en un servidor hagamos tareas de mantenimiento y, durante ese tiempo, no deberíamos tener ninguna entrada de visitantes. Se pueden encontrar con cosas que no deben, fallos, de esos que asustan a los visitantes y podemos exponer información del sistema de esa que hace que a un atacante se le iluminen los ojos.
Otro caso, que es muy es cuando tenemos que rehacer el sistema (hay veces que una reinstalación sale más barato que actualizar), reservemos una máquina nueva y empecemos a trabajar en ella. Mientras tanto, todos los visitantes estarán accediendo a nuestra web alojada en nuestro servidor antiguo. Pero, cuando hayamos terminado de montar la nueva máquina, después de hacer pruebas y todo, cuando esté a punto, hacer un cambio de IP del servidor viejo al nuevo…

La solución de DigitalOcean

En este caso, DigitalOcean nos presenta las IPs flotantes. Esto son direcciones IP que podemos “enchufar” a un servidor. De modo que nuestros visitantes y usuarios accederán siempre a la IP flotante. Dejando la IP del servidor para un uso privado e interno, todavía no podemos eliminar dicha IP para que no sea accesible, aunque sí podríamos filtrarla por IPtables por ejemplo.

Ya que estas IP son “enchufables”, pueden estar conectadas a nuestro servidor web, y nuestros visitantes acceder a dicha IP. La ventaja es que esta dirección la podemos desenchufar de un servidor y enchufar en otro sin problema y de forma instantánea. Anteriormente podíamos actualizar la DNS del dominio para cambiar la IP, aunque la propagación DNS ha mejorado mucho los últimos años, puede tardar varios minutos o incluso horas en el peor de los casos, y dependiendo de nuestro proveedor.

Enchufando y desenchufando

Ya que podemos hacer lo que queramos, practiquemos un poco. Y es que si vamos a realizar tareas de mantenimiento en el servidor que requieran desconectar el servicio, en lugar de dejar a nuestros visitantes con la dirección IP de nuestra web sin respuesta podemos crear un pequeño VPS con un servidor web y que dirija a una página estática que diga: “Lo sentimos, estamos de mantenimiento”. Seguro que encontráis por Internet plantillas muy buenas con páginas que hagan que nuestros usuarios no quieran matarnos, sino que nos den su apoyo por querer mejorar el servicio. Una vez creado el VPS que sirve páginas estáticas (muy importante, porque si son dinámicas seguramente necesitemos más servidor), vinculamos la IP flotante que apunta al servidor que tenemos que parar a nuestro nuevo servidor de páginas estáticas. En este momento, nuestros usuarios comenzarán a entrar al servidor de “vuelva más tarde”. Así no perderemos desesperaremos a nuestras visitas o clientes mientras mejoramos nuestro servidor. Incluso podríamos dejar algunos servicios mínimos activos.

Como decíamos antes, también podemos empezar a trabajar en una actualización de nuestros servicios poco a poco, reinstalar una nueva máquina y luego cuando esté todo hecho cambiar la IP flotante de nuestro servidor al nuevo, seguidamente destruir el antiguo servidor, que ya no nos importa.

Como vemos, son muchas las posibilidades que nos da tener IPs flotantes cuando contratamos el servicio. Y, a partir de ahora es una buena práctica cuando trabajamos con esta empresa. Aunque para otros servicios en la nube suele haber conceptos parecidos, esto de enchufar y desenchufar direcciones IP no es nuevo y podemos ponerlo en práctica en otros proveedores.

Jugando con la API

DigitalOcean, tiene una ventaja añadida, desde el primer día, y es su API. Desde ahí nos dejan tocar muchas y, sobre todo, automatizar acciones. Podemos crear y destruir droplets, administrar DNS, imágenes, e IPs flotantes, tamaños de servidores, etc… pero hoy vamos a hablar de la API de metadatos de DigitalOcean. Esta API hace que desde una misma instancia se pueda acceder a información sobre la misma. Es decir, que una misma instancia pueda preguntar su dirección IP pública, o privada, o la IP flotante, conocer su ID, etc.

Aunque ya que utilizamos GNU/Linux sabemos que podemos utilizar ifconfig para sacar direcciones IP locales, combinandolo con grep, cortando la cadena resultante, etc, las llamadas a la API de DigitalOcean suelen ser más directas. Además, nadie nos dice que en el futuro este proveedor no cambie la forma en la que asigna las direcciones IP a nuestra máquina (Amazon lo hizo hace unos años), haciendo que nuestra antigua forma de hacerlo no sea efectiva ya. Además, con estas llamadas a la API de metadatos podremos crear scripts generales que podremos subir en varias máquinas y cada uno averigüe información de la máquina por sí mismo.

Todas estas llamadas se hacen haciendo una petición GET a http://169.254.169.254/ , al ser una conexión interna y directa no necesita protocolo SSL (y es tan rápida que el servicio estará alojado en la misma máquina física). Esta llamada la podemos hacer con cURL, o desde cualquier lenguaje de programación. Tenemos algunas llamadas interesantes, como por ejemplo:

  • Extraer hostname de la máquina:
    curl -s http://169.254.169.254/metadata/v1/hostname
  • Extraer IP pública:
    curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address
  • Extraer IP privada:
    curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address
  • Extraer información del usuario (esta información con algún script de inicialización para la máquina):
    curl -s http://169.254.169.254/metadata/v1/user-data
  • Extraer región geográfica:
    curl -s http://169.254.169.254/metadata/v1/region
  • Extraer etiquetas:
    curl -s http://169.254.169.254/metadata/v1/tags
  • ¿Tenemos IP flotante? (true/false)
    curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active
  • Extraer IP flotante:
    curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/ip_address

Y con esta información podremos hacer muchas cosas.

¿Quieres un servidor en Digital Ocean?

Este post no es patrocinado. Sólo quería compartir esta utilidad de este servicio que utilizo. Aunque aprovechando esto, ya que estamos, si quieres contratar el servicio con este proveedor, si te registras de mi parte te darán $10 para gastar en hospedaje. Aunque sea en dólares puedes contratarlo con independencia de tu país.
Para contratar el servicio de mi parte, sigue este enlace: https://m.do.co/c/fa10e4099dbc.
Y yo también me llevaré algo por recomendarte.

The post ¿Qué son y cómo utilizar direcciones IP flotantes en DigitalOcean? [Vídeo] appeared first on Poesía Binaria.

» Leer más, comentarios, etc...

Una sinfonía en C#

Novedades de Visual Studio 2017: Intellisense Filtering

February 20, 2017 01:45 PM

Entre las muchas novedades que nos trae la nueva versión de Visual Studio una que me resultó muy útil es Intellisense filtering, una características que nos permite aplicar filtros sobre los que nos muestra intellisense, es decir, hasta hoy si presionamos Ctrl + Space vemos algo así:

image

Lo clásico un listado con todo lo que tenemos disponible en el contexto actual, por supuesto que la lista puede ser muy larga lo cual dificulta encontrar lo que estamos buscando, más aún si se trata de una API que no conocemos y no tenemos muy claro qué estamos buscando

Intellisense filtering al rescate

Intellisense filtering permite justamente eso, poder usar intellisense y aplicar filtros en el mismo momento

image

Ahí debajo tenemos los filtros, podemos ir con el mouse y tocarlos pero mejor que eso, tenemos teclas de acceso directo para hacerlo

Teclas rápidas

  • Methods (Alt + M)
  • Interface (Alt + I)
  • Classes (Alt + C)
  • Structure (Alt + S)
  • Enums (Alt + E)
  • Delegates (Alt +D)
  • Namespace (Alt + N)
  • Keywords (Alt + K)
  • Snippets (Alt + T)

intellisense filtering

Como se ve se pueden ir tocando las teclas rápidas y agregando o quitando filtros.

De momento no existe la posibilidad de hacer nuestros propios filtros, por ejemplo si quisiéramos mostrar elementos con ciertos atributos hoy no lo podemos hacer.

De todos modos es una característica excelente que seguro le vamos a sacar provecho.

Hasta la próxima, nos leemos.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 270

February 20, 2017 10:28 AM

Happy 15th Birthday .NET!Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET

ASP.NET

.NET Core / ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Componentes/bibliotecas

Publicado en Variable not found

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Recuperando programas antiguos: El proceso

February 20, 2017 08:30 AM

Llevaba unos diez años intentado encontrar una disquetera de 5 y cuarto, las que manejaban disquetes que se llamaban, erróneamente, blandos, de 5,25 pulgadas. Había mirado en tiendas de segunda mano, preguntado a conocidos entusiastas de la informática que llevan tiempo en el mundillo, y nada. Resulta extraño que nadie se haya planteado crear una […]

La entrada Recuperando programas antiguos: El proceso aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Ejemplo con PB/CC

February 18, 2017 02:23 PM

Cuando escribía Ejemplo con PB/Forms, creo que la conclusión a la que llegasteis es que PowerBasic es un lenguaje bastante tedioso. Nada más lejos de la realidad, lo que en realidad es tedioso es crear aplicaciones Windows, usando su API, y el bucle de proceso de mensajes. Algo en donde PBForms / DDT ayuda, pero […]

La entrada Ejemplo con PB/CC aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Blog Bitix

Ejemplo de RabbitMQ con Java para enviar y recibir mensajes

February 18, 2017 09:00 AM

Entre las ventajas de integrar dos aplicaciones mediante el envío de mensajes están que evita que estén acopladas y la comunicación es asíncrona. Con RabbitMQ también podremos implementar cada uno de ellas con el lenguaje de programación que prefiramos de entre las varias posibilidades para las que ofrece clientes y por esto último podemos preferir usarlo en vez de las especificación JMS propia de Java EE que nos obligaría a usar un servidor de aplicaciones que lo implemente, posiblemente JBoss/Wildfly o Weblogic en vez de Tomcat o Jetty. En el artículo incluyo un ejemplo para el lenguaje Java mostrando el envío y recepción de mensajes junto con la aplicación de administración que nos proporcionará información útil.

RabbitMQ
Java

Las aplicaciones que se integran mediante el envío y recepción de mensajes evitan el acoplamiento y sincronía junto con la posibilidad de implementar cada una de ellas con diferentes lenguajes o plataformas. Entre las especificaciones que componen Java EE está JMS pero tanto la aplicación que envía como la que recibe mensajes deben estar programadas en el lenguaje Java, a menos que incluyamos un adaptador que permita a la aplicación no Java interactuar con JMS.

RabbitMQ es un software que proporciona una funcionalidad similar a JMS pero con la ventaja que ofrece soporte para los lenguajes más populares como Java y JVM, Ruby, Python, .NET, PHP, Node.js, Go y varias más. Usa varios conceptos similares a los presentes en JMS como que el emisor envía los mensajes a una cola y el receptor los lee de ella de modo que ni el emisor ni receptor se conocen consiguiendo de este modo el desacoplamiento entre ellos. Los mensajes son leídos de las colas con la posibilidad de que cada mensaje sea recibido por un único receptor o por cada uno de ellos.

Realmente en RabbitMQ los mensajes no son enviados directamente por el emisor a las colas sino que se envían a un exchange que finalmente lo enruta y encola en la cola destino. Los exchanges pueden ser directos basando su lógica de encolado según el valor del binding key enviada junto con el mensaje y un routing key asociada con la cola o basados en temas en los que se usa una cadena formada por una lista de palabras separada por puntos, la lógica de enrutado se toma según si el binding key cumple el patrón del routing key que puede contener sustituidores de palabras, siendo un * una palabra exacta y # varias palabras contiguas.

En la documentación de RabbitMQ hay 6 tutoriales en diferentes lenguajes para el envío y recepción de mensajes.

Basándome en estos ejemplos he creado un proyecto uno muy similar al Tutorial 1, ejecutable más fácilmente con Docker y Gradle.

Tanto en el emisor como en el receptor deberemos declarar las colas que van a usar (si una no existe se creará y si existe se usará), a la cola se le asigna un nombre y el receptor define un manejador para recibir los mensajes según se envían.

Para ejecutar el ejemplo usaré el contenedor de Docker para RabbitMQ iniciándolo con Docker Compose y el siguiente archivo descriptor. Puedes consultar la serie de artículos sobre Docker que escribí para conocer cómo usarlo.

Una vez iniciado el contenedor y con el código fuente del ejemplo, iniciamos en cualquier orden la parte receptora de los mensajes y la parte emisora de mensajes con los comandos ./gradlew receive y ./gradlew send respectivamente, momento en el cual veremos que en la consola salen las notificaciones de recepción y envío.

En la comunicación con RabbitMQ se puede usar TLS/SSL así como mecanismos de autenticación y autorización para mayor seguridad. Usando confirmaciones si el receptor falla en el procesado el mensaje no se pierde ya que no se habrá declarado como acknowledge aún así si RabbitMQ falla los mensajes se perderán a menos que las colas se declaren como persistentes las cuales se guardarán en disco perdurando a una catástrofe.

RabbitMQ posee un plugin para la administración con el que podemos administrar permisos, tener una vista global, ver ratios de mensajes, estadísticas, colas, exchanges y más información, nos da información muy interesante sobre el estado del procesamiento de mensajes. Es accesible mediante el navegador y la URL http://localhost:15672/. En la captura del estado de la cola hello hay 10 mensajes encolados pendientes de entregar a algún receptor.

Para profundizar más en las aplicaciones basadas en mensajes con RabbitMQ dos buenos libros son Learning RabbitMQ y Matering RabbitMQ cubriendo temas más avanzados como clustering, alta disponibilidad, arquitectura, patrones de diseño, seguridad y rendimiento.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando docker-compose up && ./gradlew receive && ./gradle send.

» Leer más, comentarios, etc...

xailer.info

La mejor documentación de Harbour

February 15, 2017 09:30 AM

Estimado usuario de Xailer,

Queremos compartir con vosotros la que pensamos es la mejor documentación de Harbour realizada hasta la fecha. Es un estupendo trabajo realizado por Viktor Szakats y desde aquí queremos agradecerlo por el gran esfuerzo realizado. Este es el enlace:

https://harbour.github.io/doc/

Saludos,

» Leer más, comentarios, etc...

xailer.info

Servidor virtual y en la nube, una opción cada vez más real para la pyme

February 14, 2017 04:27 PM

Buenas tardes,

No lo digo yo, lo dice un blog muy conocido enfocado a la PYME. Os aconsejo que le echéis un vistazo y se lo paséis a vuestros clientes para empezar a crearles la necesidad del cambio.

https://www.pymesyautonomos.com/tecnologia/servidor-virtual-y-en-la-nube-una-opcion-cada-vez-mas-real-para-la-pyme

Por supuesto, Xailer en su versión Enterprise ofrece todo lo necesario para hacer software de acceso remoto a la nube, siendo su gran baluarte el data control WebDataSource que permite realizar aplicaciones completamente autónomas (un sólo archivo EXE) que no requieren ningún tipo de instalación y que acceden remotamente a los datos en servidores en la nube con absoluta seguridad.

Si alguno de vosotros tiene algo de experiencia o un caso de éxito, os agradezco que pongáis un comentario al respecto.

Un saludo

» Leer más, comentarios, etc...

Variable not found

Refresco automático de setting tipados en ASP.NET Core 1.1

February 14, 2017 09:34 AM

ASP.NET CoreHace algunos meses comentábamos por aquí cómo en ASP.NET Core es posible modificar los archivos de configuración de una aplicación en caliente, sin necesidad de detenerla, siendo los cambios aplicados de forma inmediata.

En aquél momento ya vimos que era realmente sencillo conseguirlo cuando usábamos settings no tipados, bastaba con añadir el parámetro reloadOnChanges a la hora de añadir el origen de configuración, como en el siguiente ejemplo:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
Sin embargo, también vimos que conseguir lo mismo cuando queríamos acceder a los settings de forma tipada era algo más engorroso, puesto que había que configurar manualmente el proceso de recarga y bindeado de datos con la instancia de la clase de configuración, para poder acceder luego a ella a través de un objeto IOptions<T> disponible en el contenedor de dependencias.

Pues bien, en ASP.NET Core 1.1, la cosa se ha simplificado bastante :) Vamos a ver paso a paso cómo acceder de forma tipada a los settings almacenados en un archivo JSON, y que éstos se refresquen automáticamente cuando el archivo de configuración sea modificado.

1. Añadimos al raíz del proyecto un archivo de configuración, al que llamamos por ejemplo MySettings.json, e introducimos un contenido como el siguiente. Observad que podemos estructurar los settings como más nos convenga:
{
"AppTitle": "Settings demo",
"Author": {
"Name": "John Smith",
"Age": 99
}
}
2. En el constructor de la clase Startup, creamos un objeto de configuración añadiendo el archivo JSON como origen, indicando que debe recargar automáticamente mediante el parámetro reloadOnChanges:
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("mysettings.json", optional: false, reloadOnChange: true)
... // Other setting sources
Configuration = builder.Build();
}

public IConfigurationRoot Configuration { get; }
...
}
3. Creamos una clase cuya estructura coincida con la de los settings a los que queremos acceder de forma tipada, por ejemplo como la que sigue. Aseguraos de que los nombres de las propiedades coincidan con los usados en el archivo de configuración:
public class MySettings 
{
public string AppTitle { get; set; }
public AuthorInfo Author { get; set; }

public class AuthorInfo
{
public string Name { get; set; }
public int Age { get; set; }
}
}
4. En ConfigureServices() configuramos la instancia de la clase de settings en el contenedor de dependencias, asociándola al objeto de configuración que hemos creado anteriormente:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
... // Other services
services.Configure<MySettings>(Configuration);
}
Como podréis comprobar, no hay nada nuevo en lo que hemos hecho hasta el momento. En versiones de ASP.NET Core anteriores a la 1.1 eran exactamente los pasos que debíamos seguir para tener nuestra instancia tipada disponible a través de instancias IOptions<T> obtenidas a través del inyector de dependencias. La novedad viene ahora ;)

5. Para acceder a los datos de configuración siempre frescos lo hacemos a través de una instancia de IOptionsSnapshot<T>, como en el siguiente ejemplo:
public class TestController : Controller
{
private readonly MySettings _settings;

public TestController(IOptionsSnapshot<MySettings> settings)
{
_settings = settings.Value;
}
public IActionResult Index()
{
var message = $"{_settings.AppTitle}, " +
$"created by {_settings.Author.Name} " +
$"({_settings.Author.Age} years old)";

return Content(message);
}
}
Observad que el único cambio respecto a las versiones anteriores es que el acceso a la instancia de la clase de settings tipada lo hacemos solicitando un IOptionsSnapshot<T> en lugar de usar IOptions<T>.

Tras esto, si ejecutamos la aplicación, veremos que las modificaciones al archivo de configuración son tenidas en cuenta sobre la marcha, mostrándose en cada acceso a /test los valores actualizados.

Publicado en Variable not found.

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

La corta, y tormentosa vida del genio de la computación Phil Katz

February 14, 2017 08:14 AM

Hace ya mucho tiempo, escribía ¿Por qué escribí PGP?, el visionario manifiesto de Phil Zimmermann sobre la privacidad. Hoy quiero hacerme eco del documento The short, tormented life of computer genius Phil Katz, escrito por Lee Hawkins Jr, que se publicase el 21 de mayo del 2000 en el Milwaukee Journal Sentinel, y que hoy […]

La entrada La corta, y tormentosa vida del genio de la computación Phil Katz aparece primero en Bitácora de Javier Gutiérrez Chamorro (Guti).

» Leer más, comentarios, etc...

Picando Código

Tomb Raider en GNU/Linux

February 13, 2017 12:00 PM

Feral Interactive es una de las empresas favoritas de quienes jugamos en GNU/Linux. Han publicado en nuestro querido sistema operativo juegos como XCOM, la saga Warhamer, Mad Max, Middle-earth: Shadow of Mordor, y más.

En abril de 2016, Feral publicó Tomb Raider. Este nuevo título es un reboot de la saga y reconstruye el origen de Lara Croft. Con motivo del cumpleaños de Lara, Feral tiene alguno de sus juegos de oferta en su sitio web:

Oferta Tomb Raider

Generalmente podemos comprar el juego a USD 19.99, pero con este descuento del 50% podemos obtenerlo a USD 9.99 y con un descuento del 70% el DLC a 5.99. No había jugado un Tomb Raider desde el original en los 90, y aprovechando que decidieron portarlo a Linux, lo compré (sólo el juego, no el DLC). Obtuve una clave para Steam y lo dejé descargando en el cliente mientras salía a hacer unos mandados. ¡Atención que la oferta es válida hasta el viernes que viene!

Los requisitos mínimos para sistemas Steam OS y Linux son:

Mínimo:
Ubuntu 14.04 o Steam OS 2.0 (64 bit)
Procesador Intel i3 o AMD FX-6300
4GB de memoria RAM
15 GB de espacio en disco (una vez instalado en mi computadora ocupa unos 10.48 GB)
Tarjeta de video: Nvidia GeForce 640 con 1GB de memoria (testeado en driver 364.12), AMD R7 260X (testeado con driver MESA 11.2).

Sugerido:
Ubuntu 14.04 o Steam OS 2.0 (64 bit)
Procesador Intel i5
8GB de memoria
Tarjeta de video Nvidia GeForce 760 con 3GB de memoria

La computadora donde lo instalé es una laptop de 2012 con Debian Stretch (testing), un procesador Intel Core i7-3517U @ 1.90GHz, tarjeta de video Nvidia GeForce 610M y 8GB de memoria Ram. Se le notan los años ya, porque estoy jugando con los gráficos al mínimo y el benchmark no es muy optimista:

Tomb Raider - Benchmark

De todas formas se deja jugar, sabiendo que podría verse mucho mejor y tener muchos más FPS en una computadora más potente. Habiendo jugado unas horas desde que lo compré, ya estoy enganchado.

Desde el principio tenemos varias cinemáticas que nos van introduciendo en la historia. Uno de los recursos que usa (y viene estando muy de moda en juegos AAA últimamente) son escenas interactivas (Quick time events). En medio de una cinemática o evento tenemos que reaccionar apretando un botón o serie de botones que se muestran en pantalla en un tiempo determinado para lograr un resultado. Hace un poco más interactivas algunas escenas, pero el abuso que he notado de este recurso en distintos juegos hace que no sea muy partidario. Además me resulta perezoso, pero por algo tampoco juego tantos juegos AAA…

La historia es entretenida y vamos siendo testigos del desarrollo de la personalidad de Lara Croft. Empieza siendo una inocente arqueóloga -en un momento del juego hasta le escuchamos decir “Odio las tumbas”- y pasa por miles de situaciones que van formando su carácter de heroína aventurera asesina. Así también se van dando pistas de a poco del misterio que cubre la isla donde se desarrolla todo.

Como me lo esperaba, premia la exploración. Hay muchos secretos e ítems que podemos encontrar explorando y usando elementos del ambiente. Algunas situaciones me dieron la impresión de estar jugando una versión de The Legend Of Zelda, pero para adultos. Hay incluso unas escenas en las tumbas escondidas donde Lara abre un cofre de tesoro enorme que me resultó muy familiar. La observación de “para adultos” es porque incluye mucha violencia, lenguaje “fuerte” y un poco de gore. En ciertas partes hasta se incluyen elementos del género terror, creando ambiente tenso seguido por la aparición de algún tipo de susto de golpe.

Lara tiene que cazar, escalar, explorar, prender fuego cosas y asesinar para mantenerse viva. Las armas que vamos obteniendo se pueden mejorar con cosas que encontramos en el camino. A su vez, Lara gana experiencia al realizar ciertas acciones, y podemos usarla para aprender distintas habilidades de caza, supervivencia y ataque. Los controles son cómodos, los vamos aprendiendo a medida que necesitamos nuevas acciones. Ahora que le agarré un poco la mano, por alguna razón matar a los maleantes de un headshot con arco y flecha me resulta muy disfrutable.

Lo estoy jugando con el control de XBox en la PC. Con la palanca de la izquierda movemos a Lara y con la de la derecha la cámara, la configuración común para este tipo de juegos. El Steam Controller parece no haber funcionado, pero debería probar de nuevo.

En conclusión me viene resultando muy bueno por ahora y lo recomiendo. Si les interesa comprarlo, aprovechen la oferta en la tienda de Feral.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 269

February 13, 2017 08:08 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET

ASP.NET

.NET Core / ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Data

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Componentes/bibliotecas

Y para acabar, añado una tira que refleja algo que seguro habéis vivido en algún momento. Todos llevamos dentro un desarrollador que sigue trabajando mientras dormimos, y a veces incluso nos ayuda a resolver problemas espesos…

image

Publicado en Variable not found

» Leer más, comentarios, etc...

Koalite

Tratar con Fechas en JSON en Javascript y TypeScript

February 13, 2017 05:06 AM

Hace ya tiempo que JSON ganó la batalla de los formatos de transmisión de datos y se hizo ubicuo. Es simple, fácil de leer, fácil de editar manualmente… una maravilla, vamos. O no. Por desgracia, un lenguaje cuya grámatica cabe en el reverso de una tarjeta de visita también tiene limitaciones importantes, y una de ellas, con la que todos tropezamos de vez en cuando, es la falta de soporte estandarizado para fechas.

Al final cada serializador de JSON utiliza su propio sistema para tratar con fechas. Algunos optan por convertir fechas a strings usando el formato ISO 8601, otros prefieren utilizar formato epoch para convertirlas a números, y otros muchos utilizan formatos específicos en sus aplicaciones.

El problema de esto es que al recomponer los datos serializados hemos perdido información del tipo original, por lo que en lugar de un valor Date/DateTime/etc., tendremos un string o number. Si a eso le unes que generalmente JSON se utiliza sin acompañarlo de un esquema, interpretar los datos que tenemos es complicado y acaba siendo incómodo.

Hace unos días comentaba el tema con los señores Landeras y Ros, reconocidos expertos en la materia, y acabamos con un pequeño catálogo de opciones para tratar con esta situación. Algunas son más simples, otras aportan más magia. Hasta dónde quieras llegar es cosa tuya.

Todos los ejemplos son aplicables a Javascript, pero veremos también hasta dónde son “tipables” con TypeScript.

En TypeScript el problema es aun mayor, porque al tener el tipado estático es fácil pensar que estamos trabajando con C# o Java, y que si tenemos una referencia a algo que dice ser un Date realmente es un Date, pero no tiene por qué ser necesariamente así. Podemos escribir let d: Date = "Macario" as any, y no descubriremos el problema hasta que intemos usar d, lo que puede ocurrir mucho tiempo después. En Java o C#, aunque podríamos engañar al compilador pasando por los casts correspondientes, en tiempo de ejecución al menos obtendríamos el error en el momento de hacer la asignación incompatible y no mucho tiempo después al intentar usar la referencia.

Vaya por delante que, por las características de JSON, vamos a necesitar saber a priori el formato que usará el servidor para serializar las fechas. Si no, la parte de convertirlas a objetos Date se puede complicar enormemente porque implicaría empezar a probar formas de conversión hasta que alguna funcione, y nunca estaríamos muy seguros de si esa conversión es correcta o sólo fruto de la casualidad.

Parsing manual

Esta es la opción más directa y que casi todos habremos usado alguna vez. La idea es realizar una conversión explícita de las propiedades que necesitamos:

getCustomer('/customer/1').then(function(customer) {
  customer.birthdate = new Date(customer.birthdate);
  customer.lastLogin = new Date(custoemr.lastLogin);
  return customer;
});

Cuando obtenemos el objeto deserializado desde JSON, nos encargamos de actualizar las propiedades que son de tipo Date (en este caso asumiendo que nos llega un valor que new Date es capaz de interpretar, pero podríamos usar técnicas más avanzadas para parsearlo).

Como esto es un poco tedioso, podemos escribir una función que nos eche una mano:

function convertDates(target, ...properties) {
  for (let prop of properties)
    target[prop] = new Date(target[prop]);

  return target;
}

getCustomer('/customer/1').then(function(customer) {
  return convertDates(customer, 'birthdate', 'lastLogin');
});

En TypeScript podemos tipar parte de la función convertDates usando keyof T, pero necesitaremos recurrir a algún any dentro de la función y intentar parsear propiedades que no son fechas:

function convertDates<T, S extends keyof T>(target: T, ...properties: S[]) {
  for (let prop of properties)
  target[prop] = new Date(target[prop] as any) as any;
  return target;
}

// Esto es válido
convertDates(customer, 'birthdate');

// Esto genera un error de compilación
convertDates(customer, 'invalid-property');

// Pero desgraciadamente esto no lo detecta el compilador
convertDates(customer, 'name');

No es una maravilla, pero algo ayuda el tipado.

Lo peor que tiene esta opción es que es laboriosa de mantener y muy propensa a errores. Si añadimos nuevas propiedades al objeto serializado o les cambiamos el nombre, hay que actualizar las invocaciones a la función convertDates para que las tenga en cuenta.

Una forma de solucionarlo es tener algún mecanismo que nos permita detectar potenciales fechas y haga la conversión automática. Para ello podríamos aplicar alguna convención del tipo “todos las propiedades fecha lleva el sufijo Date” o “todos los strings con formato ISO 8601 son fechas”.

Aun así, hay que recordar llamar a convertDates cada vez que obtengamos un objeto que proceda de deserializar JSON.

Aprovechando JSON.parse

La forma que todos conocemos de deserializar JSON en Javascript es utilizando JSON.parse, que recibe un string y devuelve el objeto deserializado.

Lo que no es tan conocido es que JSON.parse recibe un segundo parámetro, el reviver, que permite controla la forma en que se realiza la deserialización.

Llevado esto a nuestro problema de fechas, si pudiéramos ser capaces de detectar los valores que representan fechas, por ejemplo porque se ajustan a una expresión regular, podríamos automatizar la conversión:

const customer = JSON.parse(someJsonString, function(key, value) {
  if (typeof value !== 'string')
    return value;

  const isoDate = /(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})[+-](\d{2})\:(\d{2})/;

  return value.match(isoDate) ? new Date(value) : value;
});

Con esta solución tenemos dos problemas.

El primero es que volvemos a necesitar acordarnos de invocar JSON.parse con nuestro reviver, y si se nos olvida tendremos problemas. Si tienes un único punto de la aplicación que parsea JSON no es demasiado grave porque sólo tendrás que hacerlo ahí, pero si andas parseando JSON por toda la aplicación es más incómodo (y tal vez deberías darle una vuelta a ese diseño).

De todas formas, podrías evitar el problema usando monkey patching sobre JSON.parse:

(function() {

  const customReviver = function(key, value) {
    if (typeof value !== 'string')
      return value;

    const isoDate = /(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})[+-](\d{2})\:(\d{2})/;

    return value.match(isoDate) ? new Date(value) : value;
  }

  const _parse = JSON.parse;
  JSON.parse = function(text, reviver) {
    return _parse(text, reviver || customReviver);
  }
})();

¿Qué tal se lleva esto con el tipado de TypeScript? Igual de bien o mal que antes de hacer el parcheado. El tipo de JSON.parse no ha cambiado y sigue siendo:

parse(text: string, reviver?: (key: any, value: any) => any): any;

Por tanto, lo que nos devolverá es un any, del cual haremos un cast al tipo que queramos y ya está, ya tendremos algo que parece un Customer (por ejemplo) de cara al compilador, pero que vete tú a saber qué lleva dentro y, lo más importante, ya veremos cuándo te enteras de que no es lo que pensabas.

El segundo problema que tiene esta solución es que no siempre que se parsea JSON se pasa por este método, lo que hace que aunque lo hayamos parcheado se nos puedan escapar casos. Por ejemplo, si estás utilizando fetch y response.json(), el parsing se hace a nivel más bajo (al menos en Chrome), por lo que esta solución no te sirve.

Interceptando las respuestas del servidor

En la mayoría de los casos el momento en que necesitamos deserializar JSON es cuando estamos recibiendo una respuesta de un servidor. Hay otros escenarios, como recuperar datos de LocalStorage o SessionStorage, pero son menos frecuentes.

Muchas librerías permiten interceptar de alguna forma la respuesta y procesarla, por lo que es un buen punto para enganchar nuestra conversión de fechas. Si estás utilizando fetch, podemos extender el objeto Request para parchear el método json(), o incluso añadir nuestro propio método haciendo algo así:

Response.prototype.typedJson = function () {
  // Aquí podemos usar cualquiera de las técnicas anteriores,
  // por ejemplo, la del reviver
  const customReviver = function(key, value) {
    if (typeof value !== 'string')
      return value;

    const isoDate = /(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})[+-](\d{2})\:(\d{2})/;

    return value.match(isoDate) ? new Date(value) : value;
  }

  return this.text().then(text => JSON.parse(text, revivir));
}

Podríamos haber reescrito directamente el método json, pero en este caso prefiero mantener también el método original por si fuese necesario acceder al JSON “puro” en algún escenario.

Llevado a TypeScript, podemos aplicar la técnica para extender tipos existentes que vimos hace unas semanas. Además del añadir typedJson al prototipo de Response usaríamos el declaration merging para tiparlo incluyendo esto en nuestro código:

interface Response {
  typedJson<T>(): T;
}	

Con esto, el uso quedaría bastante cómodo:

fetch('/customer/1')
  .then(response => response.typedJson<Customer>())
  .then(customer => customer.name);

No tenemos más seguridad de tipos que antes (seguimos convirtiendo por debajo de any a T), pero al menos las fechas estarán convertidas a Date y el código queda muy legible.

Resumen

Todas estas técnicas no dejan de ser parches para el problema subyacente, que es la elección de un formato de serialización con muchas limitaciones como es JSON. Desgraciadamente es también uno de los formatos más populares y toca lidiar con él.

Probablemente lo más limpio sea la primera opción porque no implica andar tocando los prototipos de cosas existentes, pero también es cierto que, ya que estamos en un lenguaje que lo permite (y pagas un precio por ello), parece razonable intentar aprovecharlo.

Posts relacionados:

  1. Echo de menos la BCL: formato y parsing de fechas en Javascript
  2. Sopa de Siglas: AJAX, JSON, JSONP y CORS
  3. TypeScript, ¿ahora sí?

» Leer más, comentarios, etc...

Blog Bitix

Cómo crear un servicio de systemd para una aplicación con Spring Boot

February 11, 2017 09:00 AM

La mayoría de distribuciones Linux ya usan systemd como gestor y supervisor de los servicios del sistema. Creando un descriptor podremos gestionar un servicio propio con los mismos comandos de systemd que usamos para cualquier otro servicio del sistema.

Linux
Java

Habiendo creado una aplicación o microservicio, por ejemplo con Spring Boot, necesitaremos que se inicie con el sistema y una forma de gestionarlo para detenerlo, reiniciarlo y que se reinicie en caso de salida abrupta.

systemd es el gestor de servicios que han adoptado la mayoría de distribuciones importantes como Debian, CentOS, RHEL, openSUSE, incluso Ubuntu después de abandonar su propio gestor de servicios Upstart. Podemos usar systemd para que gestione como servicio una aplicación propia. Para ello deberemos crear un archivo unit que describa el servicio y sus dependencias con otros servicios para que se inicie correctamente, él y sus dependencias.

Los servicios se definen en archivos de texto denominados unit que tienen un formato similar a los archivos .desktop que a su vez están inspirados en los archivos .ini de Windows. En la documentación de los archivos unit de systemd se detalla con amplitud los archivos unit de systemd, tienen tres secciones:

  • [Unit]: contiene información genérica independiente del tipo de servicio como descripción, requerimientos, deseos o orden de inicio.
  • [Service]: define el tipo de servicio, los comandos de preinicio, inicio, postinicio, parada, postparada, condiciones reinicio y más parámetros comentados en la documentación de los sevicios de systemd.
  • [Install]: esta sección es usada al habilitar o deshabilitar un servicio en el sistema con el comando systemctl, pudiendo por ejemplo que se inicie este servicio cuando otro se inicie siendo otra forma de declarar dependencias. De este modo se puede indicar que un servicio tiene otros como dependencia pero también se puede indicar que un servicio se inicie cuando otro lo haga.

Usando la aplicación del Ejemplo de API REST en Java con JAX-RS y Spring Boot, crearé un archivo unit de systemd para que se inicie con el sistema y se reinicie en caso de fallo. Primeramente deberemos crear los archivos que definen el servicio para systemd y sus dependencias si las tienen. En los siguientes ejemplos spring-boot-jaxrs.service es una aplicación de Spring Boot con una interfaz REST que simplemente devuelve el mensaje indicado por parámetro con la fecha en la dirección http://localhost:8080/message?message=Hola. spring-boot-jaxrs-postgres.service es el mismo servicio pero que tiene una dependencia sobre un contenedor de Docker con una base PostgreSQL, aunque la aplicación Spring Boot no hace uso de la base de datos PostgreSQL sirve para observar que si se inicia el servicio de la aplicación Java también se inicia el servicio de la base de datos si no estuviera ya en ejecución. postgres.service es el servicio de la base de datos PostgreSQL en un contenedor de Docker y que tiene como dependencia el servicio de Docker.

<noscript><a href="https://asciinema.org/a/102785" target="_blank"><img src="https://asciinema.org/a/102785.png" width="734" /></a></noscript> Servicio de systemd para una aplicación con Spring Boot

La instalación de la aplicación y de los servicios de systemd en el sistema se realizan copiando archivos, cambiando algunos permisos y usando los comandos de systemd para gestionar los servicios. Los mensajes de salida que emite el servicio se obtienen con el comando journalctl -u spring-boot-jaxrs.service.

Los archivos unit propios deben ser ubicados en el directorio /etc/systemd/system/, siendo el directorio /usr/lib/systemd/system/ donde se ubican los instalados por los paquetes del sistema. Iniciado el servicio con el comando sudo systemctl start spring-boot-jaxrs.service, si queremos habilitarlo con el inicio del sistema usamos el comando sudo systemctl enable spring-boot-jaxrs.service. Para ver el estado del servicio usamos el comando sudo systemctl status spring-boot-jaxrs.service.

En los enlaces de referencia hay documentación más detallada tanto para gestionar los servicios con systemd como también documentación de sus archivos unit.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando sudo systemctl start spring-boot-jaxrs.service.

» Leer más, comentarios, etc...

xailer.info

Múltiples escritorios de Windows 10

February 10, 2017 10:01 AM

Estimados usuarios de Xailer,

Tan sólo quiero compartir con vosotros una pequeña herramienta que acabo de descubrir. Siempre he echado en falta en Windows la posibilidad de tener varios escritorios virtuales, y de hecho probé varias aplicaciones, que no me gustaron, antes de que por fin con Windows 10 los incluyese. La solución aportada por Windows 10 funciona muy bien, pero de forma inconcebible se les ha olvidado incluir algo que para mi es esencial que consiste en saber que escritorio virtual estoy en cada momento. Manias de uno 😉

Pues bien, si alguno tenéis manías como las mías, existe una pequeñísima utilidad que hace el trabajo poniendo un pequeño icono en la barra de tareas que además permite cambiar el fondo de pantalla cuando cambiemos de escritorio. Su nombre es VirtualDesktopManager y lo podéis descargar de aqui: https://github.com/m0ngr31/VirtualDesktopManager/releases. Como veis es un enlace un proyecto en GitHub, por lo que incluso está todo el código fuente del proyecto.

¡Espero que os guste!

Un saludo

» Leer más, comentarios, etc...

Picando Código

Personalizar el inicio de sesión de la terminal con fortune, cowsay y lolcat

February 09, 2017 12:00 PM

Ayer publiqué en Twitter mi nuevo mensaje de bienvenida de la terminal cuando inicia una nueva sesión. Como me preguntaron cómo se hacía, aprovecho para dejar la información por acá para quienes quieran usarlo. No lo inventé yo, lo he visto varias veces en foros y sitios sobre Linux, y parece ser de uso común para personalizar la terminal.

Se trata de un mensaje del comando fortune de Unix, un programa que muestra un mensaje al azar de una base de datos de mensajes. Algunos son citas directas de distintos autores, chistes, y más. El texto que sale de fortune se pasa al comando cowsay que es un filtro de texto que genera una imagen en ASCII de una vaca diciendo el mensaje que le pasemos. Este texto a su vez se manda al comando lolcat que se encarga de darle color al mensaje.

El comando final quedó así (por ahora):


fortune -a | cowsay -p | lolcat

Lo agregué a mi archivo ~/.bashrc, el script que ejecuta Bash cada vez que inicia una sesión interactiva.

fortune

Por lo menos en Debian, el paquete fortune requiere un paquete adicional fortunes-min que incluye una base de datos bastante chica de mensajes. Para obtener más mensajes podemos instalar el paquete fortunes, y si buscamos más, podemos encontrar paquetes como fortunes-off (mensajes ofensivos) y fortunes-es (mensajes en español) y fortunes-es-off (mensajes ofensivos en español).

cowsay

Algo interesante de cowsay es que tiene varios formatos para el personaje que muestra el mensaje que no necesariamente debe ser una vaca. Si ejecutamos cowsay -l, podemos ver todos los formatos disponibles en nuestro sistema. Ejemplo:


$ cowsay -l
Cow files in /usr/share/cowsay/cows:
apt beavis.zen bong bud-frogs bunny calvin cheese cock cower daemon default
dragon dragon-and-cow duck elephant elephant-in-snake eyes flaming-sheep
ghostbusters gnu head-in hellokitty kiss koala kosh luke-koala mech-and-cow
milk moofasa moose mutilated pony pony-smaller ren sheep skeleton snowman
sodomized-sheep stegosaurus stimpy suse three-eyes turkey turtle tux
unipony unipony-smaller vader vader-koala www

Así que tenemos varias opciones como un tux, una tortuga, el demonio de BSD, Ren & Stimpy y más. Para hacer uso de uno de estos formatos, simplemente ejecutamos cowsay -f formato, como cowsay -f turtle por ejemplo. Existen varios parámetros para cambiar la apariencia de la vaca misma, dependiendo de sus emociones o estado físico. La opción -b inicia en modo Borg, -d muestra una vaca muerta, y más. RTFM con man cowsay para conocer más parámetros.

lolcat

Es una gema Ruby para darle los colores del arcoíris a lo que le mandes desde un archivo o la entrada estándar.

La instalamos con:

$ gem install lolcat

Lo podemos usar para un archivo o desde la salida estándar directamente:

$ echo "Hola mundo, esto es un texto desde la entrada estándar" | lolcat

Tiene varios parámetros para personalizar el arcoíris que muestra y si queremos animación. Pueden ver el código fuente en GitHub.

Es el componente final para obtener un inicio asombroso de sesión en nuestra terminal:

fortune-cowsay-lolcat

 

» Leer más, comentarios, etc...

Blog Bitix

Conferencia BilboStack 2017

February 08, 2017 08:30 PM

Cuando me inscribí en la BilboStack para reservar entrada no me llamaron mucho la atención las presentaciones del programa pero ya a una semana de decidir a cuales iba a ir definitivamente he tenido dificultades para elegir y en varios casos me hubiese gustado ir a las de los dos tracks. Como años anteriores la BilboStack se ha celebrado en Bilbao en el mismo emplazamiento de la Universidad de Deusto pero volviendo como en años precedentes al edificio de las ingenierías. Otro cambio ha sido que este año fueron cuatro presentaciones por track cuando en años anteriores fueron cinco.

El número de asistentes ha sido numeroso quedando algo de sitio libre en el track 2 que era un aula pero en la sala de conferencias del track 1 aunque tiene cómodas butacas salvo por su estrechez el sitio libre era inexsitente de modo que en algunas presentaciones ha habido algunos asistentes que han debido estar de pie.

BilboStack 2017
Universidad de Deusto

Este era el programa completo con su horario, temas muy distintos y variados como Xamarin, internet of things, el siempre presente JavaScript con Angular y Node, Lean Analytics y DDD entre algunos otros de la siguiente agenda:

Hora Track 1
09:30-10:20 Xamarin.Forms en el mundo real™ : Verdades y Mitos por Josué Yeray
10:30-11:20 Una visión de Angular 2 y TypeScript por Hugo Biarge
11:20-11:50 Café
11:50-12:40 Lights, Camera, Node! por Catalina Oyaneder
12:50-13:40 Domain-Driven Design, uniendo negocio con el software por Gorka Laucirica y Beñat Espiña
Hora Track 2
09:30-10:20 Invisible o desaparece... por Isabel Cabezas y Juliet Moreiro
10:30-11:20 Érase una vez... el Design System por Naiara Abaroa
11:20-11:50 Café
11:50-12:40 Agile for scrummies por Jorge Uriarte
12:50-13:40 Lean Analytics, mi faro de cabecera por Carlos Iglesias
Agenda

Al igual que en ediciones previas hago un pequeño resumen de las presentaciones a las que asistí. Los resúmenes no le hace justicia a las grandes ponencias que fueron en realidad pero espero haber captado y transmitir aquí escuetamente las ideas básicas que se expusieron. Y con este es el tercer resumen consecutivo que escribo de la BilboStack, los anteriores (y posteriores que si tengo oportunidad espero escribir) de esta serie de artículos están al final de este artículo.

Invisible o desaparece… por Isabel Cabezas y Juliet Moreiro

El IoT o esos pequeños dispositivos que tienen conexión a internet están surgiendo como una forma de ayudarnos en algunas situaciones cotidianas como cambiar la ruta cuando hay un accidente para no llegar a un atasco o encender la calefacción antes de llegar a casa o antes de levantarnos, espejos que proporcionan información como notificaciones o el tiempo o un centro comercial que te posiciona y ofrece ofertas según la localización en la que estas y tus hábitos de consumo. Aparatos como Amazon Echo son asistentes a través de los cuales mediante comandos de voz podemos realizar acciones como pedir comida a domicilio.

Estos aparatos conectados a internet nos ofrecen una nuevo área posibilidades. Muestra de ellos es la demostración presentada que consistía en base a los mensajes escritos en Twitter iluminar una lámpara PLAYBULB con color verde si eran positivos, rojo si eran negativos y azul si eran neutros haciendo uso de Microsoft Cognitive Services y de algunas de sus APIs para evaluar el sentido de los mensajes. Por ejemplo el mensaje BilboStak is an awesome event! se evaluará como positivo y sumará a la media para que la lampara cambie a color verde.

El hardware era la propia lámpara y una placa de computación Intel Edison junto con un servicio en la nube de Azure pero perfectamente podría ser una Raspberry Pi u otra de las numerosas pequeñas placas que están surgiendo en este nuevo mercado. El código fuente del ejemplo está compartido en un repositorio de GitHub.

Referencia:

Érase una vez… el Design System por Naiara Abaroa

El diseño de una página es una parte importante de la misma, no considerarlo así seguramente nos encontremos con problemas.

  1. Requiere de un conocimiento específico para hacerlo bien y esta es la habilidad que posee un front-designer.
  2. Falta de arquitectura de CSS a pesar de que existen herramientas como Sass o less se sigue produciendo código espagueti.
  3. Hay duplicidades y está poco estructurado.
  4. Falta de coherencia en la tipografía, color, …
  5. Problemas de especifidad al no considerar la evaluación en cascada y el orden de precedencia de inline, id, clases y elementos con lo que se ha de usar el denostado !important como último recurso.
  6. Mezcla de varias convenciones, en el nombrado de elementos.

La solución es el Design System consiguiendo primero claridad, segundo eficiencia y finalmente «belleza». Siguiendo el Atomic Design se consigue una mayor reutilización y facilidad de mantenimiento combinándolo con herramientas como Sketch para el desarrollo de mockups.

Algunos recursos de diseño e implementaciones conocidas de Design Systems son:

Referencia:

Agile for scrummies por Jorge Uriarte

La situación respecto a las metodologías de desarrollo ha cambiado, hace 10 años había resistencia al cambio ahora se aplica pero tampoco resuelve mágicamente los problemas del desarrollo de todos los casos donde se usa.

Algunas esencias de scrum que permanecerán son:

  • En el producto: no detallar en exceso el backlog ya que cambiará.
  • En las historias: siendo completas, entregables individualmente y según el valor que aportan.
  • En los equipos: siendo estos autoorganizados, multidisciplinares, alineados, dueños del proceso y autónomos.
  • En las entregas: serán incrementales y continuas.
  • En el proceso: no estará sacralizado y cambiará con el fin de mejorar al igual que tratan de conseguir las retrospectivas.

Un sistema ágil es una aproximación a la incertidumbre. Incertidumbre que siempre está presente en los desarrollos de software al tratar de responder preguntas como ¿que hay que hacer? ¿cuanto tiempo se tardará? ¿que tecnología se usará?. Para evitar los problemas que genera la incertidumbre un work in progress o WIP pequeño es un buen arma. Lo terminado elimina incertidumbres, se considera que es lo menos que se puede hacer ahora que de el máximo valor. Una consecuencia es que en el flujo de desarrollo habrá menos cosas pero pasando más rápido. Esto se resume en título del libro Stop Starting, Start Finishing! y que tiene la siguiente reseña.

This booklet tells the story of Justin - a project manager who achieved remarkable results with his team by doing very simple things! This guide covers the core concepts of Kanban for knowledge work, and shows how limiting your amount of work-in-progress can lead to getting things done better and faster.

La combinación de un WIP pequeño junto con un sistema pull en el que no se construye lo no necesario, no se prueba lo que no se puede entregar, no se desarrolla lo que no se puede probar y no se especifica lo no se puede desarrollar produce una reducción de tiempos de entrega, hay mayor predictibilidad y elimina rehacer trabajo.

Referencia:

Domain-Driven Design, uniendo negocio con el software por Gorka Laucirica y Beñat Espiña

El Domain-Driven Design o DDD se centra en el dominio de la aplicación, la lógica de negocio y lo que quiere el negocio de la aplicación.

Los modelos anémicos con getters y setters se consideran un antipatrón y hace que la lógica esté dispersa. En el patrón MVC los controladores pueden contener múltiples responsabilidades generando duplicidad de código. Aplicar los principios SOLID generan código limpio y una arquitectura hexagonal ayuda a no crear en la aplicación una dependencia con el framework posibilitando usar por ejemplo Symfony como herramienta y no como base.

DDD se divide en patrones estratégicos (bounded context) que no tienen código y tácticos (entities, agregados, eventos de dominio, factorías, repositorios) que si tienen código. Hay un servicio para cada caso de uso de la aplicación. Para cosas simples junto con su curva de aprendizaje esto seguramente será demasiado complejo pero en los casos en los que haya lógica de negocio, equipos medianos/grandes si será útil.

Un ejemplo de aplicación donde han aplicado DDD es Kreta.

Referencia:

Nuevamente gracias la dedicación de los organizadores por crear otra edición de este gran pequeño evento anual, los ponentes que altruistamente colaboran compartiendo su conocimiento y a la Universidad de Deusto por acoger un año más uno de los mejores eventos para desarrolladores de Bilbao y alrededores.

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin