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

com.adobe.campaign.tests.bridge.service.IntegroAPI Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2022 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it.
 */
package com.adobe.campaign.tests.bridge.service;

import com.adobe.campaign.tests.bridge.service.exceptions.*;
import com.adobe.campaign.tests.bridge.service.utils.ServiceTools;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;

import javax.servlet.MultipartConfigElement;
import javax.servlet.http.Part;
import java.io.File;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static spark.Spark.*;

public class IntegroAPI {
    public static final String ERROR_CALL_TIMEOUT = "The call you made exceeds the set timeout limit.";
    public static final String ERROR_CONTENT_TYPE = "application/problem+json";
    public static final String SYSTEM_UP_MESSAGE = "All systems up";
    public static final String ERROR_IBS_INTERNAL = "Internal IBS error. Please file a bug report with the project and provide this JSON in the report.";
    public static final String ERROR_PAYLOAD_INCONSISTENCY = "We detected an inconsistency in your payload.";
    public static final String UPLOADED_FILE_REF = "uploaded_file";
    public static final String JAVA_CALL_REF = "call_part";
    protected static final String ERROR_JSON_TRANSFORMATION = "JSON Transformation issue : Problem processing request. The given json could not be mapped to a Java Call";
    protected static final String ERROR_CALLING_JAVA_METHOD = "Error during call of target Java Class and Method.";
    protected static final String ERROR_JAVA_OBJECT_NOT_FOUND = "Could not find the given class or method.";
    protected static final String ERROR_IBS_CONFIG = "The provided class and method for setting environment variables is not valid.";
    protected static final String ERROR_IBS_RUNTIME = "Problems with payload.";
    protected static final String ERROR_AMBIGUOUS_METHOD = "No unique method could be identified that matches your request.";
    protected static final String ERROR_JAVA_OBJECT_NOT_ACCESSIBLE = "The java object you want to call is inaccessible. This is very possibly a scope problem.";
    private static final Logger log = LogManager.getLogger();
    public static final String ERROR_BAD_MULTI_PART_REQUEST = "When sending a multi-part request, you need to at least have a payload for the callContent.";
    public static final String STD_UPLOAD_DIR = "upload";

    public static void startServices(int port) {

        if (!ServiceTools.isPortFree(port)) {
            throw new IBSConfigurationException("The port " + port + " is not currently free.");
        }

        IBSPluginManager.loadPlugins();

        if (Boolean.parseBoolean(ConfigValueHandlerIBS.SSL_ACTIVE.fetchValue())) {
            File l_file = new File(ConfigValueHandlerIBS.SSL_KEYSTORE_PATH.fetchValue());
            if (!l_file.exists()) {
                log.error("Could not find the Keystore file path {}", l_file.getAbsolutePath());
            }
            secure(ConfigValueHandlerIBS.SSL_KEYSTORE_PATH.fetchValue(),
                    ConfigValueHandlerIBS.SSL_KEYSTORE_PASSWORD.fetchValue(),
                    ConfigValueHandlerIBS.SSL_TRUSTSTORE_PATH.fetchValue(),
                    ConfigValueHandlerIBS.SSL_TRUSTSTORE_PASSWORD.fetchValue());
        } else {
            port(port);
        }

        get("/test", (req, res) -> {
            res.type("application/json");
            Map status = new HashMap<>();
            status.put("overALLSystemState", SYSTEM_UP_MESSAGE);
            status.put("deploymentMode", ConfigValueHandlerIBS.DEPLOYMENT_MODEL.fetchValue());
            status.put("bridgeServiceVersion", ConfigValueHandlerIBS.PRODUCT_VERSION.fetchValue());

            if (ConfigValueHandlerIBS.PRODUCT_USER_VERSION.isSet()) {
                status.put("hostVersion", ConfigValueHandlerIBS.PRODUCT_USER_VERSION.fetchValue());
            }

            return BridgeServiceFactory.transformMapTosResult(status);
        });

        post("/service-check", (req, res) -> {
            ServiceAccess l_serviceAccess = BridgeServiceFactory.createServiceAccess(req.body());

            return BridgeServiceFactory.transformServiceAccessResult(
                    l_serviceAccess.checkAccessibilityOfExternalResources());
        });

        File uploadDir = new File(STD_UPLOAD_DIR);
        uploadDir.mkdir(); // create the upload directory if it doesn't exist
        //staticFiles.externalLocation("upload");

        post("/call", (req, res) -> {

            boolean isMultiPart = false;
            JavaCalls fetchedFromJSON;

            //Extract multipart information
            if (req.contentType() != null && req.contentType().toLowerCase().startsWith("multipart/form-data")) {
                req.attribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement("./temp"));
                Map fileRefs = new HashMap<>();
                isMultiPart = true;
                //Extract file information
                for (Part p : req.raw().getParts().stream().filter(p -> p.getSubmittedFileName() != null)
                        .collect(Collectors.toList())) {

                    Path tempFile = Files.createTempFile(uploadDir.toPath(), "", "");
                    ThreadContext.put(p.getName(), tempFile.getFileName().toString());
                    fileRefs.put(p.getName(), tempFile);

                    try (InputStream is = p.getInputStream()) {
                        // https://github.com/tipsy/spark-file-upload/blob/master/src/main/java/UploadExample.java
                        Files.copy(is, tempFile, StandardCopyOption.REPLACE_EXISTING);
                    }
                }

                ThreadContext.put(UPLOADED_FILE_REF, String.join(",",
                        fileRefs.values().stream().map(p -> p.getFileName().toString()).collect(Collectors.toList())));

                List l_parts = req.raw().getParts().stream().filter(t -> t.getSubmittedFileName() == null)
                        .collect(Collectors.toList());

                if (l_parts.size() != 1) {
                    throw new IBSPayloadException(
                            ERROR_BAD_MULTI_PART_REQUEST);
                }

                fetchedFromJSON = BridgeServiceFactory.createJavaCalls(
                        new String(l_parts.get(0).getInputStream().readAllBytes(), StandardCharsets.UTF_8));

                //Store file in context
                fileRefs.forEach((k, v) -> fetchedFromJSON.getLocalClassLoader().getCallResultCache().put(k, v.toFile()));

            } else {
                fetchedFromJSON = BridgeServiceFactory.createJavaCalls(req.body());
            }


            fetchedFromJSON.addHeaders(req.headers().stream().collect(Collectors.toMap(k -> k, req::headers)));

            return BridgeServiceFactory.transformJavaCallResultsToJSON(fetchedFromJSON.submitCalls(),
                    fetchedFromJSON.fetchSecrets());
        });

