Procedimiento para crear, publicar y administrar un flujo de trabajo de Workflow Manager 1.0

 

Publicada: mayo de 2016

La creación, publicación y administración de flujos de trabajo usa la API de Workflow Manager.En este tema se explica cómo usar los métodos y las clases de la API de Workflow Manager Client para trabajar con flujos de trabajo.

Creación de flujos de trabajo

La creación de flujos de trabajo en Workflow Manager 1.0 es similar a la creación en cualquier entorno de flujos de trabajo.Los flujos de trabajo se crean de manera declarativa mediante XAML que define una jerarquía de actividades predefinidas.El siguiente ejemplo de código (del ejemplo Actividades personalizadas) es un flujo de trabajo declarativo creado para ejecutarse en Workflow Manager 1.0.

<Activity mc:Ignorable="sap sap2010 sads" x:Class="MoviesActivityLibrary.GetMovies"
 xmlns="https://schemas.microsoft.com/netfx/2009/xaml/activities"
 xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:mca="clr-namespace:Microsoft.CSharp.Activities;assembly=System.Activities"
 xmlns:p="https://schemas.microsoft.com/workflow/2012/07/xaml/activities"
 xmlns:sads="https://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"
 xmlns:sap="https://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
 xmlns:sap2010="https://schemas.microsoft.com/netfx/2010/xaml/activities/presentation"
 xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
 xmlns:sco="clr-namespace:System.Collections.ObjectModel;assembly=mscorlib"
 xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
  <x:Members>
    <x:Property Name="searchKeyword" Type="InArgument(x:String)" />
    <x:Property Name="numItems" Type="InArgument(x:Int32)" />
    <x:Property Name="videoDV" Type="OutArgument(p:DynamicValue)" />
  </x:Members>
  <sap2010:ExpressionActivityEditor.ExpressionActivityEditor>C#</sap2010:ExpressionActivityEditor.ExpressionActivityEditor>
  <sap2010:WorkflowViewState.IdRef>ActivityLibrary2.Activity1_1</sap2010:WorkflowViewState.IdRef>
  <TextExpression.NamespacesForImplementation>
    <sco:Collection x:TypeArguments="x:String">
      <x:String>System</x:String>
      <x:String>System.Collections.Generic</x:String>
      <x:String>System.Data</x:String>
      <x:String>System.Linq</x:String>
      <x:String>System.Text</x:String>
      <x:String>Microsoft.Activities</x:String>
    </sco:Collection>
  </TextExpression.NamespacesForImplementation>
  <TextExpression.ReferencesForImplementation>
    <sco:Collection x:TypeArguments="AssemblyReference">
      <AssemblyReference>Microsoft.Activities</AssemblyReference>
      <AssemblyReference>Microsoft.CSharp</AssemblyReference>
      <AssemblyReference>Microsoft.Workflow.Common</AssemblyReference>
      <AssemblyReference>Microsoft.Workflow.Tracing</AssemblyReference>
      <AssemblyReference>System</AssemblyReference>
      <AssemblyReference>System.Activities</AssemblyReference>
      <AssemblyReference>System.Core</AssemblyReference>
      <AssemblyReference>System.Data</AssemblyReference>
      <AssemblyReference>System.Runtime.Serialization</AssemblyReference>
      <AssemblyReference>System.ServiceModel</AssemblyReference>
      <AssemblyReference>System.ServiceModel.Activities</AssemblyReference>
      <AssemblyReference>System.Xaml</AssemblyReference>
      <AssemblyReference>System.Xml</AssemblyReference>
      <AssemblyReference>System.Xml.Linq</AssemblyReference>
      <AssemblyReference>mscorlib</AssemblyReference>
      <AssemblyReference>MoviesActivityLibrary</AssemblyReference>
    </sco:Collection>
  </TextExpression.ReferencesForImplementation>
  <Sequence DisplayName="GetMovies" sap2010:WorkflowViewState.IdRef="Sequence_1">
    <p:HttpGet DisplayName="HttpGetFromNetflix" sap2010:WorkflowViewState.IdRef="HttpGet_1" RetryOnConnectionFailure="True">
      <p:HttpGet.ResponseContent>
        <OutArgument x:TypeArguments="p:DynamicValue">
          <mca:CSharpReference x:TypeArguments="p:DynamicValue">videoDV</mca:CSharpReference>
        </OutArgument>
      </p:HttpGet.ResponseContent>
      <p:HttpGet.Uri>
        <InArgument x:TypeArguments="x:String">
          <mca:CSharpValue x:TypeArguments="x:String">"http://odata.netflix.com/Catalog/Titles?$filter=substringof('" + searchKeyword + "', Name)&amp;$format=json&amp;$top=" + numItems + "&amp;$select=Name, Synopsis"</mca:CSharpValue>
        </InArgument>
      </p:HttpGet.Uri>
    </p:HttpGet>
    <sads:DebugSymbol.Symbol>d3dcXHNjcmF0Y2gyXHNjcmF0Y2hcZ2dvZ29sb1xCMiAtIFRlc3RcQ3VzdG9tQ29kZUFjdGl2aXRpZXNcQ3VzdG9tQ29kZUFjdGl2aXR5U2FtcGxlXE1vdmllc0FjdGl2aXR5TGlicmFyeVxHZXRNb3ZpZXMueGFtbAQxAz8OAgEBMgU9EQIBAjoLOusBAgEHNQs1XgIBAw==</sads:DebugSymbol.Symbol>
  </Sequence>
  <sap2010:WorkflowViewState.ViewStateManager>
    <sap2010:ViewStateManager>
      <sap2010:ViewStateData Id="HttpGet_1" sap:VirtualizedContainerService.HintSize="284,120" />
      <sap2010:ViewStateData Id="Sequence_1" sap:VirtualizedContainerService.HintSize="306,244">
        <sap:WorkflowViewStateService.ViewState>
          <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
          </scg:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
      </sap2010:ViewStateData>
      <sap2010:ViewStateData Id="ActivityLibrary2.Activity1_1" sap:VirtualizedContainerService.HintSize="346,324" />
    </sap2010:ViewStateManager>
  </sap2010:WorkflowViewState.ViewStateManager>
