/// <summary>
 /// CALLED FROM INVOKER. Run the activity in the provided context. Used to execute an activity within a workflow. If this activity metadata has not been added to the context it
 /// will be done now.
 /// </summary>
 /// <returns>True if completed, false if bookmarked.</returns>
 public bool RunInContext(IRunState runState, ActivityInputs inputs)
 {
     return(Execute(runState, inputs));
 }
        void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var OriginKey          = GetArgumentKey("setRelationshipActivityOriginArgument");
            var DestinationKey     = GetArgumentKey("setRelationshipActivityDestinationArgument");
            var RelationshipKey    = GetArgumentKey("setRelationshipActivityRelationshipArgument");
            var replaceExistingKey = GetArgumentKey("setRelationshipActivityReplaceExisting");
            var isReverseKey       = GetArgumentKey("setRelationshipActivityIsReverse");

            var originRef       = (IEntity)inputs[OriginKey];
            var relationshipRef = (IEntity)inputs[RelationshipKey];

            IEntity destinationRef = null;

            object destinationRefObj;

            if (inputs.TryGetValue(DestinationKey, out destinationRefObj))
            {
                destinationRef = (IEntity)destinationRefObj;
            }

            bool replaceExisting = false;

            object replaceExistingObj;

            if (inputs.TryGetValue(replaceExistingKey, out replaceExistingObj))
            {
                replaceExisting = (bool?)replaceExistingObj ?? false;
            }

            var direction = Direction.Forward;

            object isReverseObj;

            if (inputs.TryGetValue(isReverseKey, out isReverseObj))
            {
                direction = ((bool?)isReverseObj ?? false) ? Direction.Reverse : Direction.Forward;
            }


            var relationship = relationshipRef.As <Relationship>();

            SecurityBypassContext.RunAsUser(() =>
            {
                var origin = originRef.AsWritable <Entity>();

                var cardinality = relationship.Cardinality_Enum ?? CardinalityEnum_Enumeration.ManyToMany;

                replaceExisting =
                    replaceExisting
                    ||
                    cardinality == CardinalityEnum_Enumeration.OneToOne
                    ||
                    (direction == Direction.Forward && cardinality == CardinalityEnum_Enumeration.ManyToOne)
                    ||
                    (direction == Direction.Reverse && cardinality == CardinalityEnum_Enumeration.OneToMany)
                ;

                var relCollection = origin.GetRelationships(relationshipRef, direction);

                if (replaceExisting)
                {
                    relCollection.Clear();
                }

                if (destinationRef != null)
                {
                    relCollection.Add(destinationRef);
                }

                origin.Save();
            });
        }
        private const decimal DefaultTimeOutMins = 0;     // no time out

        public override bool OnStart(IRunState context, ActivityInputs inputs)
        {
            var assignedTo          = GetArgumentEntity <Person>(inputs, "inDisplayFormForUser");
            var recordToPresent     = GetArgumentEntity <UserResource>(inputs, "inDisplayFormResource");
            var form                = GetArgumentEntity <CustomEditForm>(inputs, "inDisplayFormForm");
            var timeoutDays         = GetArgumentValue <decimal>(inputs, "inDisplayFormTimeOut", DefaultTimeOutMins);
            var priority            = GetArgumentEntity <EventEmailPriorityEnum>(inputs, "inDisplayFormPriority");
            var activityInstanceAs  = ActivityInstance.Cast <DisplayFormActivity>();
            var percentageCompleted = GetArgumentValue <decimal?>(inputs, "inDisplayFormPercentageCompleted", null);
            var waitForNext         = GetArgumentValue <bool>(inputs, "inDisplayFormWaitForNext", false);
            var recordHistory       = GetArgumentValue <bool>(inputs, "inDisplayFormRecordHistory", false);
            var hideComment         = GetArgumentValue <bool>(inputs, "inHideComment", false);
            var openInEditMode      = GetArgumentValue <bool>(inputs, "inOpenInEditMode", false);

            priority = priority ?? Entity.Get <EventEmailPriorityEnum>(new EntityRef("core", "normalPriority"));

            var workflowRun = context.WorkflowRun;


            var dueDate = DateTime.UtcNow.AddDays((double)timeoutDays);

            var userTask = new DisplayFormUserTask
            {
                Name                 = ActivityInstance.Name ?? DefaultTitle,
                RecordToPresent      = recordToPresent,
                FormToUse            = form,
                AvailableTransitions = GetAvailableUserTransitions(),
                AssignedToUser       = assignedTo,
                TaskPriority         = priority,
                TaskStatus_Enum      = TaskStatusEnum_Enumeration.TaskStatusNotStarted,
                PercentageCompleted  = percentageCompleted,
                WaitForNextTask      = waitForNext,
                UserTaskDueOn        = dueDate,
                HideComment          = hideComment,
                OpenInEditMode       = openInEditMode,
                DfutLinkToken        = CryptoHelper.GetRandomPrintableString(8)
            };

            context.SetUserTask(userTask.Cast <BaseUserTask>());

            if (recordHistory)
            {
                CreateLogEntry(context, userTask);
            }

            SetTimeoutIfNeeded(context, timeoutDays);

            var tenantSetting = Entity.Get <TenantGeneralSettings>(WellKnownAliases.CurrentTenant.TenantGeneralSettingsInstance);

            if (Factory.FeatureSwitch.Get("enableWfUserActionNotify"))
            {
                //
                // IN PROGRESS - Please leave
                // This code is in development and switched off until email and SMS approvals are required by PM.
                //
                Notifier notifier = null; // tenantSetting.UserActionNotifier;
                if (notifier != null)
                {
                    // TODO: Format correctly for where it is being sent SMS email etc. Move the decision out of here and make the notfier decide on the type of message
                    var generator = new HtmlGenerator();

                    string message = null;
                    if (notifier.Is <EmailNotifier>())           // TODO: This is wrong, it should be somehow tied to the Router
                    {
                        var transitionOptions = userTask.AvailableTransitions.Select(t => t.FromExitPoint.Name).Where(n => !String.IsNullOrEmpty(n));

                        if (transitionOptions.Any())
                        {
                            message = generator.GenerateSelectionPage(userTask);
                        }
                    }
                    else if (notifier.Is <TwilioNotifier>())
                    {
                        message = generator.GenerateSelectionPageUrl(userTask.DfutLinkToken);
                    }

                    if (message != null)
                    {
                        var userList = userTask.AssignedToUser.ToEnumerable();

                        var notification = new Notification {
                            NMessage = message
                        };

                        //TOOD: Add alternative text in the email with a link to the SMS page
                        NotificationRouter.Instance.Send(notifier, notification, userList, false);
                    }
                }
            }

            context.SetArgValue(ActivityInstance, GetArgumentKey("core:outDisplayFormUserTask"), userTask);
            context.SetArgValue(ActivityInstance, GetArgumentKey("core:dfaInternalKeepHistory"), recordHistory);

            return(false);
        }
 /// <summary>
 /// Builds a request from the current state of the workflow run to initiate the appropriate action remotely.
 /// </summary>
 /// <param name="context">The workflow run context.</param>
 /// <param name="inputs">The activity input arguments.</param>
 /// <returns>The request object.</returns>
 protected abstract TRequest GetRequest(IRunState context, ActivityInputs inputs);