        after((req, res) -> {
            res.type("application/json");
        });

        exception(JsonProcessingException.class, (e, req, res) -> {
            int statusCode = 404;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(
                    new ErrorObject(e, ERROR_JSON_TRANSFORMATION, statusCode)));
        });

        exception(IBSPayloadException.class, (e, req, res) -> {
            int statusCode = 404;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(
                    new ErrorObject(e, ERROR_PAYLOAD_INCONSISTENCY, statusCode)));
        });

        exception(AmbiguousMethodException.class, (e, req, res) -> {
            int statusCode = 404;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(
                    new ErrorObject(e, ERROR_AMBIGUOUS_METHOD, statusCode, false)));
        });

        exception(IBSConfigurationException.class, (e, req, res) -> {
            int statusCode = 500;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(new ErrorObject(e, ERROR_IBS_CONFIG, statusCode)));
        });

        exception(IBSRunTimeException.class, (e, req, res) -> {
            int statusCode = 500;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(new ErrorObject(e, ERROR_IBS_RUNTIME, statusCode)));
        });

        exception(TargetJavaMethodCallException.class, (e, req, res) -> {
            int statusCode = 500;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(
                    new ErrorObject(e, ERROR_CALLING_JAVA_METHOD, statusCode)));
        });

        exception(NonExistentJavaObjectException.class, (e, req, res) -> {
            int statusCode = 404;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(
                    new ErrorObject(e, ERROR_JAVA_OBJECT_NOT_FOUND, statusCode, false)));
        });

        exception(JavaObjectInaccessibleException.class, (e, req, res) -> {
            int statusCode = 404;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(
                    new ErrorObject(e, ERROR_JAVA_OBJECT_NOT_ACCESSIBLE, statusCode, false)));
        });

        exception(IBSTimeOutException.class, (e, req, res) -> {
            int statusCode = 408;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(
                    new ErrorObject(e, ERROR_CALL_TIMEOUT, statusCode, false)));
        });

        //Internal exception
        exception(Exception.class, (e, req, res) -> {
            int statusCode = 500;
            res.status(statusCode);
            res.type(ERROR_CONTENT_TYPE);
            res.body(BridgeServiceFactory.createExceptionPayLoad(new ErrorObject(e, ERROR_IBS_INTERNAL, statusCode)));
        });

        afterAfter((req, res) -> {
            if (ThreadContext.containsKey(UPLOADED_FILE_REF)) {
                Arrays.stream(ThreadContext.get(UPLOADED_FILE_REF).split(",")).forEach(f -> {
                    log.debug("Cleaning up file {}. succeeded {}.", f, (new File(uploadDir.getName(), f)).delete());
                });

            }
        });
    }

    protected enum DeploymentMode {
        TEST, PRODUCTION
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy