예제 #1
0
        protected override async Task <ICollection <MessageToken> > Process(BPMNExecutionContext context, UserTask elt, CancellationToken cancellationToken)
        {
            var handler = _handlers.First(_ => _.Implementation == elt.Implementation);
            var result  = await handler.Execute(context, elt, cancellationToken);

            return(result);
        }
예제 #2
0
        protected override Task <BPMNExecutionResult> Handle(BPMNExecutionContext executionContext, T nodeDef, CancellationToken cancellationToken)
        {
            var flowNodeIds = GetNextFlowNodeIds(executionContext, nodeDef);

            if (nodeDef.EventDefinitions.Any())
            {
                var lst = new List <bool>();
                foreach (var evtDef in nodeDef.EventDefinitions)
                {
                    lst.Add(executionContext.Pointer.Incoming.Any(_ => evtDef.IsSatisfied(executionContext.Instance, _)));
                }

                if ((nodeDef.ParallelMultiple && lst.All(_ => _ == true)) ||
                    (!nodeDef.ParallelMultiple && lst.Any(_ => _ == true)))
                {
                    var outcome = new List <MessageToken>();
                    outcome.AddRange(executionContext.Pointer.Incoming);
                    return(Task.FromResult(BPMNExecutionResult.Next(flowNodeIds, executionContext.Pointer.Incoming.ToList(), isEltInstanceCompleted: false, isNewExecutionPointerRequired: true)));
                }

                return(Task.FromResult(BPMNExecutionResult.Block()));
            }

            return(Task.FromResult(BPMNExecutionResult.Next(flowNodeIds, new List <MessageToken>()
            {
                MessageToken.EmptyMessage()
            })));
        }
예제 #3
0
        protected override Task <ICollection <MessageToken> > Process(BPMNExecutionContext context, EmptyTask elt, CancellationToken cancellationToken)
        {
            ICollection <MessageToken> result = new List <MessageToken> {
                MessageToken.EmptyMessage(context.Pointer.InstanceFlowNodeId, elt.EltId)
            };

            return(Task.FromResult(result));
        }
예제 #4
0
        protected override async Task <BPMNExecutionResult> Handle(BPMNExecutionContext executionContext, T elt, CancellationToken cancellationToken)
        {
            var pointer = executionContext.Pointer;

            if (pointer.Incoming.Count() < elt.StartQuantity)
            {
                return(BPMNExecutionResult.Block());
            }

            // Page : 428 : BPMN2.0.2
            var flowNodeIds = GetNextFlowNodeIds(executionContext, elt);
            var instance    = executionContext.Instance.GetInstance(pointer.InstanceFlowNodeId);

            if (instance.ActivityState == null)
            {
                executionContext.Instance.UpdateState(instance, ActivityStates.READY);
            }

            if (instance.ActivityState == ActivityStates.READY)
            {
                executionContext.Instance.UpdateState(instance, ActivityStates.ACTIVE);
            }

            if (instance.ActivityState == ActivityStates.ACTIVE)
            {
                executionContext.Instance.UpdateState(instance, ActivityStates.COMPLETING);
            }

            var outcome = new List <MessageToken>();

            outcome.AddRange(executionContext.Pointer.Incoming);
            if (instance.ActivityState == ActivityStates.COMPLETING)
            {
                try
                {
                    var addOutcome = await Process(executionContext, elt, cancellationToken);

                    outcome.AddRange(addOutcome);
                    executionContext.Instance.UpdateState(instance, ActivityStates.COMPLETED);
                }
                catch (FlowNodeInstanceBlockedException)
                {
                    return(BPMNExecutionResult.Block());
                }
                catch (Exception ex)
                {
                    executionContext.Instance.UpdateState(instance, ActivityStates.FAILING, ex.ToString());
                    return(BPMNExecutionResult.Block());
                }
            }

            if (instance.ActivityState == ActivityStates.FAILING)
            {
                return(BPMNExecutionResult.Block());
            }

            return(BPMNExecutionResult.Next(flowNodeIds, outcome));
        }
