internal static void SaveNodeData(Node node, NodeSaveSettings settings, out IndexDocumentData indexDocument) { indexDocument = null; var isNewNode = node.Id == 0; var data = node.Data; var deadlockCount = 0; var isDeadlock = false; while (deadlockCount++ < maxDeadlockIterations) { isDeadlock = !SaveNodeDataTransactional(node, settings, out indexDocument); if (!isDeadlock) { break; } Logger.WriteWarning("Deadlock detected in SaveNodeData", new Dictionary <string, object> { { "Id: ", node.Id }, { "Path: ", node.Path }, { "Version: ", node.Version } }); System.Threading.Thread.Sleep(sleepIfDeadlock); } if (isNewNode) { Logger.WriteVerbose("Node created.", CollectLoggerProperties, data); } else { Logger.WriteVerbose("Node updated.", CollectLoggerProperties, data); } }
public override void Save(NodeSaveSettings settings) { var thisUser = this.User; if (thisUser != null) // skip when importing { this.NodeCreatedBy = thisUser; this.NodeModifiedBy = thisUser; this.CreatedBy = thisUser; this.ModifiedBy = thisUser; } base.Save(settings); }
//================================================================================= Methods public override void Save(NodeSaveSettings settings) { var isNew = this.IsNew; bool import = RepositoryConfiguration.SpecialWorkingMode == "Import"; if (isNew && !import) { Name = GenerateName(); } base.Save(settings); if (isNew && !this.CopyInProgress && !import) SendMail(); }
internal static void SaveNodeData(Node node, NodeSaveSettings settings, IIndexPopulator populator, string originalPath, string newPath) { var isNewNode = node.Id == 0; var data = node.Data; var deadlockCount = 0; var isDeadlock = false; while (deadlockCount++ < maxDeadlockIterations) { var stopper = Stopwatch.StartNew(); isDeadlock = !SaveNodeDataTransactional(node, settings, populator, originalPath, newPath); Debug.WriteLine("<? SaveNodeDataTransactional: " + node.Path + ", " + stopper.Elapsed); stopper.Stop(); if (!isDeadlock) { break; } Logger.WriteWarning(Logger.EventId.NotDefined, "Deadlock detected in SaveNodeData", properties: new Dictionary <string, object> { { "Id: ", node.Id }, { "Path: ", node.Path }, { "Version: ", node.Version } }); System.Threading.Thread.Sleep(sleepIfDeadlock); } if (isNewNode) { Logger.WriteVerbose("Node created.", CollectLoggerProperties, data); } else { Logger.WriteVerbose("Node updated.", CollectLoggerProperties, data); } }
public override void Save(NodeSaveSettings settings) { AssertUserName(); base.Save(settings); }
//==================================================================================== Overrides public override void Save(NodeSaveSettings settings) { base.Save(settings); this.MoveToFolder(); }
// caller: Node.Save, Node.SaveCopied public object BeginPopulateNode(Node node, NodeSaveSettings settings, string originalPath, string newPath) { var populatorData = new DocumentPopulatorData { Node = node, Settings = settings, OriginalPath = originalPath, NewPath = newPath, NodeHead = settings.NodeHead, IsNewNode = node.Id == 0, }; return populatorData; }
private static bool SaveNodeDataTransactional(Node node, NodeSaveSettings settings, out IndexDocumentData indexDocument) { indexDocument = null; var data = node.Data; var isNewNode = data.Id == 0; var isLocalTransaction = !TransactionScope.IsActive; if (isLocalTransaction) TransactionScope.Begin(); try { data.CreateSnapshotData(); var participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); //-- here we re-create the node head to insert it into the cache and refresh the version info if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { //-- participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) indexDocument = SaveIndexDocument(node); } if (isLocalTransaction) TransactionScope.Commit(); } catch (System.Data.Common.DbException dbe) { if (isLocalTransaction && IsDeadlockException(dbe)) return false; throw SavingExceptionHelper(data, dbe); } catch (Exception e) { var ee = SavingExceptionHelper(data, e); if (ee == e) throw; else throw ee; } finally { if (isLocalTransaction && TransactionScope.IsActive) TransactionScope.Rollback(); } return true; }
internal static void SaveNodeData(Node node, NodeSaveSettings settings, out IndexDocumentData indexDocument) { indexDocument = null; var isNewNode = node.Id == 0; var data = node.Data; var deadlockCount = 0; var isDeadlock = false; while (deadlockCount++ < maxDeadlockIterations) { isDeadlock = !SaveNodeDataTransactional(node, settings, out indexDocument); if (!isDeadlock) break; Logger.WriteWarning("Deadlock detected in SaveNodeData", new Dictionary<string, object> { { "Id: ", node.Id }, { "Path: ", node.Path }, { "Version: ", node.Version } }); System.Threading.Thread.Sleep(sleepIfDeadlock); } if (isNewNode) Logger.WriteVerbose("Node created.", CollectLoggerProperties, data); else Logger.WriteVerbose("Node updated.", CollectLoggerProperties, data); }
public override void Save(NodeSaveSettings settings) { // Check uniqueness first CheckUniqueUser(); Domain = GenerateDomain(); var originalId = this.Id; // save current password to the list of old passwords this.SaveCurrentPassword(); base.Save(settings); // AD Sync SynchUser(originalId); // set creator for performant self permission setting // creator of the user will always be the user itself. this way setting permissions to the creators group on /Root/IMS will be adequate for user permissions // if you need the original creator, use the auditlog if (originalId == 0) { this.CreatedBy = this; this.NodeCreatedBy = this; base.SaveSameVersion(); } // create profiles if (originalId == 0 && Repository.UserProfilesEnabled) CreateProfile(); }
internal static void SaveNodeData(Node node, NodeSaveSettings settings, IIndexPopulator populator, string originalPath, string newPath) { var isNewNode = node.Id == 0; var isOwnerChanged = node.Data.IsPropertyChanged("OwnerId"); if (!isNewNode && isOwnerChanged) { node.Security.Assert(PermissionType.TakeOwnership); } var data = node.Data; var attempt = 0; using (var op = SnTrace.Database.StartOperation("SaveNodeData")) { while (true) { attempt++; var deadlockException = SaveNodeDataTransactional(node, settings, populator, originalPath, newPath); if (deadlockException == null) { break; } SnTrace.Database.Write("DEADLOCK detected. Attempt: {0}/{1}, NodeId:{2}, Version:{3}, Path:{4}", attempt, maxDeadlockIterations, node.Id, node.Version, node.Path); if (attempt >= maxDeadlockIterations) { throw new Exception(string.Format("Error saving node. Id: {0}, Path: {1}", node.Id, node.Path), deadlockException); } SnLog.WriteWarning("Deadlock detected in SaveNodeData", properties: new Dictionary <string, object> { { "Id: ", node.Id }, { "Path: ", node.Path }, { "Version: ", node.Version }, { "Attempt: ", attempt } }); System.Threading.Thread.Sleep(sleepIfDeadlock); } op.Successful = true; } try { if (isNewNode) { SecurityHandler.CreateSecurityEntity(node.Id, node.ParentId, node.OwnerId); } else if (isOwnerChanged) { SecurityHandler.ModifyEntityOwner(node.Id, node.OwnerId); } } catch (EntityNotFoundException e) { SnLog.WriteException(e, $"Error during creating or modifying security entity: {node.Id}. Original message: {e}", EventId.Security); } catch (SecurityStructureException) // suppressed { // no need to log this: somebody else already created or modified this security entity } if (isNewNode) { SnTrace.ContentOperation.Write("Node created. Id:{0}, Path:{1}", data.Id, data.Path); } else { SnTrace.ContentOperation.Write("Node updated. Id:{0}, Path:{1}", data.Id, data.Path); } }
private static bool SaveNodeDataTransactional(Node node, NodeSaveSettings settings, IIndexPopulator populator, string originalPath, string newPath) { IndexDocumentData indexDocument = null; bool hasBinary = false; var data = node.Data; var isNewNode = data.Id == 0; NodeDataParticipant participant = null; var isLocalTransaction = !TransactionScope.IsActive; if (isLocalTransaction) { TransactionScope.Begin(); } Logger.WriteVerbose("Transaction: " + TransactionScope.CurrentId + " SAVING " + node.Id + ", " + node.Path); try { //-- collect data for populator var populatorData = populator.BeginPopulateNode(node, settings, originalPath, newPath); data.CreateSnapshotData(); participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); //-- here we re-create the node head to insert it into the cache and refresh the version info); if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { //-- participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) { // Elevation: we need to create the index document with full // control to avoid field access errors (indexing must be independent // from the current users permissions). using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, true, out hasBinary); } } } if (isLocalTransaction) { TransactionScope.Commit(); } //-- populate using (new SystemAccount()) populator.CommitPopulateNode(populatorData, indexDocument); if (indexDocument != null && hasBinary) { using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, indexDocument); populator.FinalizeTextExtracting(populatorData, indexDocument); } } } catch (NodeIsOutOfDateException) { RemoveFromCache(participant); throw; } catch (System.Data.Common.DbException dbe) { Logger.WriteException(new Exception(string.Format("Error saving node. Id: {0}, Path: {1}", node.Id, node.Path), dbe)); if (isLocalTransaction && IsDeadlockException(dbe)) { return(false); } throw SavingExceptionHelper(data, dbe); } catch (Exception e) { Logger.WriteException(new Exception(string.Format("Error saving node. Id: {0}, Path: {1}", node.Id, node.Path), e)); var ee = SavingExceptionHelper(data, e); if (ee == e) { throw; } else { throw ee; } } finally { if (isLocalTransaction && TransactionScope.IsActive) { TransactionScope.Rollback(); } } return(true); }
public override void Save(NodeSaveSettings settings) { base.Save(settings); }
private static bool SaveNodeDataTransactional(Node node, NodeSaveSettings settings, out IndexDocumentData indexDocument) { indexDocument = null; var data = node.Data; var isNewNode = data.Id == 0; var isLocalTransaction = !TransactionScope.IsActive; if (isLocalTransaction) { TransactionScope.Begin(); } try { data.CreateSnapshotData(); var participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); //-- here we re-create the node head to insert it into the cache and refresh the version info if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { //-- participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) { indexDocument = SaveIndexDocument(node); } } if (isLocalTransaction) { TransactionScope.Commit(); } } catch (System.Data.Common.DbException dbe) { if (isLocalTransaction && IsDeadlockException(dbe)) { return(false); } throw SavingExceptionHelper(data, dbe); } catch (Exception e) { var ee = SavingExceptionHelper(data, e); if (ee == e) { throw; } else { throw ee; } } finally { if (isLocalTransaction && TransactionScope.IsActive) { TransactionScope.Rollback(); } } return(true); }
public override void Save(NodeSaveSettings settings) { AssertTimeSpan(); base.Save(settings); }
public override void Save(NodeSaveSettings settings) { // copy abortonrelatedcontentchange info from definition to instance var workflowDefinition = Node.Load<WorkflowDefinitionHandler>(GetWorkflowDefinitionPath()); if (workflowDefinition != null) this.AbortOnRelatedContentChange = workflowDefinition.AbortOnRelatedContentChange; base.Save(settings); }
public override void Save(NodeSaveSettings settings) { base.Save(settings); DeviceManager.Reset(); }
private static Exception SaveNodeDataTransactional(Node node, NodeSaveSettings settings, IIndexPopulator populator, string originalPath, string newPath) { IndexDocumentData indexDocument = null; bool hasBinary = false; var data = node.Data; var isNewNode = data.Id == 0; NodeDataParticipant participant = null; var msg = "Saving Node#" + node.Id + ", " + node.ParentPath + "/" + node.Name; var isLocalTransaction = !TransactionScope.IsActive; using (var op = SnTrace.Database.StartOperation(msg)) { if (isLocalTransaction) { TransactionScope.Begin(); } try { // collect data for populator var populatorData = populator.BeginPopulateNode(node, settings, originalPath, newPath); data.CreateSnapshotData(); participant = new NodeDataParticipant { Data = data, Settings = settings, IsNewNode = isNewNode }; TransactionScope.Participate(participant); if (settings.NodeHead != null) { settings.LastMajorVersionIdBefore = settings.NodeHead.LastMajorVersionId; settings.LastMinorVersionIdBefore = settings.NodeHead.LastMinorVersionId; } int lastMajorVersionId, lastMinorVersionId; DataProvider.Current.SaveNodeData(data, settings, out lastMajorVersionId, out lastMinorVersionId); settings.LastMajorVersionIdAfter = lastMajorVersionId; settings.LastMinorVersionIdAfter = lastMinorVersionId; // here we re-create the node head to insert it into the cache and refresh the version info); if (lastMajorVersionId > 0 || lastMinorVersionId > 0) { var head = NodeHead.CreateFromNode(node, lastMinorVersionId, lastMajorVersionId); if (MustCache(node.NodeType)) { // participate cache items var idKey = CreateNodeHeadIdCacheKey(head.Id); var participant2 = new InsertCacheParticipant { CacheKey = idKey }; TransactionScope.Participate(participant2); var pathKey = CreateNodeHeadPathCacheKey(head.Path); var participant3 = new InsertCacheParticipant { CacheKey = pathKey }; TransactionScope.Participate(participant3); CacheNodeHead(head, idKey, pathKey); } node.RefreshVersionInfo(head); if (!settings.DeletableVersionIds.Contains(node.VersionId)) { // Elevation: we need to create the index document with full // control to avoid field access errors (indexing must be independent // from the current users permissions). using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, true, isNewNode, out hasBinary); } } } if (isLocalTransaction) { TransactionScope.Commit(); } // populate index only if it is enabled on this content (e.g. preview images will be skipped) using (var op2 = SnTrace.Index.StartOperation("Indexing node")) { if (node.IsIndexingEnabled) { using (new SystemAccount()) populator.CommitPopulateNode(populatorData, indexDocument); } if (indexDocument != null && hasBinary) { using (new SystemAccount()) { indexDocument = SaveIndexDocument(node, indexDocument); populator.FinalizeTextExtracting(populatorData, indexDocument); } } op2.Successful = true; } } catch (NodeIsOutOfDateException) { RemoveFromCache(participant); throw; } catch (System.Data.Common.DbException dbe) { if (isLocalTransaction && IsDeadlockException(dbe)) { return(dbe); } throw SavingExceptionHelper(data, dbe); } catch (Exception e) { var ee = SavingExceptionHelper(data, e); if (ee == e) { throw; } else { throw ee; } } finally { if (isLocalTransaction && TransactionScope.IsActive) { TransactionScope.Rollback(); } } op.Successful = true; } return(null); }
public override void Save(NodeSaveSettings settings) { Security.Assert(PermissionType.ManageListsAndWorkspaces); base.Save(settings); }
//====================================================================== Helper methods private static void SavingAssert(NodeSaveSettings action, string currentversion, int currentVersionId, string expectedVersion, int expectedVersionId, int? lockerId, ICollection<int> deletableVersionIds) { Assert.IsTrue(action.CurrentVersion != null, String.Concat("action.CurrentVersion is null")); Assert.IsTrue(action.CurrentVersion.ToString() == currentversion, String.Concat("action.CurrentVersion is ", action.CurrentVersion, ". Expected: ", currentversion)); Assert.IsTrue(action.CurrentVersionId == currentVersionId, String.Concat("action.CurrentVersion is ", action.CurrentVersionId, ". Expected: ", currentVersionId)); Assert.IsTrue(action.ExpectedVersion != null, String.Concat("action.ExpectedVersion is null")); Assert.IsTrue(action.ExpectedVersion.ToString() == expectedVersion, String.Concat("action.CurrentVersion is ", action.ExpectedVersion, ". Expected: ", expectedVersion)); Assert.IsTrue(action.ExpectedVersionId == expectedVersionId, String.Concat("action.ExpectedVersionId is ", action.ExpectedVersionId, ". Expected: ", expectedVersionId)); Assert.IsTrue(action.LockerUserId == lockerId, String.Concat("action.LockerUserId is '", action.LockerUserId, "', Expected: ", lockerId)); Assert.IsTrue(action.DeletableVersionIds.Count == deletableVersionIds.Count, String.Concat("action..DeletableVersions.Count is ", action.DeletableVersionIds.Count, ". Expected: ", deletableVersionIds.Count)); foreach (var versionId in deletableVersionIds) { Assert.IsTrue(action.DeletableVersionIds.Contains(versionId), String.Concat("DeletableVersionIds does not contain ", versionId)); } }