Inheritance: IReferenceByName, IReferenceByAlias
Esempio n. 1
0
 /// <summary>
 /// Creates a RevisionData object based on a single changeset and a branch name of "default".
 /// This object model is included to later support changesets and branching (May 2011 - APN).
 /// </summary>
 public static RevisionData CreateDefault(HiveId id, RevisionStatusType revisionStatusType, DateTimeOffset utcCreated, DateTimeOffset utcModified, DateTimeOffset utcStatusChanged)
 {
     var output = new RevisionData
                      {
                          Id = id,
                          StatusType = revisionStatusType,
                          UtcCreated = utcCreated,
                          UtcModified = utcModified,
                          UtcStatusChanged = utcStatusChanged
                      };
     return output;
 }
 private void AddRevision(TypedEntity entity, RevisionStatusType revisionStatusType)
 {
     using (var uow = GroupUnitFactory.Create())
     {
         // Make a new revision that is published
         var revision = new Revision<TypedEntity>(entity);
         revision.MetaData.StatusType = revisionStatusType;
         uow.Repositories.Revisions.AddOrUpdate(revision);
         uow.Complete();
     }
 }
        public void CountUsesSpecifiedRevision()
        {
            // Arrange
            LogHelper.TraceIfEnabled(typeof(QueryExtensions), "In CountUsesSpecifiedRevision");
            var newGuid = Guid.NewGuid();
            var newGuidRedHerring = Guid.NewGuid();

            var twoRevisionsOfOneEntity = CreateEntityForTest(newGuid, newGuidRedHerring, ProviderSetup);
            AddRevision(twoRevisionsOfOneEntity, FixedStatusTypes.Published);
            AddRevision(twoRevisionsOfOneEntity, FixedStatusTypes.Published);

            var revisionStatusType = new RevisionStatusType("custom", "custom for test");
            var oneRevisionOfAnEntity = CreateEntityForTest(Guid.NewGuid(), Guid.NewGuid(), ProviderSetup);
            AddRevision(oneRevisionOfAnEntity, revisionStatusType);

            var anotherRevisionOfSameType = CreateEntityForTest(Guid.NewGuid(), Guid.NewGuid(), ProviderSetup);
            AddRevision(anotherRevisionOfSameType, revisionStatusType);

            // Act
            using (var uow = GroupUnitFactory.Create())
            {
                var countOfCustomType = uow.Repositories.OfRevisionType(revisionStatusType.Alias).Count();
                var countOfPublished = uow.Repositories.OfRevisionType(FixedStatusTypes.Published).Count();

                // Assert
                Assert.That(countOfCustomType, Is.EqualTo(2));
                Assert.That(countOfPublished, Is.EqualTo(1));

                Thread.Sleep(500); // Let profiler catch up
            }
        }
 public EntityRouteResult FindEntityByUrl(Uri fullUrlIncludingDomain, RevisionStatusType revisionStatusType)
 {
     return null;
 }
Esempio n. 5
0
        public void FromModel_StatusType_ToRdbms()
        {
            // Arrange
            var model = new RevisionStatusType("myalias", "myname")
                {
                    Id = new HiveId(Guid.NewGuid()),
                    IsSystem = true
                };

            // Act
            var rdbms = _rdbmsTypeMapper.Map<NodeVersionStatusType>(model);

            // Assert
            Assert_CompareStatusType(rdbms, model);
        }
Esempio n. 6
0
 private static void Assert_CompareStatusType(NodeVersionStatusType rdbms, RevisionStatusType model)
 {
     Assert.That(model.Alias, Is.EqualTo(rdbms.Alias));
     Assert.That(model.IsSystem, Is.EqualTo(rdbms.IsSystem));
     Assert.That((string)model.Name, Is.EqualTo(rdbms.Name));
     Assert.That((Guid)model.Id.Value, Is.EqualTo(rdbms.Id));
 }
