All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.ipe.ble.irp.handler.services.HttpDestinationService Maven / Gradle / Ivy

package com.sap.ipe.ble.irp.handler.services;

import com.sap.cds.reflect.CdsAnnotation;
import com.sap.cloud.sdk.cloudplatform.connectivity.*;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException;
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceConfiguration;
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorator;
import com.sap.ipe.ble.irp.exceptions.ExtensionException;
import com.sap.ipe.ble.irp.handler.constants.Constants;
import com.sap.ipe.ble.irp.utils.Translator;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.Callable;

/***
 * HttpDestinationService is used to call the remote destination service configured and
 * Execute the HTTP Post call based on the client
 */
@Service
public class HttpDestinationService {
    @Autowired
    @Qualifier("destLoader")
    DestinationService destinationLoader;

    @Autowired
    @Qualifier("destOptions")
    DestinationOptions destinationOptions;

    @Autowired
    @Qualifier("resilience")
    ResilienceConfiguration resilienceConfiguration;

    private static final String CLASSNAME = "DestinationService";

    private final Logger log = LoggerFactory.getLogger(CLASSNAME);

    private DefaultHttpClientFactory getClientFactory() {
        return new DefaultHttpClientFactory() {
            @Override
            protected HttpClientBuilder getHttpClientBuilder(
                    HttpDestinationProperties destination) {
                return super.getHttpClientBuilder(destination)
                        .setMaxConnTotal(Constants.MAX_CONNECTION_TOTAL)
                        .setMaxConnPerRoute(Constants.MAX_CONNECTION_PER_ROUTE);
            }
        };
    }

    private HttpDestination getCachedDestination(String destinationName) throws ExtensionException{
        try {
            return destinationLoader
                    .tryGetDestination(destinationName, destinationOptions)
                    .getOrElseThrow(throwable -> {
                        if (throwable.getCause() instanceof DestinationAccessException) {
                            return new DestinationAccessException(throwable.getCause());
                        }
                        return (Exception) throwable;
                    })
                    .asHttp();
        }
        catch (Exception exception){
            log.error(Constants.DESTINATION_ERROR + exception.getLocalizedMessage());
            throw new ExtensionException(Translator.toLocale(Constants.DESTINATION_NOT_FOUND));
        }
    }

    private HttpResponse executeHttpPOST(HttpClient client, HttpPost httpPost, int timeOutConfig) throws ExtensionException{
        HttpResponse httpResponse;
        try {
            httpResponse = (HttpResponse) ResilienceDecorator.executeCallable(
                    (Callable) () ->
                            client.execute(httpPost), resilienceConfiguration
                            .timeLimiterConfiguration(ResilienceConfiguration.TimeLimiterConfiguration.of()
                                    .timeoutDuration(Duration.ofMillis(timeOutConfig))));
        }
        catch (Exception exception){
            log.error(Constants.HTTP_POST_ERROR + exception.getLocalizedMessage());
            if (exception.getMessage().contains(Constants.TIME_OUT_EXCEPTION_MESSAGE)) {
                throw new ExtensionException(Translator.toLocale(Constants.TIMEOUT_EXCEPTION));
            }
            else{
                throw new ExtensionException(Translator.toLocale(Constants.PROCESS_REQUEST_ERROR));
            }
        }
        return httpResponse;
    }

    /***
     * This method is used to call the destination and client factory
     * Based on the client information, an HTTP Post call is triggered
     * @param timeOutConfig timeout annotation defined by the user
     * @param payload the data from the application
     * @param destination destination defined in the BTP
     * @return httpResponse based on the post call
     * @throws ExtensionException custom exception defined
     */
    public HttpResponse callRemoteExtension(int timeOutConfig, String payload, Optional> destination) throws ExtensionException {
        HttpDestination httpDestination;
        String destinationName;
        String url;
        HttpResponse httpResponse;
        DefaultHttpClientFactory customFactory;
        HttpClient client;
        HttpPost httpPost;

        // Get the destination name and cache the destination
        destinationName = destination.get().getValue().toString();
        httpDestination = getCachedDestination(destinationName);

        //execute HttpPost call
        customFactory = getClientFactory();
        client = customFactory.createHttpClient(httpDestination);
        url = httpDestination.getUri() + Constants.REMOTE_SERVICES_URL;

        // Send the data
        httpPost = new HttpPost(url);
        httpPost.setHeader(Constants.ACCEPT, Constants.APPLICATION_JSON);
        httpPost.setHeader(Constants.CONTENT_TYPE, Constants.APPLICATION_JSON);
        StringEntity httpPayload = new StringEntity(payload, StandardCharsets.UTF_8);
        httpPost.setEntity(httpPayload);

        httpResponse = executeHttpPOST(client, httpPost, timeOutConfig);
        return httpResponse;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy