0% encontró este documento útil (0 votos)
16 vistas24 páginas

Implementación de API Gateway en Microservicios

El documento presenta un proyecto académico sobre la implementación de un API Gateway en el contexto de una arquitectura de microservicios para un sistema de inventario y ventas. Se describen las ventajas y desventajas de los microservicios y del API Gateway, así como los objetivos del proyecto y el desarrollo de tres microservicios específicos. Además, se detalla la configuración de los API Gateways utilizando Spring Cloud Gateway para enrutar solicitudes tanto de aplicaciones web como móviles.

Cargado por

Luis Vasquez
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
16 vistas24 páginas

Implementación de API Gateway en Microservicios

El documento presenta un proyecto académico sobre la implementación de un API Gateway en el contexto de una arquitectura de microservicios para un sistema de inventario y ventas. Se describen las ventajas y desventajas de los microservicios y del API Gateway, así como los objetivos del proyecto y el desarrollo de tres microservicios específicos. Además, se detalla la configuración de los API Gateways utilizando Spring Cloud Gateway para enrutar solicitudes tanto de aplicaciones web como móviles.

Cargado por

Luis Vasquez
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

UNIVERSIDAD DE LAS FUERZAS ARMADAS-ESPE

SEDE SANTO DOMINGO DE LOS TSÁCHILAS

DEPARTAMENTO DE CIENCIAS DE LA COMPUTACIÓN - DCCO-SS

CARRERA DE INGENIERÍA EN TECNOLOGÍAS DE LA INFORMACIÓN

PERIODO : 202450 mayo 2024 – septiembre 2024

ASIGNATURA : Arquitectura de Software

TEMA : Implementar de API Gateway

ESTUDIANTE : Luis Miguel Vasquez

Omar Maron Ferrin

Rachel Olga Garcés

NIVEL-PARALELO : 8vo

DOCENTE : Msc. Luis Ortiz

FECHA DE ENTREGA : 1 de septiembre de 2024

SANTO DOMINGO – ECUADOR


ARQUITECTURA DE SOFTWARE

Contenido

Introducción .............................................................................................................................................................................................. 3

Arquitectura de Microservicios ................................................................................................................................................... 3

Ventajas: ............................................................................................................................................................................................ 4

Desventajas: ..................................................................................................................................................................................... 4

API Gateway .......................................................................................................................................................................................... 4

Ventajas: ............................................................................................................................................................................................ 5

Desventajas: ..................................................................................................................................................................................... 5

Objetivos ...................................................................................................................................................................................................... 6

Objetivo general .................................................................................................................................................................................. 6

Objetivo específico ............................................................................................................................................................................. 6

Desarrollo.................................................................................................................................................................................................... 7

Microservicios ...................................................................................................................................................................................... 7

MS-1: Microservicio de gestión de inventarios ............................................................................................................... 7

MS-2: Microservicio de movimientos .................................................................................................................................. 9

MS-3: Microservicio de estadísticas: ................................................................................................................................. 10

API Gateway ....................................................................................................................................................................................... 11

Características de Spring Cloud Gateway: ...................................................................................................................... 11

API-GW-1: API Gateway para la aplicación web ......................................................................................................... 12

API-GW-2: API Gateway para la aplicación móvil ...................................................................................................... 12

Despliegue .......................................................................................................................................................................................... 15

Funcionamiento ............................................................................................................................................................................... 17

Página 2 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Conclusiones ........................................................................................................................................................................................... 23

Recomendación ..................................................................................................................................................................................... 23

Bibliografía/ Referencias.................................................................................................................................................................. 24

Introducción

Arquitectura de Microservicios

Es un estilo de diseño de software que estructura una aplicación como una colección de servicios

pequeños, autónomos y desplegables de manera independiente. Cada microservicio está diseñado para

realizar una función específica o un conjunto de funciones relacionadas y se comunica con otros

microservicios a través de APIs.

1. Descomposición por Funcionalidad:

