public override void WithResolvingModelHost(ModelHostResolveContext modelHostContext)
        {
            var modelHost      = modelHostContext.ModelHost;
            var model          = modelHostContext.Model;
            var childModelType = modelHostContext.ChildModelType;
            var action         = modelHostContext.Action;

            var storeModelHost = modelHost.WithAssertAndCast <TermStoreModelHost>("modelHost", value => value.RequireNotNull());
            var groupModel     = model.WithAssertAndCast <TaxonomyTermGroupDefinition>("model", value => value.RequireNotNull());

            var context = storeModelHost.HostClientContext;

            var termStore    = storeModelHost.HostTermStore;
            var currentGroup = FindGroup(storeModelHost, groupModel);

            if (currentGroup == null && IsSharePointOnlineContext(context))
            {
                TryRetryService.TryWithRetry(() =>
                {
                    currentGroup = FindGroup(storeModelHost, groupModel);
                    return(currentGroup != null);
                });
            }

            if (currentGroup == null)
            {
                throw new SPMeta2Exception(string.Format("Cannot find a taxonomy group after provision"));
            }

            action(ModelHostBase.Inherit <TermGroupModelHost>(storeModelHost, host =>
            {
                host.HostTermStore = termStore;
                host.HostGroup     = currentGroup;
            }));
        }
        private void SharePointOnlineWait(TermModelHost termModelHost, TaxonomyTermLabelDefinition definition)
        {
            // wait until the group is there
            // Nested terms provisioning in Office 365 fails #995
            // TermSet not found #994
            var context = termModelHost.HostClientContext;

            if (IsSharePointOnlineContext(context))
            {
                var term         = termModelHost.HostTerm;
                var currentLabel = FindLabelInTerm(term, definition);

                if (currentLabel == null)
                {
                    TryRetryService.TryWithRetry(() =>
                    {
                        currentLabel = FindLabelInTerm(term, definition);
                        return(currentLabel != null);
                    });
                }

                if (currentLabel == null)
                {
                    throw new SPMeta2Exception(string.Format("Cannot find a term label after provision"));
                }
            }
        }
        private void SharePointOnlineWait(TermStoreModelHost siteModelHost, TaxonomyTermGroupDefinition groupModel)
        {
            // wait until the group is there
            // Nested terms provisioning in Office 365 fails #995
            // TermSet not found #994
            var context = siteModelHost.HostClientContext;

            if (IsSharePointOnlineContext(context))
            {
                var currentGroup = FindGroup(siteModelHost, groupModel);

                if (currentGroup == null)
                {
                    TryRetryService.TryWithRetry(() =>
                    {
                        currentGroup = FindGroup(siteModelHost, groupModel);
                        return(currentGroup != null);
                    });
                }

                if (currentGroup == null)
                {
                    throw new SPMeta2Exception(string.Format("Cannot find a taxonomy group after provision"));
                }
            }
        }
Example #4
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var termModelHost = modelHost.WithAssertAndCast <TermModelHost>("modelHost", value => value.RequireNotNull());
            var definition    = model.WithAssertAndCast <TaxonomyTermLabelDefinition>("model", value => value.RequireNotNull());

            var spObject = FindLabelInTerm(termModelHost.HostTerm, definition);
            var context  = termModelHost.HostClientContext;

            if (spObject == null && IsSharePointOnlineContext(context))
            {
                TryRetryService.TryWithRetry(() =>
                {
                    spObject = FindLabelInTerm(termModelHost.HostTerm, definition);
                    return(spObject != null);
                });
            }

            var assert = ServiceFactory.AssertService
                         .NewAssert(definition, spObject)
                         .ShouldNotBeNull(spObject)
                         .ShouldBeEqual(m => m.Name, o => o.Value)
                         .ShouldBeEqual(m => m.LCID, o => o.Language)
                         .ShouldBeEqual(m => m.IsDefault, o => o.IsDefaultForLanguage);
        }
