Entradas

Mostrando las entradas con la etiqueta Java

Antipatrones, Code Smells, ... USTED NO LO HAGA

Acá escribiré mi propia colección de antipatrones o code smells, existen muchos, pero dejaré los que más me llaman la atención (o son más feos) Usar el sufijo Impl Verlo me duelen los ojos, ¿que quieren decir con Impl? nadie lo sabe, ¿no saben que quieren expresar? ¿hay un mal uso de interfaces/implementaciones (muy probable)?, tienen una interface y la unica clase que la implementa es la Impl ¡horrible! ¿problema de diseño?, supongo que tienen claro que no tendrán una nueva implementación, y si la tienen ¿le pondrán Impl2, Impl3?, me imagino que les encantaria tener una interface llamada List y cuando instancian le pondrían List l1 = new ListImpl() o List l2 = new ListImpl2()... Usar el prefijo I en interfaces Es tan desagradable como el anterior, ¿que quieren expresar con eso? ¿no saben que es lo que están diseñando? ¿es una restricción que les imponen? por que realmente no tiene una explicación lógica, tienen que tener claro lo que están representando para poder ...

Stub con Jetty embebido en Test con JUnit 5

En esta entrada mostraré un pequeño ejemplo para utilizar al servidor Jetty embebido durante las pruebas (con JUnit 5 ) para cuando necesitemos un Stub de algún servicio fuera de nuestro alcance. 1. Las dependencias: <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-webapp</artifactId> <version>9.4.28.v20200408</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.6.0</version> <scope>test</scope> </dependency> 2. La cl...

GraalVM + Java 11 + AWS Lambda + PostgreSQL + DynamoDB + Docker

Imagen
En esta ocasión mostraré la travesía que fue conseguir compilar un jar con GraalVM y que luego corra en AWS Lambda . ¿Por qué hacerlo? En la actualidad, el cold start de lanzar un jar en un lambda es alto, varios segundos (en node puede ser medio segundo o menos), pero luego de eso cada invocación tiene un tiempo de respuesta bueno, son solo algunos milisegundos. Entonces mi motivación es hacer cada vez el cold start menor y si mejora el tiempo de respuesta de las siguientes invocaciones es aún mejor 😉. ¿Que se necesita? Java 11 Docker Maven Acceso a Lambdas en AWS ¿Cómo hacerlo? Esta es la parte entretenida, en un principio fue compleja pero luego de entenderla fue divertido. Para poder lanzar el jar compilado hay que utilizar AWS Lambdas con un custom runtime. El custom runtime tiene un comportamiento que debe ser seguido y se describe en este link y acá . En resumen: existe una URL para obtener un evento, otra para indicar si hay un error al iniciar, también una...

Buenas Practicas creando AWS Lambdas con Java

En esta entrada recopilaré buenas practicas que he aprendido al momento de crear Lambdas en AWS con Java y Maven. Algunas son mis recomendaciones y otras son desde AWS (sobre todo como evitar el cold start). Comenzamos: Todo lo que pueda ser estático tiene que ser estático, de esta manera serán reutilizados en los siguientes request que se realicen en la misma instancia del Lambda. inicializar todo  lo que puedan en el handler del lambda en un bloque estático:  public class LambdaHandler implements RequestStreamHandler { static { // acá } @Override public void handleRequest(InputStream is, OutputStream os, Context ctx) throws IOException { } } Hay que hacer esto porque cuando se instancia la clase hay más poder de computo que el configurado como límite para la lambda, si hay conexiones a DynamoDB hay que instanciar la conexión y hacer una Query (cualquiera) lo importante es que se instancien todas las dependencias. Lo mismo ocurre para conexiones con R...

Java + Cognito: Pre Token Generation Lambda Trigger

En esta ocasión dejaré el código necesario para poder generar la respuesta en un Lambda de AWS que se ejecute como un  Pre Token Generation Lambda Trigger , no es ninguna explicación de que es Lambda o Cognito, lo hago porque no encontré en el universo un ejemplo que explicara el formato de la respuesta usando Java, usando NodeJS habían cientos incluso desde la misma documentación de AWS... Si alguien pasa por el mismo problema y llega acá, este es el código: public class PreTokenGenerationLambdaTrigger implements RequestStreamHandler { private static final ObjectMapper OM; static { OM = new ObjectMapper(); OM.enable(SerializationFeature.INDENT_OUTPUT); ServiceLoader.load(LambdaServicio.class).forEach(LambdaServicio::cargar); } @Override public void handleRequest(InputStream is, OutputStream os, Context ctx) throws IOException { final var request = OM.readTree(is); final var response = (ObjectNode) request; OM.writeValue(os, response); } ...

Records preview en JDK 14 ea

Hoy escribiré un ejemplo del uso del nuevo type declaration Record  en una versión del JDK 14  Early-Access Builds . ¿Que es un Record? Es una nueva declaración de tipo, similar a una clase con las siguientes características (descritas en el JEP 359 ): tiene un nombre y un  state description que define sus componentes. cada componente del estado tiene un método de acceso público con el mismo nombre del componente. tiene un constructor público con la misma firma que el  state description en el cual se inicializa cada campo desde el argumento . implementa equals y hashCode, en donde 2 records serán iguales si son del mismo tipo y contienen el mismo estado. implementa toString con la representación de todos sus componentes. cada componente del  state description es private final . no pueden extender otras clases. no pueden tener otros campos de instancia, solo los del  state description . si se definen otros campos tienen que ser static . un...

JPA-Hibernate + POJO + Projection + ConstructorResult + NativeQuery + Testcontainers + PostgreSQL

Imagen
En esta ocasión mostraré un ejemplo usando Java SE 11 de como mapear una clase no entidad (un POJO) a partir de los datos que existen en la base de datos y que representan a una entidad utilizando ConstructorResult, Projection y una construcción "manual" con JPA. Las pruebas serán realizadas usando Testcontainers junto a Postgresql como base de datos. El procedimiento es el siguiente (se omiten los metodos/imports/anotaciones que no son relevantes y usaré lombok solo para getter/setter): 1- La Entidad Representa la entidad que mantendrá datos en la base de datos y de la cual extraeremos algunos de sus campos para nuestro pojo. @Entity @Table(schema = "jpa", name = "persona") public class Persona { @Id private int id; private String nombre; private String apellido; } 2- El POJO Requiere tener un constructor con los argumentos que la query utilizará: public class PersonaPOJO { private String nn; private String a...

Redis Streams: xadd + xread

Esta ocasión mostraré un ejemplo de Redis Streams , con los metodos xadd y xread utilizando la librería Lettuce .  Generar Mensajes El Stream tendrá el nombre mensajes y cada mensaje enviado tendrá un UUID y un número indicando la cantidad de mensajes enviados: final var cliente = RedisClient.create("redis://localhost:6379"); try (final var con = cliente.connect()) { final var cmd = con.sync(); int i = 0; while (i < 500_000) { final var res = cmd.xadd("mensajes", Map.of(UUID.randomUUID().toString(), String.valueOf(i))); i++; LOGGER.info("enviados: {} - id: {}", i, res); Thread.sleep(1_000); } } cliente.shutdown();  Recibir Mensajes El cliente lee un mensaje a la vez y recuerda el último ID leido para preguntar por los nuevos mensajes y se bloquea 5 segundos esperando mensajes: final var cliente = RedisClient.crea...

Spring Boot + Spring Security + React + Keycloak

Imagen
Ahora mostraré como utilizar Spring Boot , Spring Security y Keycloak para tener recursos protegidos accediendo a ellos utilizando React 😉. Configurar Keycloak Configurar Spring Boot Configurar React   Keycloak Keycloak se puede obtener utilizando docker o desde su página como Standalone server distribution (previamente en este enlace había indicado como obtenerlo y lanzarlo).  Luego de lanzarlo estará disponible localmente y procedemos a realizar su configuración (en mi caso visitando http://localhost:8282/): Si es la primera vez configuramos el usuario administrador. Una vez ingresado entramos a la aplicación: Seleccionamos Add realm y definimos su nombre, en este ejemplo es: sso Luego vamos a Clients y presionamos Create para agregar dos clientes: cliente-uno para Spring Boot y cliente-dos para React, en ambos definimos su Root URL y Web Origins (NO olvidar presionar el boton save cuando realizamos modificaciones, web ...

Spring Boot con Redis para almacenar JSON y no la serialización predefinida

Imagen
En esta entrada mostraré como utilizar Spring Boot y Redis con el objetivo de almacenar los objetos como JSON y no como la forma de serialización de Java por defecto que tiene RedisTemplate. Los test están con Testcontainers, Junit 5 y AssertJ. Lo primero es la clase que nos convoca, la configuración de RedisTemplate: @Configuration public class RedisConfig { @Autowired private ConfigurableApplicationContext context; @Bean @Primary public RedisTemplate redisTemplate(JedisConnectionFactory conn) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(conn); template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer()); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } @Bean public JedisConnectionFactory redisConnectionFactory(@Value("$...

Usando Redis en Pruebas [versión 2]

Previamente había comentado como utilizar Redis en pruebas mediante redis embebido, pero en esta ocasión utilizaremos Testcontainers , que como lo dicen en su página, podemos utilizar cualquier cosa que corra en docker en nuestros tests 😮. Comencemos Lo primero es incluir en nuestro pom la dependencia a testcontainers: <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <version>1.11.2</version> </dependency> También incluimos otras librerías de test y el cliente redis: <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.11.1</version> <scope>test</scope> </depende...

Servicios: Invertir las dependencias utilizando el sistema de módulos

Imagen
Hoy quiero mostrar un ejemplo del uso de servicios utilizando módulos. Esta característica está presente desde Java 9 y nos permite invertir la dirección de las dependencias dejando al sistema de módulos obtener las implementaciones que serán utilizadas y nuestro modulo consumidor solo tiene que interactuar con tipos abstractos. Creando Servicios Comenzamos con la siguiente figura: El Consumidor solo tiene conocimiento de la interface Servicio, la cual utiliza en tiempo de ejecución llamando al método identificar en cada una de las implementaciones que recibe, en este caso serán ServicioA y ServicioB. Lo entretenido del sistema de módulos es que nos entrega esta funcionalidad, podemos crear los módulos que provean los servicios, agregarlos al module path y serán provistos a la clase consumidora. La siguiente imagen muestra los módulos que usaremos:    Si es necesario agregar mas servicios generamos nuevos módulos que implementan la interface Servicio y los dejamos ...