UiPath Documentation
orchestrator
2.2510
true
Guía del usuario de Orchestrator
Importante :
La localización de contenidos recién publicados puede tardar entre una y dos semanas en estar disponible.

Explicación de los modos de llamada

Cómo funcionan los modos de llamada de desencadenador de API para crear y realizar un seguimiento de las ejecuciones de trabajos a través de la comunicación basada en HTTP.

Los modos de llamada de los desencadenadores de la API están diseñados específicamente para crear y seguir ejecuciones de trabajos en Orchestrator.

El reto fundamental de la comunicación basada en HTTP es que es intrínsecamente sincrónica: normalmente, el cliente envía una solicitud y espera la respuesta del servidor. Sin embargo, en el contexto de los trabajos de UiPath Robot, Orchestrator no permite mantener la conexión abierta hasta que el trabajo haya finalizado.

To work around this, we’ve used the HTTP protocol to model multiple call modes. These modes rely on standard HTTP methods, status codes, and headers to create, monitor and get the result of jobs within the system, without unnecessarily keeping the connection open.

Each of the proposed call modes has advantages and disadvantages, so you can choose the one that is best suited for your integration needs. Bear in mind that, to ensure secure communication, each call requires proper authentication through bearer tokens.

Importante:

Incidencia conocida las solicitudes a veces pueden devolver un error de Cloudflare 502 Bad Gateway, causado por mantener un gran número de conexiones vivas durante periodos de tiempo prolongados. El trabajo subyacente de tal solicitud puede haberse ejecutado a pesar del error, por lo que puedes comprobar su estado en Orchestrator.

Este problema es intermitente y cualquier solicitud posterior funcionará como se espera.

Sondeo asíncrono

Este modo de llamada implica realizar una llamada con el verbo HTTP preconfigurado para desencadenar un nuevo trabajo y recibir un URI de estado. El URI de estado debe sondearse manualmente hasta que se complete el trabajo. En este punto, la llamada se redirige a otro punto final, que se utiliza para recuperar el resultado del trabajo (salida o error).

Figura 1. Flujo de trabajo de sondeo asíncrono

La llamada inicial se realiza utilizando el verbo HTTP configurado (OBTENER, PUBLICAR, PONER, ELIMINAR), que crea el trabajo asociado en Orchestrator. Una vez creado el trabajo, el sistema responde con un código de estado HTTP 202 (Aceptado) y un URI de estado en el encabezado Ubicación.

Once the job is created, you are expected to periodically poll its status. During this polling process, as long as the job is running, each GET request to the status URI returns an HTTP status code 200 (OK). When the job is completed, the next GET request to the status URI returns an HTTP status code 303 (See Other), redirecting to the output URI (via the Location header).

You are expected to follow the output URI to retrieve the job result (output or error).

Asegúrate siempre de incluir un token al portador válido en el encabezado de cada llamada para que la autenticación se realice correctamente.

Ejemplo de JavaScript

Este ejemplo ilustra cómo iniciar un trabajo a través de un desencadenador de API desde un explorador, utilizando el modo de llamada de sondeo asíncrono.

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

const url = 'https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth

const body = {
  'argument1': 123,
  'argument2': 'my string',
  '$callMode': 'AsyncRequestReply' // optional argument to force call mode to AsyncRequestReply
}

// if invocation is done by GET, place the parameters in query string and remove the 'Content-Type' header
const invokeRequestOptions = {
  method: 'POST',
  headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
  body: JSON.stringify(body),
};

const redirectRequestOptions = {
  method: "GET",
  credentials: 'same-origin',
  headers: new Headers({ Authorization: `Bearer ${token}` }),
  redirect: "follow", // this option must be set to follow, otherwise an 'opaqueredirect' response is returned
};

const response = await fetch(url, invokeRequestOptions);
let newLocation = response.headers.get("Location");

// first response should be 202 and have a location header
console.log(`Got ${response.status}, with location: ${newLocation}`);