Example #5
0
        public override void WithResolvingModelHost(ModelHostResolveContext modelHostContext)
        {
            var modelHost      = modelHostContext.ModelHost;
            var model          = modelHostContext.Model;
            var childModelType = modelHostContext.ChildModelType;
            var action         = modelHostContext.Action;

            var definition = model.WithAssertAndCast <TaxonomyTermDefinition>("model", value => value.RequireNotNull());

            Term      currentTerm = null;
            TermGroup group       = null;
            TermSet   termSet     = null;
            TermStore termStore   = null;

            var localModelHost = ModelHostBase.Inherit <TermModelHost>(modelHost as ModelHostBase, host =>
            {
            });

            if (modelHost is TermModelHost)
            {
                var h = (modelHost as TermModelHost);

                group     = h.HostGroup;
                termSet   = h.HostTermSet;
                termStore = h.HostTermStore;

                currentTerm = FindTermInTerm(h.HostTerm, definition);

                var context = h.HostClientContext;

                if (currentTerm == null && IsSharePointOnlineContext(context))
                {
                    TryRetryService.TryWithRetry(() =>
                    {
                        currentTerm = FindTermInTerm(h.HostTerm, definition);
                        return(currentTerm != null);
                    });
                }

                localModelHost.HostGroup     = group;
                localModelHost.HostTermSet   = termSet;
                localModelHost.HostTerm      = currentTerm;
                localModelHost.HostTermStore = termStore;
            }
            else if (modelHost is TermSetModelHost)
            {
                var h = (modelHost as TermSetModelHost);

                termStore = h.HostTermStore;
                group     = h.HostGroup;
                termSet   = h.HostTermSet;

                currentTerm = FindTermInTermSet(h.HostTermSet, definition);

                var context = h.HostClientContext;

                if (currentTerm == null && IsSharePointOnlineContext(context))
                {
                    TryRetryService.TryWithRetry(() =>
                    {
                        currentTerm = FindTermInTermSet(h.HostTermSet, definition);
                        return(currentTerm != null);
                    });
                }

                localModelHost.HostGroup     = group;
                localModelHost.HostTermSet   = termSet;
                localModelHost.HostTerm      = currentTerm;
                localModelHost.HostTermStore = termStore;
            }

            action(localModelHost);
        }
Example #6
0
        private void DeployTermUnderTerm(object modelHost, TermModelHost groupModelHost, TaxonomyTermDefinition termModel)
        {
            var termStore = groupModelHost.HostTermStore;
            var termSet   = groupModelHost.HostTerm;

            var currentTerm = FindTermInTerm(termSet, termModel);
            var termName    = NormalizeTermName(termModel.Name);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentTerm,
                ObjectType       = typeof(Term),
                ObjectDefinition = termModel,
                ModelHost        = modelHost
            });

            if (currentTerm == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new Term");

                currentTerm = termModel.Id.HasValue
                    ? termSet.CreateTerm(termName, termModel.LCID, termModel.Id.Value)
                    : termSet.CreateTerm(termName, termModel.LCID, Guid.NewGuid());

                MapTermProperties(currentTerm, termModel, true);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentTerm,
                    ObjectType       = typeof(Term),
                    ObjectDefinition = termModel,
                    ModelHost        = modelHost
                });
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing Term");

                MapTermProperties(currentTerm, termModel, false);

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentTerm,
                    ObjectType       = typeof(Term),
                    ObjectDefinition = termModel,
                    ModelHost        = modelHost
                });
            }

            try
            {
                termStore.CommitAll();
                currentTerm.RefreshLoad();

                termStore.Context.ExecuteQueryWithTrace();
            }
            catch (Exception e)
            {
                var context = groupModelHost.HostClientContext;

                if (!IsSharePointOnlineContext(context))
                {
                    throw;
                }

                var serverException = e as ServerException;

                if (serverException != null &&
                    ReflectionUtils.GetHResultValue(serverException).Value == -2146233088 &&
                    serverException.ServerErrorTypeName == "Microsoft.SharePoint.Taxonomy.TermStoreOperationException")
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing Term");

                    currentTerm = FindTermInTerm(termSet, termModel);

                    if (currentTerm == null)
                    {
                        TryRetryService.TryWithRetry(() =>
                        {
                            currentTerm = FindTermInTerm(termSet, termModel);
                            return(currentTerm != null);
                        });
                    }

                    MapTermProperties(currentTerm, termModel, false);

                    InvokeOnModelEvent(this, new ModelEventArgs
                    {
                        CurrentModelNode = null,
                        Model            = null,
                        EventType        = ModelEventType.OnProvisioned,
                        Object           = currentTerm,
                        ObjectType       = typeof(Term),
                        ObjectDefinition = termModel,
                        ModelHost        = modelHost
                    });

                    termStore.CommitAll();
                    termStore.Context.ExecuteQueryWithTrace();
                }
            }
        }
        private void DeployTaxonomyGroup(object modelHost, TermStoreModelHost siteModelHost, TaxonomyTermGroupDefinition groupModel)
        {
            var termStore    = siteModelHost.HostTermStore;
            var currentGroup = FindGroup(siteModelHost, groupModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model            = null,
                EventType        = ModelEventType.OnProvisioning,
                Object           = currentGroup,
                ObjectType       = typeof(TermGroup),
                ObjectDefinition = groupModel,
                ModelHost        = modelHost
            });

            if (currentGroup == null)
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new Term Group");

                currentGroup = groupModel.Id.HasValue
                                        ? termStore.CreateGroup(groupModel.Name, groupModel.Id.Value)
                                        : termStore.CreateGroup(groupModel.Name, Guid.NewGuid());

                if (!string.IsNullOrEmpty(groupModel.Description))
                {
                    currentGroup.Description = groupModel.Description;
                }

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model            = null,
                    EventType        = ModelEventType.OnProvisioned,
                    Object           = currentGroup,
                    ObjectType       = typeof(TermGroup),
                    ObjectDefinition = groupModel,
                    ModelHost        = modelHost
                });
            }
            else
            {
                UpdateExistingTaxonomyGroup(modelHost, groupModel, currentGroup);
            }

            termStore.CommitAll();

            termStore.Groups.RefreshLoad();
            termStore.RefreshLoad();

            try
            {
                termStore.Context.ExecuteQueryWithTrace();
            }
            catch (Exception e)
            {
                var context = siteModelHost.HostClientContext;

                if (!IsSharePointOnlineContext(context))
                {
                    throw;
                }

                // SPMeta2 Provisioning Taxonomy Group with CSOM Standard #959
                // https://github.com/SubPointSolutions/spmeta2/issues/959

                // seems that newly created group might not be available for the time being
                // handling that "Group names must be unique." exception
                // trying to find the group and only update description
                var serverException = e as ServerException;

                if (serverException != null &&
                    serverException.ServerErrorCode == -2147024809)
                {
                    currentGroup = FindGroup(siteModelHost, groupModel);

                    if (currentGroup == null)
                    {
                        TryRetryService.TryWithRetry(() =>
                        {
                            currentGroup = FindGroup(siteModelHost, groupModel);
                            return(currentGroup != null);
                        });
                    }

                    UpdateExistingTaxonomyGroup(modelHost, groupModel, currentGroup);

                    termStore.CommitAll();

                    termStore.Groups.RefreshLoad();
                    termStore.RefreshLoad();

                    termStore.Context.ExecuteQueryWithTrace();
                }
            }

            siteModelHost.ShouldUpdateHost = false;
        }
