Translate

lunes, 7 de marzo de 2022

Empezando con Cats


Cats está escrito usando una estructura modular que nos permite elegir qué class type, instancias y métodos de interfaz queremos usar. Echemos un primer vistazo usando cats.Show como ejemplo.

Show proporciona un mecanismo para producir una salida de consola amigable para los desarrolladores sin usar toString. Aquí hay una definición abreviada:

package cats

trait Show[A] {

def show(value: A): String

}

Los type classes en Cats se definen en el paquete cats. Podemos importar Show directamente desde este paquete:

import cats.Show

El objeto complementario de cada clase de tipo Cats tiene un método de aplicación que localiza una instancia para cualquier tipo que especifiquemos:

val showInt = Show.apply[Int]
// error: could not find implicit value for parameter instance: cats.Show[Int]
// val showInt: Show[Int] = Show.apply[Int]
//
 ^^^^^^^^^^^^^^^

Vaya, ¡eso no funcionó! El método apply utiliza implícitos para buscar instancias individuales, por lo que tendremos que incluir algunas instancias en el alcance.

El paquete cats.instances proporciona instancias predeterminadas para una amplia variedad de tipos. Podemos importarlos como se muestra en la siguiente tabla. Cada importación proporciona
instancias de todas las clases de tipos de Cats para un tipo de parámetro específico:

cats.instances.int proporciona instancias para Int
cats.instances.string proporciona instancias para String
cats.instances.list proporciona instancias para List
cats.instances.option proporciona instancias para Option
cats.instances.all proporciona todas las instancias que se envían listas para usar con Cats

Importemos las instancias de Show para Int y String:

import cats.instances.int._ // for Show
import cats.instances.string._ // for Show

val showInt: Show[Int] = Show.apply[Int]
val showString: Show[String] = Show.apply[String]

Ahora tenemos acceso a dos instancias de Show y podemos usarlas para imprimir Ints y Strings:

val intAsString: String = showInt.show(123)

// intAsString: String = "123"

val stringAsString: String = showString.show("abc")

// stringAsString: String = "abc"


viernes, 4 de marzo de 2022

Escribiendo clientes Eureka con Feign


Una alternativa a la clase RestTemplate habilitada para Spring Ribbon es la biblioteca cliente Feign de Netflix. La biblioteca Feign adopta un enfoque diferente para llamar a un servicio REST al hacer que el desarrollador primero defina una interfaz Java y luego anote esa interfaz con las anotaciones de Spring Cloud para mapear qué servicio basado en Eureka invocará Ribbon.

Spring Cloud generará dinámicamente una clase de proxy que se utilizará para invocar el servicio REST de destino. No se escribe ningún código para llamar al servicio que no sea una definición de interfaz.

Para habilitar el uso del cliente Feign se debe agregar una anotación, @EnableFeignClients, a la clase Application.java

Luego de habilitar el cliente de Feign, veamos una definición de interfaz de cliente de Feign que se puede usar para llama:


/*Package and import left off for conciseness*/

@FeignClient("ejemploService")

public interface EjemploFeignClient {

 @RequestMapping(method= RequestMethod.GET,  value="/v1/ejemplo/{ejemploId}",
 consumes="application/json")
Ejemplo getEjemplo( @PathVariable("ejemploId") String ejemploId);

}

La gente mayor recordarán un framework que trabajaba de forma similar llamado cxf. 

En la anotación @FeignClient le pasámos el nombre de la identificación del servicio que deseamos que represente la interfaz. A continuación, defimos un método, getEjemplo el cual retorna un objeto Ejemplo.

Como se puede ver la definición de la clase usa anotaciones de las cual ya estamos familiarizados. 

Para usar la clase EjemploFeignClient, todo lo que necesitamos hacer es injectarla y usarla. El código de Feign Client se encargará de todo el trabajo de codificación.

Cuando utiliza la clase Spring RestTemplate estándar, todos los códigos de estado HTTP de las llamadas de servicio se devolverán a través del método getStatusCode() de la clase ResponseEntity. Con Feign Client, cualquier código de estado HTTP 4xx – 5xx devuelto por el servicio al que se llama se asignará a una FeignException. FeignException contendrá un cuerpo JSON que se puede analizar para el mensaje de error específico. Feign le brinda la capacidad de escribir una clase de decodificación de errores que asignará el error a una clase de excepción personalizada. 