o Los microservicios se diseñan en torno a dominios específicos de negocio, permitiendo

una mayor flexibilidad y escalabilidad.

o Cada microservicio puede ser desarrollado, desplegado y escalado de manera

independiente.

2. Despliegue Independiente:

o Los equipos pueden desplegar y actualizar microservicios de manera autónoma sin

afectar el resto del sistema.

3. Tecnologías Diversas:

o Diferentes microservicios pueden ser escritos en diferentes lenguajes de programación y

utilizar diferentes tecnologías, adecuándose a los requisitos específicos del servicio.

4. Escalabilidad:

Página 3 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

o Los microservicios permiten escalar componentes individuales en lugar de escalar la

aplicación completa, optimizando el uso de recursos.

Ventajas:

• Permite escalar servicios individuales según sea necesario.

• Los equipos pueden trabajar en paralelo en diferentes servicios.

• Facilita la implementación y la integración continuas.

Desventajas:

• La gestión de múltiples servicios puede ser compleja.

• Sin un control adecuado, puede ser difícil mantener la consistencia de los datos entre servicios.

API Gateway

Es un patrón de arquitectura que actúa como un punto único de entrada para todas las solicitudes de

cliente. Dirige estas solicitudes a los microservicios adecuados y maneja tareas transversales como

autenticación, enrutamiento, y monitoreo.

1. Enrutamiento de Solicitudes:

o Redirige las solicitudes del cliente a los microservicios apropiados basándose en la URL y

el tipo de solicitud.

2. Autenticación y Autorización:

o Maneja la autenticación y autorización de solicitudes, asegurando que solo los usuarios

autorizados puedan acceder a ciertos servicios.

3. Registro y Monitoreo:

o Centraliza el registro y monitoreo de las solicitudes, proporcionando visibilidad sobre el

comportamiento y el rendimiento del sistema.

4. Control de Carga:

Página 4 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

o Implementa mecanismos para manejar la carga y proteger los servicios de posibles

ataques, como el control de velocidad y el enrutamiento inteligente.

Ventajas:

• El cliente interactúa con un único punto de entrada en lugar de múltiples microservicios.

• Ofrece un único lugar para implementar seguridad y control de acceso.

• Permite realizar cambios en el enrutamiento y en la lógica de negocio sin afectar a los clientes.

Desventajas:

• Si el API Gateway falla, puede afectar a todos los servicios que dependen de él.

• Puede convertirse en un cuello de botella si no está bien gestionado.

Página 5 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Objetivos

Objetivo general

● Definir y desarrollar al menos 3 microservicios cuyos clientes se comuniquen con ellos mediante

APIs Gateway

Objetivo específico

● Desarrollar un API Gateway para la web y otro para móvil.

● Consumir los servicios de prueba para verificar su funcionamiento

Página 6 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Desarrollo

Para el presente caso de estudio se nombrarán a los microservicios y API Gateway con los prefijos MS y API-

GW respectivamente seguido de un guion y numero que lo identifica a cada uno.

Microservicios

El tema elegido para el presente proyecto se llama “Sistema de inventario y ventas” en el cual funcionan

3 microservicios, a continuación, se muestra un diagrama de los microservicios y como estos se

comunican entre sí.

MS-1: Microservicio de gestión de inventarios

MS-1 se encarga de la gestión de inventarios y está configurado para interactuar con una base de datos

PostgreSQL. A continuación, se presenta un resumen de los principales componentes y funcionalidades:

Página 7 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Controladores

SupplierController

Endpoints:

● DELETE /suppliers/{id}: Elimina un proveedor.

● GET /suppliers/{id}: Obtiene un proveedor por su ID.

● GET /suppliers: Obtiene todos los proveedores.

CategoryController

Endpoints:

● POST /categories: Crea una nueva categoría.

● PUT /categories/{id}: Actualiza una categoría existente.

● DELETE /categories/{id}: Elimina una categoría.

● GET /categories/{id}: Obtiene una categoría por su ID.

● GET /categories: Obtiene todas las categorías.

