Si miras de cerca el CreateAddressCommand
s constructor encontrará la siguiente declaración agregada en el mismo:
withExecutionTimeoutInMilliseconds(10000)
Establece un límite de tiempo para nuestra solicitud de 10 segundos y es solo una parte de un intento de hacer que la solicitud sea resistente contra fallas. Con 3.0 esto ya no se hace por extensión ErpCommand
o CachingErpCommand
pero intentando volver con ResilienceConfiguration
.
Considere el siguiente código:
private final TimeLimiterConfiguration timeLimit = TimeLimiterConfiguration.of()
.timeoutDuration(Duration.ofSeconds(10));
private final ResilienceConfiguration resilienceConfiguration =
ResilienceConfiguration.of(AddressServlet.class)
.timeLimiterConfiguration(timeLimit);
Establece una ResilienceConfiguration
que mantiene todos los parámetros y la configuración necesarios para ejecutar aplicaciones resistentes. Uno de ellos es el límite de tiempo definido en un TimeLimiterConfiguration
que luego se agrega al ResilienceConfiguration
.
Aquí volvemos a establecer el límite de tiempo en 10 segundos. Por supuesto, la configuración permite ajustar más parámetros. Aquí vamos con los valores predeterminados (en lugar del límite de tiempo), pero siéntase libre de ver lo que se proporciona en su totalidad guía de migración. Por último, pero no menos importante, observe el of(AddressServlet.class)
parte que crea la configuración de resiliencia. El nombre de la clase solo se utiliza aquí como identificador. Puede proporcionar su propio identificador de transferencia si lo desea.
Una configuración de este tipo puede adjuntarse a cualquier solicitud que se realice de manera flexible. Esto no solo permite un ensamblaje claro de las propiedades deseadas, sino que también reutiliza la configuración. Se puede usar una configuración con múltiples solicitudes.
Así que agregue el código anterior al AddressServlet
casi donde se define el servicio.
Ahora veremos cómo podemos usar la configuración en nuestras aplicaciones. Nuevamente, primero comprendamos el código:
final BusinessPartnerAddress addressCreated = ResilienceDecorator.executeCallable(
() -> service.createBusinessPartnerAddress(address).execute(destination),
resilienceConfiguration);
Como puede ver, en lugar de llamar al servicio directamente, ahora envolvemos la llamada a través del ResilienceDecorator
. Proporcionamos nuestra solicitud inicial como se llama junto con el resilienceConfiguration
que acabamos de crear. Y eso es. El ilustrador se encarga de manejar la solicitud de la manera flexible que configuramos anteriormente.
Así que juntemos las piezas individuales y adaptemos toda la solicitud.
-
Mueve el
ErpHttpDestination
introdujimos la fase 2 deCreateAddressCommand
a laAddressServlet
:private final ErpHttpDestination destination = ErpHttpDestinationUtils.getErpHttpDestination("ERP_SYSTEM");
-
I
AddressServlet
navegar hasta elCreateAddressCommand(service, address).execute()
llamar adentrodoPost()
y reemplácelo para usar la configuración de resiliencia ahora:final BusinessPartnerAddress addressCreated = ResilienceDecorator.executeCallable( () -> service.createBusinessPartnerAddress(address).execute(destination), resilienceConfiguration);
- Por último, pero no menos importante, elimine el
CreateAddressCommand
toda la clase.
Eso es correcto, no el CreateAddressCommand
más clase. En lugar de heredar siempre ErpCommand
en una clase de comando dedicada ahora podemos construir y ejecutar nuestra aplicación en una sola línea de código. El es ResilienceDecorator
él se encarga del trabajo pesado por nosotros.
Con eso, logramos mover nuestra aplicación resistente a la versión 3.0. Ahora puede aplicar lo que ha aprendido y probarlo a través del UpdateAddressCommand
y DeleteAddressCommand
del mismo modo. Para este último, tome el addressToDelete
necesidades deleteBusinessPartnerAdrdress
directamente en el servlet. Si desea pasar directamente a la siguiente sección, copie las secciones relevantes a continuación o vuelva más tarde para personalizar los comandos.
Al final de esta etapa, el AddressServlet
esto debería verse así (el código se ha acortado para ver qué ha cambiado):
package com.sap.cloud.s4hana.examples.addressmgr;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.io.CharStreams;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import org.slf4j.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Duration;
import com.sap.cloud.s4hana.examples.addressmgr.util.HttpServlet;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceConfiguration;
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceConfiguration.TimeLimiterConfiguration;
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorator;
import com.sap.cloud.sdk.s4hana.connectivity.ErpHttpDestination;
import com.sap.cloud.sdk.s4hana.connectivity.ErpHttpDestinationUtils;
import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.BusinessPartnerAddress;
import com.sap.cloud.sdk.s4hana.datamodel.odata.services.BusinessPartnerService;
import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultBusinessPartnerService;
@WebServlet("/api/addresses")
public class AddressServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = CloudLoggerFactory.getLogger(AddressServlet.class);
private final BusinessPartnerService service = new DefaultBusinessPartnerService();
private final ErpHttpDestination destination = ErpHttpDestinationUtils
.getErpHttpDestination("ERP_SYSTEM");
private final TimeLimiterConfiguration timeLimit = TimeLimiterConfiguration.of()
.timeoutDuration(Duration.ofSeconds(10));
private final ResilienceConfiguration resilienceConfiguration =
ResilienceConfiguration.of(AddressServlet.class)
.timeLimiterConfiguration(timeLimit);
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
// ...
logger.info("Received post request to create address {}", address);
try {
final BusinessPartnerAddress addressCreated = ResilienceDecorator.executeCallable(
() -> service.createBusinessPartnerAddress(address).execute(destination),
resilienceConfiguration);
response.setStatus(HttpServletResponse.SC_CREATED);
response.setContentType("application/json");
response.getWriter().write(new Gson().toJson(addressCreated));
} catch (Exception e) {
// ...
}
}
// ...
@Override
protected void doPatch(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
// ...
final BusinessPartnerAddress addressToUpdate = createAddressToUpdate(businessPartnerId, addressId, addressFromBody);
logger.info("Received patch request to update address {}", addressToUpdate);
try {
ResilienceDecorator.executeCallable(
() -> service.updateBusinessPartnerAddress(addressToUpdate).execute(destination),
resilienceConfiguration);
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
} catch (Exception e) {
// ...
}
}
// ...
@Override
protected void doDelete(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
// ...
logger.info("Received delete request to delete address {},{}", businessPartnerId, addressId);
final BusinessPartnerAddress addressToDelete = BusinessPartnerAddress.builder()
.businessPartner(businessPartnerId)
.addressID(addressId)
.build();
try {
ResilienceDecorator.executeCallable(
() -> service.deleteBusinessPartnerAddress(addressToDelete).execute(destination),
resilienceConfiguration);
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
} catch (Exception e) {
// ...
}
}
}