for (let i = 0; i < 20; i++) {
  await sleep(SLEEP_DURATION);

  // follow the location header to the new endpoint
  const statusResponse = await fetch(newLocation, redirectRequestOptions);

  // if the response was redirected (and automatically followed), then the output endpoint has been reached
  // the output of the job can be found in the body of the response in JSON format
  if (statusResponse.status != 200 || statusResponse.redirected)
  {
    // read the job output
    const output = await statusResponse.json();
    console.log(`Got ${statusResponse.status}, with body: ${JSON.stringify(output)}`);

    break;
}
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

const url = 'https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth

const body = {
  'argument1': 123,
  'argument2': 'my string',
  '$callMode': 'AsyncRequestReply' // optional argument to force call mode to AsyncRequestReply
}

// if invocation is done by GET, place the parameters in query string and remove the 'Content-Type' header
const invokeRequestOptions = {
  method: 'POST',
  headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
  body: JSON.stringify(body),
};

const redirectRequestOptions = {
  method: "GET",
  credentials: 'same-origin',
  headers: new Headers({ Authorization: `Bearer ${token}` }),
  redirect: "follow", // this option must be set to follow, otherwise an 'opaqueredirect' response is returned
};

const response = await fetch(url, invokeRequestOptions);
let newLocation = response.headers.get("Location");

// first response should be 202 and have a location header
console.log(`Got ${response.status}, with location: ${newLocation}`);

for (let i = 0; i < 20; i++) {
  await sleep(SLEEP_DURATION);

  // follow the location header to the new endpoint
  const statusResponse = await fetch(newLocation, redirectRequestOptions);

  // if the response was redirected (and automatically followed), then the output endpoint has been reached
  // the output of the job can be found in the body of the response in JSON format
  if (statusResponse.status != 200 || statusResponse.redirected)
  {
    // read the job output
    const output = await statusResponse.json();
    console.log(`Got ${statusResponse.status}, with body: ${JSON.stringify(output)}`);

    break;
}

Ejemplo de C#

Este ejemplo ilustra cómo iniciar un trabajo a través de un desencadenador de API desde una aplicación basada en C#, utilizando el modo de llamada de sondeo asíncrono.

public async Task<string> AsyncPollingExample()
{
    const string url = "https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
    const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth

    // create an http client that does not follow redirects and adds a bearer token on each call
    var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var arguments = new Dictionary<string, object>
    {
        { "argument1", 123 },
        { "argument2", "my string" },
        { "$callMode", "AsyncRequestReply" }, // optional argument to force call mode to AsyncRequestReply
    };

    var httpResponseStart = await httpClient.PostAsJsonAsync(url, arguments);
    var redirectUri = httpResponseStart.Headers.Location;

    if (httpResponseStart.StatusCode != HttpStatusCode.Accepted)
        throw new Exception("Could not invoke workflow");

    while (true)
    {
        var httpPollingResponse = await httpClient.GetAsync(redirectUri);

        if (httpPollingResponse.StatusCode == HttpStatusCode.Redirect)
        {
            var outputLocation = httpPollingResponse.Headers.Location;
            var outputResponse = await httpClient.GetAsync(outputLocation);
            var jobOutput = await outputResponse.Content.ReadAsStringAsync();

            return jobOutput;
        }

        await Task.Delay(1000);
    }
}
public async Task<string> AsyncPollingExample()
{
    const string url = "https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
    const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth

    // create an http client that does not follow redirects and adds a bearer token on each call
    var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var arguments = new Dictionary<string, object>
    {
        { "argument1", 123 },
        { "argument2", "my string" },
        { "$callMode", "AsyncRequestReply" }, // optional argument to force call mode to AsyncRequestReply
    };

    var httpResponseStart = await httpClient.PostAsJsonAsync(url, arguments);
    var redirectUri = httpResponseStart.Headers.Location;

    if (httpResponseStart.StatusCode != HttpStatusCode.Accepted)
        throw new Exception("Could not invoke workflow");

    while (true)
    {
        var httpPollingResponse = await httpClient.GetAsync(redirectUri);

        if (httpPollingResponse.StatusCode == HttpStatusCode.Redirect)
        {
            var outputLocation = httpPollingResponse.Headers.Location;
            var outputResponse = await httpClient.GetAsync(outputLocation);
            var jobOutput = await outputResponse.Content.ReadAsStringAsync();

            return jobOutput;
        }

        await Task.Delay(1000);
    }
}

Enviar y olvidar asíncrono

El modo de llamada inmediato devuelve un estado 200 OK al crearse correctamente el trabajo, sin ninguna otra información sobre el mismo.

Figura 2. Flujo de trabajo de enviar y olvidar asíncrono

Ejemplo de JavaScript

Este ejemplo ilustra cómo iniciar un trabajo a través de un desencadenador de API desde un explorador, utilizando el modo de llamada inmediato asíncrono.

const url = 'https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth

const body = {
  'argument1': 123,
  'argument2': 'my string',
  '$callMode': 'FireAndForget' // optional argument to force call mode to FireAndForget
}

const options = {
  method: 'POST',
  headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
  body: JSON.stringify(body),
};

let response = await fetch(url, options);

console.log(`Got ${response.status}`);
const url = 'https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth

const body = {
  'argument1': 123,
  'argument2': 'my string',
  '$callMode': 'FireAndForget' // optional argument to force call mode to FireAndForget
}

const options = {
  method: 'POST',
  headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
  body: JSON.stringify(body),
};

let response = await fetch(url, options);

console.log(`Got ${response.status}`);

Ejemplo de C#

Este ejemplo ilustra cómo iniciar un trabajo a través de un desencadenador de API desde una aplicación basada en C#, utilizando el modo de llamada inmediato asíncrono.

public async Task FireAndForgetExample()
{
    const string url = "https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
    const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth

    // create an http client that does not follow redirects and adds Bearer <token> on each call
    // if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
    var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var arguments = new Dictionary<string, object>
    {
        { "argument1", 123 },
        { "argument2", "my string" },
        { "$callMode", "FireAndForget" }, // optional argument to force call mode to LongPolling
    };

    var response = await httpClient.PostAsJsonAsync(url, arguments);

    Console.WriteLine(response.StatusCode);
}
public async Task FireAndForgetExample()
{
    const string url = "https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
    const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth

    // create an http client that does not follow redirects and adds Bearer <token> on each call
    // if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
    var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var arguments = new Dictionary<string, object>
    {
        { "argument1", 123 },
        { "argument2", "my string" },
        { "$callMode", "FireAndForget" }, // optional argument to force call mode to LongPolling
    };

    var response = await httpClient.PostAsJsonAsync(url, arguments);

    Console.WriteLine(response.StatusCode);
}

Sincronización (sondeo largo)

Este modo de llamada implica una llamada inicial que se bloquea y espera un tiempo a que se complete el trabajo, seguida de varias posibles llamadas de bloqueo y redireccionamientos. Por último, una vez finalizado el trabajo, se recupera el resultado del trabajo (salida o error).

En función de la configuración del tenant, la autenticación puede ser necesaria para todas las llamadas o solo para la llamada inicial.

Figura 3. Flujo de trabajo de sincronización (sondeo largo) en el que el resultado se devuelve con la llamada inicial

Figura 4. Flujo de trabajo de sincronización (sondeo largo) en el que se realizan automáticamente varias llamadas para completar el trabajo

La llamada inicial se realiza utilizando el verbo HTTP configurado (OBTENER, PUBLICAR, PONER, ELIMINAR), que crea el trabajo asociado en Orchestrator. Una vez creado el trabajo con éxito, el sistema bloquea la llamada actual mientras espera a que se complete el trabajo. Cuando el trabajo finaliza, se libera la llamada bloqueada y se devuelve una respuesta que incluye los argumentos de salida del trabajo.

If after a timeout period the job has not yet completed, the system responds with an HTTP status code 303 (See Other), redirecting to the status URI (via the Location header). You are expected to follow the status URI, which is blocked until the job is completed.

If the job is not completed after a timeout, you are yet again redirected to the status URI, thus creating a redirect loop. Upon successful completion of the job, the job result (output or error) is retrieved as part of the HTTP response.

Por defecto, todas las llamadas deben incluir un token al portador válido para su autorización. Sin embargo, si no se selecciona la opción de configuración de tenant Requerir encabezado de autenticación para las redirecciones de desencadenadores de API de sincronización, solo la llamada inicial al desencadenador requiere el encabezado de autenticación. Las llamadas posteriores al punto final de estado pueden realizarse sin un encabezado de autorización.

La duración máxima del trabajo para este modo de llamada es de 15 minutos.

Ejemplo de JavaScript

Este ejemplo ilustra cómo iniciar un trabajo a través de un desencadenador de API desde un explorador, utilizando el modo de llamada de sincronización (sondeo largo).

const url = 'https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth

const body = {
  'argument1': 123,
  'argument2': 'my string',
  '$callMode': 'LongPolling' // optional argument to force call mode to LongPolling
}

const options = {
  method: 'POST',
  headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
  body: JSON.stringify(body),
  redirect: "follow", // follow redirects automatically
};

let response = await fetch(url, options);
const output = await response.json();

console.log(`Got ${response.status} with body ${JSON.stringify(output)}`);
const url = 'https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>';
const token = '<PERSONAL_ACCESS_TOKEN>'; // could also be an access token retrieved via OAuth

const body = {
  'argument1': 123,
  'argument2': 'my string',
  '$callMode': 'LongPolling' // optional argument to force call mode to LongPolling
}

const options = {
  method: 'POST',
  headers: new Headers({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }),
  body: JSON.stringify(body),
  redirect: "follow", // follow redirects automatically
};

let response = await fetch(url, options);
const output = await response.json();

console.log(`Got ${response.status} with body ${JSON.stringify(output)}`);

Ejemplo de C#

Este ejemplo ilustra cómo iniciar un trabajo a través de un desencadenador de API desde una aplicación basada en C#, utilizando el modo de llamada de sincronización (sondeo largo).

public async Task SyncExample()
{
    const string url = "https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
    const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth

    // create an http client that does not follow redirects and adds Bearer <token> on each call
    // if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
    var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var arguments = new Dictionary<string, object>
    {
        { "argument1", 123 },
        { "argument2", "my string" },
        { "$callMode", "LongPolling" }, // optional argument to force call mode to LongPolling
    };

    var response = await httpClient.PostAsJsonAsync(url, arguments);

    while(response.StatusCode == HttpStatusCode.SeeOther)
    {
        // in case of redirection, keep following the latest location in the header
        var location = response.Headers.Location;
        response = await httpClient.GetAsync(location);
    }

    // read the job output/error from the last request
    var jobOutput = response.Content.ReadAsStringAsync();

    Console.WriteLine(jobOutput);
}
public async Task SyncExample()
{
    const string url = "https://{yourDomain}/{organizationName}/{tenantName}/orchestrator_/t/<INVOKE_URL>";
    const string token = "<PERSONAL_ACCESS_TOKEN>"; // could also be an access token retrieved via OAuth

    // create an http client that does not follow redirects and adds Bearer <token> on each call
    // if the follow redirects option is enabled, C# will not add a bearer token by default after the redirect
    var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

    var arguments = new Dictionary<string, object>
    {
        { "argument1", 123 },
        { "argument2", "my string" },
        { "$callMode", "LongPolling" }, // optional argument to force call mode to LongPolling
    };

    var response = await httpClient.PostAsJsonAsync(url, arguments);

    while(response.StatusCode == HttpStatusCode.SeeOther)
    {
        // in case of redirection, keep following the latest location in the header
        var location = response.Headers.Location;
        response = await httpClient.GetAsync(location);
    }

    // read the job output/error from the last request
    var jobOutput = response.Content.ReadAsStringAsync();

    Console.WriteLine(jobOutput);
}

¿Te ha resultado útil esta página?

Conectar

¿Necesita ayuda? Soporte

¿Quiere aprender? UiPath Academy

¿Tiene alguna pregunta? Foro de UiPath

Manténgase actualizado