예제 #5
0
        public async Task <ICollection <MessageToken> > Execute(BPMNExecutionContext context, ICollection <MessageToken> incoming, DelegateConfigurationAggregate delegateConfiguration, CancellationToken cancellationToken)
        {
            var user = incoming.FirstOrDefault(i => i.Name == "user");

            if (user == null)
            {
                throw new BPMNProcessorException("user must be passed in the request");
            }

            var userId = user.GetProperty("userId");

            if (string.IsNullOrWhiteSpace(userId))
            {
                throw new BPMNProcessorException("userId is not passed in the request");
            }

            var parameter = GenerateOTPPasswordParameter.Create(delegateConfiguration);

            using (var httpClient = new HttpClient())
            {
                var tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                {
                    Address      = parameter.TokenUrl,
                    ClientId     = parameter.ClientId,
                    ClientSecret = parameter.ClientSecret,
                    Scope        = parameter.Scope
                }, cancellationToken);

                if (tokenResponse.IsError)
                {
                    throw new BPMNProcessorException(tokenResponse.Error);
                }

                var url     = parameter.UserUrl.Replace("{id}", userId);
                var request = new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri(url)
                };
                request.Headers.Add("Authorization", $"Bearer {tokenResponse.AccessToken}");
                var httpResponse = await httpClient.SendAsync(request, cancellationToken);

                httpResponse.EnsureSuccessStatusCode();
                var content = await httpResponse.Content.ReadAsStringAsync();

                var otp = long.Parse(content);
                ICollection <MessageToken> result = new List <MessageToken>
                {
                    MessageToken.NewMessage(context.Pointer.InstanceFlowNodeId, "otp", new JObject
                    {
                        { "otpCode", otp }
                    }.ToString())
                };
                return(result);
            }
        }
        public Task <ICollection <MessageToken> > Execute(BPMNExecutionContext context, ICollection <MessageToken> incoming, DelegateConfigurationAggregate delegateConfiguration, CancellationToken cancellationToken)
        {
            ICollection <MessageToken> result = new List <MessageToken>();

            result.Add(MessageToken.NewMessage(context.Pointer.InstanceFlowNodeId, "weatherInformation", new JObject
            {
                { "city", "Bruxelles" },
                { "degree", "31" }
            }.ToString()));
            return(Task.FromResult(result));
        }
예제 #7
0
        protected override Task <BPMNExecutionResult> Handle(BPMNExecutionContext executionContext, InclusiveGateway elt, CancellationToken cancellationToken)
        {
            var flowNodeIds = GetNextFlowNodeIds(executionContext, elt);

            if (flowNodeIds.Count() == 0 && string.IsNullOrWhiteSpace(elt.Default))
            {
                throw new BPMNProcessorException(Global.NoDefaultSequenceFlow);
            }

            if (flowNodeIds.Count() == 0)
            {
                flowNodeIds.Add(elt.Default);
            }

            return(Task.FromResult(BPMNExecutionResult.Next(flowNodeIds, executionContext.Pointer.Incoming)));
        }
예제 #8
0
        public Task <ICollection <MessageToken> > Execute(BPMNExecutionContext context, ICollection <MessageToken> incoming, DelegateConfigurationAggregate delegateConfiguration, CancellationToken cancellationToken)
        {
            var user = incoming.FirstOrDefault(i => i.Name == "user");

            if (user == null)
            {
                throw new BPMNProcessorException("user must be passed in the request");
            }

            var email = user.GetProperty("email");

            if (string.IsNullOrWhiteSpace(email))
            {
                throw new BPMNProcessorException("email is not passed in the request");
            }

            var parameter = SendDelegateParameter.Build(delegateConfiguration);

            using (var smtpClient = new SmtpClient())
            {
                smtpClient.EnableSsl             = parameter.SmtpEnableSsl;
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials           = new NetworkCredential(parameter.SmtpUserName, parameter.SmtpPassword);
                smtpClient.Host           = parameter.SmtpHost;
                smtpClient.Port           = parameter.SmtpPort;
                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                var mailMessage = new MailMessage
                {
                    From       = new MailAddress(parameter.FromEmail),
                    Subject    = parameter.Subject,
                    Body       = DelegateHelper.Parse(delegateConfiguration, incoming, parameter.HttpBody),
                    IsBodyHtml = true
                };

                mailMessage.To.Add(email.ToString());
                smtpClient.Send(mailMessage);
            }

            ICollection <MessageToken> result = new List <MessageToken>
            {
                MessageToken.EmptyMessage(context.Pointer.InstanceFlowNodeId, "sendEmail")
            };

            return(Task.FromResult(result));
        }
