Exemplo n.º 1
0
        public int ProcessLaunch(HeContext heContext, int parentActivityId, int parentProcessId, List <Pair <string, object> > inputs, out List <Pair <int, ActivityKind> > nextActIds)
        {
            nextActIds = new List <Pair <int, ActivityKind> >();
            //Sanity check to make sure we dont get here with the singleton process instance for the "definitions"
            if (Object.ReferenceEquals(((IProcess)this).Instance, this))
            {
                return(NewInstance().ProcessLaunch(heContext, parentActivityId, parentProcessId, inputs, out nextActIds));
            }

            int tenantId = heContext.AppInfo.Tenant.Id;
            Pair <int, ObjectKey> startActivity;

            processIdOverride = BPMRuntime.CreateProcessInstance(heContext, tenantId, GlobalKey.OwnerKey, GlobalKey.Key, parentActivityId, parentProcessId, out startActivity);

            var inputDefinitions = AllProcessInputsDefinitions;
            Dictionary <ObjectKey, IActivityVariable> inputsProcessed = new Dictionary <ObjectKey, IActivityVariable>(inputDefinitions.Count);
            IActivityVariable curInput;

            foreach (Pair <string, object> input in inputs)
            {
                ObjectKey key = ObjectKey.Parse(input.First);
                if (inputDefinitions.TryGetValue(key, out curInput))
                {
                    inputsProcessed[key] = curInput.NewInstance(input.Second);
                }
            }

            using (Transaction trans = DatabaseAccess.ForSystemDatabase.GetRequestTransaction()) {
                foreach (var input in inputsProcessed.Values)
                {
                    DBRuntimePlatform.Instance.AddProcessInput(trans, ProcessId, tenantId, input);
                    this.ProcessInputs[input.Key] = input;
                }
            }

            Debugger.SetRequestName("Launch '" + Name + "'");

            OnProcessStartCallback(heContext);

            //#586734 Check if the process was created.
            //A rollback in the OnProcessStart can delete the process that was created.
            using (Transaction trans = DatabaseAccess.ForSystemDatabase.GetRequestTransaction()) {
                if (!DBRuntimePlatform.Instance.CheckProcessExists(trans, ProcessId))
                {
                    throw new InvalidOperationException("Failed to created process " + ProcessId);
                }
            }

            int previousTenantId = tenantId;

            tenantId = heContext.AppInfo.Tenant.Id;
            if (previousTenantId != tenantId)
            {
                //Do not use the same variable as above because that transaction can already be commited
                using (Transaction trans = DatabaseAccess.ForSystemDatabase.GetRequestTransaction()) {
                    DBRuntimePlatform.Instance.SwitchProcessTenant(trans, ProcessId, previousTenantId, tenantId);
                }
            }

            SaveProcessOutputs(heContext);
            DatabaseAccess.CommitAllTransactions();

            try {
                IProcessActivity startActivityInstance;
                if (GetProcessActivityInstance(ProcessId, startActivity.First, startActivity.Second, true, out startActivityInstance))
                {
                    var nextActivities = startActivityInstance.StartWork(heContext, false, ActivityStatus.Created)
                                         .Select(nextAct => Pair.Create(nextAct.First, nextAct.Second));

                    nextActIds = new List <Pair <int, ActivityKind> >(nextActivities);

                    //TODO #124852
                    //if (!nextActivities.IsEmpty()) {
                    //    //Do not use the same variable as above because that transaction will already be commited
                    //    nextHumanActivity = BPMRuntime.GetNextHumanActivity(heContext,
                    //        DBTransactionManager.Current.SystemConnectionManager.GetMainTransaction(), nextActivities, heContext.Session.UserId);
                    //}
                }
            } catch (Exception e) {
                // This should only happen if there are problems getting the next human activity, but we still want to return the process Id that was already created.
                Log.ErrorLog.StaticWrite(DateTime.Now, "", heContext.AppInfo.eSpaceId, heContext.AppInfo.Tenant.Id,
                                         heContext.Session.UserId, e.Message, e.StackTrace, "BPM");
            }


            return(ProcessId);
        }