====== Java enterprise edition ======
Cada proceso de un servidor de aplicaciones tiene dos contenedores (como weblogic, jboss, websphere):
* 1.- Contenedor web
* Se pueden utilizar protocolos http y https
* Se usan servlets, java server pages, struts, jsf, adf (frameworks del contenedor web)
* Se despliegan los war
* 2.- Contenedor ejb
* Se usa el protocolo rmi
* Se despliegan los jar
Un ear es un compendio entre un war y un jar para poder desempaquetarlos juntos.
Se pueden hacer servlets basados en otros protocolos como ftp. Todos heredan de httpservlet (o el que corresponda).
Los jsp se pasan a java y luego se compilan como si fuera otro servlet.
Los controladores son servlets, y las vistas son jsp o jspx, facelet (no se permite utilizar java)
Tomcat únicamente implementa los contenedores web, no implementan los ejb. Existe TomEE que incorpora el contenedor de ejb
EJB:
* Session beans(1)
* Lógica de negocio reutilizable
* Pueden ser:
* - Stateless (no se recuerda otras peticiones ni dos hilos de ejecución a dos métodos en el mismo objeto)
* - Stateful (recuerda las peticiones y pertenece a cada cliente)
* - Singleton (todos los usuarios de la app reciben la referencia de la misma instancia. Puede haber varios usuarios accediendo a la vez)
Para el patrón "session facade" se utilizan beans del tipo stateless
Una aplicación enterprise (corporativa) permite el acceso al modelo (ejb) por más d eun interfaz (web, aplicación de escritorio...)
* message driven beans(2)
(2) jms => servicios de mensajería de java. Se separan completamente productores de consumidores, permitiendo un modelo de comunicación asíncrono @MessageDriven
Dentro de los servidores de aplicaciones se implementa un servicio de nombres(jndi). Se asocian con una clave
====== Arquitecturas monolíticas vs arqutiectura distribuida ======
Si está empaquetado en un paquete, totalmente acoplada es monolítica. La capa de interfaz de usuario y de acceso a datos está acopladas en una misma plataforma y programa. La comunicación es local y es más rápida que en la versión distribuida. La aplicación resultante es independiente, pero sus componentes tienen un acoplamiento muy fuerte.
===== Arquitectura de N capas =====
Separación de los componentes volátiles de los estables.
Capa de presentación: Servlets, jsp, struts
Capa de negocio: ejbs
Capa de integración: dao o jpa
===== Problemas de una aplicación monolítica =====
* El tamaño de la aplicación dificulta su comprensión
* Cualquier cambio en el software hace falta una nueva versión
* Es difícil de escalar
* El despliegue es complejo
===== Arquitecturas distribuídas =====
Distribución basada en componentes, desplegados en diferentes procesos
* Necesaria la transparencia de ubicación
* Concurrencia soportada por la arquitectura
* Compartición de recursos
* La comunicación entre componentes es remota (implica más lentitud)
* Se requiere un sistema de llamadas estables
* En el modelo SOAP con cada cambio implica recompilar y cambiar los clientes
* En el modelo REST pueden coexistir diferentes versiones del servicio al mismo tiempo
===== Arquitectura orientada a servicios =====
Cada componente de la aplicación se modela como un servicio independiente, coordinados entre intercambios de mensajes
Cada servicio debe tener las siguiente propiedades:
* Cada servicio debe representar una actividad de negocio
* Los servicios no tienen estado
* Tienen bajo acoplamiento
* Todo se orquesta mediante Enterprise Service Bus (está centralizado) o Service Mesh (está distribuído).
* Hay pocas llamadas que retornan mucha información.
* Los cambios de versión afectan al sistema (está pensado para SOAP)
===== Arquitectura basada en microservicios =====
Enfoque para llevar aplicaciones a gran escala. Crea infraestructuras más flexibles y adaptables. Cada microservicio se puede utilizar en su propio proceso y con su propia base de datos.
* Hay muchas llamadas con poca información
* Se utiliza REST.
* Diferentes versiones del servicio pueden coexistir
* La traza de logs se debería centralizar en un solo repositorio
===== Diseño de una aplicación basada en microservicios =====
* Proporciona una infraestructura enfocada en la innovación continua y agilidad
* Es posible recomponer servicios
* Cada microservicio puede ser tecnológicamente independiente
* Existen estándares como RAML (RestFUl API Modeling Language)
* Service to service: Mediante HTTP, TCP, gRPC
* Comunicación asíncrona: Mediante eventos (Apache kafka, RabiitMQ, AWS...)
Estrategias de transición:
* Ice cream scoop: ir dando cucharadas a la aplicación monolítica y pasarla a microservicios. Es fundamental la rotación entre el equipo y es lento
* Lego: capa de microservicios por encima del monolito. El problema es que el monolito tiene que seguir coexistiendo con el resto del código
* Nuclear option: Reescribir la aplicación completamente.
Se prefiere empezar con una versión monolítica y a partir de ahí separar en microservicios.
La capa de acceso a datos también deberá desacoplarse.
Cada microservicio debería tener su propio repositorio de datos. Un servicio como Apache Kafka puede propagar los cambios. Cada microservicio es accesible mediante un API, y son agnósticos a cómo son implementados internamente.
====== Modelo SOAP ======
Estan pensados para enviar y recibir xml.
WSDL Es un formato xml estándar (Lenguaje de descripción del servicio web). Se encuentran los mensajes que se pueden usar, tipos de datos y operaciones.
* Mensaje
* Partes (las estructuras complejas tienen un esquema a parte)
* Operaciones
* Endpoint
UDDI (Interfaz de directorios y descubrimiento universal)
SOAP Establece unas etiquetas xml y las manda en el body de la petición. Sobre http/https
====== Modelo RESTFul ======
transferencia del estado representacional de un recurso. Es mucho más ligero. La idea es "ir tirando del hilo". Es más rápido de implementar. El contenido de los mensajes no está especificado. Se puede enviar cualquier tipo de información. No estamos obligados a usar json. No hay estándares.
===== Operaciones CRUD =====
* GET: Recupera información
* POST: Añadir información (No es idempotente)
* PUT: Actualizar información o creación de recursos con un id conocido (es idempotente)
* DELETE: Borra un elemento
===== Exponer ficheros planos en java con spring boot =====
en el directorio src/main/resources/static están expuestos automáticamente
====== Domain Driven design ======
Libro Domain-driven Design: Tackling Coplexity in the Heart of the Sofware(2003) - Eric Evans.
Evitar realizar traducciones del lenguaje entre usuario y programadores
Se trata de conseguir un profundo conocimiento del dominio hasta conseguir un lenguaje común, durante toda la vida del proyecto. Lo fundamental es resolver un problema de dominio para los usuarios.
Si la comunicación oral se interrumple entre participantes, el conocimiento se pierde.
* Contexto: Configuración en la que una palabra o etiqueta tiene significado.
* Modelo: Sistema de abstracciones que describe aspectos de un dominio.
* Ubiquitous Language (Lenguaje común)
* Bounded Context: Descripción de un límite en el que se aplica un modelo particular
* Entidad: Objeto que se identifica por un identificador único, independientemenet del resto de valores.
* Objeto de valor:
* Evento de dominio: Objeto que se utiliza para registrar un evento de una actividad.
* Agregado: Cluster de objetos de valor o entidades.
* Servicio: Una operación de negocio que no encaja en los objetos anteriores.
* Repositorio: Servicio que permite el acceso a las entidades y objetos de valor dentro de un agregado.
* Fábricas: Encapsulan la lógica de la creación de objetos.
===== Event Sourcing =====
En lugar de modelar las entidades de negocio con un estado, se modelan como secuencias de eventos inmutables. Ejemplo una cuenta bancaria.
===== CQRS (Command-Query Responsibility Segregation) =====
Separación de las responsabilidades entre comandos y consultas. Ambos modelos son diferentes. Lecturas rápidas, pero sistema complejo. Con este patrón se utilizará event sourcing para la escritura.
(Ver Martin Fowler)
http://www.methodsandtools.com/archive/archive.php?id=97
https://khalilstemmler.com/articles/typescript-domain-driven-design/entities/
https://dzone.com/articles/ddd-part-ii-ddd-building-blocks
http://dddsample.sourceforge.net/architecture.html
https://medium.com/@jonathanloscalzo/domain-driven-design-principios-beneficios-y-elementos-primera-parte-aad90f30aa35
https://martinfowler.com/eaaDev/EventSourcing.html
https://martinfowler.com/eaaDev/EventSourcing.html
https://martinfowler.com/bliki/CQRS.html
===== Spring Boot =====
Herramienta que nace con la finalidad de simplificar el desarrollo de Spring Core.
Crear proyecto con maven o gradle
**Crear en la aplicación**
Empaquetar y desplegar la aplicación
* Configuración automática
* Resolución de dependencias
* Despliegue standalone y en contenedores integrados
* Métricas. SpringBoot proporciona métricas (actuators) para consultar el estado de la aplicación
* Extensible mediante plugins
@Restcontroller
Una clase se puede utilizar desde SpringMVC y puede recibir peticiones web
@RequestMapping asigna el patrón de la ulr con el método sobre el que se aplica. anotación @Controller y @ResponseBody
@SpringBootApplication es lo mismo que usar
* @Configuration Marca la clase como origen de definiciones de beans
* @EnableAutoConfiguration Indica a SpringBoot que comience a añadir beans basándose en la configuración de claspath
* @ComponentScan Indica a Spring que busque otros componentes en el mismo paquete
No hay ficheros de configuración. Únicamente anotaciones.
./mvnw package => Crea el paquete
Añadir dependencia spring-boot-starter-test del pom
./mvnw spring-boot:run => Ejecuta la aplicación
java -jar target/gs-spring-boot-0.1.0.jar => ejecuta la aplicación
==== Test Driven Development ====
Añadiendo la dependencia spring-boot-starter-test hace que todas las clases que acaben en Test sean candidatos para examinar los métodos de tests que tiene dentro. Esté en el paquete que esté
La anotación @Test marca que el método se tiene que ejecutar como test
@RunWith(SpringRunner.class) dentro de la anotación de junit se crea un puente entre los tests de SpringBoot y Junit
@SpringBootTest carga todo el contexto de spring para los tests
@AutoConfigureMockMvc configura los mocks
MockMvc proviene de SpringTest. Envia solicitudes HTTP al DispatcherServlet y hacer assert
@SpringBootTest(webEnvironment = SprinbBootTest.webEnvironment.RANDOM_PORT)
unido a @LocalServerPort levanta un servidor de spring en un puerto aleatorio
Dependencia spring-boot-starter-actuator lo que hace es habilitar urles para hacer comprobaciones. Escribir localhost:8080/actuator y aparecen checks. Algunos hay que activar de manera manual
==== En eclipse ====
Spring Tools 4 (aka Spring Tool Suite 4)
https://start.spring.io/
Tests utilizados por BDD Behavior-Driven Development
El @Autowired se puede aplicar a un método. Entonces lo que hace es inyectar dependencias en los argumentos
Para lanzar los tests:
mvnw -Dtest=MultiplicationServiceTest test
Se encarga de pasar los tests desde línea de comandos
El contexto de aplicación de tests de Spring se crea una vez por aplicación, no por cada test
@RequiredArgsConstructor genera un constructor con los parámetros finales o con restricciones @NotNull
@Override en un método es una ayuda visual para el programador
@RestController declara la clase para servicios rest
Cada método de esa clase se puede anotar con el tipo. @GetMapping equilave a @RequestMapping(method=RequestMethod.GET)
@WebMvcTest iniciará el contexto de la aplicación wewb. Sólo carga la capa de controladores
@MockBean indica a Spring
@NoArgsConstructor(force=true) inicializa todos los valores a nulo, vacío o 0
@Entity asocia el nombre de una clase al de una tabla
@GeneratedValue genera automáticamente un valor para el id
@Column(name= "xxx") establece el nombre de un campo en bbdd a un atributo en java
@RequestBody se utiliza para recibir los datos de una petición dentro del cuerpo de la petición
@Param se utiliza para recibir los datos de una petición como argumento
@PathVariable se utiliza para recibir los datos de una petición dentro de la url
Para utilizar estas etiquetas hay que declarar las siguientes dependencias en el fichero pom como alternativa a utilizar las dependencias de spring boot
org.springframework
spring-webmvc
5.2.1.RELEASE
org.springframework
spring-web
5.2.1.RELEASE
com.fasterxml.jackson.core
jackson-databind
2.9.8
=== Proyecto web ===
Para poder crear una aplicación que escuche conexiones hay que añadir la dependencia
org.springframework.boot
spring-boot-starter-web
Para poder lanzar un servidor tomcat embebido hay que añadir la siguiente dependencia. Esta dependencia no es necesaria si únicamente se quiere tener un servidor web
org.springframework.boot
spring-boot-starter-tomcat
=== Entity ===
Para poder utilizar la anotación @Entity hay que añadir la dependencia
org.springframework.boot
spring-boot-starter-data-jpa
====== Arquitectura basada en eventos ======
Event driven arquitecture. Los microservicios intercambian mensajes entre sí cada vez que ocurre alguna acción relevante.
Se intercambian mediante un bus de eventos (event bus)
Los servicios se suscriben a los eventos y reaccionan con ellos.
Los eventos son acciones que ya han ocurrido, por ello los nombres son de acciones pasadas.
CQRS => operaciones de escrituras en eventos y lecturas síncronas?
Proporciona un acomplamiento débil.
No se utilizan transacciones ACID. En su lugar hay consistencia eventual.
===== RabbitMQ =====
Servidor de mensajería que se integra con Spring Boot. Implementa AMQP (Advanced Message Quering Poll)
==== Exchange ====
Canal al que enviar mensajes (el topic de mqtt)
Los topic no son persistentes.
Cada microservicio crea su propia cola. No existe topic central (diferencia con JMS)
==== Spring AMQP ====
Crea desde Java el topic exchange y la cola. No hay servicios centrales.
Los servicios no pueden asumir que el servicio estará
@Slf4j es una fachada común para usar los logs.
Jetty es un servidor web y de aplicaciones de Eclipse. Al estilo Tomcat
====== Descubrimiento de servicios ======
Consul o Eureka (Stack de Netflix OSS)
Service Registry
Register Agent
Service Discovery Client
====== Balanceo de carga ======
Eureka y Ribbon
https://tdp.io/lb-opts
====== Enrutamiento con API Gateway ======
Zuul
====== Patrón circuit breaker ======
Evita que fallos de un componente aislado provoque un fallo total en el sistema
Hystrix