</Activity>

Las siguientes capturas de pantalla muestran el flujo de trabajo abierto en Visual Studio 2012.

GetMovies Workflow

El flujo de trabajo en este ejemplo recupera información de películas de un servicio web público según los parámetros de búsqueda.Estos parámetros se definen como propiedades (una palabra clave de búsqueda y un número de registros).A continuación, el flujo de trabajo devuelve la información recuperada como DynamicValue y así permite al llamador manejar los datos obtenidos como un contenedor de propiedades.

Publicación de flujos de trabajo

Los flujos de trabajo hospedados mediante Workflow Manager primero deben publicarse en un ámbito.La interacción con un ámbito se realiza mediante de WorkflowManagementClient.En el código de ejemplo a continuación se muestra cómo crear un ámbito de flujo de trabajo con los objetivos de este ejemplo.

var rootClient = new WorkflowManagementClient(new Uri(rootScope));

            return rootClient.CurrentScope.PublishChildScope(scopeName,
                new ScopeDescription()
                {
                    UserComments = string.Format("For {0} sample only", scopeName)
                });

Una vez que se ha establecido el ámbito, el flujo de trabajo se puede publicar en el ámbito.Todos los documentos XAML se cargan como actividades mediante ActivityDescription.A continuación, los flujos de trabajo reciben los metadatos asociados por medio de WorkflowDescription.En el siguiente código de ejemplo se muestra cómo publicar el flujo de trabajo y las actividades correspondientes.

// publish the activity description related with the workflow
client.Activities.Publish(
new ActivityDescription(WorkflowUtils.Translate(xamlFilePath)) { Name = workflowName });

// now, publish the workflow description
WorkflowDescription description = new WorkflowDescription
{
Name = workflowName,
ActivityPath = workflowName,
// additional properties elided for simplicity
};

// publish!
client.Workflows.Publish(description);

Administración de flujos de trabajo

Una vez publicados los flujos de trabajo en Workflow Manager, se ejecutan y es posible recuperar su estado.El siguiente código de ejemplo demuestra cómo ejecutar un flujo de trabajo publicado.El inicio de un flujo de trabajo usa un objeto T:Microsoft.Workflow.Client.WorkflowStartInfo para almacenar información de inicio, similar a la forma en que un proceso usa un objeto StartInfo.

Console.Write("Starting workflow instance...");
WorkflowStartParameters startParameters = new WorkflowStartParameters();
startParameters.Content.Add("Title", "Titanic");
startParameters.Content.Add("NumberOfMovies", 3);
string instanceId = client.Workflows.Start(workflowName, startParameters);

El siguiente código de ejemplo demuestra cómo consultar el estado de un flujo de trabajo en ejecución.El estado se devuelve como una cadena.

WorkflowInstanceInfo instanceInfo = client.Instances.Get(workflowName, instanceId);
currentStatus = instanceInfo.UserStatus;

if (instanceInfo.WorkflowStatus == WorkflowInstanceStatus.Completed)
{
    Console.WriteLine("\nWorkflow instance completed");
}