Beispiel #5
0
        /// <summary>
        /// Keep running outstanding activities until completion.
        /// </summary>
        /// <returns>True, workflow has completed, False if there are pending activities.</returns>
        bool RunTillCompletion(WorkflowInvoker invoker, IRunState runState)
        {
            bool hasCompleted = invoker.RunTillCompletion(runState);

            return(hasCompleted);
        }
Beispiel #6
0
 private string GetSafeWfDescription(IRunState runState)
 {
     return(runState != null?runState.GetSafeWorkflowDescription() : "");
 }
Beispiel #7
0
 void IRunNowActivity.OnRunNow(IRunState context, ActivityInputs inputs)
 {
     Action(ActivityInstance.Id);
 }
Beispiel #8
0
        private WorkflowRun ProcessWorkflowInContext(WorkflowRun run, IWorkflowEvent wfEvent)
        {
            var workflow = run.WorkflowBeingRun;

            using (Profiler.Measure("WorkflowRunner.Instance.StartWorkflowInContext " + workflow.Id))
            {
                var stopWatch = StartWorkflowTimer();

                IRunState runState = null;

                try
                {
                    if (!run.IsTemporaryId)
                    {
                        PrecacheWorkflow(run.Id);
                    }

                    using (new SecurityBypassContext())
                    {
                        var metadata = MetadataFactory.Create(workflow);

                        runState = CreateRunState(metadata, run);

                        if (runState.EffectiveSecurityContext == null)
                        {
                            throw new WorkflowMissingOwnerException();
                        }
                    }

                    // Wrap a Security bypass with the effective context. This less us "Pop" to run as the effective context.
                    using (CustomContext.SetContext(runState.EffectiveSecurityContext))
                    {
                        using (new SecurityBypassContext())
                        {
                            if (runState.Metadata.HasViolations)
                            {
                                MarkRunFailedHasErrors(runState);
                            }
                            else if (run.TriggerDepth > WorkflowTriggerHelper.MaxTriggerDepth)
                            {
                                MarkRunFailedTriggerDepth(runState);
                            }
                            else
                            {
                                var isCompleted = ProcessWorkflow(workflow, runState, wfEvent);
                            }
                        }
                    }
                }
                catch (WorkflowRunException ex)
                {
                    MarkRunFailed(runState, ex);

                    if (runState != null)
                    {
                        runState.FlushInternalArgs();
                    }
                }
                catch (Exception ex)
                {
                    MarkRunInternalError(runState, ex);

                    if (runState != null)
                    {
                        runState.FlushInternalArgs();
                    }
                }
                finally
                {
                    if (!Factory.WorkflowRunTaskManager.HasCancelled(runState.RunTaskId))
                    {
                        run = FinalizeRun(runState);
                    }
                }

                EndWorkflowTimer(stopWatch);
            }

            return(run);
        }
 /// <summary>
 /// Run an activity on the invoker
 /// </summary>
 /// <param name="runState">The runState for the workflow</param>
 /// <param name="windowsActivity">The activity to run</param>
 /// <param name="inputs">The inputs</param>
 /// <returns></returns>
 public bool Run(IRunState runState, ActivityImplementationBase windowsActivity, ActivityInputs inputs)
 {
     ScheduleActivity(runState, windowsActivity, inputs, null, null);
     return(RunTillCompletion(runState));
 }
 /// <summary>
 /// Resume a paused activity on the invoker
 /// </summary>
 /// <param name="runState">The runstate</param>
 /// <param name="windowsActivity">The activity</param>
 /// <param name="resumeEvent">The trigger event for the resume</param>
 /// <returns></returns>
 public bool Resume(IRunState runState, ActivityImplementationBase windowsActivity, IWorkflowEvent resumeEvent)
 {
     ScheduleResume(runState, windowsActivity, resumeEvent, null, null);
     return(RunTillCompletion(runState));
 }
