Translate

Mostrando las entradas con la etiqueta Quarkus. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Quarkus. Mostrar todas las entradas

viernes, 22 de octubre de 2021

Mutiny!

 



Si leen este blog, algo sabran de reactive programming y de quarkus, Mutiny! es el framework elegido por la gente de red hat para implementar reactive programming en quarkus.

Podemos usarlo en nuestros proyectos, sin necesidad de usar quarkus, es decir, de forma independiente. A la vez se acopla muy bien con vert.x. Y entre sus características, podemos nombrar que es un framework moderno, liviano y pequeño. 

Veamos un "hola mundo" : 

import io.smallrye.mutiny.Uni;


public class FirstProgram {


  public static void main(String[] args) {

    Uni.createFrom().item("hello")

      .onItem().transform(item -> item + " mutiny")

      .onItem().transform(String::toUpperCase)

      .subscribe().with(

        item -> System.out.println(">> " + item));

  }

}

Podemos ver como sigue los conceptos básicos de un framework reactive, es decir, tiene Observable, transformaciones y suscriptores.  Lo interesante es cómo se construye el mensaje. Describimos una tubería de procesamiento que toma un item, lo procesa y finalmente lo consume.

Primero, creamos un Uni, uno de los dos tipos con Multi que proporciona Mutiny. Un Uni es un flujo que emite un solo elemento o un error.

Aquí, creamos un Uni que emite el elemento "hello". Esta es la entrada de nuestro pipeline. Luego procesamos este item:

  • agregamos "mutiny", luego
  • lo convertimos en una cadena en mayúsculas.
  • Esto forma la parte de procesamiento de nuestra canalización, y luego finalmente nos suscribimos a la canalización.


Esta última parte es fundamental. Si no tiene un suscriptor final, no sucederá nada. Los tipos de mutiny son perezosos, lo que significa que debes suscribirte. Si no lo hace, el cálculo ni siquiera comenzará.

Si su programa no hace nada, tenemos que verificar que no se nos olvidó de suscribirnos.

Dejo link : https://smallrye.io/smallrye-mutiny/ 

viernes, 24 de septiembre de 2021

Creando la primera aplicación con Quarkus parte 5


Seguimos con quarkus

Vamos a guardar unos saludos para luego poder recuperarlos y usarlos para saludar. 

Para esto vamos a crear una clase con el saludo : 

package com.hexacta.model;

import javax.persistence.*;
import java.util.Objects;

@Entity
public class Greeting {

@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
@Id
private Integer id;

@Column
private String value;

public void setId(Integer id) {
this.id = id;
}

public Integer getId() {
return id;
}

public Greeting() {}

public Greeting(String value) {
this.value = value;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Greeting greeting = (Greeting) o;
return Objects.equals(value, greeting.value);
}

@Override
public int hashCode() {
return Objects.hash(value);
}
}

Luego vamos a hacer una clase DAO para acceso a la base de datos : 

package com.hexacta.dao;

import com.hexacta.model.Greeting;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;

@ApplicationScoped
public class GreetingDAO {

@Inject
private EntityManager em;

public int save(Greeting aGreeting) {
this.em.persist(aGreeting);
return aGreeting.getId();
}

public Greeting get(int id) {
var qr = em.createQuery("from com.hexacta.model.Greeting g " +
"where g.id = ?1");
qr.setParameter(1, id);
return (Greeting) qr.getSingleResult();
}
}

Modificamos el servicio para que permita guardar los saludos : 

package com.hexacta;

import com.hexacta.dao.GreetingDAO;
import com.hexacta.model.Greeting;

import javax.transaction.Transactional;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

@ApplicationScoped
public class GreetingServices {

@Inject
private GreetingDAO dao;

public String greeting(String name) {
return "hola " + name;
}

public String greeting(int id,String name) {
Greeting aGreeting = dao.get(id);
if (aGreeting == null) {
return name;
}
return aGreeting.getValue() + " " + name;
}

@Transactional
public int saveGreeting(String greeting) {
Greeting aGreeting = new Greeting(greeting);
return dao.save(aGreeting);
}
}

Y por último vamos a modificar los servicios REST : 

package com.hexacta;

import org.jboss.resteasy.annotations.jaxrs.PathParam;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

private GreetingServices service;

