/// <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; }
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); }
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)); }
public RevisionData(RevisionStatusType revisionStatusType) : this() { StatusType = revisionStatusType; }
public RevisionData(Changeset changeset, RevisionStatusType revisionStatusType) { Changeset = changeset; StatusType = revisionStatusType; }
public RevisionData(HiveId revisionId, RevisionStatusType revisionStatusType) : this(revisionStatusType) { Id = revisionId; }
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; } }); }