Example #8
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var termStoreModelHost = modelHost.WithAssertAndCast <TermStoreModelHost>("modelHost", value => value.RequireNotNull());
            var definition         = model.WithAssertAndCast <TaxonomyTermGroupDefinition>("model", value => value.RequireNotNull());

            var context  = termStoreModelHost.HostClientContext;
            var spObject = FindGroup(termStoreModelHost, definition);

            if (spObject == null && IsSharePointOnlineContext(context))
            {
                TryRetryService.TryWithRetry(() =>
                {
                    spObject = FindGroup(termStoreModelHost, definition);
                    return(spObject != null);
                });
            }

            var assert = ServiceFactory.AssertService
                         .NewAssert(definition, spObject)
                         .ShouldNotBeNull(spObject);

            if (definition.IsSiteCollectionGroup)
            {
                assert.SkipProperty(m => m.Name, "IsSiteCollectionGroup is TRUE. Skipping Name property validation.");

                assert.ShouldBeEqual((p, s, d) =>
                {
                    var srcProp = s.GetExpressionValue(m => m.IsSiteCollectionGroup);
                    var group   = FindSiteCollectionGroup(termStoreModelHost, definition);

                    var isValid = group.IsSiteCollectionGroup;

                    return(new PropertyValidationResult
                    {
                        Tag = p.Tag,
                        Src = srcProp,
                        Dst = null,
                        IsValid = isValid
                    });
                });
            }
            else
            {
                assert.SkipProperty(m => m.IsSiteCollectionGroup, "IsSiteCollectionGroup is false. Skipping property.");
                assert.ShouldBeEqual(m => m.Name, o => o.Name);
            }

            if (!string.IsNullOrEmpty(definition.Description))
            {
                assert.ShouldBeEqual(m => m.Description, o => o.Description);
            }
            else
            {
                assert.SkipProperty(m => m.Description, "Description is null. Skipping property.");
            }

            if (definition.Id.HasValue)
            {
                assert.ShouldBeEqual(m => m.Id, o => o.Id);
            }
            else
            {
                assert.SkipProperty(m => m.Id, "Id is null. Skipping property.");
            }
        }