@Inject
public GreetingResource(GreetingServices service) {
this.service = service;
}

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy";
}

@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/{name}")
public String hello(@PathParam String name) {
return this.service.greeting(name);
}

@POST
@Path("/save/{greeting}")
public int saveGreeting(@PathParam String greeting) {
return this.service.saveGreeting(greeting);
}

@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/{id}/{name}")
public String hello(@PathParam int id,@PathParam String name) {
return this.service.greeting(id, name);
}


}

Y tengo que configurar h2 que es la base que estamos usando, en el application.properties : 

# datasource configuration
quarkus.datasource.db-kind = h2
quarkus.datasource.username = sa
quarkus.datasource.password = a
quarkus.datasource.jdbc.url = jdbc:h2:~/quarkus.db

quarkus.hibernate-orm.database.generation=update

Y listo, podemos guardar diferentes saludos y usarlos. 

Dejo el link del repo : 

https://github.com/emanuelpeg/quarkusExample/


martes, 21 de septiembre de 2021

Creando la primera aplicación con Quarkus parte 4


Seguimos con quarkus

Ahora vamos a empaquetar nuestra app, lo hacemos con gradle jar y la ejecutamos con 

java -jar build/quarkus-app/quarkus-run.jar

y listo tenemos nuestra app andando en http://localhost:8080/hello 

El directorio quarkus-app que contiene el archivo jar quarkus-run.jar, que es un jar ejecutable. Pero no tiene todas las dependencias estas se copian en subdirectorios de quarkus-app/lib /. Por lo tanto debemos deployar todo el directorio quarkus-app la primera vez y cada vez que hay cambio de librerías. 

Bueno, ya estamos! con esto tenemos nuestra app andando pero vamos a hacer un paso más vamos a hacer nuestra applicación nativa. Para eso debemos utilizar GraalVM 11. 

La construcción de un ejecutable nativo requiere el uso de una distribución de GraalVM. Hay tres distribuciones: Oracle GraalVM Community Edition (CE), Oracle GraalVM Enterprise Edition (EE) y Mandrel. Las diferencias entre las distribuciones de Oracle y Mandrel son las siguientes:

Mandrel es una distribución descendente de Oracle GraalVM CE. El objetivo principal de Mandrel es proporcionar una forma de crear ejecutables nativos diseñados específicamente para admitir Quarkus.

Las versiones de Mandrel se crean a partir de una base de código derivada de la base de código anterior de Oracle GraalVM CE, con solo cambios menores pero algunas exclusiones importantes que no son necesarias para las aplicaciones nativas de Quarkus. Admiten las mismas capacidades para crear ejecutables nativos que Oracle GraalVM CE, sin cambios significativos en la funcionalidad. En particular, no incluyen soporte para programación políglota. El motivo de estas exclusiones es proporcionar un mejor nivel de soporte para la mayoría de los usuarios de Quarkus. Estas exclusiones también significan que Mandrel ofrece una reducción considerable en su tamaño de distribución en comparación con Oracle GraalVM CE/EE.

Mandrel está construido de forma ligeramente diferente a Oracle GraalVM CE, utilizando el proyecto estándar OpenJDK. Esto significa que no se beneficia de algunas pequeñas mejoras que Oracle ha agregado a la versión de OpenJDK utilizada para crear sus propias descargas de GraalVM. Estas mejoras se omiten porque OpenJDK no las gestiona y no puede responder por ellas. Esto es particularmente importante cuando se trata de conformidad y seguridad.

Actualmente, Mandrel solo se recomienda para compilar ejecutables nativos destinados a entornos Linux en contenedores. Esto significa que los usuarios de Mandrel deben usar contenedores para construir sus ejecutables nativos. Si está creando ejecutables nativos para plataformas de destino macOS o Windows, debería considerar usar Oracle GraalVM en su lugar, porque Mandrel no se dirige actualmente a estas plataformas. Es posible compilar ejecutables nativos directamente en Linux.

Los requisitos previos varían ligeramente dependiendo de si está utilizando Oracle GraalVM CE/EE o Mandrel.

Primero, tenemos que configurar las variables de entorno JAVA_HOME y GRAALVM_HOME (y tener instalado docker). 

Y luego tenemos que hacer : 

gradel build -Dquarkus.package.type=native

docker build -f src/main/docker/Dockerfile.native -t quarkus/demo .