예제 #9
0
        protected override Task <BPMNExecutionResult> Handle(BPMNExecutionContext executionContext, ParallelGateway elt, CancellationToken cancellationToken)
        {
            var outgoingFlowNodeIds = GetOutgoingFlowNodeIds(executionContext, elt);
            var incomingFlowNodeIds = GetIncomingFlowNodeIds(executionContext, elt);

            if (elt.GatewayDirection == GatewayDirections.CONVERGING && outgoingFlowNodeIds.Count() != 1)
            {
                throw new BPMNProcessorException("Must have no more than one outgoing sequence flow");
            }

            if (elt.GatewayDirection == GatewayDirections.DIVERGING && incomingFlowNodeIds.Count() != 1)
            {
                throw new BPMNProcessorException("Must have no more than one incoming sequence flow");
            }

            var incoming = executionContext.Pointer.Incoming;
            ICollection <MessageToken> outcome = new List <MessageToken>();

            if (elt.GatewayDirection == GatewayDirections.CONVERGING)
            {
                if (incoming.Count() != incomingFlowNodeIds.Count())
                {
                    return(Task.FromResult(BPMNExecutionResult.Block()));
                }

                foreach (var record in incoming)
                {
                    if (!outcome.Any(_ => _.Name == record.Name))
                    {
                        outcome.Add(record);
                    }
                }
            }
            else
            {
                outcome = incoming.ToList();
            }

            return(Task.FromResult(BPMNExecutionResult.Next(outgoingFlowNodeIds, outcome)));
        }
        public async Task <ICollection <MessageToken> > Execute(BPMNExecutionContext context, ICollection <MessageToken> incoming, DelegateConfigurationAggregate delegateConfiguration, CancellationToken cancellationToken)
        {
            var user = incoming.FirstOrDefault(i => i.Name == "user");

            if (user == null)
            {
                throw new BPMNProcessorException("user must be passed in the request");
            }

            var userId = user.GetProperty("userId");

            if (string.IsNullOrWhiteSpace(userId))
            {
                throw new BPMNProcessorException("userId is not passed in the request");
            }

            var humanTaskInstanceId = incoming.First(i => i.Name == "humanTaskCreated").JObjMessageContent.SelectToken("humanTaskInstance.id").ToString();

            using (var httpClient = new HttpClient())
            {
                var parameter     = AssignHumanTaskInstanceParameter.Create(delegateConfiguration);
                var tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                {
                    Address      = parameter.TokenUrl,
                    ClientId     = parameter.ClientId,
                    ClientSecret = parameter.ClientSecret,
                    Scope        = "manage_humantaskinstance"
                }, cancellationToken);
                await Claim(httpClient, parameter, humanTaskInstanceId, userId, tokenResponse.AccessToken, cancellationToken);
                await Start(httpClient, parameter, humanTaskInstanceId, userId, tokenResponse.AccessToken, cancellationToken);
            }

            ICollection <MessageToken> result = new List <MessageToken>
            {
                MessageToken.EmptyMessage(context.Pointer.InstanceFlowNodeId, "assignHumanTaskInstance")
            };

            return(result);
        }
예제 #11
0
 protected override Task InternalHandle(BPMNExecutionContext executionContext, BoundaryEvent nodeDef, CancellationToken cancellationToken)
 {
     return(Task.CompletedTask);
 }
예제 #12
0
        protected override Task <ICollection <MessageToken> > Process(BPMNExecutionContext context, EmptyTask elt, CancellationToken cancellationToken)
        {
            ICollection <MessageToken> emptyTokens = new List <MessageToken>();

            return(Task.FromResult(emptyTokens));
        }
예제 #13
0
 protected abstract Task InternalHandle(BPMNExecutionContext executionContext, T nodeDef, CancellationToken cancellationToken);