Example #9
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var definition = model.WithAssertAndCast <TaxonomyTermDefinition>("model", value => value.RequireNotNull());

            Term spObject = null;

            if (modelHost is TermModelHost)
            {
                var context = (modelHost as TermModelHost).HostClientContext;
                spObject = FindTermInTerm((modelHost as TermModelHost).HostTerm, definition);

                if (spObject == null && IsSharePointOnlineContext(context))
                {
                    TryRetryService.TryWithRetry(() =>
                    {
                        spObject = FindTermInTerm((modelHost as TermModelHost).HostTerm, definition);
                        return(spObject != null);
                    });
                }
            }
            else if (modelHost is TermSetModelHost)
            {
                var context = (modelHost as TermSetModelHost).HostClientContext;
                spObject = FindTermInTermSet((modelHost as TermSetModelHost).HostTermSet, definition);

                if (spObject == null && IsSharePointOnlineContext(context))
                {
                    TryRetryService.TryWithRetry(() =>
                    {
                        spObject = FindTermInTermSet((modelHost as TermSetModelHost).HostTermSet, definition);
                        return(spObject != null);
                    });
                }
            }
            else
            {
                throw new SPMeta2UnsupportedModelHostException(string.Format("Model host of type: [{0}] is not supported", modelHost.GetType()));
            }

            TermExtensions.CurrentLCID = definition.LCID;

            var assert = ServiceFactory.AssertService
                         .NewAssert(definition, spObject)
                         .ShouldNotBeNull(spObject)
                         //.ShouldBeEqual(m => m.Name, o => o.Name)
                         .ShouldBeEqual(m => m.Description, o => o.GetDefaultLCIDDescription());

            assert.SkipProperty(m => m.LCID, "LCID is not accessible from OM. Should be alright while provision.");

            assert.ShouldBeEqual((p, s, d) =>
            {
                var srcProp = s.GetExpressionValue(m => m.Name);
                var dstProp = d.GetExpressionValue(m => m.Name);

                var isValid = NormalizeTermName(s.Name) == d.Name;

                return(new PropertyValidationResult
                {
                    Tag = p.Tag,
                    Src = srcProp,
                    Dst = dstProp,
                    IsValid = isValid
                });
            });

            if (!string.IsNullOrEmpty(definition.CustomSortOrder))
            {
                assert.ShouldBeEqual(m => m.CustomSortOrder, o => o.CustomSortOrder);
            }
            else
            {
                assert.SkipProperty(m => m.CustomSortOrder);
            }

            if (definition.Id.HasValue)
            {
                assert.ShouldBeEqual(m => m.Id, o => o.Id);
            }
            else
            {
                assert.SkipProperty(m => m.Id, "Id is null. Skipping property.");
            }

            if (definition.IsAvailableForTagging.HasValue)
            {
                assert.ShouldBeEqual(m => m.IsAvailableForTagging, o => o.IsAvailableForTagging);
            }
            else
            {
                assert.SkipProperty(m => m.IsAvailableForTagging, "IsAvailableForTagging is null. Skipping property.");
            }

            assert.ShouldBeEqual((p, s, d) =>
            {
                var srcProp = s.GetExpressionValue(m => m.CustomProperties);

                var isValid = true;

                // missed props, or too much
                // should be equal on the first provision
                if (s.CustomProperties.Count != d.CustomProperties.Count)
                {
                    isValid = false;
                }

                // per prop
                foreach (var customProp in s.CustomProperties)
                {
                    if (!d.CustomProperties.ContainsKey(customProp.Name))
                    {
                        isValid = false;
                        break;
                    }

                    if (d.CustomProperties[customProp.Name] != customProp.Value)
                    {
                        isValid = false;
                        break;
                    }
                }

                return(new PropertyValidationResult
                {
                    Tag = p.Tag,
                    Src = srcProp,
                    // Dst = dstProp,
                    IsValid = isValid
                });
            });


            assert.ShouldBeEqual((p, s, d) =>
            {
                var srcProp = s.GetExpressionValue(m => m.LocalCustomProperties);

                var isValid = true;

                // missed props, or too much
                // should be equal on the first provision
                if (s.LocalCustomProperties.Count != d.LocalCustomProperties.Count)
                {
                    isValid = false;
                }

                // per prop
                foreach (var customProp in s.LocalCustomProperties)
                {
                    if (!d.LocalCustomProperties.ContainsKey(customProp.Name))
                    {
                        isValid = false;
                        break;
                    }

                    if (d.LocalCustomProperties[customProp.Name] != customProp.Value)
                    {
                        isValid = false;
                        break;
                    }
                }

                return(new PropertyValidationResult
                {
                    Tag = p.Tag,
                    Src = srcProp,
                    // Dst = dstProp,
                    IsValid = isValid
                });
            });
        }