docker run -i --rm -p 8080:8080 quarkus/demo

Cuando lo corrí la primera vez, me tiro error porque estoy usando Windows y me dijo que instale el generador de imágenes windows haciendo esto : 

gu install native-image

 

martes, 7 de septiembre de 2021

Quarkus para desarrolladores Spring



Quiero recomendarles este libro gratuito Quarkus for Spring Developers de la gente de Red hat. 

Quarkus for Spring Developers presenta Quarkus a los desarrolladores de Java, con un ojo especial en ayudar a quienes están familiarizados con las convenciones de Spring a realizar una transición rápida y sencilla.

Y sin más dejo link: 

https://developers.redhat.com/books/quarkus-for-spring-developers?sc_cid=7013a000002ph3pAAA

lunes, 6 de septiembre de 2021

Creando la primera aplicación con Quarkus parte 3

Seguimos con quarkus

quarkus:dev ejecuta Quarkus en modo desarrollo. Esto permite deployment en caliente con compilación en segundo plano, lo que significa que cuando modifica sus archivos Java y / o sus archivos de recursos y actualiza su navegador, estos cambios se aplicarán automáticamente. Esto también funciona para archivos de recursos como el archivo de propiedades de configuración. La actualización del navegador desencadena un análisis del espacio de trabajo y, si se detecta algún cambio, los archivos Java se vuelven a compilar y la aplicación se vuelve a implementar; su solicitud luego es atendida por la aplicación redistribuida. Si hay algún problema con la compilación o la implementación, una página de error se lo informará.

Esto también escuchará un depurador en el puerto 5005. Si desea esperar a que el depurador se conecte antes de ejecutarse, puede pasar -Dsuspend en la línea de comandos. Si no desea el depurador en absoluto, puede usar -Ddebug = false.

En mi caso quiero hacer debug con intellij pero no funciona, si el deploy en caliente pero no me funciona el debug llamando a gradle quarkus:dev en debug.  Lo que hay que hacer es muy fácil, ir a run -> attach to process y en ese menú se va a listar el puerto 5005 que es el puerto de debug y luego el debug anda joya. 

Ya tenemos el debug y el deployment en caliente. Ahora vamos a ver los test, los test unitarios tienen que estar y escapa a este post y a la tecnología que usemos. Ahora bien, esta bueno hacer test de integración para poder revisar toda mi aplicación. desde el servicio REST a la base. Para esto, quarkus nos crea un test por defecto : 

@QuarkusTest

public class GreetingResourceTest {


    @Test

    public void testHelloEndpoint() {

        given()

          .when().get("/hello")

          .then()

             .statusCode(200)

             .body(is("Hello RESTEasy"));

    }


}

Con esto estamos probando que el servicio /hello retorne 200 y su body sea "Hello RESTEasy"

Si corremos el test, quarqus nos levanta el server y le pega. 

Vamos a hacer un test de nuestro servicio /hello/mundo 

    @Test

    public void testHelloWithParameterEndpoint() {

        var name = "Mundo";

        given()

                .when().get("/hello/" + name)

                .then()

                .statusCode(200)

                .body(is("hola " + name));

    }


Y listo!! 


 


jueves, 2 de septiembre de 2021

Creando la primera aplicación con Quarkus parte 2

 Seguimos con quarkus


Ahora vamos a tomar la app del post pasado y vamos a hacer un servicio que salude y lo vamos a inyectar y luego creamos un web services REST que permita utilizarlo. 


import javax.enterprise.context.ApplicationScoped;


@ApplicationScoped

public class GreetingServices {


    public String greeting(String name) {

        return "holas " + name;

    }

}

Y ahora inyectamos : 

import org.jboss.resteasy.annotations.jaxrs.PathParam;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

    private GreetingServices service;

    @Inject
    public GreetingResource(GreetingServices service) {
        this.service = service;
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello RESTEasy";
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/{name}")
    public String hello(@PathParam String name) {
        return this.service.greeting(name);
    }
}

Siempre que podamos debemos inyectar a nivel de constructor, de esta manera queda más explicita la dependencia. 

Y listo!! si vamos a http://localhost:8080/hello/mundo vamos a obtener : 

holas mundo



Creando la primera aplicación con Quarkus



