public async Task <bool> Handle(CompleteHumanTaskInstanceCommand request, CancellationToken cancellationToken)
        {
            if (request.Claims == null || !request.Claims.Any())
            {
                _logger.LogError("User is not authenticated");
                throw new NotAuthenticatedException(Global.UserNotAuthenticated);
            }

            if (request.OperationParameters == null)
            {
                _logger.LogError("Output data must be specified");
                throw new BadRequestException(string.Format(Global.MissingParameter, "operationParameters"));
            }

            var humanTaskInstance = await _humanTaskInstanceQueryRepository.Get(request.HumanTaskInstanceId, cancellationToken);

            if (humanTaskInstance == null)
            {
                _logger.LogError($"HumanTask '{request.HumanTaskInstanceId}' doesn't exist");
                throw new UnknownHumanTaskInstanceException(string.Format(Global.UnknownHumanTaskInstance, request.HumanTaskInstanceId));
            }

            if (humanTaskInstance.Status != HumanTaskInstanceStatus.INPROGRESS)
            {
                _logger.LogError("Complete operation can be performed only on INPROGRESS human task instance");
                throw new BadOperationExceptions(string.Format(Global.OperationCanBePerformed, "Complete", "INPROGRESS"));
            }

            var operationParameters = request.OperationParameters;
            var parameters          = _parameterParser.ParseOperationParameters(humanTaskInstance.OutputOperationParameters, operationParameters);
            var nameIdentifier      = request.Claims.GetUserNameIdentifier();

            if (nameIdentifier != humanTaskInstance.ActualOwner)
            {
                _logger.LogError("Authenticated user is not the actual owner");
                throw new NotAuthorizedException(Global.NotActualOwner);
            }

            var completionResult = await CheckCompletionBehavior(humanTaskInstance, parameters, cancellationToken);

            if (completionResult.IsSatisfied)
            {
                parameters = completionResult.Content;
            }

            await Complete(humanTaskInstance, parameters, nameIdentifier, cancellationToken);

            if (!string.IsNullOrWhiteSpace(humanTaskInstance.ParentHumanTaskId))
            {
                var parentTask = await _humanTaskInstanceQueryRepository.Get(humanTaskInstance.ParentHumanTaskId, cancellationToken);

                if (parentTask.CompletionBehavior == CompletionBehaviors.AUTOMATIC)
                {
                    completionResult = await CheckCompletionBehavior(parentTask, new Dictionary <string, string>(), cancellationToken, false);

                    if (completionResult.IsSatisfied)
                    {
                        await Complete(parentTask, new Dictionary <string, string>(), nameIdentifier, cancellationToken);
                    }
                }
            }

            foreach (var cb in humanTaskInstance.CallbackOperations)
            {
                var jObj = new JObject
                {
                    { "parameters", parameters.ToJObj() }
                };
                using (var httpClient = _httpClientFactory.Build())
                {
                    var tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                    {
                        Address      = _options.OAuthTokenEndpoint,
                        ClientId     = _options.ClientId,
                        ClientSecret = _options.ClientSecret,
                        Scope        = _options.Scope
                    }, cancellationToken);

                    var req = new HttpRequestMessage
                    {
                        Method     = HttpMethod.Post,
                        RequestUri = new Uri(cb.Url),
                        Content    = new StringContent(jObj.ToString(), Encoding.UTF8, "application/json")
                    };
                    req.Headers.Add("Authorization", $"Bearer {tokenResponse.AccessToken}");
                    await httpClient.SendAsync(req, cancellationToken);
                }
            }

            return(true);
        }
        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);
        }
Example #3
0
        public async Task <string> Create(CMMNExecutionContext executionContext, CaseEltInstance humanTaskElt, CancellationToken token)
        {
            using (var httpClient = _httpClientFactory.Build())
            {
                var operationParameters = new JObject
                {
                    { "nameIdentifier", executionContext.Instance.NameIdentifier }
                };

                var inputParameters = humanTaskElt.GetInputParameters();
                if (inputParameters != null && inputParameters.Any())
                {
                    foreach (var inputParameter in inputParameters)
                    {
                        if (string.IsNullOrWhiteSpace(inputParameter.Value))
                        {
                            continue;
                        }

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

                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 CMMNProcessorException(tokenResponse.Error);
                }

                var jArr = new JArray();
                var link = _options.CallbackUrl.Replace("{id}", executionContext.Instance.AggregateId);
                link = link.Replace("{eltId}", humanTaskElt.Id);
                jArr.Add(link);
                var obj = new JObject
                {
                    { "humanTaskName", humanTaskElt.GetFormId() },
                    { "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();
                return(humanTaskInstancId);
            }
        }