Skip to content

4. Caso practico

Nelson Manuel Moreno Restrepo edited this page May 5, 2016 · 3 revisions

Para desarrollar el caso práctico usare Spring Cloud Netflix, que es además Amazon la plataforma con mayor madures para el desarrollo de microservicios, iniciare con el caso de mínimo esfuerzo usando únicamente Spring Boot.

Spring Boot: es parte de las herramientas de la suite Spring que permite la creación rápida de aplicaciones Stand Alone. Proporciona dos tipos de contenedores Tomcat y Jetty, no requieren despliegues WAR ni realiza ningún tipo de generación automática de código. Existen otras alternativas como WSO2 Microservices Server, Consul, Netflix,

**Ejemplo básico: **

En este ejemplo se expone un servicio RestFull que responde a un llamado con el mensaje “hello world” cuando se invoca la ruta por omisión “/”. Las anotación @Controller significa que la clase usara la implementación Spring del patrón MVC, la anotación @RequestMapping permite definir la ruta por la cual se invocara este servicio, la anotación @ResponseBody define el tipo y la respuesta del método home, que es el que recibe las llamadas a la ruta por omisión “/”.

Finalmente el método main se comporta tal cual una aplicación StandAlone de Java, sin embargo al iniciar corre también el contenedor (tomcat o jetty) y la aplicación REST con el patrón MVC automáticamente, no se requiere descargar o inicializar ningún otro componente.

Configuración con maven:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.0.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

La clase hello/SampleController.java

package hello;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

@Controller
@EnableAutoConfiguration
public class SampleController {
    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SampleController.class, args);
    }
}

Aplicación práctica Accounts:

Esta aplicación permite a los usuarios registrarse, para ello provee varios microservicios, uno para crear el Account, otro para exponer la interfaz WEB y otro para descubrir los servicios de la aplicación.

Microservicio ServiceRegistrationServer

En los casos de CORBA y RMI, cuando se tienen multiples procesos ejecutándose conjuntamente y alguno de estos requiere encontrar al otro, es posible hacerlo con una simple llamada al repositorio central de procesos (ejm: para el caso de JAVA (TestService) InitialContext.doLookup(" services/TestService"). Para el caso de los microservicios existe un componente llamado Eureka que fue creado por los desarrolladores de Netflix, que es un servidor para registrar los microservicios. Eureka es open source y la siguiente es la forma de inicializar este servidor usando Spring Cloud.

@SpringBootApplication
@EnableEurekaServer
public class ServiceRegistrationServer {
    
    public static void main(String[] args) {
    // Tell Boot to look for registration-server.yml
    System.setProperty("spring.config.name", "registration-server");
    SpringApplication.run(ServiceRegistrationServer.class, args);
  }
}

Spring Cloud fue escrito con Spring Boot el cual permite utilizar Maven para importar los componentes requeridos para correr el producto. El siguiente es el archivo POM que utiliza esta aplicación:

<parent>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-parent</artifactId>
    <version>Angel.SR3</version>  <!-- Name of release train -->
</parent>
<dependencies>
    <dependency>
        <!-- Setup Spring Boot -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <!-- Setup Spring MVC & REST, use Embedded Tomcat -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <!-- Spring Cloud starter -->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter</artifactId>
    </dependency>
    <dependency>
        <!-- Eureka for service registration -->
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
</dependencies>

Por omisión Spring Boot busca el archivo de configuración application.yml, el siguiente es el contenido de este archivo para la aplicación del microservicio de registro:

# Configure this Discovery Server
eureka:
  instance:
    hostname: localhost
  client:  # No auto registrarse como cliente
    registerWithEureka: false
    fetchRegistry: false

server:
  port: 8761   # HTTP (Tomcat) port

Esta configuración indica que el servicio de registro no será a su vez un cliente del mismo y que la dirección y puerto del servidor Eureka serán localhost y 8761 respectivamente.

Microservicio AccountService

La siguiente es la aplicación del microservicio: está construida con Spring Boot, usa Spring Data para acceder al repositorio de Accounts utilizando JPA y Spring REST para proveer una interfaz RESTFull. Es importante entender que este microservicio no requiere ser desplegado, el código de la aplicación es exactamente el código de la clase que se muestra a continuación y se inicia con una simple llamada Stand Alone (todos los componentes necesarios para su inicialización y ejecución, incluyendo el servidor de aplicaciones y contenedor REST están embebidos y son exclusivos para el microservicio). Sin embargo lo que hace especial a este microservicio es que se registra el mismo en el Service Registro en el momento de la inicialización. La siguiente es una breve descripción de las anotaciones usadas en este microservicio:

@EnableAutoConfiguration define que esta es una aplicación Spring Boot.
@EnableDiscoveryClient habilita el registro y descubrimiento de servicios. Esto permite que el microservicio se autoregistre el Service Registry usando el nombre de la aplicación.
@Import(AccountsWebApplication.class) es la clase de configuración para todos los demás valores de la aplicación.

El siguiente es el código de la clase AccountService:

@EnableAutoConfiguration
@EnableDiscoveryClient
@Import(AccountsWebApplication.class)
public class AccountsServer {

    @Autowired
    AccountRepository AccountRepository;

    public static void main(String[] args) {
        // Will configure using Account-server.yml
        System.setProperty("spring.config.name", "Account-server");

        SpringApplication.run(AccountsServer.class, args);
    }
}

El archivo de configuración usado por este microservicio es el siguiente:

# Spring properties
spring:
  application:
     name: Account-service
# Discovery Server Access
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
# HTTP Server
server:
  port: 2222   # HTTP (Tomcat) port

Esta configuración indica que el nombre del servicio es Account-service, el puerto del servidor es 2222 y que la URL del servidor de registro es http://localhost:8761/eureka/ Al ejecutar la aplicación del microservicio AccountService y refrescar el dashboard del ServiceRegistry http://localhost:8761/eureka/ se puede ver en el listado de aplicaciones al microservicio AccountService.

Encapsulando el microservicio AccountService

Para consumir un servicio RESTFul, Spring provee una plantilla (RestTemplate) que permite realizar llamadas HTTP a un servidor RESTFul, el siguiente es el código del wrapper para la plantilla RestTemplate que obtiene los valores de los parámetros del servicio AccountService en el formato JSON.

@Service
public class WebAccountsService {

    @Autowired        // Created automatically by Spring Cloud
    @LoadBalanced
    protected RestTemplate restTemplate; 

    protected String serviceUrl;
    public WebAccountsService(String serviceUrl) {
        this.serviceUrl = serviceUrl.startsWith("http") ?
               serviceUrl : "http://" + serviceUrl;
    }

    public Account getByNumber(String accountNumber) {
        Account account = restTemplate.getForObject(serviceUrl + "/accounts/{number}", Account.class, accountNumber);

        if (account == null)
            throw new AccountNotFoundException(accountNumber);
        else
            return account;
    }
    ...
}

Accediendo al microservicio AccountService

La Url del microservicio es proveida por la el programa principal WebServer al controlador WebAccountController que a su vez pasa este parámetro a programa que lo encapsula WebAccountsService. El código del programa principal es el siguiente:

@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(useDefaultFilters=false)  // Disable component scanner
public class WebServer {

    public static void main(String[] args) {
        // Will configure using web-server.yml
        System.setProperty("spring.config.name", "web-server");
        SpringApplication.run(WebServer.class, args);
    }

    @Bean
    public WebAccountsController accountsController() {
         return new WebAccountsController
                   ("http://ACCOUNTS-SERVICE");  // serviceUrl
    }
}