Esempio n. 7
0
 public RevisionData(RevisionStatusType revisionStatusType) : this()
 {
     StatusType = revisionStatusType;
 }
Esempio n. 8
0
 public RevisionData(Changeset changeset, RevisionStatusType revisionStatusType)
 {
     Changeset = changeset;
     StatusType = revisionStatusType;
 }
Esempio n. 9
0
 public RevisionData(HiveId revisionId, RevisionStatusType revisionStatusType)
     : this(revisionStatusType)
 {
     Id = revisionId;
 }
Esempio n. 10
0
 public RevisionData(Changeset changeset, HiveId revisionId, RevisionStatusType revisionStatusType)
     : this(changeset, revisionStatusType)
 {
     Id = revisionId;
 }
        /// <summary>
        /// Finds a TypedEntity based on the Uri
        /// </summary>
        /// <param name="fullUrlIncludingDomain"></param>
        /// <param name="revisionStatusType"></param>
        /// <returns></returns>
        public EntityRouteResult FindEntityByUrl(Uri fullUrlIncludingDomain, RevisionStatusType revisionStatusType)
        {
            Mandate.ParameterNotNull(fullUrlIncludingDomain.Scheme, "Scheme");

            //cache key is full uri except query string and revision status
            var cacheKey = EntityMappedKey + "-" + fullUrlIncludingDomain.GetLeftPart(UriPartial.Path) + "-" + revisionStatusType;

            //TODO: We need to change how the NiceUrls are cached because if we store them in one entry as a dictionary in cache, then
            // we can do a reverse lookup to see if we've already generated the URL for the entity which may match the fullUrlIncludingDomain,
            // if so, then all we have to do is return the entity with the cached ID.

            return ApplicationContext.FrameworkContext.ApplicationCache
                .GetOrCreate(cacheKey, () =>
                    {
                        using (DisposableTimer.Start(timer =>
                            LogHelper.TraceIfEnabled<DefaultRoutingEngine>("FindEntityByUrl for URL {0} took {1}ms", () => fullUrlIncludingDomain, () => timer)))
                        {
                            var persistenceManager = ApplicationContext.Hive.GetReader<IContentStore>(fullUrlIncludingDomain);
                            if (persistenceManager != null)
                            {
                                using (var uow = persistenceManager.CreateReadonly())
                                {
                                    //first, lets check if it's an ID URL
                                    var path = fullUrlIncludingDomain.AbsolutePath.Substring(
                                        _httpContext.Request.ApplicationPath.TrimEnd('/').Length,
                                        fullUrlIncludingDomain.AbsolutePath.Length - _httpContext.Request.ApplicationPath.TrimEnd('/').Length);
                                    var urlId = HiveId.TryParse(path.TrimStart('/'));
                                    if (urlId.Success && urlId.Result.ProviderGroupRoot != null)
                                    {
                                        LogHelper.TraceIfEnabled<DefaultRoutingEngine>("Resolving entity by Id URL (Id: {0} ", () => urlId.Result.ToFriendlyString());
                                        try
                                        {
                                            var entityById = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(urlId.Result, revisionStatusType);
                                            if (entityById == null)
                                            {
                                                LogHelper.Warn<DefaultRoutingEngine>("Resolving entity by Id URL failed (Id: {0} ", urlId.Result.ToFriendlyString());
                                                return null;
                                            }
                                            return new HttpRuntimeCacheParameters<EntityRouteResult>(
                                                   new EntityRouteResult(entityById.Item, EntityRouteStatus.SuccessById));
                                        }
                                        catch (ArgumentException)
                                        {
                                            //this occurs if the Id parsed but 'not really'
                                            return null;
                                        }
                                    }

                                    Revision<TypedEntity> lastRevisionFound;
                                    TypedEntity lastItemFound;
                                    //is the current requesting hostname/port in our list ?
                                    if (DomainList.ContainsHostname(fullUrlIncludingDomain.Authority))
                                    {
                                        //domain found so get the first item assigned to this domain
                                        LogHelper.TraceIfEnabled<DefaultRoutingEngine>("Resolving entity by Domain URL");
                                        var hostnameEntry = DomainList[fullUrlIncludingDomain.Authority];
                                        lastRevisionFound = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(hostnameEntry.ContentId, revisionStatusType);
                                        Mandate.That(lastRevisionFound != null, x => new InvalidOperationException("Could not find an entity with a revision status of '" + revisionStatusType.Alias + "', having a hostname '" + fullUrlIncludingDomain.Authority + "' and id: " + hostnameEntry.ContentId));
                                        lastItemFound = lastRevisionFound.Item;
                                    }
                                    else
                                    {
                                        //no domain found for the current request, so we need to find the first routable node that doesn't require a domain
                                        LogHelper.TraceIfEnabled<DefaultRoutingEngine>("Resolving entity by Non-Domain URL");
                                        //var root = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(FixedHiveIds.ContentVirtualRoot, revisionStatusType);
                                        //Mandate.That(root != null, x => new InvalidOperationException("Could not find the content root"));
                                        var domainListIds = DomainList.Select(d => d.ContentId);

                                        var firstLevelRelations =
                                            uow.Repositories.GetChildRelations(FixedHiveIds.ContentVirtualRoot, FixedRelationTypes.DefaultRelationType).OrderBy(
                                                x => x.Ordinal).ToArray();

                                        //try to find a first level node that doesn't exist in our domain list
                                        var firstNonHostnameEntity = firstLevelRelations.FirstOrDefault(x => !domainListIds.Contains(x.DestinationId));

                                        //if there is no first level node anywhere, then there is no content. Show a friendly message
                                        if (firstNonHostnameEntity == null && firstLevelRelations.Count() == 0)
                                            return null;

                                        //if we have a first level node not assigned to a domain, use the first, otherwise if all nodes are assigned to domains, then just use the first
                                        lastRevisionFound = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(
                                            firstNonHostnameEntity == null
                                                ? firstLevelRelations.First().DestinationId
                                                : firstNonHostnameEntity.DestinationId, revisionStatusType);

                                        lastItemFound = lastRevisionFound != null ? lastRevisionFound.Item : null;
                                    }


                                    // Now we will have the path from the current application root like:
                                    //      /this/is/a/path/to/a/document
                                    // Now we need to walk down the tree
                                    if (lastItemFound != null && !string.IsNullOrWhiteSpace(path) && path != "/")
                                        lastItemFound = uow.Repositories.GetEntityByPath<TypedEntity>(lastItemFound.Id, path, revisionStatusType, true);

                                    if(lastItemFound == null)
                                        return new HttpRuntimeCacheParameters<EntityRouteResult>(
                                                new EntityRouteResult(null, EntityRouteStatus.FailedNotFoundByName));

                                    return new HttpRuntimeCacheParameters<EntityRouteResult>(
                                        new EntityRouteResult(lastItemFound, EntityRouteStatus.SuccessWithoutHostname));
                                }
                            }

                            return null; 
                        }
                    });
        }
        /// <summary>
        /// Finds a TypedEntity based on the Uri
        /// </summary>
        /// <param name="fullUrlIncludingDomain"></param>
        /// <param name="revisionStatusType"></param>
        /// <returns></returns>
        public EntityRouteResult FindEntityByUrl(Uri fullUrlIncludingDomain, RevisionStatusType revisionStatusType = null)
        {
            Mandate.ParameterNotNull(fullUrlIncludingDomain.Scheme, "Scheme");

            var statusTypeCacheKey = (revisionStatusType != null) ? revisionStatusType.Alias : string.Empty;

            //cache key is full uri except query string and revision status
            var cacheKey = EntityMappedKey + "-" + fullUrlIncludingDomain.GetLeftPart(UriPartial.Path) + "-" + statusTypeCacheKey;

            //TODO: We need to change how the NiceUrls are cached because if we store them in one entry as a dictionary in cache, then
            // we can do a reverse lookup to see if we've already generated the URL for the entity which may match the fullUrlIncludingDomain,
            // if so, then all we have to do is return the entity with the cached ID.

            return ApplicationContext.FrameworkContext.ApplicationCache
                .GetOrCreate(cacheKey, () =>
                    {
                        using (DisposableTimer.Start(timer =>
                            LogHelper.TraceIfEnabled<DefaultRoutingEngine>("FindEntityByUrl (not from cache) for URL {0} took {1}ms", () => fullUrlIncludingDomain, () => timer)))
                        {
                            ReadonlyGroupUnitFactory<IContentStore> persistenceManager;

                            using (DisposableTimer.TraceDuration<DefaultRoutingEngine>("FindEntityByUrl: Getting a reader", "FindEntityByUrl: Got a reader"))
                                persistenceManager = ApplicationContext.Hive.GetReader<IContentStore>(fullUrlIncludingDomain);

                            if (persistenceManager != null)
                            {
                                IReadonlyGroupUnit<IContentStore> readonlyGroupUnit;
                                using (DisposableTimer.TraceDuration<DefaultRoutingEngine>("FindEntityByUrl: Opening a reader", "FindEntityByUrl: Opened a reader"))
                                    readonlyGroupUnit = persistenceManager.CreateReadonly();

                                using (var uow = readonlyGroupUnit)
                                {
                                    //first, lets check if it's an ID URL
                                    var trimmedAppPath = _httpContext.Request.ApplicationPath.TrimEnd('/');
                                    var appPathLength = trimmedAppPath.Length;

                                    // gate-check for the incoming url because some code (e.g. the alt-template checker) could be unaware of vdirs etc.
                                    var absolutePath = fullUrlIncludingDomain.AbsolutePath;
                                    var path = (absolutePath.Length < appPathLength) ? absolutePath : absolutePath.Substring(appPathLength, absolutePath.Length - appPathLength);

                                    var urlId = HiveId.TryParse(path.TrimStart('/'));
                                    if (urlId.Success && urlId.Result.ProviderGroupRoot != null)
                                    {
                                        LogHelper.TraceIfEnabled<DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Id URL (Id: {0} ", () => urlId.Result.ToFriendlyString());
                                        try
                                        {
                                            //var entityById = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(urlId.Result, revisionStatusType);
                                            var entityById = uow.Repositories.OfRevisionType(revisionStatusType).InIds(urlId.Result.AsEnumerableOfOne()).FirstOrDefault();
                                            if (entityById == null)
                                            {
                                                LogHelper.Warn<DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Id URL failed (Id: {0} ", urlId.Result.ToFriendlyString());
                                                return null;
                                            }
                                            return new HttpRuntimeCacheParameters<EntityRouteResult>(new EntityRouteResult(entityById, EntityRouteStatus.SuccessById));
                                        }
                                        catch (ArgumentException)
                                        {
                                            //this occurs if the Id parsed but 'not really'
                                            return null;
                                        }
                                    }

                                    TypedEntity lastItemFound;
                                    //is the current requesting hostname/port in our list ?
                                    if (DomainList.ContainsHostname(fullUrlIncludingDomain.Authority))
                                    {
                                        //domain found so get the first item assigned to this domain
                                        LogHelper.TraceIfEnabled<DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Domain URL {0}", () => fullUrlIncludingDomain.Authority);
                                        var hostnameEntry = DomainList[fullUrlIncludingDomain.Authority];
                                        //lastRevisionFound = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(hostnameEntry.ContentId, revisionStatusType);
                                        lastItemFound = uow.Repositories.OfRevisionType(revisionStatusType).InIds(hostnameEntry.ContentId.AsEnumerableOfOne()).FirstOrDefault();
                                        Mandate.That(lastItemFound != null, x => new InvalidOperationException("Could not find an entity with a revision status of '" + revisionStatusType.Alias + "', having a hostname '" + fullUrlIncludingDomain.Authority + "' and id: " + hostnameEntry.ContentId));
                                    }
                                    else
                                    {
                                        //no domain found for the current request, so we need to find the first routable node that doesn't require a domain
                                        LogHelper.TraceIfEnabled<DefaultRoutingEngine>("In FindEntityByUrl: Resolving entity by Non-Domain URL");
                                        //var root = uow.Repositories.Revisions.GetLatestRevision<TypedEntity>(FixedHiveIds.ContentVirtualRoot, revisionStatusType);
                                        //Mandate.That(root != null, x => new InvalidOperationException("Could not find the content root"));
                                        var domainListIds = DomainList.Select(d => d.ContentId).ToArray();

                                        var firstLevelRelations =
                                            uow.Repositories.GetChildRelations(FixedHiveIds.ContentVirtualRoot, FixedRelationTypes.DefaultRelationType).OrderBy(
                                                x => x.Ordinal).ToArray();

                                        //try to find a first level node that doesn't exist in our domain list
                                        var firstNonHostnameEntity = firstLevelRelations.FirstOrDefault(x => !domainListIds.Contains(x.DestinationId));

                                        // Issue #U5-112
                                        // If we have found no entities that are NOT assigned to a domain, given that we have already tried to find
                                        // content matching the current request's domain, we cannot route any content, therefore return null

                                        // Also return null if there is no content
                                        if (firstNonHostnameEntity == null || !firstLevelRelations.Any())
                                            return null;

                                        var idToUse = firstNonHostnameEntity.DestinationId;
                                        using (DisposableTimer.TraceDuration<DefaultRoutingEngine>("FindEntityByUrl: Querying for " + idToUse, "FindEntityByUrl: Query"))
                                            lastItemFound = uow.Repositories.OfRevisionType(revisionStatusType).InIds(idToUse.AsEnumerableOfOne()).FirstOrDefault();

                                        ////if there is no first level node anywhere, then there is no content. Show a friendly message
                                        //if (firstNonHostnameEntity == null && !firstLevelRelations.Any())
                                        //    return null;

                                        ////if we have a first level node not assigned to a domain, use the first, otherwise if all nodes are assigned to domains, then just use the first
                                        //var idToUse = firstNonHostnameEntity == null ? firstLevelRelations.First().DestinationId : firstNonHostnameEntity.DestinationId;
                                        //lastItemFound = uow.Repositories.OfRevisionType(revisionStatusType).InIds(idToUse.AsEnumerableOfOne()).FirstOrDefault();
                                    }


                                    // Now we will have the path from the current application root like:
                                    //      /this/is/a/path/to/a/document
                                    // Now we need to walk down the tree
                                    if (lastItemFound != null && !string.IsNullOrWhiteSpace(path) && path != "/")
                                    {
                                        using (DisposableTimer.TraceDuration<DefaultRoutingEngine>("FindEntityByUrl: Calling GetEntityByPath for " + lastItemFound.Id + " " + path, "FindEntityByUrl: GetEntityByPath"))
                                            lastItemFound = uow
                                                .Repositories
                                                .GetEntityByPath<TypedEntity>(lastItemFound.Id,
                                                                              path,
                                                                              revisionStatusType,
                                                                              true);
                                    }

                                    if (lastItemFound == null)
                                        return new HttpRuntimeCacheParameters<EntityRouteResult>(
                                                new EntityRouteResult(null, EntityRouteStatus.FailedNotFoundByName));

                                    return new HttpRuntimeCacheParameters<EntityRouteResult>(
                                        new EntityRouteResult(lastItemFound, EntityRouteStatus.SuccessWithoutHostname));
                                }
                            }

                            return null;
                        }
                    });
        }