Пример #1
0
        public string Execute(Recipe recipe)
        {
            if (recipe == null) {
                throw new ArgumentNullException("recipe");
            }

            if (!recipe.RecipeSteps.Any()) {
                Logger.Information("Recipe '{0}' contains no steps. No work has been scheduled.");
                return null;
            }

            var executionId = Guid.NewGuid().ToString("n");
            ThreadContext.Properties["ExecutionId"] = executionId;

            try {
                Logger.Information("Executing recipe '{0}'.", recipe.Name);
                _recipeExecuteEventHandler.ExecutionStart(executionId, recipe);

                foreach (var recipeStep in recipe.RecipeSteps) {
                    _recipeStepQueue.Enqueue(executionId, recipeStep);
                    _recipeStepResultRecordRepository.Create(new RecipeStepResultRecord {
                        ExecutionId = executionId,
                        RecipeName = recipe.Name,
                        StepId = recipeStep.Id,
                        StepName = recipeStep.Name
                    });
                }
                _recipeScheduler.ScheduleWork(executionId);

                return executionId;
            }
            finally {
                ThreadContext.Properties["ExecutionId"] = null;
            }
        }
Пример #2
0
        public RecipeComparisonResult Compare(Recipe left, Recipe right, Func<XElement, XElement, bool> comparison)
        {
            var leftParts = left.RecipeSteps.Where(s => s.Name == "Data").SingleOrDefault().Step.Elements();
            var rightParts = right.RecipeSteps.Where(s => s.Name == "Data").SingleOrDefault().Step.Elements();

            var matching = new List<ContentPair>();
            var unmatched = new List<ContentPair>();
            bool matched = false;

            // enumerate content items
            for (int leftIndex = 0; leftIndex < leftParts.Count(); leftIndex++)
            {
                matched = false;
                var leftPart = leftParts.ElementAt(leftIndex);
                for (int rightIndex = 0; rightIndex < rightParts.Count(); rightIndex++)
                {
                    var rightPart = rightParts.ElementAt(rightIndex);
                    if (comparison(leftPart, rightPart))
                    {
                        matching.Add(new ContentPair(leftPart, rightPart));
                        matched = true;
                    }
                }
                if (!matched)
                {
                    unmatched.Add(new ContentPair(leftPart, null));
                }
            }

            unmatched.AddRange(
                rightParts.Where(part => !matching.Any(pair => pair.Right == part))
                .Select(part => new ContentPair(null, part)));

            return new RecipeComparisonResult(matching, unmatched);
        }
Пример #3
0
        public Recipe ParseRecipe(string recipeText) {
            var recipe = new Recipe();
            
            try {
                var recipeSteps = new List<RecipeStep>();
                TextReader textReader = new StringReader(recipeText);
                var recipeTree = XElement.Load(textReader, LoadOptions.PreserveWhitespace);
                textReader.Close();

                foreach (var element in recipeTree.Elements()) {
                    // Recipe mETaDaTA
                    if (element.Name.LocalName == "Recipe") {
                        foreach (var metadataElement in element.Elements()) {
                            switch (metadataElement.Name.LocalName) {
                                case "Name":
                                    recipe.Name = metadataElement.Value;
                                    break;
                                case "Description":
                                    recipe.Description = metadataElement.Value;
                                    break;
                                case "Author":
                                    recipe.Author = metadataElement.Value;
                                    break;
                                case "WebSite":
                                    recipe.WebSite = metadataElement.Value;
                                    break;
                                case "Version":
                                    recipe.Version = metadataElement.Value;
                                    break;
                                case "IsSetupRecipe":
                                    recipe.IsSetupRecipe = !string.IsNullOrEmpty(metadataElement.Value) ? bool.Parse(metadataElement.Value) : false;
                                    break;
                                case "ExportUtc":
                                    recipe.ExportUtc = !string.IsNullOrEmpty(metadataElement.Value) ? (DateTime?)XmlConvert.ToDateTime(metadataElement.Value, XmlDateTimeSerializationMode.Utc) : null;
                                    break;
                                case "Tags":
                                    recipe.Tags = metadataElement.Value;
                                    break;
                                default:
                                    Logger.Error("Unrecognized recipe metadata element {0} encountered. Skipping.", metadataElement.Name.LocalName);
                                    break;
                            }
                        }
                    }
                    // Recipe step
                    else {
                        var recipeStep = new RecipeStep { Name = element.Name.LocalName, Step = element };
                        recipeSteps.Add(recipeStep);
                    }
                }
                recipe.RecipeSteps = recipeSteps;
            }
            catch (Exception exception) {
                Logger.Error(exception, "Parsing recipe failed. Recipe text was: {0}.", recipeText);
                throw;
            }

            return recipe;
        }