Empecemos por el principio, necesitamos graalvm 11 o superior (en realidad cualquier Jdk 11 o superior pero yo voy a utilizar graalvm para sacar todo el jugo) , maven o gradle (yo voy a usar intellij que viene con gradle y listo) y un ide. 

Pueden usar maven o gradle para crear el proyecto o intellij (tambien) pero yo utilice la pagina https://code.quarkus.io/ y luego lo abrí con intellij. Pero eso lo hice porque quise, pueden hacerlo como quieran. 

Más allá de si eligieron maven o gradle o como hiciero para crear el proyecto, deberían tener esta dependencia : 

implementation 'io.quarkus:quarkus-resteasy'

Ahora veamos el código que genero, es un hola mundo común en un servicio REST : 


import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import javax.ws.rs.core.MediaType;


@Path("/hello")

public class GreetingResource {


    @GET

    @Produces(MediaType.TEXT_PLAIN)

    public String hello() {

        return "Hello RESTEasy";

    }

}

Si ejecutamos esto con : 

gradle :quarkusDev 

Va a demorar un rato pero luego si vamos a http://localhost:8080/hello vemos : 

Hello RESTEasy

Y como primer acercamiento, bien, en proximos post vamos a seguir desarrollando este ejemplo. 



viernes, 27 de agosto de 2021

Imperativo vs reactivo


Para comprender mejor el contraste entre los 2 mundos, necesitamos explicar la diferencia entre los modelos de ejecución reactiva e imperativa. 

En el enfoque tradicional e imperativo, los frameworks asignan un hilo para manejar una solicitud. Entonces, todo el procesamiento de la solicitud se ejecuta en este hilo de trabajo. Este modelo no escala muy bien. De hecho, para manejar múltiples solicitudes simultáneas, necesita múltiples subprocesos; por lo que la simultaneidad de su aplicación está limitada por el número de subprocesos. Además, estos subprocesos se bloquean tan pronto como su código interactúe con servicios remotos. Por lo tanto, conduce a un uso ineficiente de los recursos, ya que es posible que necesite más subprocesos, y cada subproceso, ya que están asignados a subprocesos del sistema operativo, tiene un costo en términos de memoria y CPU.

Por otro lado, el modelo reactivo se basa en E/S sin bloqueo y en un modelo de ejecución diferente. La E/S sin bloqueo proporciona una forma eficaz de tratar las E/S simultáneas. Una cantidad mínima de subprocesos denominados subprocesos de E/S puede manejar muchas E/S simultáneas. Con un modelo de este tipo, el procesamiento de solicitudes no se delega a un subproceso de trabajo, sino que utiliza estos subprocesos de E/S directamente. Ahorra memoria y CPU, ya que no es necesario crear subprocesos de trabajo para manejar las solicitudes. También mejora la simultaneidad ya que elimina la restricción sobre el número de subprocesos. Finalmente, también mejora el tiempo de respuesta ya que reduce el número de cambios de hilo.

Entonces, con el modelo de ejecución reactiva, las solicitudes se procesan mediante subprocesos de E/S. Pero eso no es todo. Un subproceso de E/S puede manejar varias solicitudes simultáneas. ¿Cómo? Aquí está el truco y una de las diferencias más significativas entre reactivo e imperativo.

Cuando el procesamiento de una solicitud requiere interactuar con un servicio remoto, como una API HTTP o una base de datos, no bloquea la ejecución mientras espera la respuesta. En cambio, programa la operación de E/S y adjunta una continuación, es decir, el código restante de procesamiento de la solicitud. Esta continuación se puede pasar como una devolución de llamada (una función invocada con el resultado de E/S) o utilizar construcciones más avanzadas como programación reactiva o co-rutinas. 

Independientemente de cómo se exprese la programación no bloqueante, lo esencial es la liberación del subproceso de E/S y, en consecuencia, el hecho de que este subproceso pueda utilizarse para procesar otra solicitud. Cuando se completa la E/S, el subproceso de E/S continúa el procesamiento de la solicitud pendiente.

Entonces, a diferencia del modelo imperativo, donde la E/S bloquea la ejecución, los conmutadores reactivos a un diseño basado en la continuación, donde se liberan los subprocesos de E/S y se invoca la continuación cuando se completan las E/S. Como resultado, el subproceso de E/S puede manejar múltiples solicitudes concurrentes, mejorando la concurrencia general de la aplicación.