ProductController

Endpoints:

● POST /products: Crea un nuevo producto.

● PUT /products/{id}: Actualiza un producto existente.

● DELETE /products/{id}: Elimina un producto.

● GET /products/{id}: Obtiene un producto por su ID.

● GET /products: Obtiene todos los productos.

● POST /products/add-stock/{id}: Agrega stock a un producto.

● POST /products/remove-stock/{id}: Remueve stock de un producto.

● POST /products/sales: Registra ventas de productos.

● GET /products/category/{id}: Obtiene productos por categoría.

● GET /products/supplier/{id}: Obtiene productos por proveedor.

● GET /products/exists/{id}: Verifica si un producto existe por su ID.

Página 8 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Comunicación con MS-2

MS-1 se comunica con otro microservicio de movimientos mediante la clase MicroserviceClient. Esta

clase utiliza RestTemplate para realizar solicitudes HTTP a MS-2.

Métodos principales:

● changeStatusToNotExistProduct: Cambia el estado de un producto a "no existente" en el

microservicio de movimientos, esto se hace para indicarle a MS-1 que un producto fue eliminado

y por ende debe marcar con una bandera a todas las facturas y movimientos almacenados que el

producto ya no existe.

● post: Método genérico para realizar solicitudes POST a microservice2.

MS-2: Microservicio de movimientos

Este microservicio esta conectado a una base de datos mongo y se encarga de la parte transaccional del

sistema, es decir: clientes, facturas y movimientos (entradas y salidas de inventario) comunicándose con

MS-1 para realizar los cambios de estados:

Controladores

CustomerController

Endpoints:

● POST /customers: Crea un nuevo cliente.

● PUT /customers/{id}: Actualiza un cliente existente.

● DELETE /customers/{id}: Elimina un cliente por su ID.

● GET /customers/{id}: Obtiene un cliente por su ID.

● GET /customers: Obtiene una lista de todos los clientes.

MovementsController

Endpoints:

● POST /movements: Crea un nuevo movimiento en el inventario.

● DELETE /movements/{id}: Elimina un movimiento por su ID.

Página 9 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

● GET /movements: Obtiene una lista de todos los movimientos.

● GET /movements/{id}: Obtiene un movimiento por su ID.

● POST /movements/change-status-to-not-exist-product/{id}: Cambia el estado de un producto a

"no existente".

SalesController

Endpoints:

● POST /sales: Registra una nueva venta.

● GET /sales/{id}: Obtiene una venta por su ID.

● GET /sales: Obtiene una lista de todas las ventas.

Comunicación con MS-1

MS-1 se comunica con el MS-2 mediante la clase MicroserviceClient la igual que lo hace MS-2, solo que en

este caso el objetivo es traer la información de los productos y validar la existencia de estos.

MS-3: Microservicio de estadísticas:

Maneja la lógica de negocio relacionada con la generación de estadísticas, incluyendo la agregación y

procesamiento de datos de movimientos y ventas para proporcionar información analítica.

Controladores

StatisticsController

● GET /stats/movements-by-type: Obtiene estadísticas sobre movimientos por tipo

(entrada/salida).

● GET /stats/movements-by-product: Obtiene estadísticas sobre movimientos por producto.

● GET /stats/movements-by-month: Obtiene estadísticas sobre movimientos por mes.

● GET /stats/movements-quantity-by-date: Obtiene estadísticas sobre la cantidad de movimientos

por fecha.

● GET /stats/total-sales-by-month: Obtiene estadísticas sobre ventas totales por mes.

Página 10 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

● GET /stats/total-quantity-by-product: Obtiene estadísticas sobre la cantidad total de ventas por

producto.

● GET /stats/total-sales-with-iva-by-month: Obtiene estadísticas sobre ventas totales con IVA por

mes.

● GET /stats/average-sale-per-customer: Obtiene estadísticas sobre el promedio de ventas por

cliente.

● GET /stats/total-sales-by-customer: Obtiene estadísticas sobre ventas totales por cliente.