Dejo link : https://github.com/OpenFeign/feign


miércoles, 2 de marzo de 2022

Raml, un modo simple de modelar APIs


Claramente no hemos encontrado el camino correcto y flexible de modelar APIs, porque si no tenemos un router que es una clase o archivo que tiene parte de la información. Tenemos que llenar nuestras clases de muchas anotaciones. 

Para resolver este problema llego Raml, y veamos un ejemplo: 

%RAML 1.0

title: Mobile Order API

baseUri: http://localhost:8081/api

version: 1.0


uses:

  assets: assets.lib.raml


annotationTypes:

  monitoringInterval:

    type: integer


/orders:

  displayName: Orders

  get:

    is: [ assets.paging ]

    (monitoringInterval): 30

    description: Lists all orders of a specific user

    queryParameters:

      userId:

        type: string

        description: use to query all orders of a user

  post:

  /{orderId}:

    get:

      responses:

        200:

          body:

            application/json:

              type: assets.Order

            application/xml:

              type: !include schemas/order.xsd


Dejo link: https://raml.org

lunes, 28 de febrero de 2022

Descubrir un servicio publicado con Eureka con Spring boot, parte 3


Seguimos con el post anterior.

Veamos un ejemplo de cómo usar un RestTemplate que es Ribbonaware. Este es uno de los mecanismos más comunes para interactuar con Ribbon a través de Spring. Para usar una clase RestTemplate con un balanceador de carga, debe definir un método de construcción de bean RestTemplate con una anotación de Spring Cloud llamada @LoadBalanced. 

El siguiente código muestra el método getRestTemplate() que creará el bean Spring RestTemplate respaldado por Ribbon.

package com.thoughtmechanix.licenses;

//...Most of import statements have been removed for consiceness

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

public class Application {

  @LoadBalanced
  @Bean
  public RestTemplate getRestTemplate(){
    return new RestTemplate();
  }

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

Ahora que la definición del bean para la clase RestTemplate respaldada por Ribbon está definida, cada vez que desee usar el bean RestTemplate para llamar a un servicio, solo necesita conéctelo automáticamente a la clase que lo usa.

El uso de la clase RestTemplate con balanceador de carga se comporta prácticamente como una clase Spring RestTemplate estándar, excepto por una pequeña diferencia en cómo se define la URL para el servicio de destino. En lugar de utilizar la ubicación física del servicio en la llamada RestTemplate, creará la URL de destino utilizando el ID de servicio de Eureka del servicio al que desea llamar.

Veamos esta diferencia mirando el siguiente código.

/*Package and import definitions left off for conciseness*/

@Component

public class OrganizationRestTemplateClient {

  @Autowired
  RestTemplate restTemplate;

  public Organization getOrganization(String organizationId){
    ResponseEntity<Organization> restExchange =
    restTemplate.exchange("http://organizationservice/v1/organizations/{organizationId}",
                   HttpMethod.GET, null, Organization.class, organizationId);
    return restExchange.getBody();
  }
}

Este código debería parecerse un poco al ejemplo anterior, excepto por dos diferencias clave. Primero, Spring Cloud DiscoveryClient no está a la vista. En segundo lugar, la URL que se utiliza en la llamada restTemplate.exchange() debería parecerte extraña:

restTemplate.exchange("http://organizationservice/v1/organizations/{organizationId}",
                   HttpMethod.GET, null, Organization.class, organizationId);

El nombre del servidor en la URL coincide con el ID de la aplicación de la clave de servicio de la organización con la que registró el servicio de la organización en Eureka:

http://{identificación de la aplicación}/v1/organizaciones/{identificación de la organización}

El RestTemplate habilitado para Ribbon analizará la URL que se le pasó y usará lo que se le pase como el nombre del servidor como clave para consultar a Ribbon por una instancia de un servicio. La ubicación real del servicio y el puerto están completamente abstraídos del desarrollador.

Además, al usar la clase RestTemplate, Ribbon equilibrará la carga por turnos de todas las solicitudes entre todas las instancias de servicio.


sábado, 26 de febrero de 2022

Descubrir un servicio publicado con Eureka con Spring boot, parte 2


Seguimos con el post anterior. Pero para no quedar tan colgado retomemos este código : 

/*Packages and imports removed for conciseness*/

@Component

public class OrganizationDiscoveryClient {


