Ir al contenido principal

Destacado

Monitoring your micro services with Spring Boot Admin

This new joetip is for those who have in their architecture some micro-services developed with Spring Boot and are already using some Spring Cloud projects such as Spring Cloud Config and Spring Cloud Eureka as Discovery server.

The Spring Boot Admin is a project developed by CodeCentric which is available for free at https://github.com/codecentric/spring-boot-admin so we can monitor our microservices.

In order for these micro-services to be monitored, we have 2 options:


Placing the dependency of spring boot admin client on each projectOr configuring the Eureka (Consul or Zookeeper) so that you can monitor the micro-services that are already registered in it.

I will explain step by step what has to be done to work with the spring boot admin in our microservices cluster. But, if you are impatient and already want to try it, here is the GitHub repository: https://github.com/joedayz/spring-boot-admin-cloud-finchley.

For my demos I will use the following projects and the following versions…

El nuevo HttpClientModule


HttpClientModule  

Se ha escrito un nuevo HttpClientModule en reemplazo del HttpModule. Este nuevo módulo soluciona ya no exige extraer el JSON de la respuesta de cada request y trea mejoras para hacer nuestro testing al API de forma menos verbosa.

Cambiar tu import de:

import { HttpModule } from '@angular/http';

a:

import { HttpClientModule } from '@angular/common/http';


De un código como este:




import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { UserModel } from './user.model';

@Injectable()
export class UserService {

  constructor(private http: Http) {}

  list(): Observable {
    return this.http.get('/api/users')
      .map(response => response.json())
  }
}

Lo puedes cambiar a:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { UserModel } from './user.model';

@Injectable()
export class UserService {

  constructor(private http: HttpClient) {}

  list(): Observable {
    return this.http.get('/api/users');
  }
}

Testing

Ahora nuestros tests serán menos verbosos:





describe('UserService', () => {

  beforeEach(() => TestBed.configureTestingModule({
    imports: [HttpClientTestingModule],
    providers: [UserService]
  }));

  it('should list the users', () => {
    const userService = TestBed.get(UserService);
    const http = TestBed.get(HttpTestingController);
    // fake response
    const expectedUsers = [{ name: 'Pepito' }];

    let actualUsers = [];
    userService.list().subscribe((users: Array) => {
      actualUsers = users;
    });

    http.expectOne('/api/users').flush(expectedUsers);

    expect(actualUsers).toEqual(expectedUsers);
  });
});


También podemos añadir headers y parámetros a nuestros requests. Por ejemplo:


const params = new HttpParams().set('page', '1');
this.http.get('/api/users', { params });

const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);
this.http.get('/api/users', { headers });

El ejemplo anterior es muy útil cuando necesitas establecer el header Authorization cuando trabajas con JWT.

Interceptors

Ahora podemos usar interceptors por cada request y response y así podemos añadir un header a un request o manejar un error de una forma centralizada.

Por ejemplo, agregar un OAUTH Token a cada request de forma centralizada:







@Injectable()
export class BackendAPIInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest, next: HttpHandler): Observable> {

    // if it is a Github API request
    if (req.url.includes('api.backend.com')) {
      // we need to add an OAUTH token as a header to access the Github API
      const clone = req.clone({ setHeaders: { 'Authorization': `token ${OAUTH_TOKEN}` } });
      return next.handle(clone);
    }
    // if it's not a Backend API request, we just handle it to the next handler
    return next.handle(req);
  }

}

Y esas son las novedades por ahora. Enjoy!

Comentarios