/// <summary> /// Adds an <see cref="ExceptionLogEntry"/>. If the <see cref="ExceptionLogEntry"/> cannot be created, the error is logged to the log file instead. /// </summary> /// <param name="operationName"></param> /// <param name="e"></param> public static void Log(string operationName, Exception e) { try { // log the error to the database using (PersistenceScope scope = new PersistenceScope(PersistenceContextType.Update, PersistenceScopeOption.RequiresNew)) { // disable change-set auditing for this context ((IUpdateContext)PersistenceScope.CurrentContext).ChangeSetRecorder = null; DefaultExceptionRecorder recorder = new DefaultExceptionRecorder(); ExceptionLogEntry logEntry = recorder.CreateLogEntry(operationName, e); PersistenceScope.CurrentContext.Lock(logEntry, DirtyState.New); scope.Complete(); } } catch (Exception x) { // if we fail to properly log the exception, there is nothing we can do about it // just log a message to the log file Platform.Log(LogLevel.Error, x); // also log the original exception to the log file, since it did not get logged to the DB Platform.Log(LogLevel.Error, e); } }
protected sealed override bool ClaimItem(TItem item) { try { using (var scope = new PersistenceScope(PersistenceContextType.Update)) { var context = (IUpdateContext)PersistenceScope.CurrentContext; context.ChangeSetRecorder.OperationName = this.GetType().FullName; // need to lock the item in context, to allow loading of extended properties collection by subclass context.Lock(item); // mark item as being in process MarkItemClaimed(item); // complete the transaction scope.Complete(); } return(true); } catch (EntityVersionException) { // if we get a version exception, the item has already been claimed by another process // this is not an error return(false); } }
protected sealed override IList <TItem> GetNextBatch(int batchSize) { using (var scope = new PersistenceScope(PersistenceContextType.Read)) { var items = GetNextEntityBatch(batchSize); scope.Complete(); return(items); } }
public void RunApplication(string[] args) { SetupCommandLine cmdLine = new SetupCommandLine(); try { cmdLine.Parse(args); using (PersistenceScope scope = new PersistenceScope(PersistenceContextType.Update)) { ((IUpdateContext)PersistenceScope.CurrentContext).ChangeSetRecorder.OperationName = GetType().FullName; // import authority tokens AuthorityTokenImporter tokenImporter = new AuthorityTokenImporter(); IList<AuthorityToken> allTokens = tokenImporter.ImportFromPlugins((IUpdateContext)PersistenceScope.CurrentContext); // create the sys admin group, which has all tokens assigned by default string[] tokenStrings = CollectionUtils.Map<AuthorityToken, string, List<string>>(allTokens, t => t.Name).ToArray(); AuthorityGroupDefinition adminGroupDef = new AuthorityGroupDefinition(cmdLine.SysAdminGroup, cmdLine.SysAdminGroup, false, tokenStrings); AuthorityGroupImporter groupImporter = new AuthorityGroupImporter(); IList<AuthorityGroup> groups = groupImporter.Import(new AuthorityGroupDefinition[] { adminGroupDef }, (IUpdateContext)PersistenceScope.CurrentContext); // find the admin group entity that was just created AuthorityGroup adminGroup = CollectionUtils.SelectFirst(groups, g => g.Name == cmdLine.SysAdminGroup); // create the "sa" user CreateSysAdminUser(adminGroup, cmdLine, PersistenceScope.CurrentContext, Console.Out); // optionally import other default authority groups defined in other plugins if (cmdLine.ImportDefaultAuthorityGroups) { groupImporter.ImportFromPlugins((IUpdateContext) PersistenceScope.CurrentContext); } scope.Complete(); } } catch (CommandLineException e) { Console.WriteLine(e.Message); cmdLine.PrintUsage(Console.Out); } }
protected sealed override void ProcessItem(TItem item) { Exception error = null; using (var scope = new PersistenceScope(PersistenceContextType.Update)) { var context = (IUpdateContext)PersistenceScope.CurrentContext; context.ChangeSetRecorder.OperationName = this.GetType().FullName; // need to lock the item in context, to allow loading of extended properties collection by subclass context.Lock(item); try { // take action based on item ActOnItem(item); // ensure that the commit will ultimately succeed context.SynchState(); // success callback OnItemSucceeded(item); // complete the transaction scope.Complete(); } catch (Exception e) { // one of the actions failed Platform.Log(LogLevel.Error, e); error = e; } } // exceptions thrown upon exiting the using block above are intentionally not caught here, // allow them to be caught by the calling method // post-processing if (error == null) { AfterCommit(item); } else { UpdateItemOnError(item, error); } }
public void RunApplication(string[] args) { var cmdLine = new SetupCommandLine(); try { cmdLine.Parse(args); using (var scope = new PersistenceScope(PersistenceContextType.Update)) { ((IUpdateContext)PersistenceScope.CurrentContext).ChangeSetRecorder.OperationName = GetType().FullName; // import authority tokens var tokenImporter = new AuthorityTokenImporter(); var allTokens = tokenImporter.ImportFromPlugins((IUpdateContext)PersistenceScope.CurrentContext); var tokenStrings = CollectionUtils.Map<AuthorityToken, string, List<string>>(allTokens, t => t.Name).ToArray(); // import built-in groups var builtInAuthorityGroups = new[] { GetSysAdminGroupDefinition(tokenStrings), BuiltInAuthorityGroups.SystemAccounts }; var groupImporter = new AuthorityGroupImporter(); var groups = groupImporter.Import(builtInAuthorityGroups, (IUpdateContext)PersistenceScope.CurrentContext); // create the "sa" user var adminGroup = CollectionUtils.SelectFirst(groups, g => g.Name == BuiltInAuthorityGroups.Administrators.Name); CreateSysAdminUser(adminGroup, cmdLine, PersistenceScope.CurrentContext, Console.Out); // optionally import other default authority groups defined in other plugins if (cmdLine.ImportDefaultAuthorityGroups) { groupImporter.ImportFromPlugins((IUpdateContext)PersistenceScope.CurrentContext); } scope.Complete(); } } catch (CommandLineException e) { Console.WriteLine(e.Message); cmdLine.PrintUsage(Console.Out); } }
private void UpdateItemOnError(TItem item, Exception error) { // use a new scope to mark the item as failed, because we don't want to commit any changes made in the outer scope using (var scope = new PersistenceScope(PersistenceContextType.Update, PersistenceScopeOption.RequiresNew)) { var failContext = (IUpdateContext)PersistenceScope.CurrentContext; failContext.ChangeSetRecorder.OperationName = this.GetType().FullName; // bug #7191 : Reload the TItem in this scope; using the existing item results in NHibernate throwing a lazy loading exception var itemForThisScope = failContext.Load <TItem>(item.GetRef(), EntityLoadFlags.None); // lock item into this context failContext.Lock(itemForThisScope); // failure callback OnItemFailed(itemForThisScope, error); // complete the transaction scope.Complete(); } }
/// <summary> /// Disposes of this scope. /// </summary> /// <remarks> /// If this scope is associated with an update context and is the owner of that context, /// then disposal will commit or rollback the changes made in the update context, depending /// on whether this scope was marked Completed. If <see cref="Complete"/> was called on this scope, /// then disposal will attempt to commit the update context, otherwise it will simply dispose it, /// which is effectively a rollback. /// </remarks> public void Dispose() { if (!_disposed) { _disposed = true; if (this != _head) { throw new InvalidOperationException("Disposed out of order."); } try { if (OwnsContext) { CloseContext(); } else { // if the vote is still "undecided", treat it as an abort if (_vote == Vote.Undecided) { _vote = Vote.Abort; // we have an inherited context, so we need to propagate "aborts" up to the parent _parent._vote = Vote.Abort; } } } finally { // if CloseContext fails, we are still disposing of this scope, so we set the head // to point to the parent _head = _parent; } } }
public void RunApplication(string[] args) { using (var scope = new PersistenceScope(PersistenceContextType.Update)) { ((IUpdateContext)PersistenceScope.CurrentContext).ChangeSetRecorder.OperationName = this.GetType().FullName; ImportFromPlugins((IUpdateContext)PersistenceScope.CurrentContext); scope.Complete(); } }
/// <summary> /// Creates a new persistence scope for the specified context. The scope assumes ownership of the context /// and closes it when the scope terminates. /// </summary> /// <param name="context"></param> public PersistenceScope(IPersistenceContext context) { _context = context; _parent = _head; _head = this; }
internal static SystemIdentityStore Load() { if (_store != null) return _store; lock (_syncroot) { if (_store == null) { const string userName = "******"; var serializer = new XmlSerializer(typeof (SystemIdentityStore)); var documentName = typeof (SystemIdentityStore).FullName; var versionString = VersionUtils.ToPaddedVersionString(new Version(0, 0), false, false); var criteria = new ConfigurationDocumentSearchCriteria(); criteria.User.EqualTo(userName); criteria.DocumentName.EqualTo(documentName); criteria.DocumentVersionString.EqualTo(versionString); SystemIdentityStore store = null; using (var scope = new PersistenceScope(PersistenceContextType.Read)) { var broker = scope.Context.GetBroker<IConfigurationDocumentBroker>(); var document = broker.Find(criteria).FirstOrDefault(); if (document != null) { try { using (var reader = new StringReader(document.Body.DocumentText)) store = (SystemIdentityStore) serializer.Deserialize(reader); } catch (Exception) { store = null; } } scope.Complete(); } if (store == null || store.SecretKey == null || store.SecretKey.Length == 0) { if (store == null) store = new SystemIdentityStore(); store.SecretKey = new byte[128]; using (var crng = new RNGCryptoServiceProvider()) crng.GetBytes(store.SecretKey); using (var scope = new PersistenceScope(PersistenceContextType.Update)) using (var writer = new StringWriter()) { serializer.Serialize(writer, store); var broker = scope.Context.GetBroker<IConfigurationDocumentBroker>(); var document = broker.Find(criteria).FirstOrDefault(); if (document != null) { document.Body.DocumentText = writer.ToString(); } else { document = new ConfigurationDocument(documentName, versionString, userName, null); document.Body.DocumentText = writer.ToString(); scope.Context.Lock(document, DirtyState.New); } scope.Complete(); } } Interlocked.Exchange(ref _store, store); } return _store; } }
private static void DryRunHelper(bool dryRun, Action<object> action) { if (dryRun) { // create a new persistence scope, so that we do not use the scope inherited by the service using (var scope = new PersistenceScope(PersistenceContextType.Update, PersistenceScopeOption.RequiresNew)) { action(null); // try to synch state to see if DB will accept changes scope.Context.SynchState(); //note: do not call scope.Complete() under any circumstances - we want this transaction to rollback } } else { // just do the action in the usual scope action(null); } }
/// <summary> /// Disposes of this scope. /// </summary> /// <remarks> /// If this scope is associated with an update context and is the owner of that context, /// then disposal will commit or rollback the changes made in the update context, depending /// on whether this scope was marked Completed. If <see cref="Complete"/> was called on this scope, /// then disposal will attempt to commit the update context, otherwise it will simply dispose it, /// which is effectively a rollback. /// </remarks> public void Dispose() { if (!_disposed) { _disposed = true; if (this != _head) throw new InvalidOperationException("Disposed out of order."); try { if (OwnsContext) { CloseContext(); } else { // if the vote is still "undecided", treat it as an abort if (_vote == Vote.Undecided) { _vote = Vote.Abort; // we have an inherited context, so we need to propagate "aborts" up to the parent _parent._vote = Vote.Abort; } } } finally { // if CloseContext fails, we are still disposing of this scope, so we set the head // to point to the parent _head = _parent; } } }