Files
java-design-patterns/localization/es/ambassador/README.md
T
Luis Mateo Hincapié Martinez dc7495e8bd translation: Translated all creational patterns category to Spanish (Task of issue #2277) (#2813)
* Typo corrections

* bridge pattern translated to spanish

* builder pattern translated to spanish

* context-object pattern translated to spanish

* converter pattern translated to spanish

* dependency injection pattern translated to spanish

* factory pattern translated to spanish

* factory-kit pattern translated to spanish

* factory-method pattern translated to spanish

* monostate pattern translated to spanish

* multiton pattern translated to spanish

* object mother pattern translated to spanish

* object pool pattern translated to spanish

* property pattern translated to spanish

* prototype pattern translated to spanish

* registry pattern translated to spanish

* step builder pattern translated to spanish

* value object pattern translated to spanish

* typo corrections and resources urls refactor

* grammar corrections

* Add image to each pattern

---------

Co-authored-by: luismateoh <luismateohm@gmail.com>
Co-authored-by: luis.hincapie <luis.hincapie@blankfactor.com>
2024-03-23 11:53:54 +02:00

209 lines
6.4 KiB
Markdown

---
title: Ambassador
category: Structural
language: es
tag:
- Decoupling
- Cloud distributed
---
## Propósito
Proporcionar una instancia de servicio auxiliar a un cliente y delegar en ella las funcionalidades comunes de un recurso compartido.
## Explicación
Ejemplo real
> Un servicio remoto tiene muchos clientes accediendo a una función que este servicio proporciona. El servicio es una aplicación heredada y
> es imposible actualizarla. Un gran número de solicitudes por parte de los usuarios están causando problemas de conectividad. Nuevas reglas
> respecto a la frecuencia de solicitudes deberían implementarse junto con comprobaciones de latencia y registros del lado del cliente.
En otras palabras
> Con el patrón Ambassador, podemos implementar una menor frecuencia en solicitudes de clientes junto con comprobaciones de latencia y
> registros.
Según la Documentación de Microsoft
> Un servicio de Ambassador puede considerarse como un proxy fuera de proceso que coexiste con el cliente.
>
> Este patrón puede ser útil para la descarga de tareas comunes de conectividad de cliente, como la supervisión, el registro, el enrutamiento,
> la seguridad (por ejemplo, TLS) y los patrones de resistencia(*) de una manera independiente del lenguaje. A menudo se utiliza con aplicaciones heredadas,
> u otras aplicaciones que son difíciles de modificar, con el fin de ampliar sus capacidades de red. También puede
> habilitar un equipo especializado para implementar esas características.
**Código de ejemplo**
Con la introducción anterior en mente vamos a imitar su funcionalidad en el siguiente ejemplo. Tenemos una interface implementada
por el servicio remoto así como el servicio ambassador:
```java
interface RemoteServiceInterface {
long doRemoteFunction(int value) throws Exception;
}
```
Un servicio remoto representado como un singleton (Instancia única).
```java
@Slf4j
public class RemoteService implements RemoteServiceInterface {
private static RemoteService service = null;
static synchronized RemoteService getRemoteService() {
if (service == null) {
service = new RemoteService();
}
return service;
}
private RemoteService() {}
@Override
public long doRemoteFunction(int value) {
long waitTime = (long) Math.floor(Math.random() * 1000);
try {
sleep(waitTime);
} catch (InterruptedException e) {
LOGGER.error("Thread sleep interrupted", e);
}
return waitTime >= 200 ? value * 10 : -1;
}
}
```
Un servicio ambassador añadiendo funcionalidades adicionales como registros, comprobación de latencia
```java
@Slf4j
public class ServiceAmbassador implements RemoteServiceInterface {
private static final int RETRIES = 3;
private static final int DELAY_MS = 3000;
ServiceAmbassador() {
}
@Override
public long doRemoteFunction(int value) {
return safeCall(value);
}
private long checkLatency(int value) {
var startTime = System.currentTimeMillis();
var result = RemoteService.getRemoteService().doRemoteFunction(value);
var timeTaken = System.currentTimeMillis() - startTime;
LOGGER.info("Time taken (ms): " + timeTaken);
return result;
}
private long safeCall(int value) {
var retries = 0;
var result = (long) FAILURE;
for (int i = 0; i < RETRIES; i++) {
if (retries >= RETRIES) {
return FAILURE;
}
if ((result = checkLatency(value)) == FAILURE) {
LOGGER.info("Failed to reach remote: (" + (i + 1) + ")");
retries++;
try {
sleep(DELAY_MS);
} catch (InterruptedException e) {
LOGGER.error("Thread sleep state interrupted", e);
}
} else {
break;
}
}
return result;
}
}
```
Un cliente tiene un servicio ambassador local usado para interactuar con el servicio remoto:
```java
@Slf4j
public class Client {
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
long useService(int value) {
var result = serviceAmbassador.doRemoteFunction(value);
LOGGER.info("Service result: " + result);
return result;
}
}
```
A continuación dos clientes usando el servicio.
```java
public class App {
public static void main(String[] args) {
var host1 = new Client();
var host2 = new Client();
host1.useService(12);
host2.useService(73);
}
}
```
Esta es la salida que obtendremos tras ejecutar el ejemplo:
```java
Time taken (ms): 111
Service result: 120
Time taken (ms): 931
Failed to reach remote: (1)
Time taken (ms): 665
Failed to reach remote: (2)
Time taken (ms): 538
Failed to reach remote: (3)
Service result: -1
```
## Diagrama de clase
![alt text](./etc/ambassador.urm.png "Ambassador class diagram")
## Aplicaciones
Ambassador es aplicable cuando trabajamos con un servicio remoto heredado que no puede ser modificado o que sería extremamente
difícil de modificar. Las características de conectividad pueden implementarse en el cliente sin necesidad de realizar cambios en el servicio
remoto.
* Ambassador proporciona una interface local para un servicio remoto.
* Ambassador proporciona registros, interrupción de circuitos, reintentos y seguridad en el cliente.
## Casos de uso típicos
* Control de acceso a otro objeto
* Implementación de registros o logs
* Implementación de interrupciones de circuito
* Delegar tareas de servicios remotos
* Facilitar la conexión a la red
## Usos conocidos
* [Pasarela API Kubernetes-native para microservicios](https://github.com/datawire/ambassador)
## Patrones relacionados
* [Proxy](https://java-design-patterns.com/patterns/proxy/)
## Créditos
* [Ambassador Pattern (Documentación de Microsoft en inglés)](https://docs.microsoft.com/en-us/azure/architecture/patterns/ambassador)
* [Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services](https://www.amazon.com/s?k=designing+distributed+systems&sprefix=designing+distri%2Caps%2C156&linkCode=ll2&tag=javadesignpat-20&linkId=a12581e625462f9038557b01794e5341&language=en_US&ref_=as_li_ss_tl)
## Notas del traductor
(*) La versión original en inglés de la documentación de Microsoft hace referencia al término resiliencia y
en su traducción al español lo traduce como resistencia, aunque enlaza al apartado patrones de confiabilidad. Véase:
* [Versión de la Documentación para el Patrón Ambassador de Microsoft en español.](https://learn.microsoft.com/es-es/azure/architecture/patterns/ambassador)