You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Xml;
|
||||
using System.Workflow.Activities.Common;
|
||||
|
||||
namespace System.Workflow.Activities
|
||||
{
|
||||
internal static class ActivityHelpers
|
||||
{
|
||||
internal static void InitializeCorrelationTokenCollection(Activity activity, CorrelationToken correlator)
|
||||
{
|
||||
if (correlator != null && !String.IsNullOrEmpty(correlator.OwnerActivityName))
|
||||
{
|
||||
string ownerActivityId = correlator.OwnerActivityName;
|
||||
Activity owner = activity.GetActivityByName(ownerActivityId);
|
||||
if (owner == null)
|
||||
owner = System.Workflow.Activities.Common.Helpers.ParseActivityForBind(activity, ownerActivityId);
|
||||
if (owner == null)
|
||||
throw new ArgumentException("ownerActivity");
|
||||
|
||||
CorrelationTokenCollection collection = owner.GetValue(CorrelationTokenCollection.CorrelationTokenCollectionProperty) as CorrelationTokenCollection;
|
||||
if (collection == null)
|
||||
{
|
||||
collection = new CorrelationTokenCollection();
|
||||
owner.SetValue(CorrelationTokenCollection.CorrelationTokenCollectionProperty, collection);
|
||||
}
|
||||
|
||||
if (!collection.Contains(correlator.Name))
|
||||
{
|
||||
collection.Add(correlator);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#region Using directives
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Remoting;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Workflow.Runtime.Hosting;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.Runtime;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Activities
|
||||
{
|
||||
internal static class InboundActivityHelper
|
||||
{
|
||||
internal static ActivityExecutionStatus ExecuteForActivity(HandleExternalEventActivity activity, ActivityExecutionContext context, Type interfaceType, string operation, out object[] args)
|
||||
{
|
||||
WorkflowQueuingService queueSvcs = (WorkflowQueuingService)context.GetService(typeof(WorkflowQueuingService));
|
||||
args = null;
|
||||
IComparable queueName = CorrelationService.ResolveQueueName(activity, interfaceType, operation);
|
||||
if (queueName != null)
|
||||
{
|
||||
WorkflowQueue queue;
|
||||
object message = DequeueMessage(queueName, queueSvcs, activity, out queue);
|
||||
CorrelationService.UninitializeFollowers(interfaceType, operation, queue);
|
||||
if (message != null)
|
||||
{
|
||||
args = ProcessEvent(activity, context, message, interfaceType, operation);
|
||||
return ActivityExecutionStatus.Closed;
|
||||
}
|
||||
}
|
||||
|
||||
return ActivityExecutionStatus.Executing;
|
||||
}
|
||||
|
||||
internal static object DequeueMessage(IComparable queueId, WorkflowQueuingService queueSvcs, Activity activity, out WorkflowQueue queue)
|
||||
{
|
||||
object message = null;
|
||||
queue = queueSvcs.GetWorkflowQueue(queueId);
|
||||
|
||||
if (queue.Count != 0)
|
||||
{
|
||||
message = queue.Dequeue();
|
||||
if (message == null)
|
||||
throw new ArgumentException(SR.GetString(SR.Error_InvalidEventMessage, activity.QualifiedName));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
private static object[] ProcessEvent(HandleExternalEventActivity activity, ActivityExecutionContext context, object msg, Type interfaceType, string operation)
|
||||
{
|
||||
IMethodMessage message = msg as IMethodMessage;
|
||||
if (message == null)
|
||||
{
|
||||
Exception excp = msg as Exception;
|
||||
if (excp != null)
|
||||
throw excp;
|
||||
throw new InvalidOperationException(SR.GetString(SR.Error_InvalidLocalServiceMessage));
|
||||
}
|
||||
|
||||
CorrelationService.InvalidateCorrelationToken(activity, interfaceType, operation, message.Args);
|
||||
|
||||
IdentityContextData identityData =
|
||||
(IdentityContextData)message.LogicalCallContext.GetData(IdentityContextData.IdentityContext);
|
||||
ValidateRoles(activity, identityData.Identity);
|
||||
|
||||
if (ProcessEventParameters(activity.ParameterBindings, message, interfaceType, operation))
|
||||
return message.Args;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool ProcessEventParameters(WorkflowParameterBindingCollection parameters, IMethodMessage message, Type interfaceType, string operation)
|
||||
{
|
||||
bool isKnownSignature = false;
|
||||
if (parameters == null)
|
||||
return isKnownSignature;
|
||||
|
||||
EventInfo eventInfo = interfaceType.GetEvent(operation);
|
||||
MethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");
|
||||
int index = 0;
|
||||
|
||||
foreach (ParameterInfo formalParameter in methodInfo.GetParameters())
|
||||
{
|
||||
if ((typeof(ExternalDataEventArgs).IsAssignableFrom(formalParameter.ParameterType)))
|
||||
{
|
||||
if (index == 1)
|
||||
isKnownSignature = true;
|
||||
}
|
||||
|
||||
if (parameters.Contains(formalParameter.Name))
|
||||
{
|
||||
WorkflowParameterBinding binding = parameters[formalParameter.Name];
|
||||
binding.Value = message.Args[index];
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return isKnownSignature;
|
||||
}
|
||||
|
||||
internal static void ValidateRoles(Activity activity, string identity)
|
||||
{
|
||||
DependencyProperty dependencyProperty = DependencyProperty.FromName("Roles", activity.GetType().BaseType);
|
||||
if (dependencyProperty == null)
|
||||
dependencyProperty = DependencyProperty.FromName("Roles", activity.GetType());
|
||||
|
||||
if (dependencyProperty == null)
|
||||
return;
|
||||
|
||||
ActivityBind rolesBind = activity.GetBinding(dependencyProperty) as ActivityBind;
|
||||
if (rolesBind == null)
|
||||
return;
|
||||
|
||||
WorkflowRoleCollection roles = rolesBind.GetRuntimeValue(activity) as WorkflowRoleCollection;
|
||||
if (roles == null)
|
||||
return;
|
||||
|
||||
if (!roles.IncludesIdentity(identity))
|
||||
throw new WorkflowAuthorizationException(activity.Name, identity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Workflow.ComponentModel;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
|
||||
namespace System.Workflow.Activities
|
||||
{
|
||||
internal static class InvokeHelper
|
||||
{
|
||||
internal static void InitializeParameters(MethodInfo methodBase, WorkflowParameterBindingCollection parameterBindings)
|
||||
{
|
||||
ParameterInfo[] parameters = methodBase.GetParameters();
|
||||
foreach (ParameterInfo parameter in parameters)
|
||||
{
|
||||
if (!parameterBindings.Contains(parameter.Name))
|
||||
parameterBindings.Add(new WorkflowParameterBinding(parameter.Name));
|
||||
}
|
||||
|
||||
if (methodBase.ReturnType != typeof(void))
|
||||
{
|
||||
if (!parameterBindings.Contains("(ReturnValue)"))
|
||||
parameterBindings.Add(new WorkflowParameterBinding("(ReturnValue)"));
|
||||
}
|
||||
}
|
||||
|
||||
internal static object[] GetParameters(MethodBase methodBase, WorkflowParameterBindingCollection parameterBindings)
|
||||
{
|
||||
ParameterInfo[] formalParameters = methodBase.GetParameters();
|
||||
object[] actualParameters = new object[formalParameters.Length];
|
||||
int index = 0;
|
||||
|
||||
foreach (ParameterInfo formalParameter in formalParameters)
|
||||
{
|
||||
if (parameterBindings.Contains(formalParameter.Name))
|
||||
{
|
||||
WorkflowParameterBinding binding = parameterBindings[formalParameter.Name];
|
||||
actualParameters[index] = binding.Value;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return actualParameters;
|
||||
}
|
||||
|
||||
internal static object[] GetParameters(MethodBase methodBase, WorkflowParameterBindingCollection parameterBindings, out ParameterModifier[] parameterModifiers)
|
||||
{
|
||||
ParameterInfo[] formalParameters = methodBase.GetParameters();
|
||||
object[] actualParameters = new object[formalParameters.Length];
|
||||
if (actualParameters.Length == 0)
|
||||
{
|
||||
parameterModifiers = new ParameterModifier[0];
|
||||
return actualParameters;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
BinaryFormatter formatter = null;
|
||||
ParameterModifier parameterModifier = new ParameterModifier(actualParameters.Length);
|
||||
foreach (ParameterInfo formalParameter in formalParameters)
|
||||
{
|
||||
if (formalParameter.ParameterType.IsByRef)
|
||||
{
|
||||
parameterModifier[index] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
parameterModifier[index] = false;
|
||||
}
|
||||
if (parameterBindings.Contains(formalParameter.Name))
|
||||
{
|
||||
WorkflowParameterBinding binding = parameterBindings[formalParameter.Name];
|
||||
|
||||
if (formatter == null)
|
||||
formatter = new BinaryFormatter();
|
||||
actualParameters[index] = CloneOutboundValue(binding.Value, formatter, formalParameter.Name);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
parameterModifiers = new ParameterModifier[1] { parameterModifier };
|
||||
return actualParameters;
|
||||
}
|
||||
|
||||
internal static object CloneOutboundValue(object source, BinaryFormatter formatter, string name)
|
||||
{
|
||||
if (source == null || source.GetType().IsValueType)
|
||||
return source;
|
||||
|
||||
ICloneable clone = source as ICloneable;
|
||||
if (clone != null)
|
||||
return clone.Clone();
|
||||
|
||||
System.IO.MemoryStream stream = new System.IO.MemoryStream(1024);
|
||||
try
|
||||
{
|
||||
formatter.Serialize(stream, source);
|
||||
}
|
||||
catch (SerializationException e)
|
||||
{
|
||||
throw new InvalidOperationException(SR.GetString(SR.Error_CallExternalMethodArgsSerializationException, name), e);
|
||||
}
|
||||
stream.Position = 0;
|
||||
object cloned = formatter.Deserialize(stream);
|
||||
return cloned;
|
||||
}
|
||||
|
||||
internal static void SaveOutRefParameters(object[] actualParameters, MethodBase methodBase, WorkflowParameterBindingCollection parameterBindings)
|
||||
{
|
||||
int index = 0;
|
||||
BinaryFormatter formatter = null;
|
||||
foreach (ParameterInfo formalParameter in methodBase.GetParameters())
|
||||
{
|
||||
if (parameterBindings.Contains(formalParameter.Name))
|
||||
{
|
||||
if (formalParameter.ParameterType.IsByRef || (formalParameter.IsIn && formalParameter.IsOut))
|
||||
{
|
||||
WorkflowParameterBinding binding = parameterBindings[formalParameter.Name];
|
||||
|
||||
if (formatter == null)
|
||||
formatter = new BinaryFormatter();
|
||||
binding.Value = CloneOutboundValue(actualParameters[index], formatter, formalParameter.Name);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*******************************************************************************
|
||||
// Copyright (C) 2000-2006 Microsoft Corporation. All rights reserved.
|
||||
* ****************************************************************************/
|
||||
#region Using directives
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
using System.Collections.Specialized;
|
||||
using System.Threading;
|
||||
using System.Web.Services;
|
||||
using System.Workflow.Runtime;
|
||||
using System.Workflow.Runtime.Hosting;
|
||||
using System.Security.Permissions;
|
||||
using System.Security.Principal;
|
||||
using System.Reflection;
|
||||
#endregion
|
||||
|
||||
namespace System.Workflow.Activities
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract WorkflowWebService Base class for all the Workflow's Web Service.
|
||||
/// </summary>
|
||||
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
|
||||
public abstract class WorkflowWebService : WebService
|
||||
{
|
||||
Type workflowType;
|
||||
/// <summary>
|
||||
/// Protected Constructor for the Workflow Web Service.
|
||||
/// </summary>
|
||||
/// <param name="workflowType"></param>
|
||||
protected WorkflowWebService(Type workflowType)
|
||||
{
|
||||
this.workflowType = workflowType;
|
||||
}
|
||||
protected Object[] Invoke(Type interfaceType, String methodName, bool isActivation, Object[] parameters)
|
||||
{
|
||||
Guid workflowInstanceId = GetWorkflowInstanceId(ref isActivation);
|
||||
WorkflowInstance wfInstance;
|
||||
|
||||
EventQueueName key = new EventQueueName(interfaceType, methodName);
|
||||
|
||||
MethodInfo mInfo = interfaceType.GetMethod(methodName);
|
||||
|
||||
bool responseRequired = (mInfo.ReturnType != typeof(void));
|
||||
|
||||
if (!responseRequired)
|
||||
{
|
||||
foreach (ParameterInfo parameter in mInfo.GetParameters())
|
||||
{
|
||||
if (parameter.ParameterType.IsByRef || parameter.IsOut)
|
||||
{
|
||||
responseRequired = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MethodMessage methodMessage = PrepareMessage(interfaceType, methodName, parameters, responseRequired);
|
||||
|
||||
EventHandler<WorkflowTerminatedEventArgs> workflowTerminationHandler = null;
|
||||
EventHandler<WorkflowCompletedEventArgs> workflowCompletedHandler = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (isActivation)
|
||||
{
|
||||
wfInstance = WorkflowRuntime.CreateWorkflow(this.workflowType, null, workflowInstanceId);
|
||||
SafeEnqueueItem(wfInstance, key, methodMessage);
|
||||
wfInstance.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
wfInstance = WorkflowRuntime.GetWorkflow(workflowInstanceId);
|
||||
SafeEnqueueItem(wfInstance, key, methodMessage);
|
||||
}
|
||||
|
||||
bool workflowTerminated = false;
|
||||
|
||||
//Handler for workflow termination in b/w outstanding req-response.
|
||||
workflowTerminationHandler = delegate(Object sender, WorkflowTerminatedEventArgs e)
|
||||
{
|
||||
if (e.WorkflowInstance.InstanceId.Equals(workflowInstanceId))
|
||||
{
|
||||
methodMessage.SendException(e.Exception);
|
||||
workflowTerminated = true;
|
||||
}
|
||||
};
|
||||
|
||||
workflowCompletedHandler = delegate(Object sender, WorkflowCompletedEventArgs e)
|
||||
{
|
||||
if (e.WorkflowInstance.InstanceId.Equals(workflowInstanceId))
|
||||
{
|
||||
methodMessage.SendException(new ApplicationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_WorkflowCompleted)));
|
||||
}
|
||||
};
|
||||
|
||||
WorkflowRuntime.WorkflowTerminated += workflowTerminationHandler;
|
||||
WorkflowRuntime.WorkflowCompleted += workflowCompletedHandler;
|
||||
|
||||
ManualWorkflowSchedulerService scheduler = WorkflowRuntime.GetService<ManualWorkflowSchedulerService>();
|
||||
|
||||
if (scheduler != null)
|
||||
{
|
||||
scheduler.RunWorkflow(wfInstance.InstanceId);
|
||||
}
|
||||
|
||||
if (!responseRequired)
|
||||
{
|
||||
// no ret, out or ref
|
||||
return new Object[] { };
|
||||
}
|
||||
|
||||
IMethodResponseMessage response = methodMessage.WaitForResponseMessage();
|
||||
|
||||
if (response.Exception != null)
|
||||
{
|
||||
if (!workflowTerminated)
|
||||
throw response.Exception;
|
||||
else
|
||||
throw new ApplicationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_WorkflowTerminated), response.Exception);
|
||||
}
|
||||
|
||||
if (response.OutArgs != null)
|
||||
return ((ArrayList)response.OutArgs).ToArray();
|
||||
else
|
||||
return new Object[] { };
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (workflowTerminationHandler != null)
|
||||
WorkflowRuntime.WorkflowTerminated -= workflowTerminationHandler;
|
||||
|
||||
if (workflowCompletedHandler != null)
|
||||
WorkflowRuntime.WorkflowCompleted -= workflowCompletedHandler;
|
||||
}
|
||||
}
|
||||
protected WorkflowRuntime WorkflowRuntime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext.Current != null)
|
||||
return WorkflowWebService.CurrentWorkflowRuntime;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#region Static Helpers
|
||||
private static Guid GetWorkflowInstanceId(ref bool isActivation)
|
||||
{
|
||||
Guid workflowInstanceId = Guid.Empty;
|
||||
|
||||
Object instanceId = HttpContext.Current.Items["__WorkflowInstanceId__"];
|
||||
|
||||
if (instanceId == null && !isActivation)
|
||||
throw new InvalidOperationException(SR.GetString(SR.Error_NoInstanceInSession));
|
||||
|
||||
if (instanceId != null)
|
||||
{
|
||||
workflowInstanceId = (Guid)instanceId;
|
||||
|
||||
Object isActivationContext = HttpContext.Current.Items["__IsActivationContext__"];
|
||||
|
||||
if (isActivationContext != null)
|
||||
isActivation = (bool)isActivationContext;
|
||||
else
|
||||
isActivation = false;
|
||||
}
|
||||
else if (isActivation)
|
||||
{
|
||||
workflowInstanceId = Guid.NewGuid();
|
||||
HttpContext.Current.Items["__WorkflowInstanceId__"] = workflowInstanceId;
|
||||
}
|
||||
return workflowInstanceId;
|
||||
}
|
||||
private static MethodMessage PrepareMessage(Type interfaceType, String operation, object[] parameters, bool responseRequired)
|
||||
{
|
||||
// construct IMethodMessage object
|
||||
String securityIdentifier = null;
|
||||
IIdentity identity = System.Threading.Thread.CurrentPrincipal.Identity;
|
||||
WindowsIdentity windowsIdentity = identity as WindowsIdentity;
|
||||
if (windowsIdentity != null && windowsIdentity.User != null)
|
||||
securityIdentifier = windowsIdentity.User.Translate(typeof(NTAccount)).ToString();
|
||||
else if (identity != null)
|
||||
securityIdentifier = identity.Name;
|
||||
|
||||
MethodMessage msg = new MethodMessage(interfaceType, operation, parameters, securityIdentifier, responseRequired);
|
||||
return msg;
|
||||
}
|
||||
//Back - off logic for conflicting workflow load across workflow runtime boundaries.
|
||||
static void SafeEnqueueItem(WorkflowInstance instance, EventQueueName key, MethodMessage message)
|
||||
{
|
||||
while (true) //When Execution times out ASP.NET going to forcefully plung this request.
|
||||
{
|
||||
try
|
||||
{
|
||||
instance.EnqueueItem(key, message, null, null);
|
||||
return;
|
||||
}
|
||||
catch (WorkflowOwnershipException)
|
||||
{
|
||||
WorkflowActivityTrace.Activity.TraceEvent(TraceEventType.Warning, 0, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Workflow Web Host Encountered Workflow Instance Ownership conflict for instanceid {0}.", instance.InstanceId));
|
||||
//Back-off for 1/2 sec. Should we make this configurable?
|
||||
System.Threading.Thread.Sleep(500);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Singleton WorkflowRuntime Accessor
|
||||
internal const string ConfigSectionName = "WorkflowRuntime";
|
||||
|
||||
// Double-checked locking pattern requires volatile for read/write synchronization
|
||||
static volatile WorkflowRuntime wRuntime;
|
||||
static Object wRuntimeSync = new Object();
|
||||
|
||||
internal static WorkflowRuntime CurrentWorkflowRuntime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (wRuntime == null)
|
||||
{
|
||||
lock (wRuntimeSync)
|
||||
{
|
||||
if (wRuntime == null)
|
||||
{
|
||||
WorkflowRuntime workflowRuntimeTemp = new WorkflowRuntime(ConfigSectionName);
|
||||
try
|
||||
{
|
||||
workflowRuntimeTemp.StartRuntime();
|
||||
}
|
||||
catch
|
||||
{
|
||||
workflowRuntimeTemp.Dispose();
|
||||
throw;
|
||||
}
|
||||
|
||||
wRuntime = workflowRuntimeTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wRuntime;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user