public CommandResult Execute(ICommandInfo commandInfo) { var saveInfo = (SaveEntityCommandInfo)commandInfo; if (saveInfo.Entity == null) { throw new ClientException("Invalid SaveEntityCommand argument: Entity is not set."); } // We need to check delete permissions before actually deleting items // and update items before AND after they are updated. var genericRepository = _genericRepositories.GetGenericRepository(saveInfo.Entity); var updateDeleteItems = ConcatenateNullable(saveInfo.DataToDelete, saveInfo.DataToUpdate); if (updateDeleteItems != null) { if (!_serverCommandsUtility.CheckAllItemsWithinFilter(updateDeleteItems, RowPermissionsWriteInfo.FilterName, genericRepository)) { _persistenceTransaction.DiscardChanges(); Guid?missingId; if (_serverCommandsUtility.MissingItemId(saveInfo.DataToDelete, genericRepository, out missingId)) { throw new ClientException($"Deleting a record that does not exist in database. DataStructure={saveInfo.Entity}, ID={missingId}"); } else if (_serverCommandsUtility.MissingItemId(saveInfo.DataToUpdate, genericRepository, out missingId)) { throw new ClientException($"Updating a record that does not exist in database. DataStructure={saveInfo.Entity}, ID={missingId}"); } else { throw new UserException("You are not authorized to write some or all of the provided data. Insufficient permissions to modify the existing data.", "DataStructure:" + saveInfo.Entity + "."); } } } genericRepository.Save(saveInfo.DataToInsert, saveInfo.DataToUpdate, saveInfo.DataToDelete, true); var insertUpdateItems = ConcatenateNullable(saveInfo.DataToInsert, saveInfo.DataToUpdate); // We rely that this call will only use IDs of the items, because other data might be dirty. if (insertUpdateItems != null) { if (!_serverCommandsUtility.CheckAllItemsWithinFilter(insertUpdateItems, RowPermissionsWriteInfo.FilterName, genericRepository)) { _persistenceTransaction.DiscardChanges(); throw new UserException("You are not authorized to write some or all of the provided data. Insufficient permissions to apply the new data.", "DataStructure:" + saveInfo.Entity + "."); } } return(new CommandResult { Message = "Command executed", Success = true }); }
public ProcessingResult ExecuteInner(IList <ICommandInfo> commands) { var authorizationMessage = _authorizationManager.Authorize(commands); if (!String.IsNullOrEmpty(authorizationMessage)) { return new ProcessingResult { UserMessage = authorizationMessage, SystemMessage = authorizationMessage, Success = false } } ; var commandResults = new List <CommandResult>(); try { foreach (var commandInfo in commands) { _logger.Trace("Executing command {0}: {1}.", commandInfo.GetType().Name, commandInfo); var implementations = _commandRepository.GetImplementations(commandInfo.GetType()); if (implementations.Count() == 0) { throw new FrameworkException(string.Format(CultureInfo.InvariantCulture, "Cannot execute command \"{0}\". There are no command implementations loaded that implement the command.", commandInfo)); } if (implementations.Count() > 1) { throw new FrameworkException(string.Format(CultureInfo.InvariantCulture, "Cannot execute command \"{0}\". It has more than one implementation registered: {1}.", commandInfo, String.Join(", ", implementations.Select(i => i.GetType().Name)))); } var commandImplementation = implementations.Single(); _logger.Trace("Executing implementation {0}.", commandImplementation.GetType().Name); var commandObserversForThisCommand = _commandObservers.GetImplementations(commandInfo.GetType()); var stopwatch = Stopwatch.StartNew(); foreach (var commandObeserver in commandObserversForThisCommand) { commandObeserver.BeforeExecute(commandInfo); _performanceLogger.Write(stopwatch, () => "ProcessingEngine: CommandObeserver.BeforeExecute " + commandObeserver.GetType().FullName); } var commandResult = commandImplementation.Execute(commandInfo); _performanceLogger.Write(stopwatch, () => "ProcessingEngine: Command executed (" + commandInfo.GetType().FullName + ")."); _logger.Trace("Execution result message: {0}", commandResult.Message); if (commandResult.Success) { foreach (var commandObeserver in commandObserversForThisCommand) { commandObeserver.AfterExecute(commandInfo, commandResult); _performanceLogger.Write(stopwatch, () => "ProcessingEngine: CommandObeserver.AfterExecute " + commandObeserver.GetType().FullName); } } commandResults.Add(commandResult); if (!commandResult.Success) { _persistenceTransaction.DiscardChanges(); var systemMessage = String.Format(CultureInfo.InvariantCulture, "Command failed. {0} {1} {2}", commandInfo.GetType().Name, commandInfo, commandImplementation.GetType().Name); return(LogAndReturnError(commandResults, systemMessage + " " + commandResult.Message, systemMessage, commandResult.Message)); } } return(new ProcessingResult { CommandResults = commandResults.ToArray(), Success = true, SystemMessage = null }); } catch (Exception ex) { _persistenceTransaction.DiscardChanges(); if (ex is TargetInvocationException && ex.InnerException is RhetosException) { _logger.Trace(() => "Unwrapping exception: " + ex.ToString()); ex = ex.InnerException; } string userMessage = null; string systemMessage = null; var sqlException = SqlUtility.InterpretSqlException(ex); if (sqlException != null) { ex = sqlException; } if (ex is UserException) { userMessage = ex.Message; systemMessage = (ex as UserException).SystemMessage; } else if (ex is ClientException) { userMessage = _clientExceptionUserMessage; systemMessage = ex.Message; } else { userMessage = null; systemMessage = "Internal server error occurred (" + ex.GetType().Name + "). See RhetosServer.log for more information."; } return(LogAndReturnError( commandResults, "Command execution error: ", systemMessage, userMessage, ex)); } }
public ProcessingResult ExecuteInner(IList <ICommandInfo> commands, Guid executionId) { var authorizationMessage = _authorizationManager.Authorize(commands); if (!string.IsNullOrEmpty(authorizationMessage)) { return new ProcessingResult { UserMessage = authorizationMessage, SystemMessage = authorizationMessage, Success = false } } ; var commandResults = new List <CommandResult>(); var stopwatch = Stopwatch.StartNew(); foreach (var commandInfo in commands) { try { _logger.Trace("Executing command {0}.", commandInfo); var implementations = _commandRepository.GetImplementations(commandInfo.GetType()); if (implementations.Count() == 0) { throw new FrameworkException(string.Format(CultureInfo.InvariantCulture, "Cannot execute command \"{0}\". There are no command implementations loaded that implement the command.", commandInfo)); } if (implementations.Count() > 1) { throw new FrameworkException(string.Format(CultureInfo.InvariantCulture, "Cannot execute command \"{0}\". It has more than one implementation registered: {1}.", commandInfo, String.Join(", ", implementations.Select(i => i.GetType().Name)))); } var commandImplementation = implementations.Single(); _logger.Trace("Executing implementation {0}.", commandImplementation.GetType().Name); var commandObserversForThisCommand = _commandObservers.GetImplementations(commandInfo.GetType()); stopwatch.Restart(); foreach (var commandObeserver in commandObserversForThisCommand) { commandObeserver.BeforeExecute(commandInfo); _performanceLogger.Write(stopwatch, () => "ProcessingEngine: CommandObeserver.BeforeExecute " + commandObeserver.GetType().FullName); } CommandResult commandResult; try { commandResult = commandImplementation.Execute(commandInfo); } finally { _performanceLogger.Write(stopwatch, () => "ProcessingEngine: Command executed (" + commandImplementation + ": " + commandInfo + ")."); } _logger.Trace("Execution result message: {0}", commandResult.Message); if (commandResult.Success) { foreach (var commandObeserver in commandObserversForThisCommand) { commandObeserver.AfterExecute(commandInfo, commandResult); _performanceLogger.Write(stopwatch, () => "ProcessingEngine: CommandObeserver.AfterExecute " + commandObeserver.GetType().FullName); } } commandResults.Add(commandResult); if (!commandResult.Success) { _persistenceTransaction.DiscardChanges(); var systemMessage = "Command failed: " + commandImplementation + ", " + commandInfo + "."; return(LogAndReturnError(commandResults, systemMessage + " " + commandResult.Message, systemMessage, commandResult.Message, null, commands, executionId)); } } catch (Exception ex) { _persistenceTransaction.DiscardChanges(); if (ex is TargetInvocationException && ex.InnerException is RhetosException) { _logger.Trace(() => "Unwrapping exception: " + ex.ToString()); ex = ex.InnerException; } string userMessage = null; string systemMessage = null; ex = _sqlUtility.InterpretSqlException(ex) ?? ex; if (ex is UserException) { var userException = (UserException)ex; userMessage = _localizer[userException.Message, userException.MessageParameters]; // TODO: Remove this code after cleaning the double layer of exceptions in the server response call stack. systemMessage = userException.SystemMessage; } else if (ex is ClientException) { userMessage = _clientExceptionUserMessage; systemMessage = ex.Message; } else { userMessage = null; systemMessage = FrameworkException.GetInternalServerErrorMessage(_localizer, ex); } return(LogAndReturnError(commandResults, "Command failed: " + commandInfo + ".", systemMessage, userMessage, ex, commands, executionId)); } } return(new ProcessingResult { CommandResults = commandResults.ToArray(), Success = true, SystemMessage = null }); }