API Gateway

Para la implementación de los APIs Gateway se utilizó Spring Cloud Gateway el cual tiene como objetivo

proporcionar una forma sencilla pero eficaz de enrutar a las API y proporcionarles preocupaciones

transversales, como la seguridad, la supervisión/métricas y la resiliencia.

Características de Spring Cloud Gateway:

● Construido sobre Spring Framework y Spring Boot

● Capaz de hacer coincidir rutas en cualquier atributo de solicitud.

● Los predicados y los filtros son específicos de las rutas.

● Integración de disyuntores.

● Predicados y filtros fáciles de escribir

● Limitación de la tasa de solicitudes

● Reescritura de rutas

Página 11 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Los APIs Gateway en el presente caso de estudio tiene una configuración que se basa en la definición de

rutas y predicados que determinan cómo se deben manejar las solicitudes.

API-GW-1: API Gateway para la aplicación web

[Link][0].id = MS-1,
[Link][0].uri = [Link]
[Link][0].predicates[0] = Path=/categories/**, /products/**, /suppliers/**,
[Link][1].id = MS-2,
[Link][1].uri = [Link]
[Link][1].predicates[0] = Path=/sales/**, /customers/**, /movements/**

Ruta para MS-1:

● ID: MS-1 — Identificador de la ruta.

● URI: [Link] — URL de destino para las solicitudes que coincidan con esta ruta.

● Predicados:

o Path=/categories/**, /products/**, /suppliers/** — Las solicitudes que tengan un

camino que empiece con /categories/, /products/, o /suppliers/ se enrutarán a MS-1.

Ruta para MS-2:

● ID: MS-2 — Identificador de la ruta.

● URI: [Link] — URL de destino para las solicitudes que coincidan con esta ruta.

● Predicados:

o Path=/sales/**, /customers/**, /movements/** — Las solicitudes que tengan un camino

que empiece con /sales/, /customers/, o /movements/ se enrutarán a MS-2.

API-GW-2: API Gateway para la aplicación móvil

[Link][0].id = MS-2,
[Link][0].uri = [Link]
[Link][0].predicates[0] = Path=/sales/**, /customers/**, /movements/**,
[Link][0].predicates[1] = Method=GET,
[Link][0].predicates[2] = Header=X-Secret-Code, 1234,
[Link][1].id = MS-3,
[Link][1].uri = [Link]
[Link][1].predicates[0] = Path=/stats/**,
[Link][1].predicates[1] = Method=GET

Ruta para MS-2:

Página 12 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

● ID: MS-2 — Identificador de la ruta.

● URI: [Link] — URL de destino para las solicitudes que coincidan con esta ruta.

● Predicados:

o Path=/sales/**, /customers/**, /movements/** — Las solicitudes que tengan un camino

que empiece con /sales/, /customers/, o /movements/ se enrutarán a MS-2.

o Method=GET — Solo las solicitudes HTTP GET coincidirán con esta ruta.

o Header=X-Secret-Code, 1234 — La solicitud debe tener un encabezado X-Secret-Code con

el valor 1234 para coincidir con esta ruta, este código será conocido únicamente por el

cliente móvil, así evitamos que la web consuma el API Gateway.

Ruta para MS-3:

● ID: MS-3 — Identificador de la ruta.

● URI: [Link] — URL de destino para las solicitudes que coincidan con esta ruta.

● Predicados:

o Path=/stats/** — Las solicitudes que tengan un camino que empiece con /stats/ se

enrutarán a MS-3.

o Method=GET — Solo las solicitudes HTTP GET coincidirán con esta ruta.

A continuación, se muestra el diagrama de la arquitectura con los APIs Gateway implementados:

Página 13 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Página 14 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Despliegue

Los microservicios fueron contenerizados y desplegados en una red privada virtual (VPC) proporcionada

por Contabo. La orquestación de estos servicios se gestionó mediante un archivo docker-compose, que

define la construcción de las imágenes y la configuración de los contenedores. En este archivo se

especifican aspectos como la creación de las imágenes, el levantamiento de los contenedores, la

asignación de volúmenes, los nombres de host y otras configuraciones redes.

version: "3.8"

services:

microservice-1:
container_name: microservice-1
hostname: microservice-1
image: inventory-microservice-1
build:
context: ./microservice-1
dockerfile: Dockerfile
env_file: .env
environment:
SPRING_APPLICATION_JSON: '{
"[Link]" : "8000",
"[Link]" : "jdbc:postgresql://postgres_db:5432/$POSTGRES_DB",
"[Link]" : "$POSTGRES_USER",
"[Link]" : "$POSTGRES_PASSWORD",
"[Link]-class-name" : "[Link]",
"[Link]-platform" : "[Link]",
"[Link]-auto" : "update",
"[Link]" : "[Link]
}'
ports:
- "8101:8000"
depends_on:
- postgres_db

postgres_db:
image: postgres:13.3
restart: unless-stopped
hostname: postgres_db
env_file: .env
environment:
- POSTGRES_USER=$POSTGRES_USER
- POSTGRES_PASSWORD=$POSTGRES_PASSWORD
- POSTGRES_DB=$POSTGRES_DB
ports:
- "5422:5432"
volumes:
- ./volumes/postgres-data:/var/lib/postgresql/data

microservice-2:
container_name: microservice-2
hostname: microservice-2
image: inventory-microservice-2
build:
context: ./microservice-2
dockerfile: Dockerfile
env_file: .env
environment:
SPRING_APPLICATION_JSON: '{
"[Link]" : "8000",
"[Link]" :
"mongodb://$MONGODB_USER:$MONGODB_PASSWORD@mongo_db:27017/$MONGODB_DATABASE?authSource=admin",
"[Link]" : "[Link]

Página 15 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

}'
ports:
- "8102:8000"
depends_on:
- mongo_db

mongo_db:
image: mongo:5.0.2
restart: unless-stopped
hostname: mongo_db
env_file: .env
environment:
- MONGO_INITDB_ROOT_USERNAME=$MONGODB_USER
- MONGO_INITDB_ROOT_PASSWORD=$MONGODB_PASSWORD
ports:
- "27019:27017"
volumes:
- ./volumes/mongo-data:/data/db

microservice-3:
container_name: microservice-3
hostname: microservice-33
image: inventory-microservice-3
build:
context: ./microservice-3
dockerfile: Dockerfile
env_file: .env
environment:
SPRING_APPLICATION_JSON: '{
"[Link]" : "8000",
"[Link]" :
"mongodb://$MONGODB_USER:$MONGODB_PASSWORD@mongo_db:27017/$MONGODB_DATABASE?authSource=admin",
"[Link]" : "[Link]
}'
ports:
- "8103:8000"
depends_on:
- mongo_db

api-gateway-1:
container_name: api-gateway-1
hostname: api-gateway-1
image: inventory-api-gateway
build:
context: ./api-gateway
dockerfile: Dockerfile
env_file: .env
environment:
SPRING_APPLICATION_JSON: '{
"[Link]" : "8000",
"[Link]" : "true",
"[Link][0].id" : "microservice1",
"[Link][0].uri" : "[Link]
"[Link][0].predicates[0]" : "Path=/categories/**, /products/**, /suppliers/**",
"[Link][1].id" : "microservice2",
"[Link][1].uri" : "[Link]
"[Link][1].predicates[0]" : "Path=/sales/**, /customers/**, /movements/**"
}'
ports:
- "8201:8000"
depends_on:
- microservice-1
- microservice-2

api-gateway-2:
container_name: api-gateway-2
hostname: api-gateway-2
image: inventory-api-gateway
build:
context: ./api-gateway
dockerfile: Dockerfile
env_file: .env
environment:
SPRING_APPLICATION_JSON: '{
"[Link]" : "8000",

Página 16 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

"[Link]" : "true",
"[Link][0].id" : "microservice2",
"[Link][0].uri" : "[Link]
"[Link][0].predicates[0]" : "Path=/sales/**, /customers/**, /movements/**",
"[Link][0].predicates[1]" : "Method=GET",
"[Link][0].predicates[2]" : "Header=X-Secret-Code, 1234",
"[Link][1].id" : "microservice3",
"[Link][1].uri" : "[Link]
"[Link][1].predicates[0]" : "Path=/stats/**",
"[Link][1].predicates[1]" : "Method=GET"
}'
ports:
- "8202:8000"
depends_on:
- microservice-2
- microservice-3

networks:
default:
name: inventory-network

Estado de los contenedores:

Funcionamiento

Para probar el funcionamiento de las APIs a través de los API Gateways, se utilizó el estándar OpenAPI

3.0. Esto se implementó mediante una dependencia para Spring, denominada springdoc-openapi, que

permite la generación automática de documentación para las APIs. Esta herramienta facilita la

visualización y prueba de las APIs mediante una interfaz web interactiva, proporcionando detalles sobre

los endpoints, parámetros y respuestas esperadas. Además, asegura que la documentación esté siempre

actualizada y refleje los cambios realizados en las APIs a medida que se desarrollan. Como cliente http

para pruebas se utilizó postman.

Página 17 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

A continuación, se muestra la configuración de las variables que se utilizarían en postman para apuntar

a los Gateways teniendo en cuenta lo demostrado en el diagrama de la arquitectura:

Página 18 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Solicitudes a MS-1 y MS-2 mediante API-GW-1:

Página 19 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Página 20 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Solicitudes a MS-2 y MS-3 mediante API-GW-2:

Página 21 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

En la imagen anterior es normal que no encuentre la ruta ya que se había especificado que en para mapear

las rutas de MS-2 mediante API-GW-2 deben cumplirse dos predicados: la solicitud debe ser del tipo GET

y debe haber un header con un código secreto (X-Secret-Code: 1234), en la siguiente imagen se puede

observar que con la cabecera ya se puede realizar la solicitud

Página 22 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

Conclusiones

● El uso de un API Gateway centraliza la gestión del tráfico entre los clientes y los microservicios,

simplificando el enrutamiento, la autenticación, y la supervisión. Esto reduce la complejidad y

mejora la eficiencia en el manejo de solicitudes.

● La implementación de microservicios junto con un API Gateway permite una mayor escalabilidad

y flexibilidad en el sistema. Los microservicios pueden ser escalados y mantenidos de manera

independiente, y el API Gateway facilita la integración y el enrutamiento sin afectar a los clientes.

● Aunque el API Gateway proporciona beneficios significativos, también introduce desafíos como

el potencial de convertirse en un cuello de botella y la necesidad de una configuración adecuada

para evitar fallos que afecten a todos los servicios. Es crucial gestionar el API Gateway con cuidado

y realizar pruebas exhaustivas para asegurar su fiabilidad y rendimiento.

Recomendación

● Implementa una solución de monitoreo robusta para el API Gateway, como Prometheus y

Grafana, para visualizar el rendimiento y la salud del sistema en tiempo real. Esto permitirá

identificar y solucionar problemas de rendimiento o disponibilidad de manera más efectiva.

● Asegúrate de mantener la documentación de las APIs actualizada y utiliza herramientas como

OpenAPI para la generación automática de documentación. Además, considera implementar un

control de versiones en los endpoints de las APIs para gestionar cambios y evitar interrupciones

en los servicios existentes.

Página 23 de 24
GRUPO 4
ARQUITECTURA DE SOFTWARE

● Refuerza las medidas de seguridad en el API Gateway, implementando autenticación y

autorización adecuadas para proteger los endpoints. Considera usar tokens de acceso,

encriptación y otras prácticas recomendadas de seguridad para prevenir accesos no autorizados.

Bibliografía/ Referencias

[Link]

[Link]

Página 24 de 24
GRUPO 4

También podría gustarte