예제 #14
0
        public async Task <ICollection <MessageToken> > Execute(BPMNExecutionContext executionContext, UserTask userTask, CancellationToken token)
        {
            var pointer  = executionContext.Pointer;
            var instance = executionContext.Instance.GetInstance(pointer.InstanceFlowNodeId);

            if (!instance.Metadata.ContainsKey(HUMANTASK_INSTANCE_ID_NAME))
            {
                using (var httpClient = _httpClientFactory.Build())
                {
                    var operationParameters = new JObject
                    {
                        { "nameIdentifier", executionContext.Instance.NameIdentifier }
                    };
                    var ctx = new ConditionalExpressionContext(pointer.Incoming);
                    if (userTask.InputParameters != null && userTask.InputParameters.Any())
                    {
                        foreach (var inputParameter in userTask.InputParameters)
                        {
                            if (string.IsNullOrWhiteSpace(inputParameter.Value))
                            {
                                continue;
                            }

                            var value = ExpressionParser.GetString(inputParameter.Value, ctx);
                            operationParameters.Add(inputParameter.Key, value);
                        }
                    }

                    var jArr = new JArray();
                    var link = _options.CallbackUrl.Replace("{id}", executionContext.Instance.AggregateId);
                    link = link.Replace("{eltId}", pointer.InstanceFlowNodeId);
                    jArr.Add(link);
                    var tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                    {
                        Address      = _options.OAuthTokenEndpoint,
                        ClientId     = _options.ClientId,
                        ClientSecret = _options.ClientSecret,
                        Scope        = "create_humantaskinstance"
                    }, token);

                    if (tokenResponse.IsError)
                    {
                        throw new BPMNProcessorException(tokenResponse.Error);
                    }

                    var obj = new JObject
                    {
                        { "humanTaskName", userTask.HumanTaskName },
                        { "operationParameters", operationParameters },
                        { "callbackUrls", jArr }
                    };
                    var content = new StringContent(obj.ToString(), Encoding.UTF8, "application/json");
                    var request = new HttpRequestMessage
                    {
                        Method     = HttpMethod.Post,
                        Content    = content,
                        RequestUri = new Uri($"{_options.WSHumanTaskAPI}/humantaskinstances")
                    };
                    request.Headers.Add("Authorization", $"Bearer {tokenResponse.AccessToken}");
                    var httpResult = await httpClient.SendAsync(request, token);

                    var str = await httpResult.Content.ReadAsStringAsync();

                    var o = JObject.Parse(str);
                    var humanTaskInstancId = o["id"].ToString();
                    executionContext.Instance.UpdateMetadata(pointer.InstanceFlowNodeId, HUMANTASK_INSTANCE_ID_NAME, humanTaskInstancId);
                    throw new FlowNodeInstanceBlockedException();
                }
            }

            var stateTransition = executionContext.Instance.StateTransitions.FirstOrDefault(_ => _.State == "COMPLETED" && _.FlowNodeInstanceId == pointer.InstanceFlowNodeId);

            if (stateTransition == null)
            {
                throw new FlowNodeInstanceBlockedException();
            }

            var result = new List <MessageToken>();

            if (stateTransition.Content == null)
            {
                result.Add(MessageToken.EmptyMessage());
            }
            else
            {
                result.Add(MessageToken.NewMessage(userTask.Id, stateTransition.Content));
            }

            return(result);
        }
예제 #15
0
 protected abstract Task <ICollection <MessageToken> > Process(BPMNExecutionContext context, T elt, CancellationToken cancellationToken);
        public async Task <ICollection <MessageToken> > Execute(BPMNExecutionContext context, ICollection <MessageToken> incoming, DelegateConfigurationAggregate delegateConfiguration, CancellationToken cancellationToken)
        {
            var user = incoming.FirstOrDefault(i => i.Name == "user");

            if (user == null)
            {
                throw new BPMNProcessorException("userMessage must be passed in the request");
            }

            var userId = user.GetProperty("userId");

            if (string.IsNullOrWhiteSpace(userId))
            {
                throw new BPMNProcessorException("userId is not passed in the request");
            }

            var messageToken = incoming.FirstOrDefault(m => m.Name == ActivityName);

            if (messageToken == null)
            {
                throw new BPMNProcessorException($"incoming token '{ActivityName}' doesn't exist");
            }

            var password  = messageToken.GetProperty("pwd");
            var parameter = UpdateUserPasswordParameter.Create(delegateConfiguration);

            using (var httpClient = new HttpClient())
            {
                var tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                {
                    Address      = parameter.TokenUrl,
                    ClientId     = parameter.ClientId,
                    ClientSecret = parameter.ClientSecret,
                    Scope        = parameter.Scope
                }, cancellationToken);

                if (tokenResponse.IsError)
                {
                    throw new BPMNProcessorException(tokenResponse.Error);
                }

                var obj = new JObject
                {
                    { "password", password }
                };
                var content = new StringContent(obj.ToString(), Encoding.UTF8, "application/json");
                var url     = parameter.UserUrl.Replace("{id}", userId);
                var request = new HttpRequestMessage
                {
                    Method     = HttpMethod.Put,
                    Content    = content,
                    RequestUri = new Uri(url)
                };
                request.Headers.Add("Authorization", $"Bearer {tokenResponse.AccessToken}");
                var httpResponse = await httpClient.SendAsync(request, cancellationToken);

                httpResponse.EnsureSuccessStatusCode();
            }

            ICollection <MessageToken> result = new List <MessageToken>
            {
                MessageToken.EmptyMessage(context.Pointer.InstanceFlowNodeId, "updatePassword")
            };

            return(result);
        }