Пример #4
0
        public string Execute(Recipe recipe) {
            var executionId = _recipeManager.Execute(recipe);

            // Only need to update the shell if work was actually done.
            if(executionId != null)
                UpdateShell();

            return executionId;
        }
Пример #5
0
        public Recipe ParseRecipe(XDocument recipeDocument)
        {
            var recipe = new Recipe();
            var recipeSteps = new List<RecipeStep>();
            var stepId = 0;

            foreach (var element in recipeDocument.Root.Elements()) {
                // Recipe metadata.
                if (element.Name.LocalName == "Recipe") {
                    foreach (var metadataElement in element.Elements()) {
                        switch (metadataElement.Name.LocalName) {
                            case "Name":
                                recipe.Name = metadataElement.Value;
                                break;
                            case "Description":
                                recipe.Description = metadataElement.Value;
                                break;
                            case "Author":
                                recipe.Author = metadataElement.Value;
                                break;
                            case "WebSite":
                                recipe.WebSite = metadataElement.Value;
                                break;
                            case "Version":
                                recipe.Version = metadataElement.Value;
                                break;
                            case "IsSetupRecipe":
                                recipe.IsSetupRecipe = !string.IsNullOrEmpty(metadataElement.Value) ? bool.Parse(metadataElement.Value) : false;
                                break;
                            case "ExportUtc":
                                recipe.ExportUtc = !string.IsNullOrEmpty(metadataElement.Value) ? (DateTime?)XmlConvert.ToDateTime(metadataElement.Value, XmlDateTimeSerializationMode.Utc) : null;
                                break;
                            case "Category":
                                recipe.Category = metadataElement.Value;
                                break;
                            case "Tags":
                                recipe.Tags = metadataElement.Value;
                                break;
                            default:
                                Logger.Warning("Unrecognized recipe metadata element '{0}' encountered; skipping.", metadataElement.Name.LocalName);
                                break;
                        }
                    }
                }
                // Recipe step.
                else {
                    var recipeStep = new RecipeStep(id: (++stepId).ToString(CultureInfo.InvariantCulture), recipeName: recipe.Name, name: element.Name.LocalName, step: element );
                    recipeSteps.Add(recipeStep);
                }
            }

            recipe.RecipeSteps = recipeSteps;

            return recipe;
        }
Пример #6
0
 private void EnqueueRecipe(string executionId, Recipe recipe) {
     foreach (var recipeStep in recipe.RecipeSteps) {
         _recipeStepQueue.Enqueue(executionId, recipeStep);
         _recipeStepResultRecordRepository.Create(new RecipeStepResultRecord {
             ExecutionId = executionId,
             RecipeName = recipe.Name,
             StepId = recipeStep.Id,
             StepName = recipeStep.Name
         });
     }
 }
