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

com.manywho.sdk.RunService Maven / Gradle / Ivy

There is a newer version: 1.25.0
Show newest version
package com.manywho.sdk;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import com.google.common.base.Predicate;
import com.manywho.sdk.entities.draw.flow.FlowResponse;
import com.manywho.sdk.entities.draw.flow.FlowResponseCollection;
import com.manywho.sdk.entities.run.*;
import com.manywho.sdk.entities.run.elements.config.ListenerServiceResponse;
import com.manywho.sdk.entities.run.elements.config.ServiceResponse;
import com.manywho.sdk.entities.security.AuthenticatedWho;
import com.manywho.sdk.entities.security.AuthenticationCredentials;
import com.manywho.sdk.enums.InvokeType;
import com.manywho.sdk.exceptions.ManyWhoException;
import com.manywho.sdk.services.notifications.Notifier;
import com.manywho.sdk.utils.AuthorizationUtils;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.request.HttpRequestWithBody;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

// @todo Add notifier stuff to these methods
public class RunService {
    private static final Set STATUSES_SUCCESS = new HashSet(Arrays.asList(
        new Integer[] {200, 201, 202, 203, 204, 205, 206, 207, 208, 226}
    ));

    private String baseUrl = "https://flow.manywho.com";

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public AuthenticatedWho login(Notifier notifier, String tenantId, String stateId, AuthenticationCredentials authenticationCredentials) throws Exception {
        String authenticationToken = this.executePost(null, tenantId, this.baseUrl + "/api/run/1/authentication/" + stateId, authenticationCredentials);

        String tokenToDeserialize = URLDecoder.decode(authenticationToken.substring(1, authenticationToken.length() - 1), "UTF-8");

        return AuthorizationUtils.deserialize(tokenToDeserialize);
    }

    public FlowResponse loadFlow(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, String flowId) throws Exception {
        return this.executeGet(authenticatedWho, tenantId, this.baseUrl + "/api/run/1/flow/" + flowId, FlowResponse.class);
    }

    public FlowResponse loadFlowByName(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, String flowName) throws Exception {
        return this.executeGet(authenticatedWho, tenantId, this.baseUrl + "/api/run/1/flow/name/" + flowName, FlowResponse.class);
    }

    public FlowResponseCollection loadFlows(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId) throws Exception {
        return this.executeGet(authenticatedWho, tenantId, this.baseUrl + "/api/run/1/flow", FlowResponseCollection.class);
    }

    public FlowResponseCollection loadFlows(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, String filter) throws Exception {
        return this.executeGet(authenticatedWho, tenantId, this.baseUrl + "/api/run/1/flow", new HashMap() {{
            put("filter", filter);
        }}, FlowResponseCollection.class);
    }

    public EngineInitializationResponse initializeFlow(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, EngineInitializationRequest engineInitializationRequest) throws Exception {
        return this.executePost(authenticatedWho, tenantId, this.baseUrl + "/api/run/1", engineInitializationRequest, EngineInitializationResponse.class);
    }

    public EngineInvokeResponse executeFlow(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, EngineInvokeRequest engineInvokeRequest) throws Exception {
        Callable executeCallable = () -> this.executePost(
                authenticatedWho,
                tenantId,
                this.baseUrl + "/api/run/1/state/" + engineInvokeRequest.getStateId(),
                engineInvokeRequest,
                EngineInvokeResponse.class
        );

        return RunService.createRetry(response -> response.getInvokeType().equals(InvokeType.Busy))
                .call(executeCallable);
    }

    public EngineInvokeResponse joinFlow(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, String stateId) throws Exception {
        return this.executeGet(authenticatedWho, tenantId, this.baseUrl + "/api/run/1/state/" + stateId, EngineInvokeResponse.class);
    }

    public InvokeType sendEvent(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, String callbackUri, ListenerServiceResponse listenerServiceResponse) throws Exception {
        return this.executeCallback(authenticatedWho, tenantId, callbackUri, listenerServiceResponse);
    }