  @Autowired

   private DiscoveryClient discoveryClient;


   public Organization getOrganization(String organizationId) {

     RestTemplate restTemplate = new RestTemplate();

     List<ServiceInstance> instances = discoveryClient.getInstances("organizationservice");

     if (instances.size()==0) return null;

        String serviceUri = String.format("%s/v1/organizations/%s", instances.get(0).getUri().toString(),

            organizationId);

        ResponseEntity< Organization > restExchange = restTemplate.exchange(serviceUri, 

                                                                                                     HttpMethod.GET,

                                                                                                     null, Organization.class, organizationId);

      return restExchange.getBody();

   }

}

Solo debemos usar Discovery-Client directamente cuando el servicio necesita consultar Ribbon para comprender qué servicios e instancias de servicio están registrados con él. Hay varios problemas con este código, incluidos los siguientes:

No se está aprovechando el balanceador de carga del lado del cliente de Ribbon: al llamar a Discovery-Client directamente, obtenemos una lista de servicios, pero tambien responsabilidad elegir qué instancias de servicio a invocar.

Se está haciendo demasiado trabajo: en este momento, debe crear la URL que se utilizará para llamar a su servicio. Es algo pequeño, pero cada pieza de código que puede evitar escribir es una pieza menos de código que tiene que depurar.

Es posible que los desarrolladores observadores de Spring hayan notado que está instanciando directamente la clase RestTemplate en el código. Esto es la antítesis de las invocaciones normales de Spring REST, ya que normalmente Spring Framework inyectaría RestTemplate en la clase que lo usa a través de la anotación @Autowired.

Ha creado una instancia de la clase RestTemplate porque una vez que haya habilitado Spring DiscoveryClient en la clase de aplicación a través de la anotación @EnableDiscovery-Client, todas las RestTemplates administradas por Spring Framework tendrán un interceptor habilitado para Ribbon. Al instanciar directamente la clase RestTemplate le permite evitar este comportamiento.

En resumen, existen mejores mecanismos para llamar a un servicio respaldado por Ribbon.

jueves, 24 de febrero de 2022

Libros Gratuitos de Java code Geeks

 

Download IT Guides!

 

JPA Minibook

The basic Java framework to access the database is JDBC. Unfortunately, with JDBC, a lot of hand work is needed to convert a database query result into Java classes. Other disadvantages...

 
 

Microservices for Java Developers

Microservices are a software development technique – a variant of the service-oriented architecture (SOA) structural style – that arranges an application as a collection of loosely...

 
 

JMeter Tutorial

JMeter is an application that offers several possibilities to configure and execute load, performance and stress tests using different technologies and protocols. It allows simulating...

 
 

Java Design Patterns

A design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be...

 

martes, 22 de febrero de 2022

Curso de introducción a Linux en español

 Me llego este mail y queria compartirlo : 

 
Courses   /   Programs   /   My Account
 
Introduccion a Linux.
 
 
Linux es el sistema operativo del 100% de las supercomputadoras del mundo, también de la mayoría de los servidores que alimentan el Internet y de los que realizan operaciones financieras en todo el mundo, siendo además la base de los dos mil millones de dispositivos Android.

Este curso te ayudará a desarrollar un buen conocimiento práctico de Linux, utilizando tanto la interfaz gráfica como la línea de comandos y conociendo las principales distribuciones de este sistema operativo de software libre.

Este curso es ofrecido por The Linux Foundation y la Universitat Politècnica de València. Únete a los más de 1,000,000 de estudiantes que ya están inscritos en la versión de este curso en inglés y comienza tu viaje por Linux.

Lo que aprenderás:
Obtendrás un buen conocimiento práctico de Linux
Aprenderás cómo navegar por las principales distribuciones de Linux
Conocerás la configuración del sistema y de la interfaz gráfica de Linux
Aprenderás las operaciones básicas de la línea de comandos
Identificarás las aplicaciones comunes de Linux
 
Explora el curso
 
 

edX is the trusted platform for education and learning.

Save 10% on select programs! Click here

edX for Business — eLearning Solutions for Your Company

© 2022 edX Inc. All rights reserved.

Update Your Preferences / Unsubscribe

141 Portland St. 9th Floor, Cambridge, MA 02139

lunes, 21 de febrero de 2022

Descubrir un servicio publicado con Eureka con Spring boot


Ya tenemos el servicio registrado en Eureka. Ahora necesitamos llamarlo sin tener conocimiento directo de la ubicación. De tal manera que este ultimo buscará la ubicación física mediante Eureka.

Para nuestros propósitos, vamos a ver tres bibliotecas de clientes de Spring/Netflix diferentes en las que un consumidor de servicios puede interactuar con Ribbon. Estas bibliotecas pasarán del nivel más bajo de abstracción para interactuar con Ribbon al más alto.

Las bibliotecas que exploraremos incluyen

  •  Spring Discovery 
  •  Spring Discovery  con RestTemplate habilitado 
  •  Netflix Feign

Spring Discovery Client ofrece el nivel más bajo de acceso a Ribbon y los servicios registrados en él. Usando Discovery Client, puede consultar todos los servicios registrados con el cliente y sus URL correspondientes.

Veamos un ejemplo simple del uso de DiscoveryClient para recuperar una de las direcciones URL de un servicio y luego llamaremos al servicio mediante una clase RestTemplate estándar. Para comenzar a usar DiscoveryClient, primero debe anotar la clase Application.java con la anotación @EnableDiscoveryClient:

@SpringBootApplication

@EnableDiscoveryClient

public class Application {
   public static void main(String[] args) {
     SpringApplication.run(Application.class, args);
  }
}

Veamos un ejemplo de un descubrimiento de un cliente : 

/*Packages and imports removed for conciseness*/
@Component
public class OrganizationDiscoveryClient {

  @Autowired
   private DiscoveryClient discoveryClient;

   public Organization getOrganization(String organizationId) {
     RestTemplate restTemplate = new RestTemplate();
     List<ServiceInstance> instances = discoveryClient.getInstances("organizationservice");
     if (instances.size()==0) return null;
        String serviceUri = String.format("%s/v1/organizations/%s", instances.get(0).getUri().toString(),
            organizationId);
        ResponseEntity< Organization > restExchange = restTemplate.exchange(serviceUri, 
                                                                                                     HttpMethod.GET,
                                                                                                     null, Organization.class, organizationId);
      return restExchange.getBody();
   }
}

DiscoveryClient es la clase que usamos para interactuar con Ribbon. Para recuperar todas las instancias de los servicios de la organización registrados con Eureka, se puede usar el método getInstances(), pasando la clave del servicio que está buscando, para recuperar una lista de objetos ServiceInstance.

La clase ServiceInstance se utiliza para contener información sobre una instancia específica de un servicio, incluido su nombre de host, puerto y URI.

Tomamos la primera clase ServiceInstance de su lista para crear una URL de destino que luego se puede usar para llamar a su servicio. Una vez que tenga una URL de destino, puede usar un Spring RestTemplate estándar para llamar al servicio y recuperar datos.

En post posteriores veremos otras opciones. 

viernes, 18 de febrero de 2022

El poder de las type class y los implícitos en Scala


El poder de las type class y los implícitos radica en la capacidad del compilador para combinar definiciones implícitas al buscar instancias candidatas.

Anteriormente insinuamos que todas las instancias de type class son valores implícitos. Esto fue una simplificación. De hecho, podemos definir instancias de dos maneras:

