Saltar al contenido

Cambiar una aplicación existente a la versión 3.0 del SDK de Cloud

Si miras de cerca el CreateAddressCommands 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.

  1. Mueve el ErpHttpDestination introdujimos la fase 2 de CreateAddressCommand a la AddressServlet:

    private final ErpHttpDestination destination = ErpHttpDestinationUtils.getErpHttpDestination("ERP_SYSTEM");
    
  2. I AddressServlet navegar hasta el CreateAddressCommand(service, address).execute() llamar adentro doPost() y reemplácelo para usar la configuración de resiliencia ahora:

    final BusinessPartnerAddress addressCreated = ResilienceDecorator.executeCallable(
                    () -> service.createBusinessPartnerAddress(address).execute(destination),
                    resilienceConfiguration);
    
  3. 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) {
           // ...
       }
   }
}

Hecho

Inicie sesión para responder la pregunta