Pero hay una trampa. Necesitamos una forma de escribir código continuation-passing o no bloqueante. Hay muchas maneras de hacer esto. Por ejemplo en Quarkus propone:

  • Mutiny: una biblioteca de programación reactiva intuitiva e impulsada por eventos
  • Co-rutinas de Kotlin: una forma de escribir código asincrónico de manera secuencial

Dejo link: https://quarkus.io/guides/getting-started-reactive

viernes, 13 de agosto de 2021

Red Hat Developer eBooks


Medio tarde encontré este link el cual tiene unos buenos libros para desarrolladores y que quiero compartir con ustedes : 

https://developers.redhat.com/ebooks

miércoles, 1 de julio de 2020

Quarkus


No dejo de escuchar de Quarkus, pero que es quarkus? 

Quarkus es un framework Java integral y nativo de Kubernetes que se creó para las compilaciones nativas y las máquinas virtuales Java (JVM), el cual permite optimizar Java, especialmente para los contenedores y convertirla en una plataforma efectiva para entornos sin servidor, de nube y de Kubernetes.

Quarkus se diseñó para integrarse con Eclipse MicroProfile, Apache Kafka, RESTEasy (JAX-RS), Hibernate ORM (JPA), Spring, Infinispan, Camel y muchos más. 

La solución de inyección de dependencias de Quarkus se basa en CDI (inyección de dependencias y contextos) e incluye un marco de extensión para ampliar las funciones y configurar, iniciar e integrar un marco en las aplicaciones.Dado que agregar una extensión es tan sencillo como incorporar una dependencia, puede optar por esa opción o utilizar las herramientas de Quarkus.

Además, proporciona la información correcta a GraalVM (una máquina virtual universal para ejecutar aplicaciones escritas con varios lenguajes, incluidos Java y JavaScript) para la compilación nativa de las aplicaciones.

Quarkus se diseñó para que fuera fácil de utilizar desde el principio, y cuenta con características que funcionan correctamente con poca o ninguna configuración.

Los desarrolladores pueden elegir los frameworks de Java que deseen para sus aplicaciones, los cuales pueden ejecutarse en modo JVM o compilarse y ejecutarse en el modo original. 

Diseñado para que los desarrolladores lo disfruten, Quarkus también incluye las siguientes funciones:
  • Programación en vivo para que los desarrolladores puedan verificar de inmediato el efecto de los cambios en el código y solucionarlos rápidamente
  • Programación imperativa y reactiva unificada con un bus de eventos integrado y gestionado
  • Configuración unificada
  • Creación sencilla de archivos ejecutables nativos
Independientemente de que una aplicación se aloje en una nube pública o en un clúster de Kubernetes alojado internamente, las características como el inicio rápido y el poco consumo de memoria son importantes para mantener bajos los costos generales del host.

Quarkus se diseñó en torno a una filosofía que prioriza los contenedores, lo que significa que se encuentra optimizado para disminuir el uso de la memoria y acelerar los tiempos de inicio, a través de lo siguiente:
  • Respaldo de primer nivel para GraalVM y SubstrateVM
  • Procesamiento de metadatos en tiempo de compilación
  • Reducción en el uso del proceso de reflexión
  • Inicio previo de imágenes nativas
Por lo tanto, Quarkus compila aplicaciones que consumen un décimo de la memoria en comparación con Java tradicional, y ofrece tiempos de inicio hasta 300 veces más rápidos, lo cual reduce significativamente el costo de los recursos de la nube.

Quarkus está diseñado para combinar a la perfección la programación imperativa conocida con la reactiva sin bloqueos durante el desarrollo de aplicaciones. 

Esta característica resulta útil tanto para los desarrolladores de Java que suelen trabajar con el modelo imperativo y no desean cambiar las cosas, como para aquellos que trabajan con un enfoque reactivo/nativo de la nube. 

El modelo de desarrollo de Quarkus se adapta a cualquier aplicación en proceso de desarrollo.

Además, es una solución efectiva para ejecutar Java en este mundo nuevo de la arquitectura sin servidor, los microservicios, los contenedores, Kubernetes, la función como servicio (FaaS) y la nube, ya que se creó teniendo en cuenta todos estos elementos. 

Dejo link : https://quarkus.io/