  1. definiendo instancias concretas como valores implícitos del tipo requerido;
  2. mediante la definición de métodos implícitos para construir instancias a partir de otras instancias de clases de tipo.

¿Por qué construiríamos instancias a partir de otras instancias? Como ejemplo motivacional, considere definir un JsonWriter para Option. necesitaríamos un JsonWriter[Option[A]] para cada A que nos interesa en nuestra aplicación. Podríamos intentar resolver el problema por fuerza bruta creando una biblioteca de valores implícitos:

implicit val optionIntWriter: JsonWriter[Option[Int]] =

???

implicit val optionPersonWriter: JsonWriter[Option[Person]] =

???

// and so on...


Sin embargo, este enfoque claramente no escala. Terminamos requiriendo dos valores implícitos para cada tipo A en nuestra aplicación: uno para A y otro para Opción[A].

Afortunadamente, podemos abstraer el código para manejar la Opción[A] en un constructor común basado en la instancia de A:

• si la opción es Some(aValue), escriba aValue usando el escritor para A;

• si la opción es None, devuelve JsNull.

Aquí está el mismo código escrito como una definición implícita:

implicit def optionWriter[A] (implicit writer: JsonWriter[A]): JsonWriter[Option[A]] =

  new JsonWriter[Option[A]] {

    def write(option: Option[A]): Json =

       option match {

           case Some(aValue) => writer.write(aValue)

           case None => JsNull

      }

  }

Este método construye un JsonWriter para Option[A] basándose en un parámetro implícito para completar la funcionalidad específica de A. Cuando el compilador ve una expresión como esta:

  Json.toJson(Option("A string"))

busca un JsonWriter[Option[String]] implícito. Encuentra el método implícito para JsonWriter[Option[A]]:

  Json.toJson(Option("A string"))(optionWriter[String])

y busca recursivamente un JsonWriter[String] para usarlo como parámetro para optionWriter:

  Json.toJson(Option("A string"))(optionWriter(stringWriter))

De esta forma, la resolución implícita se convierte en una búsqueda a través del espacio de posibles combinaciones de definiciones implícitas, para encontrar una combinación que cree una instancia de clase de tipo del tipo general correcto.

Trabajar con implícitos en Scala


Trabajar con type class en Scala significa trabajar con valores implícitos y parámetros implícitos. Hay algunas reglas que necesitamos saber para hacer esto de manera efectiva.

Implícitos de empaquetado : En una peculiaridad curiosa del lenguaje, cualquier definición marcada como implícita en Scala debe colocarse dentro de un objeto o trait en lugar de en el nivel superior. Colocar instancias en un objeto complementario a la clase de tipo tiene un significado especial en Scala porque juega con algo llamado alcance implícito.

Ámbito implícito : El compilador busca instancias de clase de tipo candidato por tipo. Los lugares donde el compilador busca instancias candidatas se conocen como ámbito implícito. El alcance implícito se aplica en el sitio de la llamada; ese es el punto donde llamamos a un método con un parámetro implícito. El alcance implícito que consta aproximadamente de:

• definiciones locales o heredadas;

• definiciones importadas;

• definiciones en el objeto complementario de la clase de tipo o el tipo de parámetro (en este caso, JsonWriter o String).

Las definiciones solo se incluyen en el ámbito implícito si están etiquetadas con la palabra clave implícita. Además, si el compilador ve múltiples definiciones candidatas, falla con un error de valores implícitos ambiguos:

implicit val writer1: JsonWriter[String] = JsonWriterInstances.stringWriter

implicit val writer2: JsonWriter[String] = JsonWriterInstances.stringWriter

Json.toJson("A string")

// error: ambiguous implicit values:

//  both value writer1 in object App0 of type => repl.Session.App0. JsonWriter[String]

//  and value writer2 in object App0 of type => repl.Session.App0. JsonWriter[String]

// match expected type repl.Session.App0.JsonWriter[String]

// Json.toJson("A string")

// ^^^^^^^^^^^^^^^^^^^^^^^

Las reglas precisas de la resolución implícita son más complejas que esto, pero la complejidad es en gran medida irrelevante para el uso diario. Para nuestros propósitos, podemos empaquetar instancias de clases de tipo en aproximadamente cuatro formas:

1. colocándolos en un objeto;

2. colocándolos en un trait;

3. colocándolos en el objeto compañero de la clase de tipos;

4. colocándolos en el objeto complementario del tipo de parámetro.

Con la opción 1 traemos las instancias al alcance importándolas. Con la opción 2 los traemos al alcance con la herencia. Con las opciones 3 y 4, las instancias siempre están en un alcance implícito, independientemente de dónde intentemos usarlas.

Es convencional colocar instancias de clase de tipo en un objeto complementario (opción 3 y 4 anteriores) si solo hay una implementación sensata, o al menos una implementación ampliamente aceptada como predeterminada. Esto hace que las instancias de clase de tipo sean más fáciles de usar, ya que no se requiere importarlas para incluirlas en el ámbito implícito.

jueves, 17 de febrero de 2022

Type class en Scala parte 2


Seguimos con Type class en Scala

Un uso de clase de tipo es cualquier funcionalidad que requiere una instancia de clase de tipo para funcionar. En Scala esto significa cualquier método que acepte instancias de la clase de tipo como parámetros implícitos.

La forma más sencilla de crear una interfaz que utilice una clase de tipo es colocar métodos en un objeto único:

object Json {

  def toJson[A](value: A)(implicit w: JsonWriter[A]): Json =

    w.write(value)

}

Para usar este objeto, importamos cualquier instancia de clase de tipo que nos interese y llamamos al método relevante:

import JsonWriterInstances._
Json.toJson(Person("Dave", "dave@example.com"))
// res1: Json = JsObject(
// Map("name" -> JsString("Dave"), "email" -> JsString("dave@example.com"))
// )

El compilador detecta que hemos llamado al método toJson sin proporcionar los parámetros implícitos. Intenta arreglar esto buscando instancias de clase de tipo de los tipos relevantes e insertándolos en el sitio de la llamada:

Json.toJson(Person("Dave", "dave@example.com"))(personWriter)

Alternativamente, podemos usar métodos de extensión para extender los tipos existentes con métodos de interfaz. 

object JsonSyntax {
  implicit class JsonWriterOps[A](value: A) {
    def toJson(implicit w: JsonWriter[A]): Json =
      w.write(value)
  }
}

Usamos la sintaxis de la interfaz importándola junto con las instancias para los tipos que necesitamos:

import JsonWriterInstances._

import JsonSyntax._

Person("Dave", "dave@example.com").toJson

// res3: Json = JsObject(

// Map("name" -> JsString("Dave"), "email" -> JsString("dave@example.com"))

// )

Nuevamente, el compilador busca candidatos para los parámetros implícitos y los completa por nosotros:

Person("Dave", "dave@example.com").toJson(personWriter)

La biblioteca estándar de Scala proporciona una interfaz de clase de tipo genérico llamada implicitly. Su definición es muy sencilla:

def implicitly[A](implicit value: A): A = value

Podemos usar implicitly para invocar cualquier valor del alcance implícito. Proporcionamos el tipo que queremos e implícitamente hace el resto:

import JsonWriterInstances._

implicitly[JsonWriter[String]]
// res5: JsonWriter[String] = repl.

Podemos usar implicitly para invocar cualquier valor del alcance implícito. Proporcionamos el tipo que queremos e implícitamente hace el resto:

import JsonWriterInstances._
implicitly[JsonWriter[String]]
// res5: JsonWriter[String] = repl.

Podemos insertar una llamada a implícitamente dentro del flujo general de nuestro código para garantizar que el compilador pueda encontrar una instancia de una clase de tipo y asegurarse de que no haya errores implícitos ambiguos.

domingo, 13 de febrero de 2022

Haciendo test con Spock


Si deseas hacer tus test más legibles y acordes a la metodologia BDD, spock es para vos. 

Spock es un framework de test y especificación para aplicaciones Java y Groovy. Lo que lo hace destacar entre la multitud de framework de test es su hermoso y altamente expresivo lenguaje de especificaciones. Gracias a que corre sobre JUnit, Spock es compatible con la mayoría de los IDE, herramientas de compilación y servidores de integración continua. Spock está inspirado en JUnit, jMock, RSpec, Groovy, Scala, Vulcans y otros frameworks y lenguajes.

La idea de spock es que hay diferentes bloques donde uno puede definir el setup del test, el estimulo y la respuesta esperada : 


Bueno, nada mejor que un ejemplo para mostrar la propuesta de este framework: 

def "two plus two should equal four"() {

    given:

        int left = 2

        int right = 2

    when:

        int result = left + right

    then:

        result == 4

}

def "Should be able to remove from list"() {

    given:

        def list = [1, 2, 3, 4]

    when:

        list.remove(0)

    then:

        list == [2, 3, 4]

}


Dejo link: https://spockframework.org/