Пример #7
0
        public string Execute(Recipe recipe) {
            if (recipe == null)
                return null;

            var executionId = Guid.NewGuid().ToString("n");
            _recipeJournal.ExecutionStart(executionId);

            foreach (var recipeStep in recipe.RecipeSteps) {
                _recipeStepQueue.Enqueue(executionId, recipeStep);
            }
            _recipeScheduler.ScheduleWork(executionId);

            return executionId;
        }
        public ActionResult InstallPackageDetailsPOST(PackagingInstallViewModel packagingInstallViewModel, string redirectUrl) {
            if (_shellSettings.Name != ShellSettings.DefaultName || !Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add sources")))
                return new HttpUnauthorizedResult();

            try {
                if (_recipeHarvester != null && _recipeManager != null) {
                    IEnumerable<Recipe> recipes = _recipeHarvester.HarvestRecipes(packagingInstallViewModel.ExtensionDescriptor.Id)
                        .Where(loadedRecipe => packagingInstallViewModel.Recipes.FirstOrDefault(recipeViewModel => recipeViewModel.Execute && recipeViewModel.Recipe.Name.Equals(loadedRecipe.Name)) != null);

                    foreach (Recipe recipe in recipes) {
                        try {
                            _recipeManager.Execute(recipe);
                        }
                        catch {
                            Services.Notifier.Error(T("Recipes contains {0} unsupported module installation steps.", recipe.Name));
                        }
                    }
                }

                // Enable selected features
                if (packagingInstallViewModel.Features.Count > 0) {
                    IEnumerable<string> featureIds = packagingInstallViewModel.Features
                        .Where(feature => feature.Enable)
                        .Select(feature => feature.FeatureDescriptor.Id);

                    // Enable the features and its dependencies using recipes, so that they are run after the module's recipes

                    var recipe = new Recipe {
                        RecipeSteps = featureIds.Select(
                            x => new RecipeStep {
                                Name = "Feature",
                                Step = new XElement("Feature", new XAttribute("enable", x))
                            })
                    };

                    _recipeManager.Execute(recipe);
                }
            } catch (Exception exception) {
                Services.Notifier.Error(T("Post installation steps failed with error: {0}", exception.Message));
            }

            return Redirect(redirectUrl);
        }
        private IOrderedEnumerable<IGrouping<string, IGrouping<XElement, ContentPair>>> BuildRemoteOnlyViewModel(Recipe localRecipe, Recipe remoteRecipe)
        {
            var contentTypeComparer = new ContentTypeContentComparer();
            var identifierComparer = new IdentifierContentComparer();
            var layerNameComparer = new LayerNameComparer();

            var comparison = new RecipeComparer().Compare(localRecipe, remoteRecipe,
                            (left, right) => contentTypeComparer.IsMatch(left, right)
                                            && (identifierComparer.IsMatch(left, right) ||
                                            layerNameComparer.IsMatch(left, right)));

            var localonly = comparison.Unmatched
                .Where(pair => pair.Left == null)
                .OrderBy(pair => pair.Right.DisplayLabel())
                .OrderBy(pair => pair.Right.PartType())
                .GroupBy(pair => pair.Right)
                .GroupBy(layer => layer.Key.LayerName())
                .OrderBy(layer => layer.Key);
            return localonly;
        }
Пример #10
0
        private IOrderedEnumerable<IGrouping<string, IGrouping<XElement, ContentPair>>> BuildMismatchesViewModel(Recipe localRecipe, Recipe remoteRecipe)
        {
            var contentTypeComparer = new ContentTypeContentComparer();
            var identityComparer = new IdentifierContentComparer();
            var layerComparer = new LayerNameComparer();

            var mismatched = new RecipeComparer()
                .Compare(localRecipe, remoteRecipe,
                (left, right) => 
                    contentTypeComparer.IsMatch(left, right) /*&& layerComparer.IsMatch(left,right)*/
                    && (!localRecipe.RecipeSteps.SingleOrDefault(step=>step.Name=="Data").Step.Elements()
                                    .Any(element=>element.Attribute("Id").Value.Equals(right.Attribute("Id").Value, StringComparison.InvariantCulture))
                        ||
                        !remoteRecipe.RecipeSteps.SingleOrDefault(step=>step.Name=="Data").Step.Elements()
                                    .Any(element=>element.Attribute("Id").Value.Equals(left.Attribute("Id").Value, StringComparison.InvariantCulture)))
                    && (_softComparers.Where(comparer => comparer.IsMatch(left, right)).Count() > 1))
                .Matching // all items of same type and title, body or layer name match
                .Where(pair => !identityComparer.IsMatch(pair.Left, pair.Right));
            // where the identifier is different

            var groupedMismatches = mismatched
                .GroupBy(pair => pair.Left)
                .GroupBy(set => set.Key.LayerName())
                .OrderBy(layer => layer.Key);
            return groupedMismatches;
        }
Пример #11
0
 private IOrderedEnumerable<IGrouping<string, IGrouping<XElement, ContentPair>>> BuildDifferencesViewModel(Recipe localRecipe, Recipe remoteRecipe)
 {
     var matched = new RecipeComparer().Compare(localRecipe, remoteRecipe,
                                                (left, right) => _hardComparers.All(comparer => comparer.IsMatch(left, right))
                                                && _softComparers.Any(comparer => !comparer.IsMatch(left, right, true)));
     var differences = matched.Matching
         .OrderBy(pair => pair.Left.DisplayLabel())
         .OrderBy(pair => pair.Left.PartType())
         .GroupBy(pair => pair.Left)
         .GroupBy(layer => layer.Key.LayerName())
         .OrderBy(layer => layer.Key);
     return differences;
 }
 private void CheckRecipeSteps(Recipe recipe)
 {
     foreach (var step in recipe.RecipeSteps) {
         switch (step.Name) {
             case "Metadata":
             case "Settings":
             case "Data":
                 break;
             default:
                 throw new InvalidOperationException(T("Step {0} is not a supported import step.", step.Name).Text);
         }
     }
 }
 void IRecipeExecuteEventHandler.ExecutionStart(string executionId, Recipe recipe) { }