Example #10
0
        public override void DeployModel(object modelHost, DefinitionBase model)
        {
            var termGroupModelHost = modelHost.WithAssertAndCast <TermGroupModelHost>("modelHost", value => value.RequireNotNull());
            var definition         = model.WithAssertAndCast <TaxonomyTermSetDefinition>("model", value => value.RequireNotNull());

            var spObject = FindTermSet(termGroupModelHost.HostGroup, definition);
            var context  = termGroupModelHost.HostClientContext;

            if (spObject == null && IsSharePointOnlineContext(context))
            {
                TryRetryService.TryWithRetry(() =>
                {
                    spObject = FindTermSet(termGroupModelHost.HostGroup, definition);
                    return(spObject != null);
                });
            }

            var assert = ServiceFactory.AssertService
                         .NewAssert(definition, spObject)
                         .ShouldNotBeNull(spObject)
                         .ShouldBeEqual(m => m.Name, o => o.Name);

            //.ShouldBeEqual(m => m.IsAvailableForTagging, o => o.IsAvailableForTagging)
            //.ShouldBeEqual(m => m.IsOpenForTermCreation, o => o.IsOpenForTermCreation);

            assert.SkipProperty(m => m.LCID, "LCID is not accessible from OM. Should be alright while provision.");

            if (definition.IsAvailableForTagging.HasValue)
            {
                assert.ShouldBeEqual(m => m.IsAvailableForTagging, o => o.IsAvailableForTagging);
            }
            else
            {
                assert.SkipProperty(m => m.IsAvailableForTagging, "IsAvailableForTagging is null. Skipping property.");
            }

            if (definition.IsOpenForTermCreation.HasValue)
            {
                assert.ShouldBeEqual(m => m.IsOpenForTermCreation, o => o.IsOpenForTermCreation);
            }
            else
            {
                assert.SkipProperty(m => m.IsOpenForTermCreation, "IsOpenForTermCreation is null. Skipping property.");
            }

            if (!string.IsNullOrEmpty(definition.Description))
            {
                assert.ShouldBeEqual(m => m.Description, o => o.Description);
            }
            else
            {
                assert.SkipProperty(m => m.Description, "Description is null. Skipping property.");
            }

            if (definition.Id.HasValue)
            {
                assert.ShouldBeEqual(m => m.Id, o => o.Id);
            }
            else
            {
                assert.SkipProperty(m => m.Id, "Id is null. Skipping property.");
            }


            if (!string.IsNullOrEmpty(definition.CustomSortOrder))
            {
                assert.ShouldBeEqual(m => m.CustomSortOrder, o => o.CustomSortOrder);
            }
            else
            {
                assert.SkipProperty(m => m.CustomSortOrder);
            }


            if (!string.IsNullOrEmpty(definition.Contact))
            {
                assert.ShouldBeEqual(m => m.Contact, o => o.Contact);
            }
            else
            {
                assert.SkipProperty(m => m.Contact);
            }

            assert.ShouldBeEqual((p, s, d) =>
            {
                var srcProp = s.GetExpressionValue(m => m.CustomProperties);

                var isValid = true;

                // missed props, or too much
                // should be equal on the first provision
                if (s.CustomProperties.Count != d.CustomProperties.Count)
                {
                    isValid = false;
                }

                // per prop
                foreach (var customProp in s.CustomProperties)
                {
                    if (!d.CustomProperties.ContainsKey(customProp.Name))
                    {
                        isValid = false;
                        break;
                    }

                    if (d.CustomProperties[customProp.Name] != customProp.Value)
                    {
                        isValid = false;
                        break;
                    }
                }

                return(new PropertyValidationResult
                {
                    Tag = p.Tag,
                    Src = srcProp,
                    // Dst = dstProp,
                    IsValid = isValid
                });
            });
        }