    public InvokeType sendResponse(Notifier notifier, AuthenticatedWho authenticatedWho, String tenantId, String callbackUri, ServiceResponse serviceResponse) throws Exception {
        Callable executeCallable = () -> this.executeCallback(
                authenticatedWho,
                tenantId,
                callbackUri,
                serviceResponse
        );

        return RunService.createRetry(invokeType -> invokeType.equals(InvokeType.Busy))
                .call(executeCallable);
    }

    protected HttpRequestWithBody createHttpClient(AuthenticatedWho authenticatedWho, String tenantId, String callbackUri) throws Exception {
        String authorizationHeader = null;
        if (authenticatedWho != null) {
            authorizationHeader = URLEncoder.encode(AuthorizationUtils.serialize(authenticatedWho), "UTF-8");
        }

        return Unirest.post(callbackUri)
                .header("Authorization", authorizationHeader)
                .header("ManyWhoTenant", tenantId)
                .header("Content-Type", "application/json");
    }

    protected  T executeGet(AuthenticatedWho authenticatedWho, String tenantId, String uri, Class responseClass) throws Exception {
        return executeGet(authenticatedWho, tenantId, uri, null, responseClass);
    }

    protected  T executeGet(AuthenticatedWho authenticatedWho, String tenantId, String uri, Map queryParameters, Class responseClass) throws Exception {
        String authorizationHeader = null;
        if (authenticatedWho != null) {
            authorizationHeader = URLEncoder.encode(AuthorizationUtils.serialize(authenticatedWho), "UTF-8");
        }

        HttpResponse response = Unirest.get(uri)
                .header("Authorization", authorizationHeader)
                .header("ManyWhoTenant", tenantId)
                .queryString(queryParameters)
                .asString();

        if (!STATUSES_SUCCESS.contains(response.getStatus())) {
            throw new ManyWhoException(response.getStatus(), response.getStatusText());
        }

        return new ObjectMapper().configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true).readValue(response.getRawBody(), responseClass);
    }

    protected  T executePost(AuthenticatedWho authenticatedWho, String tenantId, String callbackUri, Request request, Class responseClass) throws Exception {
        HttpResponse response = this.createHttpClient(authenticatedWho, tenantId, callbackUri)
                .body(new ObjectMapper().configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true).writeValueAsString(request))
                .asString();

        if (!STATUSES_SUCCESS.contains(response.getStatus())) {
            throw new ManyWhoException(response.getStatus(), response.getStatusText());
        }

        return new ObjectMapper().configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true).readValue(response.getRawBody(), responseClass);
    }

    protected String executePost(AuthenticatedWho authenticatedWho, String tenantId, String callbackUri, Request request) throws Exception {
        HttpResponse response = this.createHttpClient(authenticatedWho, tenantId, callbackUri)
                .body(new ObjectMapper().configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true).writeValueAsString(request))
                .asString();

        if (!STATUSES_SUCCESS.contains(response.getStatus())) {
            throw new ManyWhoException(response.getStatus(), response.getStatusText());
        }

        return response.getBody();
    }

    protected InvokeType executeCallback(AuthenticatedWho authenticatedWho, String tenantId, String callbackUri, Response response) throws Exception {
        String responseBody = this.createHttpClient(authenticatedWho, tenantId, callbackUri)
                .body(new ObjectMapper().configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true).writeValueAsString(response))
                .asString()
                .getBody();

        return InvokeType.fromString(responseBody.replace("\"", ""));
    }

    public static  Retryer createRetry(Predicate predicate) {
        // If the invoke type is BUSY, then retry 4 times, with an exponential backoff of 500ms and a 2x multiplier
        return RetryerBuilder.newBuilder()
                .retryIfResult(predicate)
                .withWaitStrategy(WaitStrategies.exponentialWait(2, 500, TimeUnit.MILLISECONDS))
                .withStopStrategy(StopStrategies.stopAfterAttempt(4))
                .build();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy