¡Bienvenido a un post-tutorial más sobre WSO2 MSF4J! En esta ocasión vamos a aprender a cerca de las funcionalidades avanzadas necesarias para realizar microservicios de manera eficiente.
-No te pierdas: Nociones básicas sobre el módulo MSF4J-
Resulta importante destacar que WSO2 MSF4J es un framework perfecto para crear sin complicaciones y de forma rápida microservices.
Este servicio de WSO2 ofrece multitud de ventajas a la hora de generar APIs REST, además de ser un soporte ideal de Swagger.
Funcionalidades MSF4J para crear microservicios
Métrica
Esta es una de las mejores funcionalidades a utilizar con MSF4J, puesto que nos ofrece la posibilidad de poder recopilar datos y métricas de la utilización que realizamos de nuestro microservicio. Eso significa que nos da la posibilidad de poder explotar estos datos y tener mayor control sobre qué utilización tienen nuestros microservicios.
demás también podemos enviar y monitorizar esta información a través del DAS, aunque en este caso veremos un ejemplo ‘standalone’.
Para comenzar debemos incluir como dependencia ‘msf4j-analytics’ en el fichero pom.xml. Esta librería nos brindará la posibilidad de activar la métrica.
¡Importante! Recordemos que el núcleo de una aplicación MSF4J es la clase donde creamos una instancia de ‘MicroservicesRunner’, a través de la cual configuramos nuestro microservicio.
public static void main(final String[] args) { MetricsInterceptor mInterceptor = new MetricsInterceptor(); new MicroservicesRunner() .addGlobalRequestInterceptor(mInterceptor) .addGlobalResponseInterceptor(mInterceptor) .addExceptionMapper(new ServiceExceptionMapper()) .deploy(new BookServiceImpl()).start(); }
Tras ello debemos usar alguna de las distintas anotaciones que pone a nuestra disposición WSO2. A través de ellas podremos fácilmente recopilar determinadas métricas en cada uno de los métodos de la API de manera individual; de forma conjunta si ponemos la anotación a nivel de la clase. Estas anotaciones pueden ser:
- Counted: Nos permite medir el número de invocaciones realizadas al método y que se están ejecutando en el mismo momento que estamos observando la métrica. En caso de que queramos ver el total de invocaciones, tendremos que indicar la propiedad monotonic”.
- Metered: Ésta nos facilita medir el ratio de invocaciones que se realiza y el número total de invocaciones realizadas.
- Timed: Mantiene un histograma de la duración de las invocaciones y además recopila la información de las otras anotaciones (el ratio y número total de invocaciones).
@Override @GET @Path("/{bookId}") @Timed public Book getBookById(@PathParam("bookId") final Integer bookId) { return list.get(bookId); } @Override @GET @Path("/list") @Counted(name = "getList", monotonic = true) public List<Book> getList(@Context final Request request) { return list; }
El último paso sería configurar la salida de dicha métrica a través de un fichero de configuración ‘metric.yaml’. Tranquilo, ya viene uno incluido dentro del jar org.wso2.carbon.metrics.core, que además está habilitado por defecto’, por lo que podemos usar ese o bien crearnos uno propio.
Lo realmente importante se produce en el momento de arrancar la aplicación, ya que deberemos indicar a la máquina virtual, mediante a través de un parámetro, donde se encuentra dicho fichero, por ejemplo:
-Dmsf4j.conf=src/main/resources/metrics.yaml
Para poder observar las estadísticas las podremos ver en la consola desde la cual lancemos la aplicación. En esta contemplaríamos algo similar a esto:
Java Persistence API (JPA)
Ahora es el momento de aprender cómo asociar JPA y una BBDD a nuestro servicio, para poder obtener así un modelo más real y parecido a un entorno común de desarrollo.
Para ello deberemos incluir las librerías ‘hibernate-core’ e ‘hibernate-entitymanager’ que contendrán la implementación de Java Persistence API, y como base de datos utilizaremos una que trabaja en memoria como H2.
Como cualquier otra aplicación JPA, necesitará el fichero ‘persistence.xml’ con la configuración pertinente de la BBDD y el identificador de dicha unidad de persistencia. También crearemos una estructura de clases siguiendo el patrón DAO, para poder acceder a los datos de la BBDD.
En cuanto a los que nos atañe con nuestro microservicio, tendremos que modificar el núcleo de la aplicación. Para ello, deberemos acceder a la unidad de persistencia a través de su identificador y enviarla a nuestro servicio.
public static void main(final String[] args) { MetricsInterceptor mInterceptor = new MetricsInterceptor(); new MicroservicesRunner().addInterceptor(mInterceptor) .addExceptionMapper(new ServiceExceptionMapper()) .deploy(new BookServiceImpl(new BookDaoImpl(Persistence .createEntityManagerFactory( "com.chakray.msf4j.example.jpa.unit")))).start(); }
Autenticación
Por último veremos cómo implementar en nuestro microservicio un poco de autenticación. Aunque para nuestro ejemplo realizaremos una autenticación de tipo BASIC, debemos tener en cuenta que a través de WSO2 y del Identity Server también podremos realizarla de tipo OAuth2.
Para empezar con nuestro ejemplo y ya que tenemos implementado el uso de BBDD, crearemos una tabla que almacene la información de los usuarios y sus respectivas clases de acceso en la aplicación.
El segundo paso será crear un interceptor que extienda de ’AbstractBasicAuthSecurityInterceptor’. En este interceptor recibiremos el nombre de usuario y contraseña introducidos por el usuario y deberemos validarlos contra el sistema para ver si son correctos o no.
public class UsernamePasswordSecurityInterceptor extends AbstractBasicAuthSecurityInterceptor { UserDao dao; public UsernamePasswordSecurityInterceptor(final UserDao userDao) { dao = userDao; } @Override protected boolean authenticate(final String username, final String password) { String pwdEconded = Base64.getEncoder().encodeToString(password.getBytes()); User result = dao.findByNameAndPassword(username, pwdEconded); if (result != null) { return true; } return false; } }
El siguiente paso será configurar dicho interceptor en el núcleo de nuestra aplicación para que realice la autenticación en las peticiones a nuestro microservicio.
public class Application { private static UsernamePasswordSecurityInterceptor getBasicInterceptor(final EntityManagerFactory emf) { return new UsernamePasswordSecurityInterceptor(new UserDaoImpl(emf)); } public static void main(final String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.chakray.msf4j.example.jpa.unit"); MetricsInterceptor mInterceptor = new MetricsInterceptor(); new MicroservicesRunner().addInterceptor(mInterceptor) .addGlobalRequestInterceptor(getBasicInterceptor(emf)) .addExceptionMapper(new ServiceExceptionMapper()) .deploy(getBookService(emf)).start(); } private static BookServiceImpl getBookService(EntityManagerFactory emf) { return new BookServiceImpl(new BookDaoImpl(emf)); }
}
Una vez que arranquemos la aplicación e intentemos acceder a uno de nuestros métodos. El navegador web nos pedirá un usuario y contraseña para seguir con la operación.
Como has podido comprobar muchas son las funcionalidades que MSF4J ofrece para la creación de microservicios. Si quieres continuar aprendiendo sobre módulo no puedes perderte el siguiente post.