Beispiel #11
0
        /// <summary>
        /// Runs when the activity is run by the workflow.
        /// </summary>
        /// <param name="context">The run state.</param>
        /// <param name="inputs">The inputs.</param>
        public void OnRunNow(IRunState context, ActivityInputs inputs)
        {
            var startedKey    = GetArgumentKey(StartedArgumentAlias);
            var listKey       = GetArgumentKey(ListArgumentAlias);
            var appIdKey      = GetArgumentKey(ApplicationIdArgumentAlias);
            var appVersionKey = GetArgumentKey(ApplicationVersionArgumentAlias);

            var ids     = new List <Guid>();
            var started = context.GetArgValue <bool?>(ActivityInstance, startedKey) ?? false;

            if (!started)
            {
                // set that the activity has started
                context.SetArgValue(ActivityInstance, startedKey, true);

                // retrieve the product
                var productSku = GetArgumentValue <string>(inputs, ProductSkuArgumentAlias);

                var product = MarketplaceService.GetProduct(productSku);
                if (product == null)
                {
                    throw new WorkflowRunException("Product {0} was not found.", productSku);
                }

                // process the included apps and app versions and sort their ids
                ids.AddRange(GetSortedApplicationIds(product));
            }
            else
            {
                // retrieve the current state of the ordered list from the context
                var list = context.GetArgValue <string>(ActivityInstance, listKey);
                if (!string.IsNullOrEmpty(list))
                {
                    ids.AddRange(list.Split(',').Select(Guid.Parse));
                }
            }

            // loop over the next id on the list
            var current = ids.FirstOrDefault();

            if (current != default(Guid))
            {
                // set the application id and any specific version info on the output
                var variables = GetAppVariables(context, current);
                if (variables.Item1 != Guid.Empty)
                {
                    context.SetArgValue(ActivityInstance, appIdKey, variables.Item1);
                    context.SetArgValue(ActivityInstance, appVersionKey, variables.Item2);
                }

                // remove this id from the list and store it again
                ids = ids.Skip(1).ToList();

                var list = string.Join(",", ids);

                context.SetArgValue(ActivityInstance, listKey, list);
                context.ExitPointId = new EntityRef(LoopExitPointAlias);
            }
            else
            {
                // we have finished
                context.SetArgValue(ActivityInstance, startedKey, false);
                context.SetArgValue(ActivityInstance, listKey, null);
                context.ExitPointId = new EntityRef(FinishedExitPointAlias);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="HtmlReportFormatter"/> class.
 /// </summary>
 /// <param name="model">The application model.</param>
 /// <param name="context">The migration context.</param>
 /// <param name="state">The run state.</param>
 /// <param name="writer">The report writer.</param>
 /// <param name="logger">The logger.</param>
 public HtmlReportFormatter(IApplicationModel model, MigrationContext context, IRunState state, IReportWriter writer, ILogger logger)
     : base(model, context, state, writer, logger)
 {
     logger.LogTrace(TraceMessages.ReporterConstruct, nameof(HtmlReportFormatter));
 }
        /// <summary>
        /// Runs the stage runner.
        /// </summary>
        /// <param name="state">The execution state.</param>
        /// <param name="token">A cancellation token used to cancel this operation.</param>
        /// <returns>A task used to await the operation.</returns>
        protected override async Task InvokeRunAsync(IRunState state, CancellationToken token)
        {
            _ = state ?? throw new ArgumentNullException(nameof(state));

            // Get context
            var context = Container.GetRequiredService <MigrationContext>();

            // Add MSI files from directory if specified
            if (!string.IsNullOrWhiteSpace(_msiDirectory))
            {
                var dirInfo  = new DirectoryInfo(_msiDirectory);
                var msiFiles = dirInfo.GetFiles("*.msi", SearchOption.AllDirectories);

                foreach (var file in msiFiles)
                {
                    _msiFiles.Add(file.FullName);
                }
            }

            // Anything to do?
            if (_msiFiles.Count == 0)
            {
                // Nothing to do, return an error
                _logger.LogError(ErrorMessages.NoMsiFilesOrDirectorySpecified);
                context.Errors.Add(new ErrorMessage(ErrorMessages.NoMsiFilesOrDirectorySpecified));

                await Task.CompletedTask.ConfigureAwait(false);
            }

            // Default unpack directory if not specified
            if (string.IsNullOrWhiteSpace(_unpackDirectory))
            {
                _unpackDirectory = Environment.CurrentDirectory;
            }

            _logger.LogInformation(InformationMessages.UnpackDirectory, _unpackDirectory);

            // Set up resource containers
            var model = (AzureIntegrationServicesModel)state.Model;

            // Create the input criteria (distinct paths to the MSIs)
            foreach (var path in _msiFiles.Select(p => new FileInfo(p)).GroupBy(f => f.Name).Select(f => f.First()))
            {
                var pathFullName = Directory.GetFiles(path.DirectoryName, Path.GetFileName(path.Name)).First();
                var name         = Path.GetFileNameWithoutExtension(pathFullName);
                model.MigrationSource.ResourceContainers.Add(new ResourceContainer()
                {
                    Key = name, Name = name, Type = ModelConstants.ResourceContainerMsi, ContainerLocation = pathFullName
                });
            }

            // Set working folder
            context.WorkingFolder = _unpackDirectory;

            // Call the discover logic (probably should be async)
            var discoverer = Container.GetRequiredService <BizTalk.Discover.MsiDiscoverer>();

            discoverer.Discover();

            await Task.CompletedTask.ConfigureAwait(false);
        }
Beispiel #14
0
        /// <summary>
        /// Prints the execution stats.
        /// </summary>
        /// <param name="runState">The execution run state.</param>
        private void PrintExecutionStats(IRunState runState)
        {
            if (runState != null && runState.ExecutionState != null)
            {
                if (!_options.Options.Verbose)
                {
                    // Find and print any stage runners that didn't complete
                    if (runState.ExecutionState.Values.Any(s => s.ExecutionState.Any(r => r.State != State.Completed && r.State != State.Skipped)))
                    {
                        foreach (var stageState in runState.ExecutionState.Values)
                        {
                            foreach (var runnerState in stageState.ExecutionState)
                            {
                                if (runnerState.State != State.Completed && runnerState.State != State.Skipped)
                                {
                                    var runnerName = runnerState.StageRunner.Name ?? runnerState.StageRunner.GetType().FullName;

                                    switch (runnerState.State)
                                    {
                                    case State.Failed:
                                        _logger.LogError(ErrorMessages.StageRunnerFailed, runnerName, runnerState.Error.Message);
                                        break;

                                    default:
                                        _logger.LogWarning(WarningMessages.StageRunnerDidNotCompleteSuccessfully, runnerName, runnerState.State);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // Print detailed execution stats
                    var firstStageState = runState.ExecutionState.Values.Where(s => s.Stage == Stages.Discover).FirstOrDefault();
                    if (firstStageState != null)
                    {
                        var startTime = firstStageState.Started;

                        foreach (var stageState in runState.ExecutionState.Values)
                        {
                            _logger.LogDebug(TraceMessages.StageExecutionStats, stageState.Stage, stageState.State, (stageState.Started - startTime).TotalMilliseconds, (stageState.Completed - startTime).TotalMilliseconds);

                            foreach (var runnerState in stageState.ExecutionState)
                            {
                                var runnerName = runnerState.StageRunner.Name ?? runnerState.StageRunner.GetType().FullName;

                                switch (runnerState.State)
                                {
                                case State.Failed:
                                    _logger.LogDebug(TraceMessages.StageRunnerExecutionStatsWithError, runnerName, stageState.Stage, runnerState.State, (runnerState.Started - startTime).TotalMilliseconds, (runnerState.Completed - startTime).TotalMilliseconds, runnerState.Error.Message);
                                    break;

                                default:
                                    _logger.LogDebug(TraceMessages.StageRunnerExecutionStats, runnerName, stageState.Stage, runnerState.State, (runnerState.Started - startTime).TotalMilliseconds, (runnerState.Completed - startTime).TotalMilliseconds);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #15
0
 /// <summary>
 /// Default constructor for dependency injection.
 /// </summary>
 /// <param name="model">The application model.</param>
 /// <param name="context">The migration context.</param>
 /// <param name="state">The application's run state.</param>
 /// <param name="writer">An instance of a <see cref="IReportWriter"/> to be used for writing the report.</param>
 /// <param name="logger">An instance of a <see cref="ILogger"/> to be used for logging within the class.</param>
 protected BizTalkReporterBase(IApplicationModel model, MigrationContext context, IRunState state, IReportWriter writer, ILogger logger)
 {
     Model   = (AzureIntegrationServicesModel)model ?? throw new ArgumentNullException(nameof(model));
     Context = context ?? throw new ArgumentNullException(nameof(context));
     State   = state ?? throw new ArgumentNullException(nameof(state));
     Writer  = writer ?? throw new ArgumentNullException(nameof(writer));
     Logger  = logger ?? throw new ArgumentNullException(nameof(logger));
 }
Beispiel #16
0
        /// <summary>
        /// Builds a state path for execution state.
        /// </summary>
        /// <param name="statePath">The state path.</param>
        /// <param name="after">True if event raised after execution, other False for before execution.</param>
        /// <param name="stage">True to build path for a stage, otherwise False for a stage runner.</param>
        /// <param name="runState">The execution state.</param>
        /// <returns>A fully qualified path</returns>
        private static string BuildStatePath(string statePath, bool after, bool stage, IRunState runState)
        {
            var stageState = runState.ExecutionState.Values.Where(s => s.IsCurrent).First();
            var stageName  = stageState.Stage.ToString("G");

            var dateTime = DateTimeOffset.Now.ToString("yyyy-MM-dd.HH-mm-ss.fff", CultureInfo.InvariantCulture);

            if (stage)
            {
                var stageFile = string.Format(CultureInfo.InvariantCulture, "{0}-{1}.json", stageName, dateTime);

                // Stage
                if (!after)
                {
                    // Before execution
                    statePath = Path.Join(statePath, PathResources.BeforeStage, stageFile);
                }
                else
                {
                    // After execution
                    statePath = Path.Join(statePath, PathResources.AfterStage, stageFile);
                }
            }
            else
            {
                var stageRunnerState = stageState.ExecutionState.Where(s => s.IsCurrent).First();
                var stageRunnerName  = stageRunnerState.StageRunner.Name ?? stageRunnerState.StageRunner.GetType().Name;
                var stageRunnerFile  = string.Format(CultureInfo.InvariantCulture, "{0}-{1}.json", stageRunnerName, dateTime);

                // Stage runner
                if (!after)
                {
                    // Before execution
                    statePath = Path.Join(statePath, PathResources.BeforeStageRunner, stageName, stageRunnerFile);
                }
                else
                {
                    // After execution
                    statePath = Path.Join(statePath, PathResources.AfterStageRunner, stageName, stageRunnerFile);
                }
            }

            // Ensure path exists
            var dirs = new FileInfo(statePath).Directory.FullName;

            Directory.CreateDirectory(dirs);

            return(statePath);
        }
        public void ConstructWithSuccess(HtmlReportFormatter reporter, IApplicationModel model, MigrationContext context, IRunState state, IReportWriter writer, ILogger logger, Exception e)
        {
            "Given an reporter"
            .x(() => reporter.Should().BeNull());

            "And a model"
            .x(() => model = TestHelper.BuildModel());

            "And run state"
            .x(() => state = TestHelper.BuildRunState(model));

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a writer"
            .x(() => writer = _mockWriter.Object);

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "When constructing..."
            .x(() => e = Record.Exception(() => new HtmlReportFormatter(model, context, state, writer, logger)));

            "Then the constructor should NOT throw an exception"
            .x(() => e.Should().BeNull());
        }
Beispiel #18
0
        private WorkflowRun FinalizeRun(IRunState runState)
        {
            WorkflowRun run;

            using (Profiler.Measure("WorkflowRunner.Instance.FinalizeRun"))
            {
                using (new SecurityBypassContext())
                {
                    try
                    {
                        run = runState.WorkflowRun;
                        runState.CompletedAt = DateTime.UtcNow;
                        if (!run.IsTemporaryId)
                        {
                            run = Entity.Get <WorkflowRun>(runState.WorkflowRun,
                                                           true,
                                                           WorkflowRun.WorkflowRunExitPoint_Field,
                                                           WorkflowRun.HasTimeout_Field,
                                                           WorkflowRun.PendingActivity_Field,
                                                           WorkflowRun.RunStepCounter_Field,
                                                           WorkflowRun.WorkflowRunStatus_Field,
                                                           WorkflowRun.RunCompletedAt_Field,
                                                           WorkflowRun.StateInfo_Field);
                        }

                        var deferredRun = run as WorkflowRunDeferred;
                        if (deferredRun != null)
                        {
                            deferredRun.Sync();
                        }



                        runState.SyncToRun(run);

                        WorkflowRunContext.Current.DeferSave(run);

                        //
                        // Raise a completed child event
                        //
                        if (run != null && run.ParentRun != null && IsRunCompleted(run))
                        {
                            // This should be hooked into an eventing system. As we don't have one, just run the resume async.
                            runState.WorkflowInvoker.PostEvent(new ChildWorkflowCompletedEvent(run));
                        }

                        //
                        // Add a restore message to the queue if we are suspended
                        //
                        if (run != null && run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunSuspended)
                        {
                            WorkflowRunContext.Current.DeferAction(() =>
                            {
                                // This should be hooked into an eventing system. As we don't have one, just run the resume async.
                                var restoreTask = ResumeWorkflowHandler.CreateBackgroundTask(run, new WorkflowRestoreEvent());
                                Factory.BackgroundTaskManager.EnqueueTask(restoreTask);
                            });
                        }


                        //
                        // Let the world know we have finished
                        WorkflowRunContext.Current.DeferAction(() =>
                        {
                            if (run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunPaused ||
                                run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunCompleted ||
                                run.WorkflowRunStatus_Enum == WorkflowRunState_Enumeration.WorkflowRunFailed)
                            {
                                Factory.WorkflowRunTaskManager.RegisterComplete(run.TaskId, run.Id.ToString(CultureInfo.InvariantCulture));
                            }
                            else
                            {
                                Factory.WorkflowRunTaskManager.SetResult(run.TaskId, run.Id.ToString(CultureInfo.InvariantCulture));
                            }
                            HandleDiagnostics(run, run.WorkflowRunStatus_Enum.ToString());
                        });
                    }
                    catch (Exception ex)
                    {
                        Workflow workflow = runState != null?Entity.Get <Workflow>(runState.WorkflowRunId) : null;

                        var msg = string.Format("Workflow: {0}. Unexpected error when finalizing the workflow run ({1}), version ({2}).",
                                                runState != null ? runState.GetSafeWorkflowDescription() : "",
                                                runState != null ? runState.WorkflowRunId : -1L,
                                                workflow != null ? workflow.WorkflowVersion : 0);

                        var log = msg + Environment.NewLine + ex.Message;

#if DEBUG
                        log += Environment.NewLine + ex.StackTrace;
#endif

                        EventLog.Application.WriteError(log);

                        throw new Exception(msg, ex);
                    }
                }
            }

            return(run);
        }
        public void ReportHtmlGenerationHappyPath(HtmlReportFormatter reporter, AzureIntegrationServicesModel model, MigrationContext context, IRunState state, IReportWriter writer, ILogger logger, Exception e)
        {
            "Given a model"
            .x(() => model = TestHelper.BuildModel());

            "And run state"
            .x(() => state = TestHelper.BuildRunState(model));

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a writer"
            .x(() => writer = _mockWriter.Object);

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "And an reporter"
            .x(() => reporter = new HtmlReportFormatter(model, context, state, writer, logger));

            "When executing the report formatter"
            .x(() => e = Record.Exception(() => reporter.Report()));

            "Then there should be no exception"
            .x(() => e.Should().BeNull());

            "The report node should have a source application"
            .x(() =>
            {
                _mockWriter.Invocations.Count.Should().Be(5);
                _mockWriter.Invocations[0].Arguments.Count.Should().Be(2);
                _mockWriter.Invocations[0].Arguments[0].Should().Be(context.ReportFilePath);
                _mockWriter.Invocations[0].Arguments[1].Should().NotBeNull();
                _mockWriter.Invocations[0].Arguments[1].Should().NotBeEquivalentTo(string.Empty);
            });
        }
Beispiel #20
0
        /// <summary>
        /// Get an activity to be used in the error report.
        /// </summary>
        private WfActivity GetActivityForError(IRunState runState, WfActivity activity)
        {
            var act = runState.WorkflowRun != null ? runState.WorkflowRun.PendingActivity : runState.PendingActivity;

            return(act ?? activity);
        }
        public void ReportHtmlGenerationNoContainers(HtmlReportFormatter reporter, AzureIntegrationServicesModel model, MigrationContext context, IRunState state, IReportWriter writer, ILogger logger, Exception e)
        {
            "Given a model"
            .x(() => {
                model = TestHelper.BuildModel();
                model.MigrationSource.ResourceContainers.Clear();     //removes any resource containers.
            });

            "And run state"
            .x(() => state = TestHelper.BuildRunState(model));

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a writer"
            .x(() => writer = _mockWriter.Object);

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "And an reporter"
            .x(() => reporter = new HtmlReportFormatter(model, context, state, writer, logger));

            "When executing the report formatter"
            .x(() => e = Record.Exception(() => reporter.Report()));

            "Then there should be no exception"
            .x(() => e.Should().BeNull());

            "The report node should have a source application"
            .x(() =>
            {
                _mockWriter.Invocations.Count.Should().Be(4);
                _mockWriter.Invocations[0].Arguments.Count.Should().Be(2);
                _mockWriter.Invocations[0].Arguments[0].Should().Be(context.ReportFilePath);
                _mockWriter.Invocations[0].Arguments[1].Should().NotBeNull();

                var html = (string)_mockWriter.Invocations[0].Arguments[1];
                html.Should().Contain("No Input BizTalk Applications");
            });
        }
        /// <summary>
        /// Build the app container with all services.
        /// </summary>
        /// <param name="model">The application model.</param>
        /// <param name="logger">The provided logger by the tool.</param>
        /// <param name="state">The run state provided by the tool.</param>
        /// <returns>A service provider.</returns>
        public static IServiceProvider BuildContainer(IApplicationModel model, ILogger logger, IRunState state)
        {
            _ = model ?? throw new ArgumentNullException(nameof(model));
            _ = logger ?? throw new ArgumentNullException(nameof(logger));
            _ = state ?? throw new ArgumentNullException(nameof(state));

            // Create container
            var services = new ServiceCollection();

            // Add application model
            services.AddSingleton <IApplicationModel>(model);

            // Add logger
            services.AddSingleton <ILogger>(logger);

            // Add run state
            services.AddSingleton <IRunState>(state);

            // Add generators
            services.AddTransient <IResourceGenerator, YamlResourceGenerator>();

            // Add renderers
            services.AddSingleton <ITemplateRenderer, LiquidTemplateRenderer>();
            services.AddSingleton <ISnippetRenderer, LiquidSnippetRenderer>();

            // Add repositories
            services.AddTransient <BizTalk.Discover.Repositories.IFileRepository, BizTalk.Discover.Repositories.FileRepository>();
            services.AddTransient <BizTalk.Convert.Repositories.IFileRepository, BizTalk.Convert.Repositories.FileRepository>();
            services.AddTransient <IConfigurationRepository, FileConfigurationRepository>();
            services.AddTransient <ITemplateRepository, FileTemplateRepository>();

            // Add migration context
            services.AddSingleton <MigrationContext>();

            // Add discover components
            services.AddTransient <BizTalk.Discover.MsiDiscoverer>();
            services.AddTransient <BizTalk.Discover.AssemblyDiscoverer>();

            // Add parse components
            services.AddTransient <BizTalk.Parse.ApplicationDefinitionParser>();
            services.AddTransient <BizTalk.Parse.BizTalkApplicationParser>();
            services.AddTransient <BizTalk.Parse.BindingFileParser>();
            services.AddTransient <BizTalk.Parse.BizTalkOrchestrationParser>();
            services.AddTransient <BizTalk.Parse.BizTalkPipelineParser>();
            services.AddTransient <BizTalk.Parse.DistributionListParser>();
            services.AddTransient <BizTalk.Parse.DocumentSchemaParser>();
            services.AddTransient <BizTalk.Parse.PipelineComponentParser>();
            services.AddTransient <BizTalk.Parse.PropertySchemaPropertyParser>();
            services.AddTransient <BizTalk.Parse.OrchestrationCorrelationTypeParser>();
            services.AddTransient <BizTalk.Parse.OrchestrationMultiPartMessageTypeParser>();
            services.AddTransient <BizTalk.Parse.OrchestrationPortTypeParser>();
            services.AddTransient <BizTalk.Parse.OrchestrationServiceLinkTypeParser>();
            services.AddTransient <BizTalk.Parse.OrchestrationServiceDeclarationParser>();
            services.AddTransient <BizTalk.Parse.ReceivePortParser>();
            services.AddTransient <BizTalk.Parse.ReceivePortPipelineDataParser>();
            services.AddTransient <BizTalk.Parse.SendPortParser>();
            services.AddTransient <BizTalk.Parse.SendPortPipelineDataParser>();
            services.AddTransient <BizTalk.Parse.TransformParser>();

            // Add analyzer components
            services.AddTransient <BizTalk.Analyze.ResourceGeneratorAnalyzer>();
            services.AddTransient <BizTalk.Analyze.DependencyRules.DP001SchemaDependencyAnalyzer>();
            services.AddTransient <BizTalk.Analyze.DependencyRules.DP002TransformDependencyAnalyzer>();
            services.AddTransient <BizTalk.Analyze.DependencyRules.DP003OrchestrationDependencyAnalyzer>();
            services.AddTransient <BizTalk.Analyze.DependencyRules.DP004ApplicationDependencyAnalyzer>();
            services.AddTransient <BizTalk.Analyze.DependencyRules.DP005DistributionListDependencyAnalyzer>();
            services.AddTransient <BizTalk.Analyze.DependencyRules.DP006ParentChildDependencyAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.MB001MessageBusAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.AP001ApplicationAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.AP002SystemApplicationAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.AP003ReceivePortScenarioAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.AP004SendPortScenarioAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.AP005OrchestrationScenarioAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.MB002MessageBoxAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.SC001SchemaAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.SC002PropertySchemaAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.RP001FtpReceivePortAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.RP002FileReceivePortAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.RP003HttpReceivePortAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.SP001FtpSendPortAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.SP002FileSendPortAnalyzer>();
            services.AddTransient <BizTalk.Analyze.ConversionRules.MA001TransformAnalyzer>();

            // Add report components
            services.AddTransient <BizTalk.Report.IReportWriter, BizTalk.Report.FileReportWriter>();
            services.AddTransient <BizTalk.Report.HtmlReportFormatter>();

            // Add convert components
            services.AddSingleton <BizTalk.Convert.IScenarioRouteWalker, BizTalk.Convert.ScenarioRouteWalker>();
            services.AddTransient <BizTalk.Convert.TemplateRendererConverter>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP001ReceiveRoutingSlipGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP002SendRoutingSlipGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP003ReceiveConfigurationEntryGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP004SendConfigurationEntryGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP005SendRoutingPropertyGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP006ReceiveRoutingPropertyGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP007ProcessManagerRoutingSlipGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.AP008ProcessManagerConfigurationEntryGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.SC001DocumentSchemaGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.SC002PropertySchemaGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.MA001TransformGenerator>();
            services.AddTransient <BizTalk.Convert.GeneratorRules.WF001WorkflowGenerator>();

            // Build provider
            var provider = services.BuildServiceProvider();

            return(provider);
        }
        public void ReportHtmlGenerationNoApplication(HtmlReportFormatter reporter, AzureIntegrationServicesModel model, MigrationContext context, IRunState state, IReportWriter writer, ILogger logger, Exception e)
        {
            "Given a model"
            .x(() => {
                model = TestHelper.BuildModel();
                model.MigrationSource.ResourceContainers.ToList().ForEach(rc =>
                {
                    rc.ResourceContainers.Clear();
                    rc.ResourceDefinitions.Clear();
                });     //removes any resource containers.
            });

            "And run state"
            .x(() => state = TestHelper.BuildRunState(model));

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a writer"
            .x(() => writer = _mockWriter.Object);

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "And an reporter"
            .x(() => reporter = new HtmlReportFormatter(model, context, state, writer, logger));

            "When executing the report formatter"
            .x(() => e = Record.Exception(() => reporter.Report()));

            "Then there should be no exception"
            .x(() => e.Should().BeNull());

            "The report node should have a source application"
            .x(() =>
            {
                _mockWriter.Invocations.Count.Should().Be(4);
                _mockWriter.Invocations[0].Arguments.Count.Should().Be(2);
                _mockWriter.Invocations[0].Arguments[0].Should().Be(context.ReportFilePath);
                _mockWriter.Invocations[0].Arguments[1].Should().NotBeNull();

                var invocation = _mockLogger.Invocations.Where(i => i.Arguments[0].ToString() == "Warning").FirstOrDefault();
                invocation.Should().NotBeNull();
                invocation.Arguments[2].ToString().Should().Contain("no reportable BizTalk application");
            });
        }
Beispiel #24
0
        /// <summary>
        /// Renders the summary report.
        /// </summary>
        /// <param name="files">The files to generate.</param>
        /// <param name="state">The run state.</param>
        public static void RenderSummaryReport(ReportFileStructure files, IRunState state)
        {
            _ = files ?? throw new ArgumentNullException(nameof(files));
            _ = state ?? throw new ArgumentNullException(nameof(state));

            // Get the container from the file.
            var container = files.Summary.ReportHtml.DocumentNode.SelectSingleNode(HtmlResources.ReportContentJQuery);

            // Create a section for the run summary
            var runInfoNode = HtmlNode.CreateNode(HtmlResources.SummaryRunInfoHeading);

            container.AppendChild(runInfoNode);
            var runInfoContainer = runInfoNode.SelectSingleNode(HtmlResources.SummaryRunInfoJQuery);

            // Render the timings.
            RenderTimings(runInfoContainer, (RunState)state);

            // Render the arguments.
            RenderArguments(runInfoContainer, (RunState)state);

            // Render the stage runners
            RenderStageRunners(runInfoContainer, (RunState)state);

            // Add a placeholder for when there are no source applications.
            if (files.SourceApplications.Count == 0)
            {
                var node = HtmlNode.CreateNode(HtmlResources.SourceApplicationNoneFoundSnippet);
                container.AppendChild(node);
            }
            else
            {
                // Build a heading and a list of the file in the source and target reports.
                var headingNode = HtmlNode.CreateNode(HtmlResources.SummarySourceApplicationHeading);
                container.AppendChild(headingNode);
                var sourceContainer = headingNode.SelectSingleNode(HtmlResources.SummarySourceApplicationJQuery);

                foreach (var source in files.SourceApplications)
                {
                    var linkNode = HtmlNode.CreateNode(HtmlResources.SnippetEmptyDiv);
                    linkNode.InnerHtml = string.Format(CultureInfo.CurrentCulture, HtmlResources.SummaryReportFileLink, source.Filename, source.SectionName, source.ReportData.Description);
                    sourceContainer.AppendChild(linkNode);
                }
            }

            // Add a placeholder for when there are no target applications.
            if (files.TargetApplications.Count > 0 && files.TargetMessageBus != null)
            {
                // Build a heading and a list of the file in the source and target reports.
                var headingNode = HtmlNode.CreateNode(HtmlResources.SummaryTargetMessageBusHeading);
                container.AppendChild(headingNode);
                var sourceContainer = headingNode.SelectSingleNode(HtmlResources.SummaryTargetMessageBusJQuery);

                var linkNode = HtmlNode.CreateNode(HtmlResources.SnippetEmptyDiv);
                linkNode.InnerHtml = string.Format(CultureInfo.CurrentCulture, HtmlResources.SummaryReportFileLink, files.TargetMessageBus.Filename, files.TargetMessageBus.SectionName, files.TargetMessageBus.ReportData.Description);
                sourceContainer.AppendChild(linkNode);
            }

            // Add a placeholder for when there are no target applications.
            if (files.TargetApplications.Count == 0)
            {
                var node = HtmlNode.CreateNode(HtmlResources.TargetApplicationNoneFoundSnippet);
                container.AppendChild(node);
            }
            else
            {
                // Build a heading and a list of the file in the source and target reports.
                var headingNode = HtmlNode.CreateNode(HtmlResources.SummaryTargetApplicationHeading);
                container.AppendChild(headingNode);
                var sourceContainer = headingNode.SelectSingleNode(HtmlResources.SummaryTargetApplicationJQuery);

                foreach (var target in files.TargetApplications)
                {
                    var linkNode = HtmlNode.CreateNode(HtmlResources.SnippetEmptyDiv);
                    linkNode.InnerHtml = string.Format(CultureInfo.CurrentCulture, HtmlResources.SummaryReportFileLink, target.Filename, target.SectionName, target.ReportData.Application.Description);
                    sourceContainer.AppendChild(linkNode);
                }
            }
        }
        public void ConstructWithNullModel(HtmlReportFormatter reporter, IApplicationModel model, MigrationContext context, IRunState state, IReportWriter writer, ILogger logger, Exception e)
        {
            "Given an reporter"
            .x(() => reporter.Should().BeNull());

            "And a model"
            .x(() => model.Should().BeNull());

            "And run state"
            .x(() => state = TestHelper.BuildRunState(model));

            "And a context"
            .x(() => context = TestHelper.BuildContext());

            "And a writer"
            .x(() => writer = _mockWriter.Object);

            "And a logger"
            .x(() => logger = _mockLogger.Object);

            "When constructing with a null model"
            .x(() => e = Record.Exception(() => new HtmlReportFormatter(model, context, state, writer, logger)));

            "Then the constructor should throw an exception"
            .x(() => e.Should().NotBeNull().And.Subject.Should().BeOfType <ArgumentNullException>().Which.ParamName.Should().Be("model"));
        }
 /// <summary>
 /// Handles the response that was received from a request this activity made.
 /// </summary>
 /// <param name="context">The workflow run context.</param>
 /// <param name="request">The original request object.</param>
 /// <param name="response">The object that was received in response to the request.</param>
 protected abstract void OnResponse(IRunState context, TRequest request, TResponse response);
 /// <summary>
 /// The ID of the workflow run this activity is part of.
 /// </summary>
 public long GetWorkflowRunId(IRunState runState)
 {
     return(runState.WorkflowRunId);
 }